Linux系统下SSH密钥的生成与管理

在Linux环境中,安全地访问远程服务器或进行版本控制操作,SSH(Secure Shell)密钥是不可或缺的工具。它提供了一种比传统密码登录更安全、更便捷的认证方式。本篇文章将围绕SSH密钥的生成、使用与管理,详细解答您可能遇到的各种疑问。

SSH密钥到底是什么?它由哪几部分组成?

SSH密钥是一种加密认证机制,它通过非对称加密算法实现身份验证。简单来说,它由一对数学上关联但又彼此独立的密钥组成:

  1. 私钥 (Private Key):这是您自己保管的、绝对不能泄露的密钥文件。它相当于您的数字身份证明,必须妥善保管在本地机器上。
  2. 公钥 (Public Key):这是可以公开的密钥文件。您需要将它部署到您希望无密码登录的远程服务器上。当您尝试连接时,远程服务器会使用公钥来验证您的私钥。

当您尝试使用SSH连接时,客户端会使用您的私钥对会话信息进行签名,远程服务器则会使用预先部署的公钥来验证这个签名。如果验证成功,即认为您是合法的用户,允许您登录,而无需输入密码。

为什么推荐使用SSH密钥而不是密码登录?

推荐使用SSH密钥而非传统密码登录,主要基于以下几个核心原因:

  • 更高的安全性

    • 防暴力破解:密码可能被字典攻击或暴力破解。SSH密钥通常有非常长的位数(例如2048位或4096位),通过穷举法来破解私钥在计算上几乎是不可能的。
    • 无网络传输明文:密码登录时,虽然数据会被加密传输,但密码本身在客户端输入后,仍然有被键盘记录器等恶意软件截获的风险。SSH密钥认证过程中,私钥本身从不离开您的本地机器。
    • 减少人为错误:强密码很难记忆,用户可能因此设置弱密码或在多个地方重复使用密码,增加了风险。密钥则无需记忆,且每个服务可以配置独立的密钥对。
  • 更便捷的体验

    • 免密码登录:一旦设置好,您无需每次都输入密码,大大提升了工作效率。
    • 自动化脚本:SSH密钥认证非常适合自动化脚本,例如持续集成/持续部署(CI/CD)流程,无需在脚本中嵌入明文密码。

SSH密钥默认存放在哪里?公钥需要放置在哪里?

本地密钥存放位置

在Linux系统中,当您生成SSH密钥时,默认情况下它们会被存放在您的用户主目录下的一个隐藏目录中:

~/.ssh/

这个目录下通常会包含以下文件:

  • 私钥文件:通常名为 id_rsaid_ecdsaid_ed25519 等,具体取决于密钥类型。这个文件绝不能分享给任何人,并且其权限必须严格设置为只有所有者可读写(通常是600)。
  • 公钥文件:与私钥文件同名,但带有 .pub 后缀,例如 id_rsa.pub。这个文件是公开的,可以分发给您需要访问的远程服务器。
  • known_hosts:记录您连接过的远程主机的公钥指纹,用于验证远程主机的身份,防止中间人攻击。
  • config (可选):SSH客户端配置文件,用于为不同的主机设置特定的连接参数。

远程公钥部署位置

要实现对远程服务器的免密登录,您需要将您的公钥文件(例如 id_rsa.pub 的内容)添加到远程服务器上对应用户的 ~/.ssh/authorized_keys 文件中。

例如,如果您想以用户 remoteuser 的身份登录远程服务器 remote_host,则需要将您的公钥内容添加到 remote_host 上的 /home/remoteuser/.ssh/authorized_keys 文件中。这个文件的权限也应该被严格限制,通常是600

SSH密钥的长度(位数)通常是多少?推荐的密钥长度是多少?

SSH密钥的长度,或者说“位数”,指的是加密算法中密钥的强度。位数越高,理论上安全性越强,但生成和使用所需的计算资源也会相应增加。

  • RSA密钥

    • 早期常见长度:1024位。
    • 当前推荐长度:2048位。对于大多数场景,2048位RSA密钥提供了足够的安全性。
    • 更高安全性:3072位4096位。如果您对安全性有极高的要求,可以选择这些长度。
  • ECDSA密钥

    • 椭圆曲线数字签名算法,提供与RSA相同安全强度下更小的密钥尺寸和更快的性能。
    • 常见曲线长度:256位、384位、521位。推荐使用256位或384位
  • Ed25519密钥

    • 一种基于Edwards曲线的数字签名算法,由Daniel J. Bernstein等人设计。
    • 优点:相对较短的密钥长度(通常固定为256位),但提供了与2048位甚至4096位RSA相等的安全性,且生成和验证速度非常快,抗攻击性强。
    • 当前推荐:强烈推荐使用Ed25519密钥,因为它在安全性、性能和密钥长度方面取得了极佳的平衡。

