快速配置 SSH 免密登录:ssh-copy-id 使用指南 – wiki基地


快速配置 SSH 免密登录:ssh-copy-id 使用指南

告别繁琐密码,提升效率与安全性

在日常的服务器管理、开发部署或是自动化运维中,我们常常需要频繁地通过 SSH 连接到远程服务器。每次输入密码不仅耗时,容易出错,而且在编写自动化脚本时更是无法接受。SSH 免密登录正是为了解决这一痛点而生,它允许我们通过密钥对认证的方式,无需密码即可安全地登录远程主机。

实现 SSH 免密登录的方法有多种,但 ssh-copy-id 命令无疑是最为便捷、安全且推荐的方式。本文将深入浅出地讲解 SSH 免密登录的原理,详细介绍 ssh-copy-id 工具的使用方法、常见参数、背后的机制,以及如何进行验证和故障排除,帮助您快速掌握这项实用的技能。

引言:为什么选择 SSH 免密登录?

想象一下这样的场景:您需要管理几十甚至上百台服务器,每天都要多次登录不同的主机进行维护、部署或查看日志。如果每次都需要手动输入长且复杂的密码,这将极大地降低您的工作效率,并且增加了因误操作或疲劳导致输入错误的风险。此外,在自动化脚本(如 Ansible, Chef, Puppet 或简单的 Shell 脚本)中硬编码密码是极不安全的行为。

SSH 免密登录通过使用密钥对(Public Key Cryptography)来替代传统的密码认证。简单来说,您在本地生成一对密钥:一个私钥(Private Key)和一个公钥(Public Key)。私钥保存在您本地的计算机上,绝对不能泄露;公钥则被放置在您想要登录的远程服务器上。当您尝试连接时,SSH 客户端使用您的私钥与服务器上的公钥进行一系列加密和解密验证,如果验证成功,服务器就会允许您登录,而无需输入密码。

这种方式不仅提高了效率,而且在许多方面比密码认证更安全:

  1. 抵御暴力破解: 攻击者无法通过猜测密码来闯入,除非他们能同时获取到您的私钥 解开私钥的密码(如果您设置了私钥密码)。
  2. 无需传输密码: 登录过程中无需在网络上传输明文或可逆加密的密码,降低了被截获的风险。
  3. 精细的权限控制: 可以在服务器端配置 authorized_keys 文件,对不同的公钥设置特定的限制,比如只允许执行某个命令,或者只允许来自特定 IP 地址的连接。

虽然手动配置密钥对并将其复制到远程服务器是可行的,但这通常涉及多个步骤,包括创建 .ssh 目录、设置正确的权限、将公钥内容追加到 authorized_keys 文件等。这些手动步骤容易出错,特别是权限问题,经常会导致免密登录失败。ssh-copy-id 工具正是为此而生,它将这些繁琐的步骤自动化,确保公钥被正确地安装到远程主机的指定用户账户下,并设置好必要的目录和文件权限。

ssh-copy-id 命令是 OpenSSH 套件的一部分,通常在大多数 Linux、macOS 和类 Unix 系统上预装。它是一个简单而强大的脚本,专门用于将您的公钥安全地复制到远程服务器的 ~/.ssh/authorized_keys 文件中。

第一步:理解 SSH 密钥对与认证原理

