简体   繁体   English

使用Net :: SSH gem的Ruby SSH MySQL Sequel(或DataMapper)与密钥的远程连接

[英]Ruby SSH MySQL Sequel (or DataMapper) remote connection with keys using Net::SSH gem

How would I connect to my VPS based MySQL database remotely (from a cloud based app) using the Ruby Net::SSH or Net::SSH::Gateway gems and key, not password, authentication? 如何使用Ruby Net :: SSHNet :: SSH :: Gateway gem和密钥(而不是密码)远程连接(基于云的应用程序)基于VPS的MySQL数据库?

And then connect to the database with Sequel or DataMapper. 然后使用Sequel或DataMapper连接到数据库。 I'm assuming that after I manage to get the SSH connection working, I would just setup a Sequel/DM connection to 'sql_user@localhost:3306/database'. 我假设在设法使SSH连接正常工作之后,我将仅建立与'sql_user @ localhost:3306 / database'的Sequel / DM连接。

I did locate a couple of similar question here, but they all use password authentication, not keys, and only demonstrate executing raw commands to query the database. 我在这里确实找到了几个类似的问题,但是它们都使用密码认证,而不是密钥,并且仅演示执行原始命令来查询数据库。

UPDATE: I just cannot seem to get this (Net::SSH with key manager) to work. 更新:我似乎无法使此(带有密钥管理器的Net :: SSH)正常工作。

UPDATE2: Alright I have managed to get authorization when logging in from a computer that has authorized keys stored in the users local .ssh folder, with the following (port is my custom SQL port on the VPS): UPDATE2:好了,当我从具有授权密钥存储在用户本地.ssh文件夹中的计算机上登录时,已经设法获得了授权(端口是我在VPS上的自定义SQL端口):

 sql_gate = Net::SSH::Gateway.new('192.xxx.xxx.xx','sqluser', port: 26000)

However, I will not be able to create a .ssh folder in the app's VM, so I need to somehow pass the path and filename (I will be creating a public key just for SQL access for specified user) as an option ... but haven't been able to figure out how. 但是,我将无法在应用程序的VM中创建.ssh文件夹,因此我需要以某种方式传递路径和文件名(我将为指定用户的SQL访问创建公共密钥)作为选项。但还没办法弄清楚。

UPDATE: Just need to figure out DataMapper access now. 更新:现在只需要弄清楚DataMapper的访问即可。 Current code being tested ( remote_user_sql is my Ubuntu user, sql_user is the MySQL database user with localhost/127.0.0.1 privileges): 当前正在测试的代码( remote_user_sql是我的Ubuntu用户, sql_user是具有localhost/127.0.0.1特权的MySQL数据库用户):

require 'net/ssh/gateway'
require 'data_mapper'
require 'dm-mysql-adapter'

class User
  include DataMapp......
  .
  .
end

ssh_gate = Net::SSH::Gateway.new('192.n.n.n','remote_user_sql', {port: 25000, keys: ["sql_rsa"], keys_only: true})

port = ssh_gate.open('localhost',3306,3307)
  child = fork do
    DataMapper.setup(:default, {
      adapter: 'mysql',
      database: 'sql_test',
      username: 'sql_user',
      password: 'passwd',
      host: 'localhost',
      port: port})
    DataMapper.auto_upgrade!
    exit
  end
  puts "child: #{child}"
  Process.wait

ssh_gate.close(port)

My solution, in two parts: 我的解决方案分为两部分:

Well I have figured how to make the Net::SSH::Gateway gem using a specified keyfile, and then connect to the VPS through ssh via a port other than 22: 好了,我想出了如何使用指定的密钥文件制作Net :: SSH :: Gateway gem,然后通过ssh通过22以外的端口连接到VPS:

Part 1: Net::SSH::Gateway key authentication 第1部分:Net :: SSH :: Gateway密钥认证

First you must generate the keyfiles you want to use, copy the .pub to the remove server and append it to the ~/.ssh/authorized_keys file ( cat sql_rsa.pub >> authorized_keys ), and then make sure user_sql (the user I created on the VPS to be used only for this purpose) has been added to AllowUsers list in sshd_config . 首先,您必须生成要使用的cat sql_rsa.pub >> authorized_keys文件,将.pub复制到删除服务器,然后将其附加到~/.ssh/authorized_keys文件( cat sql_rsa.pub >> authorized_keys ),然后确保user_sql (用户I在VPS创建仅用于这一目的)已被添加到使用AllowUsers列表中sshd_config Make note of port used for ssh (25000 for this example) and use the following code to establish the connection: 记下用于ssh的端口(此示例为25000),并使用以下代码建立连接:

