告别输入密码:一步步设置SSH免密登录 – wiki基地


告别输入密码:一步步设置SSH免密登录

在日常的开发、运维或管理远程服务器工作中,SSH(Secure Shell)是我们最常使用的工具之一。通过SSH,我们可以安全地连接到远程主机并执行命令。然而,每次连接都需要输入密码,即使密码简单,长此以往也是一件令人感到厌烦且效率低下的事情。更不用说,频繁输入密码也增加了被暴力破解的风险(尽管SSH通常有防范措施)。

有没有办法可以跳过输入密码的步骤,实现更快速、更便捷的远程登录呢?答案是肯定的,那就是利用SSH的密钥对认证机制来实现免密登录。本文将带你一步步详细了解并设置SSH免密登录,让你彻底告别繁琐的密码输入。

为什么选择密钥对认证?它比密码更安全吗?

在深入设置之前,我们先来理解SSH密钥对认证的基本原理。与传统的密码认证(你提供密码,服务器验证密码)不同,密钥对认证依赖于一对数学上关联的密钥:一个私钥(Private Key)和一个公钥(Public Key)。

  • 私钥(Private Key): 这是你的“身份证明”,必须绝对保密,只能保存在你的本地计算机上。私钥文件通常以.pem或没有扩展名的形式存在,例如id_rsa
  • 公钥(Public Key): 这是与私钥配对的“锁”,可以公开。你需要将公钥放置在你想要免密登录的远程服务器上。公钥文件通常与私钥同名,但带有.pub扩展名,例如id_rsa.pub

工作原理简述:

  1. 当你尝试使用密钥对认证连接到远程服务器时,客户端(你的电脑)会向服务器发送一个请求,声称是某个用户。
  2. 服务器收到请求后,会在该用户的家目录下寻找一个特殊的文件(通常是~/.ssh/authorized_keys),里面存放着允许免密登录的客户端公钥列表。
  3. 服务器会找到与客户端声称身份对应的公钥,并生成一个随机字符串,使用这个公钥对其进行加密。
  4. 服务器将加密后的字符串发送回客户端。
  5. 客户端收到加密字符串后,会使用与之配对的私钥进行解密。如果能够成功解密并得到原始的随机字符串,就证明客户端拥有与服务器公钥相对应的私钥,即身份验证通过。
  6. 服务器收到客户端解密后的字符串并确认无误后,便允许客户端登录,无需密码。

安全性:

理论上,强大的密钥对(例如RSA 2048位或4096位)比大多数用户设置的密码要难得多进行暴力破解。只要你的私钥得到妥善保护,不泄露给他人,并且没有被破解(这对于长密钥来说几乎是不可能的),密钥对认证就比依赖用户设定密码更安全。此外,即使有人截获了通信过程中的公钥,也无法推算出私钥。

当然,安全性也取决于你如何使用密钥。如果你给私钥设置了空密码(passphrase),并且私钥文件本身被盗,那么任何人拿到这个私钥都可以冒充你登录。所以,为私钥设置一个复杂的passphrase(密码)是一个良好的安全实践,尽管这会引入一个新的密码输入环节(但在客户端只需输入一次,配合ssh-agent甚至可以完全免去)。但为了实现真正的“免密登录”,许多用户选择私钥不设置passphrase。本文将同时介绍这两种情况,并主要侧重于最简单的完全免密设置。

一步步设置SSH免密登录

整个设置过程主要分为三个核心步骤:

  1. 在本地计算机上生成SSH密钥对(公钥和私钥)。
  2. 将本地生成的公钥复制到远程服务器上。
  3. 测试免密登录是否成功。
  4. (可选但推荐)禁用服务器的密码认证,提高安全性。

前提条件:

  • 你拥有本地计算机的访问权限,并且已经安装了SSH客户端(大多数Linux、macOS系统自带,Windows 10及以上版本也自带或可通过安装OpenSSH获取)。
  • 你拥有远程服务器的访问权限,知道其IP地址或域名,以及一个可以通过密码登录的用户名和密码。
  • 远程服务器已经运行了SSH服务(sshd)。

步骤 1:在本地计算机生成SSH密钥对

打开你的本地计算机的终端或命令行界面。

使用 ssh-keygen 命令来生成密钥对。这个命令有很多选项,但最简单的方式是直接运行:

bash
ssh-keygen

执行命令后,系统会提示你一系列问题:

  1. Enter file in which to save the key (~/.ssh/id_rsa):
    这是询问你希望将私钥文件保存在哪里。默认位置是用户家目录下的.ssh文件夹内,文件名为id_rsa。通常情况下,直接按回车接受默认路径即可。如果你之前生成过密钥对,系统会提示是否覆盖,请谨慎选择(覆盖会丢失原有的密钥对)。

    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/your_user/.ssh/id_rsa): [按下回车]

  2. Enter passphrase (empty for no passphrase):
    这是询问你是否要为私钥设置一个密码(passphrase)。

    • 如果你希望实现完全的免密登录(连passphrase都不想输入),请直接按回车留空。
    • 如果你希望增加私钥的安全性(即使私钥文件被盗,也需要输入passphrase才能使用),请输入一个复杂的passphrase,并记住它。

    注意: 留下passphrase为空是实现真正“无需任何输入即可登录”的关键。但这意味着如果你的私钥文件被获取,任何人都可以直接使用它登录你授权过的服务器。请权衡安全性和便利性。对于大多数个人或测试环境,空passphrase是常见的选择。对于敏感或生产环境,推荐设置passphrase并结合ssh-agent使用。

  3. Enter same passphrase again:
    如果上一步设置了passphrase,这里需要再次输入以确认。如果留空,这里也直接按回车。

    Enter passphrase (empty for no passphrase): [按下回车或输入你的passphrase]
    Enter same passphrase again: [按下回车或再次输入你的passphrase]

命令执行成功后,你会看到类似以下的输出:

Your identification has been saved in /home/your_user/.ssh/id_rsa
Your public key has been saved in /home/your_user/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:......................................... your_user@your_local_machine
The key's randomart image is:
+---[RSA 2048]----+
| .+*Bo |
| . =.*+. |
| o + o o . |
| + + . . |
| o S E |
| . . . |
| . + . |
| o + |
| oo. |
+----[SHA256]-----+

这表示密钥对已经成功生成。在你的用户家目录下的.ssh隐藏文件夹中,你会找到两个新文件:

  • id_rsa (或你指定的其他名称): 这是你的私钥请妥善保管,不要泄露给任何人!
  • id_rsa.pub: 这是你的公钥。你可以将其内容复制到远程服务器上。

你可以使用 ls -l ~/.ssh/ 命令查看这两个文件及其权限。默认情况下,id_rsa的权限应该是600 (只有文件所有者有读写权限),id_rsa.pub的权限可能是644600。这些权限是很重要的,SSH客户端和服务器会检查这些文件的权限是否安全。

步骤 2:将公钥复制到远程服务器

这是最关键的一步,你需要将本地生成的id_rsa.pub文件中的公钥内容添加到远程服务器上你想登录的那个用户的~/.ssh/authorized_keys文件中。

有几种方法可以实现这一点,最推荐且最简单的是使用 ssh-copy-id 命令。

方法 1 (推荐):使用 ssh-copy-id 命令

ssh-copy-id 是专门用来做这件事的脚本,它会自动处理很多细节,比如在远程服务器上创建.ssh目录、设置正确的目录和文件权限,并将你的公钥追加到authorized_keys文件中(如果文件不存在则创建)。

在本地计算机的终端中运行以下命令:

bash
ssh-copy-id user@remote_server_ip_or_domain

  • user 替换成你在远程服务器上要登录的用户名。
  • remote_server_ip_or_domain 替换成远程服务器的IP地址或域名。

例如,如果你要以用户 myuser 登录 IP 地址为 192.168.1.100 的服务器,命令就是:

bash
ssh-copy-id [email protected]

执行命令后,你可能会看到一个提示询问是否连接(如果是第一次连接该服务器),输入 yes 并回车。

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

接着,ssh-copy-id 会要求你输入远程服务器上该用户的密码。这是你需要最后一次输入密码的地方(对于这个特定的目的而言)。

Warning: Permanently added '192.168.1.100' (ECDSA) to the list of known hosts.
[email protected]'s password: [输入远程服务器上myuser的密码]

输入密码并回车后,ssh-copy-id 会完成公钥的复制和设置工作。如果成功,你会看到类似以下的输出,告诉你添加了多少个密钥以及尝试连接的次数:

