使用内核调用 OpenSSH 实用程序
这是我认为不应该直接移植到 Ruby 的事情之一。虽然 OpenSSH 二进制文件和源代码会定期进行审核,但很少使用或很少使用的 Ruby gem 或 FFI 包装器不会得到相同级别的审查。相反,您应该使用Kernel#system或Kernel#`调用或%x()
subshell 文字,具体取决于您的用例。
从 Ruby 内部调用外部 SSH 实用程序
例如:
# Note that 3072 is currently the default size for RSA keys in
# OpenSSH. Also note that you can pass `-f path/to/keyfile` or
# `-P ""` for an empty passphrase if you don't use the `-A` flag.
system %(ssh-keygen -A -b 2048 -t rsa -C "mystring")
如果没有该-f
标志,您的 RSA 密钥将被放入~/.ssh/id_rsa
和~/.ssh/id_rsa.pub
. 如果你真的需要,你可以使用标准的 Ruby 方法来读取文件,尽管我想不出你需要这样做的很多原因。
例如,要将您的公钥读入 Ruby 变量:
public_key = File.read "#{ENV['HOME']/.ssh/id_rsa.pub"
使用 SSH 代理
请注意,如果您已经在一个正在运行的程序中,那么最大的挑战将是使用您的 SSH 代理(如果您正在使用),因为此时环境变量和密钥材料不太可能可用。但是,如果您愿意,您可以在当前会话中启动代理并加载您的密钥文件。例如:
ssh_agent = %x(eval 'ssh-agent -s')
# assumes a passwordless key
system("ssh-add") && %x(ssh-add -l)
# Your agent's SSH_AUTH_SOCK is now exported by your current Ruby
# environment.
ENV['SSH_AUTH_SOCK']
# For some reason, SSH_AGENT_PID isn't exported properly. This may be
# user error on my part. Luckily, you can easily parse it out of the
# *ssh_agent* variable if needed.
ENV['SSH_AGENT_PID'] =
ssh_agent.match(/SSH_AGENT_PID=\d+/).to_s.split(?=).last
安全说明
如果您在 macOS 或安装了钥匙串的 Linux 系统上运行,则最好使用存储在登录钥匙串中的密码或在启动 ssh-agent 时提示输入的密码。无密码密钥有其一席之地,但在大多数现代系统上也有更安全的选项,这些选项同样易于管理。YMMV 基于您的确切用例。
也可以看看
有一个net-ssh gem也包含ssh-agent support。这是否适合您的需求或是否已针对您的用例进行充分审核取决于您。但是,其他不想自行推出或调用外部实用程序的访问者应该了解此解决方案,并且可能还有其他访问者。同样,您的里程可能会有所不同。