4

我们正在使用 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
4

2 回答 2

2

这里有 2 种方法来完成它。

第一种方式

不确定你是否看过这个帖子?

它利用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 question 的回答中概述:

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

于 2013-01-20T05:56:23.973 回答
0

使用 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 主题部分

于 2015-07-23T13:09:31.113 回答