ssh_gate = Net::SSH::Gateway.new('192.n.n.n','user_sql', {port: 25000, keys: ["sql_rsa"], keys_only: true})

That will read the keyfile sql_rsa in the same directory as script file, then create a new ssh gateway for 'user_sql'@'192.nnn' on port 25000. 这将在与脚本文件相同的目录中读取密钥文件sql_rsa ,然后在端口25000上为'user_sql'@'192.nnn'创建一个新的ssh网关。

I can successfully execute raw shell commands on the remove VPS with: 我可以使用以下命令在删除的VPS上成功执行原始shell命令:

ssh_gate.exec("ls -la")

To close: 关闭:

ssh_gate.shutdown!

Unfortunately I am still having problems using DataMapper (do-mysql-adapter) to use the gateway. 不幸的是,我在使用DataMapper(do-mysql-adapter)来使用网关时仍然遇到问题。 I will update this answer if I figure that part out, but at least the first half of the problem has been solved. 如果我想出一部分,我将更新此答案,但至少问题的前半部分已解决。

These are the errors that DataMapper::Logger has reported: 这些是DataMapper :: Logger报告的错误:

When 127.0.0.1 was used: 使用127.0.0.1时:

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) (code: 2002, sql state: HY000, query: , uri: )

When localhost was used: 使用localhost时:

Access denied for user 'user_sql'@'localhost' (using password: YES) (code: 1045, sql state: 28000, query: , uri: )

When the VPS hostname was used: 使用VPS hostname时:

Unknown MySQL server host 'hostname' (25) (code: 2005, sql state: HY000, query: , uri: )

UPDATE (No success yet): So far the only way I can access the remote MySQL database is by using Net::SSH::Gateway to establish a gateway, and then use the .ssh method to open a new Net::SSH connection over that gateway, like so: 更新(尚未成功):到目前为止,我访问远程MySQL数据库的唯一方法是使用Net :: SSH :: Gateway建立网关,然后使用.ssh方法打开新的Net :: SSH连接通过该网关,如下所示:

ssh_gate.ssh('192.n.n.n','user_sql',{port: 25000, keys: ["sql_rsa"], keys_only: true}) do |ssh|
    ssh.exec("mysql -u sql_user -p'passwd' -h localhost -P 3306 -e 'SELECT DATABASE();'")
end

In other words, I can only execute SQL commands using the mysql command line. 换句话说,我只能使用mysql命令行执行SQL命令。 I cannot figure out how to get Sequel or DataMapper to use the gateway to connect. 我无法弄清楚如何使Sequel或DataMapper使用网关进行连接。

Part 2: DataMapper/Sequel/mysql2 connection through Net::SSH::Gateway 第2部分:通过Net :: SSH :: Gateway的DataMapper / Sequel / mysql2连接

Make sure your MySQL server is bound to 127.0.0.1 in /etc/mysql/my.cnf , setup your connection - DataMapper example: 请确保你的MySQL服务器绑定到127.0.0.1在/etc/mysql/my.cnf ,设置你的连接- DataMapper的例子:

DataMapper.setup(:default, {
  adapter: 'mysql',
  database: 'DATABASE',
  username: 'username',
  password: 'passwd',
  host: '127.0.0.1',
  port: 3307}) # local port being forwarded via Net::SSH:Gateway

Followed by any class table definitions and DataMapper.finalize if required. 如果需要,后跟任何class表定义和DataMapper.finalize Note that DataMapper doesn't actually connect to the remote MySQL server until either an auto_upgrade! 注意,DataMapper直到auto_upgrade才真正连接到远程MySQL服务器auto_upgrade! , auto_migrate! ,自动auto_migrate! , or query is executed, so no need to create the forwarded port yet. 或执行查询,因此无需创建转发的端口。

Then create a new Net::SSH::Gateway, and then whenever you need DataMapper/Sequel to access the remote database, just open a port for the process, like so: 然后创建一个新的Net :: SSH :: Gateway,然后每当需要DataMapper / Sequel访问远程数据库时,只需为该进程打开一个端口即可,如下所示:

port = ssh_gate.open('127.0.0.1',3306,3307)
  child = fork do
    DataMapper.auto_upgrade! # DM call that accesses MySQL server
    exit
  end
  Process.wait
ssh_gate.close(port)

You may want to put the Net::SSH::Gateway/.open code in a begin..ensure..end block, ensure 'ing the port closure and gateway shutdown. 您可能需要将Net :: SSH :: Gateway / .open代码放在begin..ensure..end块中, ensure关闭端口并关闭网关。

I had to use a fork and Process.wait to establish the connection, without it the method just hangs. 我不得不使用forkProcess.wait来建立连接,没有它,该方法只会挂起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM