告别输入密码:一步步设置SSH免密登录
在日常的开发、运维或管理远程服务器工作中,SSH(Secure Shell)是我们最常使用的工具之一。通过SSH,我们可以安全地连接到远程主机并执行命令。然而,每次连接都需要输入密码,即使密码简单,长此以往也是一件令人感到厌烦且效率低下的事情。更不用说,频繁输入密码也增加了被暴力破解的风险(尽管SSH通常有防范措施)。
有没有办法可以跳过输入密码的步骤,实现更快速、更便捷的远程登录呢?答案是肯定的,那就是利用SSH的密钥对认证机制来实现免密登录。本文将带你一步步详细了解并设置SSH免密登录,让你彻底告别繁琐的密码输入。
为什么选择密钥对认证?它比密码更安全吗?
在深入设置之前,我们先来理解SSH密钥对认证的基本原理。与传统的密码认证(你提供密码,服务器验证密码)不同,密钥对认证依赖于一对数学上关联的密钥:一个私钥(Private Key)和一个公钥(Public Key)。
- 私钥(Private Key): 这是你的“身份证明”,必须绝对保密,只能保存在你的本地计算机上。私钥文件通常以
.pem
或没有扩展名的形式存在,例如id_rsa
。 - 公钥(Public Key): 这是与私钥配对的“锁”,可以公开。你需要将公钥放置在你想要免密登录的远程服务器上。公钥文件通常与私钥同名,但带有
.pub
扩展名,例如id_rsa.pub
。
工作原理简述:
- 当你尝试使用密钥对认证连接到远程服务器时,客户端(你的电脑)会向服务器发送一个请求,声称是某个用户。
- 服务器收到请求后,会在该用户的家目录下寻找一个特殊的文件(通常是
~/.ssh/authorized_keys
),里面存放着允许免密登录的客户端公钥列表。 - 服务器会找到与客户端声称身份对应的公钥,并生成一个随机字符串,使用这个公钥对其进行加密。
- 服务器将加密后的字符串发送回客户端。
- 客户端收到加密字符串后,会使用与之配对的私钥进行解密。如果能够成功解密并得到原始的随机字符串,就证明客户端拥有与服务器公钥相对应的私钥,即身份验证通过。
- 服务器收到客户端解密后的字符串并确认无误后,便允许客户端登录,无需密码。
安全性:
理论上,强大的密钥对(例如RSA 2048位或4096位)比大多数用户设置的密码要难得多进行暴力破解。只要你的私钥得到妥善保护,不泄露给他人,并且没有被破解(这对于长密钥来说几乎是不可能的),密钥对认证就比依赖用户设定密码更安全。此外,即使有人截获了通信过程中的公钥,也无法推算出私钥。
当然,安全性也取决于你如何使用密钥。如果你给私钥设置了空密码(passphrase),并且私钥文件本身被盗,那么任何人拿到这个私钥都可以冒充你登录。所以,为私钥设置一个复杂的passphrase(密码)是一个良好的安全实践,尽管这会引入一个新的密码输入环节(但在客户端只需输入一次,配合ssh-agent
甚至可以完全免去)。但为了实现真正的“免密登录”,许多用户选择私钥不设置passphrase。本文将同时介绍这两种情况,并主要侧重于最简单的完全免密设置。
一步步设置SSH免密登录
整个设置过程主要分为三个核心步骤:
- 在本地计算机上生成SSH密钥对(公钥和私钥)。
- 将本地生成的公钥复制到远程服务器上。
- 测试免密登录是否成功。
- (可选但推荐)禁用服务器的密码认证,提高安全性。
前提条件:
- 你拥有本地计算机的访问权限,并且已经安装了SSH客户端(大多数Linux、macOS系统自带,Windows 10及以上版本也自带或可通过安装OpenSSH获取)。
- 你拥有远程服务器的访问权限,知道其IP地址或域名,以及一个可以通过密码登录的用户名和密码。
- 远程服务器已经运行了SSH服务(sshd)。
步骤 1:在本地计算机生成SSH密钥对
打开你的本地计算机的终端或命令行界面。
使用 ssh-keygen
命令来生成密钥对。这个命令有很多选项,但最简单的方式是直接运行:
bash
ssh-keygen
执行命令后,系统会提示你一系列问题:
-
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): [按下回车] -
Enter passphrase (empty for no passphrase):
这是询问你是否要为私钥设置一个密码(passphrase)。- 如果你希望实现完全的免密登录(连passphrase都不想输入),请直接按回车留空。
- 如果你希望增加私钥的安全性(即使私钥文件被盗,也需要输入passphrase才能使用),请输入一个复杂的passphrase,并记住它。
注意: 留下passphrase为空是实现真正“无需任何输入即可登录”的关键。但这意味着如果你的私钥文件被获取,任何人都可以直接使用它登录你授权过的服务器。请权衡安全性和便利性。对于大多数个人或测试环境,空passphrase是常见的选择。对于敏感或生产环境,推荐设置passphrase并结合
ssh-agent
使用。 -
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
的权限可能是644
或600
。这些权限是很重要的,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
文件并将公钥粘贴进去:
使用文本编辑器(如 nano
或 vi
)打开或创建 ~/.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 ~
) 通常权限为755
或700
。 - 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 sshd
或sudo service ssh restart
。
- 登录远程服务器,编辑SSH服务配置文件(通常是
- 查看SSH服务器日志:
- 在远程服务器上,SSH服务器的认证日志通常在
/var/log/auth.log
(Debian/Ubuntu) 或/var/log/secure
(CentOS/RHEL) 中。查看这些日志可以找到认证失败的具体原因。例如,权限问题、找不到公钥文件、公钥格式错误等都可能在这里记录。
- 在远程服务器上,SSH服务器的认证日志通常在
步骤 4 (可选但推荐):禁用服务器的密码认证
一旦你确认密钥对认证可以正常工作(即你可以免密登录了),为了进一步提高服务器的安全性,你可以选择禁用传统的密码认证方式。这样做可以有效防止针对SSH端口的暴力密码猜测攻击。
重要提示: 在禁用密码认证之前,请务必确保你的密钥登录已经稳定工作,并且你有至少一个可以通过密钥登录的账号。否则,一旦禁用密码认证,你将无法再通过密码登录服务器,如果密钥登录也出现问题,你可能会失去对服务器的SSH访问权!最好保持一个有密码认证的备份账户(不建议),或者确保你的密钥私钥永不丢失且永不泄密。
操作步骤:
- 通过SSH密钥对认证登录到远程服务器。
-
使用文本编辑器以管理员权限打开SSH服务器配置文件
sshd_config
:bash
sudo nano /etc/ssh/sshd_config
或
bash
sudo vi /etc/ssh/sshd_config -
在文件中找到以下行:
“`
PasswordAuthentication yes
或可能是
PasswordAuthentication yes
“` -
将其修改为:
PasswordAuthentication no
如果前面有#
注释符,也需要去掉。 -
同时确认
PubkeyAuthentication yes
是开启状态(通常默认就是开启的)。 -
保存并关闭
sshd_config
文件。 -
重启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免密登录是提高工作效率和安全性的重要一步。通过生成一对公钥和私钥,并将公钥授权给远程服务器,我们可以实现无需密码的快速安全连接。
整个过程概括如下:
- 生成密钥对:
ssh-keygen
(在本地)。 - 复制公钥:
ssh-copy-id
(推荐,在本地执行) 或手动复制粘贴 (在本地获取公钥内容,然后登录远程服务器编辑~/.ssh/authorized_keys
文件)。 - 测试连接:
ssh user@server
(在本地)。 - (可选)禁用密码认证: 修改远程服务器的
sshd_config
文件并重启SSH服务。
记住,保护好你的私钥是使用SSH密钥认证的关键。一旦掌握了这项技能,你会发现远程工作变得更加流畅和高效。告别繁琐的密码输入,享受SSH免密登录带来的便捷吧!