“`
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/authorized_keys文件中了。

方法 2 (手动):手动复制公钥内容

如果你的本地系统没有 ssh-copy-id 命令,或者你更喜欢手动操作,可以按以下步骤:

a. 查看并复制你的公钥内容:
在本地计算机终端执行:

```bash
cat ~/.ssh/id_rsa.pub
```
这会显示你的公钥内容,它是一串很长的字符串,以`ssh-rsa`或`ssh-ed25519`开头,以你的用户名和主机名结尾。将**整个**这一行内容复制到剪贴板。

b. 登录远程服务器:
使用传统的密码方式登录到远程服务器:

```bash
ssh user@remote_server_ip_or_domain
```
输入密码登录。

c. 创建 .ssh 目录并设置权限:
登录后,进入你的家目录(cd ~),然后创建 .ssh 目录(如果不存在)并设置正确权限。这是非常重要的安全步骤,SSH服务器会检查这些权限。

```bash
mkdir ~/.ssh
chmod 700 ~/.ssh
```
`chmod 700 ~/.ssh` 表示只有该目录的所有者有读、写、执行(进入)的权限。

d. 创建或编辑 authorized_keys 文件并将公钥粘贴进去:
使用文本编辑器(如 nanovi)打开或创建 ~/.ssh/authorized_keys 文件:

```bash
nano ~/.ssh/authorized_keys
```
或
```bash
vi ~/.ssh/authorized_keys
```

*   如果文件是新建的,直接将你在步骤 a 中复制的公钥内容粘贴进去。
*   如果文件已经存在(里面可能有其他公钥),则在文件的**新一行**粘贴你的公钥内容。**每个公钥必须单独占一行。**

粘贴完成后,保存并关闭文件。
*   使用 `nano`:按 `Ctrl+X`,然后按 `Y` 确认保存,再按回车确认文件名。
*   使用 `vi`:按 `Esc` 键退出编辑模式,输入 `:wq` 并回车保存退出。

e. 设置 authorized_keys 文件权限:
同样,这个文件的权限也非常重要。

```bash
chmod 600 ~/.ssh/authorized_keys
```
`chmod 600 ~/.ssh/authorized_keys` 表示只有文件的所有者有读写的权限。

至此,你的公钥已经成功放置在远程服务器的正确位置和正确权限下。

步骤 3:测试免密登录

在本地计算机终端中,尝试使用SSH连接到远程服务器,这次不指定密码:

bash
ssh user@remote_server_ip_or_domain

例如:
bash
ssh [email protected]

如果一切设置正确:

  • 如果你在生成私钥时没有设置passphrase,你应该会直接登录到远程服务器的shell,无需输入任何密码或passphrase。恭喜你,免密登录设置成功了!
  • 如果你在生成私钥时设置了passphrase,系统会提示你输入私钥的passphrase。输入正确的passphrase后,你应该会登录到远程服务器。虽然还需要输入passphrase,但这比输入远程服务器的密码要方便(尤其是在使用ssh-agent的情况下)。如果你追求完全的“免密”,需要重新生成私钥并留空passphrase,然后重新执行步骤2。

故障排除:

如果仍然提示输入密码:

  • 检查本地和远程的文件和目录权限:
    • 本地 ~/.ssh 目录权限是否是 700? (ls -ld ~/.ssh)
    • 本地私钥文件权限是否是 600? (ls -l ~/.ssh/id_rsa)
    • 远程 ~/.ssh 目录权限是否是 700? (ls -ld ~/.ssh)
    • 远程 ~/.ssh/authorized_keys 文件权限是否是 600? (ls -l ~/.ssh/authorized_keys)
    • 远程用户家目录权限不能对”其他”用户开放写权限。 (ls -ld ~) 通常权限为755700
    • SSH服务器对这些权限要求非常严格,任何不符合要求的权限都可能导致密钥认证失败并退回密码认证。
  • 检查公钥内容是否正确复制:
    • 登录到远程服务器,使用 cat ~/.ssh/authorized_keys 查看文件内容。
    • 回到本地计算机,使用 cat ~/.ssh/id_rsa.pub 查看公钥内容。
    • 对比两个输出,确保你的公钥完整且正确地复制到了远程的authorized_keys文件中,并且没有额外的空格、换行或字符错误。确保你的公钥是单独一行。
  • 检查远程服务器的SSH配置:
    • 登录远程服务器,编辑SSH服务配置文件(通常是 /etc/ssh/sshd_config)。
    • 确保以下配置项是启用状态(没有被 # 注释掉),并且值是 yes
      • PubkeyAuthentication yes
      • AuthorizedKeysFile .ssh/authorized_keys (确认路径是否正确,默认通常如此)
    • 修改配置后,需要重启SSH服务。在大多数Linux系统上,可以使用 sudo systemctl restart sshdsudo service ssh restart
  • 查看SSH服务器日志:
    • 在远程服务器上,SSH服务器的认证日志通常在 /var/log/auth.log (Debian/Ubuntu) 或 /var/log/secure (CentOS/RHEL) 中。查看这些日志可以找到认证失败的具体原因。例如,权限问题、找不到公钥文件、公钥格式错误等都可能在这里记录。

步骤 4 (可选但推荐):禁用服务器的密码认证

一旦你确认密钥对认证可以正常工作(即你可以免密登录了),为了进一步提高服务器的安全性,你可以选择禁用传统的密码认证方式。这样做可以有效防止针对SSH端口的暴力密码猜测攻击。

重要提示: 在禁用密码认证之前,请务必确保你的密钥登录已经稳定工作,并且你有至少一个可以通过密钥登录的账号。否则,一旦禁用密码认证,你将无法再通过密码登录服务器,如果密钥登录也出现问题,你可能会失去对服务器的SSH访问权!最好保持一个有密码认证的备份账户(不建议),或者确保你的密钥私钥永不丢失永不泄密

操作步骤:

  1. 通过SSH密钥对认证登录到远程服务器。
  2. 使用文本编辑器以管理员权限打开SSH服务器配置文件 sshd_config

    bash
    sudo nano /etc/ssh/sshd_config


    bash
    sudo vi /etc/ssh/sshd_config

  3. 在文件中找到以下行:

    “`

    PasswordAuthentication yes

    或可能是
    PasswordAuthentication yes
    “`

  4. 将其修改为:

    PasswordAuthentication no
    如果前面有 # 注释符,也需要去掉。

  5. 同时确认 PubkeyAuthentication yes 是开启状态(通常默认就是开启的)。

  6. 保存并关闭 sshd_config 文件。

  7. 重启SSH服务以使配置生效:

    bash
    sudo systemctl restart sshd

    或根据你的Linux发行版使用相应的命令,如 sudo service ssh restart

现在,尝试使用密码登录该服务器,你应该会发现密码认证已经被拒绝了,只能通过密钥对认证登录。

使用 ssh-agent 处理私钥 Passphrase

如果你为私钥设置了passphrase,每次连接服务器都需要输入它,这似乎并没有完全免去输入。ssh-agent 是一个在后台运行的程序,它可以缓存你的私钥passphrase。一旦你将私钥添加到ssh-agent中并输入一次passphrase,之后你在该会话中进行的所有SSH连接都不再需要输入passphrase了。

  • 启动 ssh-agent(通常在图形界面登录时会自动启动,或者可以通过脚本手动启动)。
  • 使用 ssh-add 命令将私钥添加到 ssh-agent 中:

    bash
    ssh-add ~/.ssh/id_rsa

    (如果你的私钥文件不是默认名称或位置,请替换路径)

    执行此命令后,会提示你输入私钥的passphrase。输入一次即可。

现在,只要 ssh-agent 还在运行,并且你的私钥已经添加到其中,你就可以免去输入passphrase进行SSH连接了。这结合了安全性和便利性。

总结

设置SSH免密登录是提高工作效率和安全性的重要一步。通过生成一对公钥和私钥,并将公钥授权给远程服务器,我们可以实现无需密码的快速安全连接。

整个过程概括如下:

  1. 生成密钥对: ssh-keygen (在本地)。
  2. 复制公钥: ssh-copy-id (推荐,在本地执行) 或手动复制粘贴 (在本地获取公钥内容,然后登录远程服务器编辑 ~/.ssh/authorized_keys 文件)。
  3. 测试连接: ssh user@server (在本地)。
  4. (可选)禁用密码认证: 修改远程服务器的 sshd_config 文件并重启SSH服务。

记住,保护好你的私钥是使用SSH密钥认证的关键。一旦掌握了这项技能,你会发现远程工作变得更加流畅和高效。告别繁琐的密码输入,享受SSH免密登录带来的便捷吧!

发表评论

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

滚动至顶部