在使用 ssh-copy-id 之前,了解其背后的原理至关重要。SSH 密钥认证基于非对称加密(Public Key Cryptography)。

  1. 密钥生成: 您使用工具(如 ssh-keygen)生成一对密钥:

    • 私钥 (Private Key): 这是您身份的秘密证明,必须严格保存在本地,绝不泄露。通常存储在 ~/.ssh/id_rsa (或 id_ed25519 等) 文件中。为了进一步保护私钥,强烈建议为其设置一个密码(Passphrase)。
    • 公钥 (Public Key): 这是可以公开分享的部分,它与私钥是数学上关联的。通常存储在 ~/.ssh/id_rsa.pub (或 id_ed25519.pub 等) 文件中。
  2. 公钥部署: 将您的公钥复制到您想要免密登录的远程服务器上的特定用户账户的 ~/.ssh/authorized_keys 文件中。每个允许免密登录的公钥都在这个文件中占据一行。

  3. 认证过程(简述):

    • 当您尝试使用私钥连接到远程 SSH 服务器时,服务器会向您发送一个随机的挑战信息。
    • 您的 SSH 客户端使用您的私钥对这个挑战信息进行签名。
    • 客户端将签名后的信息发送回服务器。
    • 服务器使用您之前部署在其 authorized_keys 文件中的 公钥 来验证这个签名。
    • 如果签名验证成功(证明您拥有与公钥配对的私钥),服务器就认为您是合法的用户,并允许您登录,无需密码。
    • 如果您为私钥设置了密码,您的 SSH 客户端会在连接时提示您输入私钥密码,用以解锁私钥进行签名操作。一旦私钥解锁,您可以在同一会话中多次使用它而无需再次输入密码(尤其结合 ssh-agent)。

ssh-copy-id 工具的核心作用就是自动化第二步:将您的公钥安全、正确地部署到远程服务器的 authorized_keys 文件中。

第二步:生成 SSH 密钥对 (ssh-keygen)

如果您还没有 SSH 密钥对,或者想为特定的目的生成新的密钥对,您需要先执行这一步。大多数情况下,您只需要一对默认的密钥就足够了。

打开您的本地终端或命令行界面,执行以下命令:

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

或者,如果您偏好 RSA(尽管 ED25519 通常更优越且推荐):

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

命令解释:

  • ssh-keygen: 用于生成、管理和转换认证密钥的工具。
  • -t ed25519-t rsa: 指定密钥类型。ED25519 是较新的、推荐的密钥类型,因为它既安全又高效。RSA 也是常用的类型,-b 4096 指定密钥长度为 4096 位,这被认为是当前安全的长度(默认通常是 2048 位,建议升级)。
  • -C "[email protected]": 为公钥添加一个注释。这有助于您在 authorized_keys 文件中识别密钥的来源和用途,通常使用您的邮箱或用户名和主机名作为注释。

执行命令后,系统会提示您几个问题:

  1. Enter file in which to save the key (/home/your_user/.ssh/id_ed25519):

    • 这是指定密钥文件保存路径。按下回车键将使用默认路径(推荐),这会在 ~/.ssh/ 目录下生成 id_ed25519 (私钥) 和 id_ed25519.pub (公钥) 文件。
    • 如果您输入其他路径,将会生成不同名称的密钥文件。这在您需要为不同服务或不同服务器使用不同的密钥时非常有用。
  2. Enter passphrase (empty for no passphrase):

    • 为您的私钥设置一个密码。强烈建议设置一个强大的密码! 即使您的私钥文件被盗,没有这个密码,攻击者也无法使用它。设置密码会增加额外的安全性。如果您不希望每次使用私钥时都输入密码,可以使用 ssh-agent 来管理密码(后面会介绍)。如果您不想设置密码,直接按回车键跳过(不推荐)。
  3. Enter same passphrase again:

    • 再次输入您设置的私钥密码进行确认。

成功生成密钥后,您会看到类似如下的输出:

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/your_user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/your_user/.ssh/id_ed25519.
Your public key has been saved in /home/your_user/.ssh/id_ed25519.pub.
The key fingerprint is:
SHA256:........................................... [email protected]
The key's randomart image is:
+--[ED25519 256]--+
| .+*=BO |
| . *+=o+ |
| o o. o |
| o + . |
| E *S . |
| . + . |
| o + |
| . . |
| |
+----[SHA256]-----+

现在,您在 ~/.ssh/ 目录下应该有了两个文件:id_ed25519 (私钥) 和 id_ed25519.pub (公钥)。请务必保护好您的私钥 (id_ed25519 文件)!

第三步:使用 ssh-copy-id 复制公钥

这是核心步骤。ssh-copy-id 命令会自动帮您完成将公钥安装到远程服务器的操作。

基本语法如下:

bash
ssh-copy-id user@remote_host

命令解释:

  • ssh-copy-id: 执行公钥复制的工具。
  • user: 您要登录的远程服务器上的用户名。
  • remote_host: 远程服务器的 IP 地址或主机名。

