由于安全配置,我绝对不能改变,我必须在我的所有盒子ssh一个联邦用户,myuser
。
我需要部署的盒子上的所有东西都归deployuser
所有,我绝对不能改变它。
myuser
可以假设用户deployuser
并拥有所有sudo权限。
最终,我希望我的Capistrano部署功能就好像我从一开始就以deployuser
的形式进行操作,因此每个命令都以deployuser
和/home/deployuser
运行。
我可以使用我想要的任何版本的Capistrano,但是现在我正在尝试使用Capistrano 3。
我创建了一个简单的Capistrano任务来测试我是否可以对我知道由deployuser
拥有的文件执行操作。
desc "Check that we can access everything"
task :check_permissions do
on roles(:all) do |host|
execute("whoami")
execute("cp /tmp/file-owned-by-deploy-user /tmp/test-file")
end
end
编辑:上面的测试实际上并没有像人们预期的那样工作。我相信这是因为当你手动声明像execute('command')
这样的东西时,它会覆盖任何说“以X用户身份做这件事”的配置。更好的测试是运行你的cap environment deploy
任务,看看失败了什么。
我尝试的第一件事是sshkit-backends-netssh_global,在他们的文档中说他们正好处理这个用例。
我将其添加到我的Capfile中,然后尝试将其添加到deploy.rb
,然后甚至高于我的任务定义以防万一:
require 'sshkit/backends/netssh_global'
SSHKit::Backend::NetsshGlobal.configure do |config|
config.owner = 'deployuser'
config.directory = '/home/deployuser'
end
这无论如何都有效果。没有新的错误消息,只有相同的权限被拒绝,而whoami返回myuser。
其次,我试图设置卡兹斯特拉诺的:ssh_backend
,我在this issue for sshkit-backends-netssh_global看到:
require 'sshkit/backends/netssh_global'
set :sshkit_backend, -> {
SSHKit::Backend::NetsshGlobal.tap do |backend|
backend.configure do |config|
config.owner = 'deployuser'
config.directory = '/home/deployuser'
end
end
}
这表明sshkit-backends-netssh_global
不再与最新版本的Capistrano兼容。它使用了一种弃用的方法checkout
。太讨厌了:
NoMethodError: undefined method `checkout' for #<SSHKit::Backend::ConnectionPool:0x007fae8340e3c0>
我尝试降级到较低版本的Capistrano,虽然这修复了弃用问题,但它并没有神奇地使这些配置设置生效。虽然我没有深入挖掘。
我觉得我在这里疯了,因为当我尝试按照SSHKit documentation将我的任务包装为'用户'时,whoami
以deployuser
运行,而cp命令仍然返回Permission Denied。
所以也许我的测试脚本没有做我认为它正在做的事情。仍然可以将此命令复制/粘贴到服务器上,并通过附加sudo -u deployuser
来运行。
在我上面的编辑中,我说这是因为我认为做一个execute('command')
有点不同,并没有考虑你的配置 - 它只是执行的东西。我认为。所以这可能仍适用于其他类型的任务(当然不是内部的Capistrano任务)。
desc "Check that we can access everything"
task :check_permissions do
on roles(:all) do
as 'deployuser' do
# this returns deployuser
execute("whoami")
# this throws permission denied
execute("cp /tmp/file-owned-by-deploy-user /tmp/test-file")
end
end
end
我尝试的另一种策略,与上面的例子相同,是:
SSHKit.config.command_map = Hash.new do |hash, command|
hash[command] = "sudo -u deployuser #{command}"
end
whoami
返回deployuser
,但cp
命令仍然返回Permission Denied。同样,这可能是因为execute
实际上并不是我需要在这里测试的。
有没有人得到这个工作?有任何想法吗?
我一整天都在努力,这就是我到目前为止所做的......而且这很糟糕,但我得到了一个基本的部署工作。
首先,虽然你大部分都希望将sudo -u deployuser
附加到命令,但对于所有命令都不是这样。我最初在这里有几个人,但我把它归结为chmod
不能作为我的deployuser
运行
SSHKit.config.command_map = Hash.new do |hash, command|
skipped_commands = [:chmod]
if skipped_commands.include?(command)
hash[command] = command
else
hash[command] = "sudo -u deployuser #{command}"
end
end
好吧那么我意识到这对所有Capistrano案件都不适用,因为这些>>
被插入Capistrano方面的几个rake任务中。
所以我为这两个任务写了一个猴子补丁:
namespace:deploy do
# MONKEY PATCH OH NO
# =======================
# you actually have to clear the old rake task
# for yours to overwrite Capistrano's
Rake::Task['deploy:set_current_revision'].clear
desc "IT'S MINE"
task :set_current_revision do
on release_roles(:all) do
within release_path do
execute :echo, "\"$(sudo -u deployuser git rev-parse HEAD)\" | sudo -u deployuser tee REVISION"
end
end
end
Rake::Task['deploy:log_revision'].clear
desc "Log details of the depl
task :log_revision do
on release_roles(:all) do
within releases_path do
execute :echo, %Q{"#{revision_log_message}" | sudo -u deployuser tee #{revision_log}}
end
end
end
end
正在进行调查(我仍然需要实施部署的其余部分),但是在这些变化之后,现在正在完成一个简单的cap test_environment deploy
。
另外,这是我未来发现的人的捆绑包:
Gems included by the bundle:
* activesupport (4.2.10)
* airbrussh (1.3.0)
* aws-partitions (1.56.0)
* aws-sdk-core (3.14.0)
* aws-sdk-ec2 (1.25.0)
* aws-sigv4 (1.0.2)
* bundler (1.16.0)
* capistrano (3.10.1)
* capistrano-bundler (1.3.0)
* capistrano-rails (1.3.1)
* coderay (1.1.2)
* concurrent-ruby (1.0.5)
* dogapi (1.28.0)
* faraday (0.14.0)
* i18n (0.9.3)
* jmespath (1.3.1)
* json (1.8.6)
* method_source (0.9.0)
* minitest (5.11.1)
* multi_json (1.13.1)
* multipart-post (2.0.0)
* net-scp (1.2.1)
* net-ssh (4.2.0)
* pry (0.11.3)
* rake (12.3.0)
* slackbot (0.0.2)
* sshkit (1.15.1)
* sshkit-backends-netssh_global (0.1.1)
* thread_safe (0.3.6)
* tzinfo (1.2.4)
昨天原始插件posted this patch的作者在Capistrano 3.10中为我工作,没有任何猴子补丁。
我不是capistrano用户,但是您可以使用OpenSSH功能来实现此目的。假设:
myuser
authorized_keys
文件)如果假设为真,则每个远程系统上的myuser
都有一个.ssh / authorized_keys文件,其中包含capistrano用于进行身份验证的公钥。您可以向该行添加一个指令,该指令强制ssh服务器在使用该密钥时运行硬编码命令,而不是远程客户端请求的命令。这允许您为请求的命令插入自己的处理程序。
处理程序可以是一个简单的shell脚本。这是未经测试但你应该明白:
#!/bin/sh
sudo -u deployuser $SSH_ORIGINAL_COMMAND
将其存储在远程系统上的文件中,使其可执行,并将其设置为在authorized_keys文件中运行的命令。当ssh服务器代表远程客户端调用此命令时,它会将SSH_ORIGINAL_COMMAND
环境变量设置为远程客户端请求的命令字符串。
authorized_keys文件描述为here。基本上,文件的每一行都指定了一个可用于进行身份验证的密钥。一行看起来像这样:
ssh-rsa AAAAB3NzaC1yc2EAA...
你可以在行前加一个command=指令:
command=/home/myuser/run-as-deployuser ssh-rsa AAAAB3NzaC1yc2EAA...
当此密钥用于身份验证时,ssh服务器将调用请求的命令,而不是调用客户端请求的任何命令。正如我之前所说,SSH_ORIGINAL_COMMAND环境变量将被设置为客户端请求的命令。