Liz*_*rtz 5 ssh capistrano ruby-on-rails capistrano3
由于我绝对无法更改安全配置,因此我必须以联合用户 ssh 方式连接到我的所有设备myuser。
我的盒子上需要部署的所有东西都归我所有deployuser,我绝对无法改变这一点。
myuser可以假设用户deployuser并拥有所有 sudo 权限。
最终,我希望我的 Capistrano 部署能够像我deployuser从一开始就 ssh 一样运行,因此每个命令都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
Run Code Online (Sandbox Code Playgroud)
编辑:上面的测试实际上并没有像人们预期的那样工作。我相信这是因为当您手动声明类似的内容时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
Run Code Online (Sandbox Code Playgroud)
这无论如何都是0效果。没有新的错误消息,只是同样的 Permission Denied,并且 whoami 返回 myuser。
其次,我尝试:ssh_backend从 Capistrano 进行设置,我在本期中看到了 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
}
Run Code Online (Sandbox Code Playgroud)
这表明它sshkit-backends-netssh_global不再与最新版本的 Capistrano 兼容。它使用的是已弃用的方法checkout。太讨厌了:
NoMethodError: undefined method `checkout' for #<SSHKit::Backend::ConnectionPool:0x007fae8340e3c0>
Run Code Online (Sandbox Code Playgroud)
我尝试降级到较低版本的 Capistrano,虽然解决了弃用问题,但它并没有神奇地使这些配置设置生效。不过我并没有挖得太深。
我有点觉得我在这里要疯了,因为当我尝试按照SSHKit 文档将我的任务包装为“用户”时,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
Run Code Online (Sandbox Code Playgroud)
我尝试的另一种策略,其结果与上面的示例相同:
SSHKit.config.command_map = Hash.new do |hash, command|
hash[command] = "sudo -u deployuser #{command}"
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
好吧,然后我意识到这并不适用于所有 Capistrano 案例,因为这些案例>>被插入到 Capistrano 端的几个 rake 任务中。
所以我为这两个任务编写了一个猴子补丁:
命名空间:部署做
# 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
Run Code Online (Sandbox Code Playgroud)
调查正在进行中(我仍然需要实现部署的其余部分),但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)
Run Code Online (Sandbox Code Playgroud)
原始插件的作者昨天发布了这个补丁,它在 Capistrano 3.10 中适用于我,无需任何猴子补丁。
我不是 capistrano 用户,但您可以使用 OpenSSH 功能来实现此目的。假设:
myuser authorized_keys文件)如果假设成立,则myuser每个远程系统上都有一个.ssh/authorized_keys文件,其中包含 capistrano 用于进行身份验证的公钥。您可以向该行添加一条指令,强制 ssh 服务器在使用该密钥时运行硬编码命令,而不是远程客户端请求的命令。这允许您为请求的命令插入自己的处理程序。
处理程序可以是一个简单的 shell 脚本。这尚未经过测试,但您应该明白:
#!/bin/sh
sudo -u deployuser $SSH_ORIGINAL_COMMAND
Run Code Online (Sandbox Code Playgroud)
将其存储在远程系统上的文件中,使其可执行,并将其设置为在authorized_keys文件中运行的命令。当 ssh 服务器代表远程客户端调用此命令时,它将SSH_ORIGINAL_COMMAND环境变量设置为远程客户端请求的命令字符串。
此处描述了authorized_keys文件。基本上,文件的每一行都指定一个可用于身份验证的密钥。一行看起来像这样:
ssh-rsa AAAAB3NzaC1yc2EAA...
Run Code Online (Sandbox Code Playgroud)
您可以在该行前面添加一个command=指令:
command=/home/myuser/run-as-deployuser ssh-rsa AAAAB3NzaC1yc2EAA...
Run Code Online (Sandbox Code Playgroud)
当使用此密钥进行身份验证时,ssh 服务器将调用请求的命令,而不是调用客户端请求的任何命令。正如我之前所说,SSH_ORIGINAL_COMMAND 环境变量将设置为客户端请求的命令。
| 归档时间: |
|
| 查看次数: |
742 次 |
| 最近记录: |