例如,如果您想将公钥复制到用户 centos 在 IP 地址为 192.168.1.100 的服务器上,命令如下:

bash
ssh-copy-id [email protected]

执行命令后,ssh-copy-id 会尝试通过 SSH 连接到远程服务器。第一次连接时,如果之前没有连接过这台服务器,您可能会收到主机密钥指纹的警告:

The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ED25519 key fingerprint is SHA256:...........................................
Are you sure you want to continue connecting (yes/no/[fingerprint])?

这是正常的安全提示,用于验证您连接的主机是否是您预期的那台。您可以手动验证指纹(通过其他安全通道获取服务器的指纹),或者在信任网络环境的情况下输入 yes 并按回车,将服务器的主机密钥添加到您本地的 ~/.ssh/known_hosts 文件中。

接着,ssh-copy-id 会提示您输入远程用户(centos)的密码:

Warning: Permanently added '192.168.1.100' (ED25519) to the list of known hosts.
[email protected]'s password:

输入远程用户的密码并按回车键。

如果密码正确,ssh-copy-id 会执行以下操作:

  1. 在远程服务器上以 centos 用户身份登录。
  2. 检查远程用户的家目录下是否存在 .ssh 目录,如果不存在则创建它。
  3. ~/.ssh 目录设置正确的权限(通常是 700,即只有文件所有者有读、写、执行权限)。
  4. 检查 ~/.ssh/authorized_keys 文件是否存在,如果不存在则创建它。
  5. 将您本地的公钥 (~/.ssh/id_ed25519.pub 或其他默认公钥文件) 的内容读取出来。
  6. 将公钥内容追加到远程服务器上 ~/.ssh/authorized_keys 文件的末尾。在追加之前,ssh-copy-id 会检查公钥是否已经存在,避免重复添加。
  7. ~/.ssh/authorized_keys 文件设置正确的权限(通常是 600,即只有文件所有者有读写权限)。
  8. 最后,ssh-copy-id 会断开连接,并显示一个总结信息,告知您添加了多少个密钥,以及尝试免密登录的提示。

成功执行的输出大致如下:

“`
[email protected]’s password:
Number of key(s) added: 1

Now try logging into the machine, with: “ssh ‘[email protected]′”
and check to make sure that only the key(s) you wanted were added.
“`

至此,您的公钥就已经成功安装到远程服务器上了。

使用其他公钥文件:

如果您生成了非默认路径或名称的密钥对(例如 ~/.ssh/my_special_key.pub),或者您想使用特定的公钥文件,可以通过 -i 参数指定:

bash
ssh-copy-id -i ~/.ssh/my_special_key.pub user@remote_host

指定端口:

如果远程 SSH 服务器运行在非默认端口(默认为 22),可以使用 -p 参数指定:

bash
ssh-copy-id -p 2222 user@remote_host

或者,您也可以将端口信息包含在主机名中(如果您已经在 ~/.ssh/config 文件中为该主机配置了端口):

bash
ssh-copy-id user@remote_host -p 2222 # 或者如果config文件有配置,直接 ssh-copy-id user@remote_host_alias

第四步:验证免密登录

公钥复制成功后,最关键的一步就是验证它是否真的工作了。

在本地终端,尝试使用 SSH 连接到远程服务器:

bash
ssh user@remote_host

或包含端口信息:

bash
ssh -p 2222 user@remote_host

如果您为私钥设置了密码(passphrase),SSH 客户端会提示您输入私钥密码:

Enter passphrase for key '/home/your_user/.ssh/id_ed25519':

输入您设置的私钥密码并回车。如果密码正确,您应该能够成功登录到远程服务器的 shell,而不会被要求输入远程用户的密码。

如果您 没有 为私钥设置密码,那么执行 ssh user@remote_host 命令后,您应该直接登录到远程服务器的 shell,不会有任何密码或私钥密码的提示。

恭喜您!您已成功配置 SSH 免密登录!

深入了解 ssh-copy-id 的幕后操作 (authorized_keys)

为了更好地理解 ssh-copy-id 的工作原理以及进行故障排除,了解远程服务器上公钥存储的位置和格式是很重要的。

