【问题标题】:Run ssh-keygen in Ruby to generate VCS deploy keys?在 Ruby 中运行 ssh-keygen 以生成 VCS 部署密钥?
【发布时间】:2022-01-23 23:46:12
【问题描述】:

我运行这个命令为我的私有仓库生成有效的部署密钥:

ssh-keygen -b 2048 -t rsa -C "mystring"

该命令提示我输入路径和密码(我将其留空),并生成文件。

mykey:

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
...
-----END OPENSSH PRIVATE KEY-----

还有一个mykey.pub

ssh-rsa AAAAB3NzaC1yc...QDBQl mystring

但是如何在纯 Ruby 中运行此命令并以字符串形式获取结果?

我试过了:

keypair = OpenSSL::PKey::RSA.new 2048
keypair.to_pem
keypair.public_key.to_s

但生成的文件与我使用ssh-keygen 获得的文件不同。

谁知道怎么做?

附:我找到了sshkey gem,但还没有尝试过,因为我宁愿避免为此使用 gem。

【问题讨论】:

  • 尤其是在生成长期密钥(例如 SSH 私钥)时,您应该完全依赖简单、经过验证且稳定的工具,例如 ssh-keygen 命令行工具。使用加密密钥生成时,如果您对系统的所有部分(包括随机数生成器和加密原语等底层库(甚至那时))没有深入了解,则很难避免很多可能的问题。因此,您通常不应自行重新实现此功能,而应使用现有的经过审查且安全的工具。

标签: ruby ssh-keys openssh ssh-keygen deploy-keys


【解决方案1】:

使用内核调用 OpenSSH 实用程序

这是我认为应该直接移植到 Ruby 的事情之一。虽然 OpenSSH 二进制文件和源代码会定期进行审核,但很少使用或很少使用的 Ruby gem 或 FFI 包装器不会得到相同级别的审查。相反,您应该使用Kernel#systemKernel#` 调用或%x() 子shell 文字,具体取决于您的用例。

从 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。这是否适合您的需求或是否已针对您的用例进行充分审核取决于您。但是,其他不想自己推出或调用外部实用程序的访问者应该了解此解决方案,并且可能还有其他访问者。同样,您的里程可能会有所不同。

【讨论】:

    猜你喜欢
    • 2020-08-06
    • 2021-09-10
    • 2022-09-30
    • 2013-09-02
    • 2016-09-15
    • 2011-07-13
    • 2019-07-02
    • 1970-01-01
    • 2018-09-08
    相关资源
    最近更新 更多