Capistrano、防火墙和隧道
Posted
技术标签:
【中文标题】Capistrano、防火墙和隧道【英文标题】:Capistrano, Firewalls and Tunnel 【发布时间】:2012-12-26 01:46:40 【问题描述】:我们正在使用 Capistrano 自动将 php 应用程序的新版本推送到生产服务器。生产服务器(我们称之为生产)是公共的,而我们的存储库服务器(我们称之为 repo)与我们自己的机器一起位于我们公司的防火墙后面。
默认配置的 Capistrano 无法工作,因为生产无法与 repo 通信。
我想知道是否有某种方法可以先将 capistrano 设置为 SSH 以进行 repo,然后 SSH 到生产在端口上打开一个隧道,然后我可以使用 SSH 从生产返回 repo 以从 SCM 中提取更改。
我只是不知道如何设置或找出更好的解决方案。想法?
编辑:
我试过了:
role :web, "deploy.com"
namespace :deploy do
task :remote_tunnel do
run 'Creating SSH tunnel...' do |channel, stream, data|
ssh = channel.connection
ssh.forward.remote(22, 'server.com', 10000, '127.0.0.1')
ssh.loop !ssh.forward.active_remotes.include?([10000, '127.0.0.1'])
end
end
end
before "deploy:update_code", "deploy:remote_tunnel"
但我不断收到此错误:
failed: "sh -c 'Creating SSH tunnel...'" on deploy.com
【问题讨论】:
看来您需要使用 SSH 设置远程端口转发 debianadmin.com/… 是的,但是如何在 Capistrano 脚本中做到这一点?它似乎忽略了我的本地 .ssh/config... Is it possible to do have Capistrano do a checkout over a reverse SSH tunnel?的可能重复 【参考方案1】:这里有两种方法来完成它。
第一种方式
不确定你是否看过这个帖子?
https://groups.google.com/forum/?fromgroups=#!topic/capistrano/RVwMim-qnMg它使用net-ssh-gateway
库,但会创建本地转发方法的副本,但它们适合远程访问。
class Net::SSH::Gateway
# Opens a SSH tunnel from a port on a remote host to a given host and port
# on the local side
# (equivalent to openssh -R parameter)
def open_remote(port, host, remote_port, remote_host = "127.0.0.1")
ensure_open!
@session_mutex.synchronize do
@session.forward.remote(port, host, remote_port, remote_host)
end
if block_given?
begin
yield [remote_port, remote_host]
ensure
close_remote(remote_port, remote_host)
end
else
return [remote_port, remote_host]
end
rescue Errno::EADDRINUSE
retry
end
# Cancels port-forwarding over an open port that was previously opened via
# open_remote.
def close_remote(port, host = "127.0.0.1")
ensure_open!
@session_mutex.synchronize do
@session.forward.cancel_remote(port, host)
end
end
end
第二种方式
在对这个 SO 问题的回答中概述:
Is it possible to do have Capistrano do a checkout over a reverse SSH tunnel?这种技术与第一种方式非常相似。首先,您需要创建 2 个存储库路径:
# deploy.rb
set :local_repository, "ssh://git@serverbehindfirewall/path/to/project.git"
set :repository, "ssh://git@localhost:9000/path/to/project.git"
然后在部署之前,您需要设置远程转发:
% ssh -R 9000:serverbehindfirewall:22 deploybot@deployserver.com
# CTRL + C + A (Screen) or ⌘ + T (Terminal.app) to open new tab
随后是您的部署:
% cap HOSTFILTER=deployserver.com deploy # HOSTFILTER reduces set to specified host. Only useful if you have multiple servers.
有关更多详细信息,请参阅该 SO 问题的答案:
https://***.com/a/3953351/33204【讨论】:
谢谢,这帮助我到达那里。【参考方案2】:使用 Capistrano 3.x,以下对我有用:
namespace :deploy do
desc "Open SSH Tunnel to GitLab"
task :open_tunnel do
on roles(:app) do
info "Opening SSH Remote Tunnel..."
self.send(:with_ssh) do |ssh|
# ssh -R 9000:192.168.1.123:22
ssh.forward.remote(22, "192.168.1.123", 9000)
end
end
end
before "deploy:check", "deploy:open_tunnel"
end
请注意ssh.forward.remote
期望的参数顺序与ssh -R
不同,上面等价于ssh -R 9000:192.168.1.123:22
这个任务调用了一个私有方法,如果有人知道官方获取Capistrano的ssh连接的方法,请评论或编辑。
编辑:另见 SSHKit 的 README 的 Tunneling and other related SSH themes 部分
【讨论】:
以上是关于Capistrano、防火墙和隧道的主要内容,如果未能解决你的问题,请参考以下文章