您的公钥被存储在远程用户家目录下的 .ssh 目录中的 authorized_keys 文件里。例如,对于用户 centos192.168.1.100 上,文件路径通常是 /home/centos/.ssh/authorized_keys

您可以手动查看这个文件的内容(在远程服务器上登录后执行):

bash
cat ~/.ssh/authorized_keys

文件内容格式是每行一个公钥。一个典型的公钥行看起来像这样:

ssh-ed25519 AAAA... [很长一串字符] ...== [email protected]

或者 RSA 密钥:

ssh-rsa AAAA... [很长一串字符] ...== [email protected]

这行包含了密钥类型(ssh-ed25519ssh-rsa),紧接着是 Base64 编码的公钥数据,最后是您生成密钥时指定的注释(-C 参数的内容)。ssh-copy-id 确保您的公钥被完整、准确地追加到这个文件的末尾,并且不会损坏现有内容。

重要的文件和目录权限:

SSH 服务器对 ~/.ssh 目录及其内部文件的权限要求非常严格,以防止其他用户篡改认证信息。ssh-copy-id 会自动设置这些权限,但如果您手动操作或遇到问题,需要检查并确保权限正确:

  • ~/.ssh 目录: 权限应为 700 (drwx——)。这意味着只有文件所有者有读、写、执行的权限。
    • 检查:ls -ld ~/.ssh
    • 设置:chmod 700 ~/.ssh
  • ~/.ssh/authorized_keys 文件: 权限应为 600 (-rw——-)。这意味着只有文件所有者有读、写的权限。
    • 检查:ls -l ~/.ssh/authorized_keys
    • 设置:chmod 600 ~/.ssh/authorized_keys
  • 远程用户家目录 ~ 权限不能是全局可写的,例如 777775 会导致 SSH 认证失败。通常家目录的权限是 755700 是可以接受的。
    • 检查:ls -ld ~
    • 设置(如果需要):chmod 755 ~chmod 700 ~ (后者更严格)

如果这些权限设置不正确,SSH 服务器会出于安全考虑拒绝使用公钥认证,即使公钥本身是正确的。ssh-copy-id 的便利性就在于它会帮您处理这些权限问题。

第五步:高级用法与最佳实践

1. 管理私钥密码 (ssh-agentssh-add)

如果您为私钥设置了密码(强烈推荐),每次使用密钥登录时都需要输入密码。这虽然增加了安全性,但牺牲了便利性。ssh-agent 是一个后台运行的小程序,它可以缓存您输入的私钥密码,这样您在当前会话中(或者直到代理停止)就不需要重复输入密码了。ssh-add 命令用于将私钥添加到 ssh-agent 中。

使用步骤:

  • 启动 ssh-agent: 大多数桌面环境或终端仿真器会自动启动 ssh-agent。如果没有,您可以手动启动:
    bash
    eval "$(ssh-agent -s)"

    这个命令会输出一些环境变量设置(如 SSH_AUTH_SOCK),eval 会将它们应用到当前 shell。
  • 将私钥添加到 ssh-agent:
    bash
    ssh-add ~/.ssh/id_ed25519

    如果您的私钥文件名不同,请替换路径。这时会提示您输入私钥密码。输入一次后,密码就会被 ssh-agent 记住。
  • 验证密钥是否已添加:
    bash
    ssh-add -l

    这会列出 ssh-agent 当前管理的密钥。

现在,只要 ssh-agent 还在运行,并且您在同一个 shell 会话或通过适当环境变量连接的 shell 会话中,使用这个私钥登录时就不需要再次输入密码了。

2. 为不同主机使用不同的密钥