总结: 对于新生成的密钥,Ed25519是首选。如果您的SSH客户端或服务器不支持Ed25519,则退而求其次选择RSA 4096位或至少RSA 2048位

如何在Linux中生成SSH密钥?

生成SSH密钥的核心命令是 ssh-keygen。以下是几种常见的生成方式及其参数解释。

1. 默认生成(RSA 2048位,无密码保护)

这是最简单的生成方式。它会生成一个2048位的RSA密钥,并且不设置密码保护(passphrase)。

ssh-keygen

执行后,系统会提示您:

  • Enter file in which to save the key (~/.ssh/id_rsa):
    这是私钥和公钥的保存路径和文件名。默认是 ~/.ssh/id_rsa。您可以直接按回车键使用默认值,或者输入新的路径和文件名。

  • Enter passphrase (empty for no passphrase):
    这是为您的私钥设置的密码保护。密码保护进一步增强了安全性,即使私钥文件泄露,没有密码也无法使用。强烈建议设置一个强大的密码保护。如果您不想设置,直接按回车键。

  • Enter same passphrase again:
    确认密码保护。

生成成功后,您会在 ~/.ssh/ 目录下看到 id_rsa(私钥)和 id_rsa.pub(公钥)两个文件。

2. 指定密钥类型和长度(推荐Ed25519或RSA 4096位)

为了获得更好的安全性或性能,您可以明确指定密钥的类型和长度。

  • 生成Ed25519密钥(推荐)

    ssh-keygen -t ed25519 -C "[email protected]"

    参数解释:

    • -t ed25519:指定密钥类型为Ed25519。
    • -C "[email protected]":为密钥添加一个注释。这个注释不会影响密钥的功能,但有助于您识别密钥的用途,特别是在拥有多个密钥时。通常使用您的邮箱地址或用途描述。

    与默认生成一样,系统会提示您设置保存路径和密码保护。

  • 生成RSA 4096位密钥

    ssh-keygen -t rsa -b 4096 -C "[email protected]"

    参数解释:

    • -t rsa:指定密钥类型为RSA。
    • -b 4096:指定密钥长度为4096位。
    • -C "[email protected]":添加注释。

3. 指定密钥的保存路径和文件名

如果您不希望密钥保存在默认位置,或者需要生成多对密钥用于不同的目的,可以使用 -f 参数指定文件名和路径。

ssh-keygen -t ed25519 -f ~/.ssh/my_new_key -C "Key for Specific Project"

这将在 ~/.ssh/ 目录下创建 my_new_keymy_new_key.pub 文件。

4. 仅修改私钥的密码保护

如果您已经有一个私钥,但想修改其密码保护,可以使用 -p 参数:

ssh-keygen -p -f ~/.ssh/id_rsa

系统会提示您输入旧密码保护,然后输入两次新密码保护。

如何查看生成的公钥内容?

生成密钥后,您需要将公钥内容复制到远程服务器上。您可以直接使用 cat 命令查看公钥文件的内容:

cat ~/.ssh/id_ed25519.pub

输出会是一长串字符,通常以 ssh-ed25519ssh-rsa 开头,以您设置的注释结尾。

如何将公钥复制到远程服务器?

1. 使用 ssh-copy-id(推荐且最便捷)

这是将公钥部署到远程服务器的最简单和最安全的方法。它会自动检查并设置正确的目录和文件权限。

ssh-copy-id username@remote_host

如果您使用了非默认的私钥名称,需要通过 -i 参数指定公钥文件:

ssh-copy-id -i ~/.ssh/my_new_key.pub username@remote_host

执行此命令后,系统会提示您输入远程服务器上 username 的密码。输入正确密码后,您的公钥就会被添加到远程服务器的 ~/.ssh/authorized_keys 文件中。

2. 手动复制

如果 ssh-copy-id 不可用或您希望手动操作,可以执行以下步骤:

  1. 在本地机器上复制公钥内容:

    cat ~/.ssh/id_ed25519.pub

    将输出的完整内容复制到剪贴板。

  2. 登录到远程服务器(使用密码):

    ssh username@remote_host

    输入远程服务器密码。

  3. 在远程服务器上创建或修改 ~/.ssh/authorized_keys 文件:

    首先,确保 ~/.ssh 目录存在并且权限正确(700)。

    mkdir -p ~/.ssh
    chmod 700 ~/.ssh

    然后,将公钥内容追加到 authorized_keys 文件中。注意:使用 >> 是追加,使用 > 是覆盖,请务必使用 >> 以免覆盖已有密钥。

    echo "粘贴您复制的公钥内容" >> ~/.ssh/authorized_keys

    或者,您可以使用文本编辑器手动粘贴:

    nano ~/.ssh/authorized_keys

    粘贴公钥内容,保存并退出。

  4. 设置 authorized_keys 文件的正确权限:

    chmod 600 ~/.ssh/authorized_keys

    如果权限设置不正确,SSH服务器会拒绝使用该文件进行认证。

  5. (可选)在远程服务器上确保SSH服务允许公钥认证:

    编辑SSH服务器配置文件 /etc/ssh/sshd_config

    sudo nano /etc/ssh/sshd_config

    确认以下行已启用或不存在 #

    PubkeyAuthentication yes
    AuthorizedKeysFile .ssh/authorized_keys

    修改后,重启SSH服务:

    sudo systemctl restart sshd (对于Systemd系统)
    sudo service ssh restart (对于Upstart/SysVinit系统)

