如何在ruby中创建ssh隧道,然后连接到远程主机上的mysql服务器

我想创建一个ruby脚本,我可以通过ssh隧道在远程服务器上运行mysql命令。

现在我有一个手动过程来执行此操作:

  1. 创建隧道 – > ssh -L 3307:127.0.0.1:3306
  2. 运行ruby脚本。
  3. 关闭隧道。

我希望能够自动执行此操作,以便我可以运行脚本。

例:

require 'rubygems' require 'net/ssh/gateway' require 'mysql' #make the ssh connection -> I don't think I am doing this right. Net::SSH.start('server','user') do |session| session.forward.local(3307,'127.0.0.1', 3306)
mysql = Mysql.connect("127.0.0.1","root","","",3307) dbs = mysql.list_dbs
dbs.each do |db|
puts db
end session.loop(0){true}
end

更新 – 2010-11-10:
我真的很接近这个代码:

 require 'rubygems' require 'mysql' require 'net/ssh/gateway' gateway = Net::SSH::Gateway.new("host","user",{:verbose => :debug}) port = gateway.open("127.0.0.1",3306,3307) # mysql = Mysql.connect("127.0.0.1","user","password","mysql",3307) # puts "here" # mysql.close sleep(10) gateway.close(port) 

当它hibernate时,我能够打开终端窗口并连接到远程主机上的mysql。 这将validation隧道是否已创建并正常工作。

现在的问题是当我取消注释3行时,它只是挂起。

我能够使用mysql2 gem在没有fork的情况下使用它

 require 'rubygems' require 'mysql2' require 'net/ssh/gateway' gateway = Net::SSH::Gateway.new( 'remotehost.com', 'username' ) port = gateway.open('127.0.0.1', 3306, 3307) client = Mysql2::Client.new( host: "127.0.0.1", username: 'dbuser', password: 'dbpass', database: 'dbname', port: port ) results = client.query("SELECT * FROM projects") results.each do |row| p row end client.close 

这可能是一种可能的解决方案:

 require 'rubygems' require 'mysql' require 'net/ssh/gateway' gateway = Net::SSH::Gateway.new("server","user") port = gateway.open("127.0.0.1",3306,3307) child = fork do mysql = Mysql.connect("127.0.0.1","user","password","mysql",port) sql = "select sleep(5)" mysql.query(sql) mysql.close exit end puts "child: #{child}" Process.wait gateway.close(port) 

也许有更好的方法,但这适用于我试图做的事情。

我一直在尝试上面的网关代码,一个主要的区别是我必须使用ssh密钥进行无密码访问,但也发现代码交给Mysql.connect语句。 但是,当我更换

 mysql = Mysql.connect("127.0.0.1",...) 

 mysql = Mysql.connect("localhost",...) 

它工作得很好。

我的最终代码如下所示:

 require 'rubygems' require 'mysql' require 'net/ssh/gateway' gateway = Net::SSH::Gateway.new('host', 'user', :keys => ['myprivatekey.pem'], :verbose => :debug) port = gateway.open("127.0.0.1",3306,3307) mysql = Mysql.connect("localhost","dbuser","dbpassword","dbname",3307) puts "here" mysql.close gateway.close(port) gateway.shutdown! 

通常,当隧道将本地端口绑定到远程应用程序端口时,您只需连接到本地端口,就像它是远程端口一样。 请记住,MySQL具有基于连接源位置的访问策略,因此您可能需要牢记这一点。 在我看来,没有session.forward.local nessessary。

当然,你仍然不会说MySQL连接协议,所以这可能不是你想要的。 删除任何要运行到文件中的查询可能更容易,然后运行mysql -u“user”-p“password”

你也可以尝试这个漂亮的rubygem: https : //github.com/progrium/localtunnel