在某些场景下,您可能希望为不同的服务器或服务使用不同的 SSH 密钥对。例如,一个密钥用于公司内部服务器,另一个密钥用于 GitHub 或 GitLab。

  • 生成不同的密钥时,在 ssh-keygen 提示输入文件路径时指定不同的名称,例如:
    bash
    ssh-keygen -t ed25519 -C "work_key" -f ~/.ssh/id_ed25519_work
    ssh-keygen -t ed25519 -C "github_key" -f ~/.ssh/id_ed25519_github
  • 使用 ssh-copy-id 将相应的公钥复制到目标服务器:
    bash
    ssh-copy-id -i ~/.ssh/id_ed25519_work.pub user@work_server
    ssh-copy-id -i ~/.ssh/id_ed25519_github.pub [email protected]
  • 配置 SSH 客户端 (~/.ssh/config): 为了方便使用不同的密钥连接不同的主机,您可以在 ~/.ssh/config 文件中进行配置:
    “`
    # Default settings for all hosts
    Host *
    ForwardAgent yes # Useful for forwarding your agent to jump hosts

    Configuration for work server

    Host work_server
    Hostname work.company.com
    User your_username
    IdentityFile ~/.ssh/id_ed25519_work # Specify the private key file
    Port 22 # Optional, if non-default port

    Configuration for GitHub

    Host github.com
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github
    ``
    这样配置后,您只需要使用
    ssh work_serverssh github.com` 即可连接,SSH 客户端会自动使用指定的密钥文件。

3. 增强远程服务器的安全性:禁用密码认证

一旦您确定所有需要通过 SSH 登录的用户都配置了密钥认证并且工作正常,为了进一步提高安全性,可以考虑在远程 SSH 服务器上完全禁用密码认证。这样,任何没有有效私钥的用户都无法通过 SSH 登录。

警告: 在禁用密码认证之前,务必确认您可以通过密钥认证成功登录! 如果您禁用了密码认证但密钥认证未能正常工作,您可能会把自己锁在服务器外面。建议保持一个备用的连接方式(如控制台访问或带内管理卡)以防万一。

  • 操作步骤(在远程服务器上):
    1. 使用密钥认证登录到远程服务器。
    2. 编辑 SSH 服务器的配置文件,通常是 /etc/ssh/sshd_config。您可能需要管理员权限(如 sudo)。
    3. 找到或添加以下行,并确保它们被设置为 no
      ini
      #PermitRootLogin yes # root 用户是否允许密码登录,建议改为 prohibit-password 或 no
      PasswordAuthentication no
      ChallengeResponseAuthentication no # 禁用键盘交互认证,有时与密码认证一起使用
      UsePAM no # 如果您不依赖 PAM 进行密码认证,也可以考虑禁用,但需谨慎
    4. 找到并确认以下行被设置为 yes
      ini
      PubkeyAuthentication yes
    5. 保存文件并退出编辑器。
    6. 重启 SSH 服务以应用更改。根据您的操作系统和发行版,命令可能不同,常见的有:
      bash
      sudo systemctl restart sshd # For systemd-based systems (CentOS 7+, Ubuntu 15.04+, etc.)
      sudo service ssh restart # For older SysVinit systems
    7. 重要: 在关闭当前连接之前,打开一个新的终端窗口,尝试使用密钥认证连接到服务器,确认可以成功登录。只有确认无误后,再关闭原有的连接。

4. 限制密钥的使用 (authorized_keys 选项)

在远程服务器的 ~/.ssh/authorized_keys 文件中,您可以在每个公钥行的开头添加一些选项,以限制该密钥的使用方式。这对于提供给特定用户或自动化进程的密钥非常有用。

例如:

“`

Restrict key usage

from=”192.168.1.*, trusted_host.example.com” ssh-ed25519 AAAA… comment
command=”/usr/local/bin/run_backup_script” no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA… another_comment
“`

常用选项:

  • from="pattern_list": 仅允许来自指定主机名或 IP 地址/网段的连接使用此密钥。
  • command="command": 忽略客户端请求的命令,强制执行指定的命令。当客户端断开连接时,此强制命令也会终止。这在创建只允许执行特定任务的账号时非常有用。
  • no-port-forwarding: 禁用此密钥的端口转发功能 (-L, -R, -D)。
  • no-X11-forwarding: 禁用此密钥的 X11 转发功能 (-X, -Y)。
  • no-agent-forwarding: 禁用此密钥的 SSH 代理转发功能 (-A)。
  • no-pty: 禁用此密钥的 TTY 分配功能,强制客户端不获取交互式终端。
  • restrict: 这是一个简写选项,等同于 no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty,command="forced_command" (需要与 command 选项一起使用)。或者单独使用 restrict 选项时,它禁用转发、pty 和代理转发,同时允许客户端指定命令(不像 command="..." 会忽略客户端的命令)。但最安全的做法是明确列出您禁用的功能并配合 command 选项。

