Capistrano,防火墙和隧道

我们正在使用Capistrano自动将新版本的PHP应用程序推送到生产服务器。 生产服务器(我们称之为生产)是公共的,而我们的存储库服务器(我们称之为repo)与我们自己的机器一起位于我们的公司防火墙后面。

默认配置的Capistrano将无法工作,因为生产无法与回购交谈。

我想知道是否有某种程度上我可以将capistrano设置为SSH以首先进行回购,然后通过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 

这是实现它的两种方法。

第一种方式

不确定你是否看过这个post?

它使用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问题时概述:

  • 是否有可能让Capistrano通过反向SSH隧道进行结账?

这种技术与第一种方式非常相似。 首先,您需要创建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问题的答案:

使用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自述文件的隧道和其他相关SSH主题部分