如何使用SSH密钥进行登录?

一旦公钥部署成功,您就可以使用私钥进行免密登录了。

1. 使用默认私钥(id_rsa, id_ed25519等)登录

如果您的私钥是默认名称并存放在 ~/.ssh/ 目录下,SSH客户端会自动检测并使用它。

ssh username@remote_host

如果您的私钥设置了密码保护,系统会提示您输入密码保护。

2. 使用非默认私钥登录

如果您生成了多对密钥,并使用 -f 参数指定了不同的文件名,那么在登录时需要通过 -i 参数明确指定使用的私钥文件。

ssh -i ~/.ssh/my_new_key username@remote_host

同样,如果私钥有密码保护,您需要输入密码保护。

如何管理多个SSH密钥以及SSH代理?

当您拥有多个SSH密钥时,管理它们可能变得复杂。SSH代理(ssh-agent)可以帮助您解决这个问题。

SSH代理 (ssh-agent) 是什么?

ssh-agent 是一个后台运行的程序,它会保管您的私钥,并在您需要连接远程服务器时,自动为您提供认证。它的主要优点是:

  • 一次解锁,多次使用:如果您为私钥设置了密码保护,使用 ssh-agent 只需在首次使用时输入一次密码保护。之后,只要 ssh-agent 还在运行,您就可以无需再次输入密码保护来使用该私钥进行连接。
  • 安全性:私钥本身不会存储在磁盘上未加密,而是由代理在内存中管理,减少了每次连接时私钥被暴露的风险。

如何启动SSH代理并添加私钥?

  1. 检查SSH代理是否运行

    通常,您的桌面环境或终端会话会自动启动 ssh-agent。您可以通过以下命令检查:

    eval "$(ssh-agent -s)"

    如果代理已经运行,它会输出类似 SSH_AUTH_SOCK=/tmp/ssh-XXXXXX/agent.XXXX; export SSH_AUTH_SOCK; SSH_AGENT_PID=XXXXX; export SSH_AGENT_PID; echo Agent pid XXXXX; 的信息。如果未运行,此命令会启动它。

  2. 将私钥添加到SSH代理

    使用 ssh-add 命令将私钥添加到代理中。如果您的私钥有密码保护,系统会提示您输入:

    ssh-add ~/.ssh/id_ed25519

    如果您有多个私钥,可以逐一添加:

    ssh-add ~/.ssh/my_new_key

    成功添加后,您可以使用 ssh-add -l 查看代理中已加载的私钥列表:

    ssh-add -l

添加后,只要SSH代理进程保持运行,您就可以无需输入密码保护而直接使用这些私钥进行SSH连接。

忘记密钥的密码保护怎么办?如何修改密码保护?

如果您忘记了私钥的密码保护,那通常是无法恢复的,因为密码保护是为了保护私钥不被未经授权的人使用。您需要重新生成一对新的SSH密钥。

如果您知道旧的密码保护,想要修改它,可以使用 ssh-keygen -p 命令:

ssh-keygen -p -f ~/.ssh/id_ed25519

系统会提示您输入旧密码保护,然后输入两次新密码保护。

如何删除或禁用一个SSH密钥?

要禁用一个SSH密钥:

  1. 从本地删除:直接删除本地的私钥文件(例如 ~/.ssh/id_ed25519)。务必谨慎操作,删除后将无法再使用该私钥。

    rm ~/.ssh/id_ed25519

  2. 从远程服务器移除公钥:登录到远程服务器,编辑 ~/.ssh/authorized_keys 文件,删除对应您要禁用密钥的公钥那一行。

    nano ~/.ssh/authorized_keys

  3. 从SSH代理中移除:如果您已经将私钥加载到SSH代理中,可以使用 ssh-add -d 命令将其移除:

    ssh-add -d ~/.ssh/id_ed25519

    或者移除所有密钥:

    ssh-add -D

总结

SSH密钥是Linux环境下进行安全、高效远程访问的核心。通过理解其“是什么”、“为什么”以及“在哪里”存放,并掌握“如何”生成、部署和管理密钥,您将能够极大地提升您的工作效率和系统安全性。从选择强大的密钥类型(如Ed25519),设置强大的密码保护,到利用SSH代理简化日常操作,每一步都旨在为您提供更流畅、更安全的SSH体验。

linux生成ssh密钥