这些选项提供了强大的灵活性和安全性控制,允许您为不同的自动化任务或临时访问创建具有最小必要权限的密钥。

第六步:故障排除常见问题

尽管 ssh-copy-id 简化了流程,但 SSH 免密登录有时仍然会遇到问题。以下是一些常见问题及其排查思路:

  1. 仍然提示输入密码(而不是私钥密码):

    • 原因: SSH 服务器未能成功使用您的公钥进行认证, fallback 到密码认证方式(如果服务器允许)。
    • 排查:
      • 检查公钥是否正确复制: 登录到远程服务器,检查 ~/.ssh/authorized_keys 文件是否存在,文件内容是否包含您本地公钥的完整、正确内容。确保没有多余的换行符或其他错误。
      • 检查文件和目录权限: 确保远程服务器上 ~, ~/.ssh, ~/.ssh/authorized_keys 的权限设置正确(通常是 755/700, 700, 600)。这是最常见的问题。在远程服务器上执行 ls -ld ~ ~/.ssh ~/.ssh/authorized_keyschmod 755 ~; chmod 700 ~/.ssh; chmod 600 ~/.ssh/authorized_keys 来修复权限。
      • 检查 SSH 服务器配置: 在远程服务器上,查看 /etc/ssh/sshd_config 文件:
        • 确保 PubkeyAuthentication yes 已开启。
        • 检查 AuthorizedKeysFile 指令是否指向正确的公钥文件路径 (默认为 .ssh/authorized_keys)。
        • 确认没有其他配置(如 AllowUsers, DenyUsers, AllowGroups, DenyGroups)阻止您的用户使用密钥认证。
        • 如果 PasswordAuthentication no 被设置,但您仍然被要求输入密码,这可能表明 SSH 服务器根本没有尝试公钥认证,或者在公钥认证阶段就失败了,直接拒绝了连接(而不是 fallback 到密码认证)。
      • 查看 SSH 服务器日志: 这是诊断问题的最佳途径。在远程服务器上查看认证日志文件,通常是 /var/log/auth.log (Debian/Ubuntu) 或 /var/log/secure (CentOS/RHEL)。搜索与您连接尝试相关的日志条目,查找指示公钥认证失败原因的信息(例如 “Authentication refused: bad permissions”, “Authentication refused: incorrect authorizaton data”, “userauth_pubkey: key not authorized” 等)。
      • 检查 SELinux 或 AppArmor: 在启用了强制访问控制的系统上 (如 RHEL/CentOS 的 SELinux, Ubuntu 的 AppArmor),它们可能会阻止 SSH 访问用户家目录下的 .ssh 文件。检查相关日志 (/var/log/audit/audit.logdmesg for SELinux, /var/log/kern.log or syslog for AppArmor) 并根据需要调整策略或将 SSH 相关文件置于允许的上下文中。
      • 检查客户端 SSH 配置: 本地 ~/.ssh/config/etc/ssh/ssh_config 是否有配置阻止密钥认证 (如 PubkeyAuthentication no) 或指定了错误的密钥文件 (IdentityFile)。
  2. 连接被拒绝 (Connection refused):

    • 原因: SSH 服务未运行、防火墙阻止连接、目标 IP 或端口错误。
    • 排查:
      • 确保远程服务器上的 SSH 服务 (sshd) 正在运行。
      • 检查服务器和客户端之间的防火墙设置,确保允许 SSH 端口(默认为 22 或您指定的端口)的流量通过。
      • 确认您连接的 IP 地址和端口是正确的。
  3. 主机密钥验证失败 (Host key verification failed):

    • 原因: 远程服务器的主机密钥发生了变化(可能是服务器重新安装、IP 地址被新机器占用或遭受中间人攻击)。
    • 排查:
      • 如果您确认变化是合法的,编辑您本地的 ~/.ssh/known_hosts 文件,删除与该服务器 IP 地址或主机名相关的行。下次连接时会再次提示您验证新的主机密钥指纹。
      • 或者使用命令删除特定主机的密钥:ssh-keygen -R remote_hostssh-keygen -R ip_address
  4. 私钥密码输入错误:

    • 原因: 输入的私钥密码不正确。
    • 排查: 仔细核对您设置的私钥密码。如果您忘记了密码,且没有备份,那么这个密钥对就无法使用了,您需要生成新的密钥对并重新部署公钥。
  5. 使用 ssh-agent 后仍然提示输入私钥密码:

    • 原因: 私钥未成功添加到 ssh-agent 中,或者您当前使用的 shell 会话没有连接到同一个 ssh-agent 进程。
    • 排查:
      • 运行 ssh-add -l 检查您的私钥是否已添加到代理。
      • 确保您在需要使用免密登录的 shell 中执行了 eval "$(ssh-agent -s)" (如果代理没有自动启动) 并且运行了 ssh-add
      • 如果您使用了 sudo 或切换用户,可能需要额外的配置来保持 ssh-agent 的连接。

替代 ssh-copy-id 的手动方法

尽管 ssh-copy-id 是推荐的方法,但了解手动复制公钥的过程有助于理解原理和进行故障排除。

手动复制公钥的步骤大致如下:

  1. 在本地查看您的公钥内容:
    bash
    cat ~/.ssh/id_ed25519.pub

    复制输出的完整公钥字符串(从 ssh-ed25519ssh-rsa 开始,到注释结束)。

  2. 使用密码认证登录到远程服务器:
    bash
    ssh user@remote_host

    输入远程用户密码。

  3. 在远程服务器上创建 .ssh 目录(如果不存在):
    bash
    mkdir -p ~/.ssh

    -p 选项确保父目录(家目录)存在且权限合适时才创建 .ssh 目录。

  4. 设置 .ssh 目录权限:
    bash
    chmod 700 ~/.ssh

  5. 将您的公钥追加到 authorized_keys 文件。可以使用文本编辑器打开文件,将公钥粘贴进去并保存,或者使用 echocat 命令追加:
    bash
    echo "粘贴您的公钥字符串在这里" >> ~/.ssh/authorized_keys

    注意: 使用 >> 是追加,如果您使用 > 会覆盖文件内容!

  6. 设置 authorized_keys 文件权限:
    bash
    chmod 600 ~/.ssh/authorized_keys

  7. (可选但推荐)检查家目录权限:
    bash
    chmod 755 ~ # 或 700

手动方法需要准确执行每一个步骤,特别是权限设置,否则很容易失败。ssh-copy-id 的优势在于它自动化了这些容易出错的部分。实际上,ssh-copy-id 在底层执行的命令就类似于上面手动过程的自动化版本,通常是通过一次 SSH 连接执行一系列远程命令来完成的。

总结

SSH 免密登录是提高工作效率、增强自动化能力和提升安全性的重要手段。ssh-copy-id 工具极大地简化了公钥在远程服务器上的安装过程,是配置 SSH 免密登录的首选工具。

通过本文的介绍,您应该已经掌握了:

  • SSH 免密登录的基本原理(密钥对认证)。
  • 如何使用 ssh-keygen 生成安全的密钥对。
  • 如何使用 ssh-copy-id 命令将公钥复制到远程服务器,包括基本用法和常见参数。
  • 如何验证免密登录是否成功。
  • 公钥在远程服务器上的存放位置和必需的权限设置。
  • 如何使用 ssh-agent 管理私钥密码,提高便利性。
  • 如何为不同目的使用不同的密钥,并通过 ~/.ssh/config 文件进行管理。
  • 增强远程服务器安全性的方法(禁用密码认证)。
  • authorized_keys 文件中限制密钥使用的高级技巧。
  • 诊断和解决 SSH 免密登录常见问题的方法。

掌握 ssh-copy-id 工具是迈向高效、安全的服务器管理和自动化工作流程的关键一步。告别重复输入密码的烦恼,立即开始使用 ssh-copy-id 吧!记住始终保护好您的私钥,并为私钥设置一个强大的密码,这将是您SSH安全的基石。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部