简介
在本实验中,你将通过实践掌握配置和保护 SSH 连接的方法,这是管理远程 Linux 系统的一项基本技能。你将首先学习如何使用 SSH 访问远程系统,理解客户端-服务器架构以及基本的连接命令。这包括验证 SSH 客户端安装、连接到远程主机、处理主机真实性提示,以及登录和注销远程系统。
在此基础上,你将深入探讨更高级的主题,例如生成和利用 SSH 密钥对实现免密登录、使用 ssh-agent 有效管理这些密钥,以及排查常见的 SSH 连接问题。最后,你将学习如何自定义 SSH 客户端配置以提高效率,并通过禁用 root 登录和密码验证来增强 OpenSSH 服务器的安全性,从而确保稳健且安全的远程访问。
使用 SSH 访问远程系统
在这一步中,你将学习如何使用 SSH(Secure Shell)访问远程系统。SSH 是一种加密网络协议,用于在不安全的网络上安全地操作网络服务。它通过客户端-服务器架构,连接 SSH 客户端与 SSH 服务器,从而在不安全的网络上提供安全通道。
注意: 在本实验环境中,出于安全考虑,可能已经配置了一些安全功能(如 root 登录限制)。这是正常现象,体现了最佳实践的应用。
在连接到远程系统之前,请通过安装 OpenSSH 客户端和服务器软件包并启动 SSH 服务来准备实验环境。SSH 使用客户端-服务器架构:客户端(ssh)发起连接,服务器(sshd)接受连接。你还将安装 nano,稍后将使用它来编辑 SSH 配置文件。
运行以下命令安装所需的软件包。-y 标志会自动确认软件包安装提示:
sudo dnf install -y openssh-clients openssh-server nano
启动 SSH 服务并将其配置为在开机时自动启动:
sudo systemctl start sshd
sudo systemctl enable sshd
验证 SSH 服务是否正在运行:
sudo systemctl status sshd
你应该在输出中看到 Active: active (running)。按 q 退出状态视图。
首先,你将使用 SSH 连接到本地系统。即使连接到同一台机器,这也演示了 SSH 的客户端-服务器架构。你将使用 ssh 命令连接到 localhost。
ssh 的基本语法为:
ssh [username]@[hostname_or_IP]
如果你不指定用户名,SSH 将尝试使用你当前的本地用户名登录。在本例中,你的本地用户名是 labex。
让我们尝试使用当前用户名连接到 localhost:
ssh localhost
当你第一次连接时,SSH 会要求你确认主机的真实性。这是一项防止中间人攻击的安全措施。输入 yes 并按 Enter。
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:h5k1mmPFylpxUCsKx+Mf8rN4wOrk9TmyRfzTvGWRm7A.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
labex@localhost's password:
系统会提示你输入 labex 用户的密码。输入 labex 并按 Enter。
labex@localhost's password:
Last login: Mon Jun 9 01:34:39 2025 from 47.251.66.143
[labex@host ~]$
你现在已通过 SSH 登录到 localhost。请注意,你的提示符可能显示为 [labex@localhost ~]$,表明你已通过 SSH 连接。
要注销 SSH 会话,请使用 exit 命令:
exit
logout
Connection to localhost closed.
[labex@host ~]$
现在,让我们尝试以 root 用户身份连接到 localhost。请注意,在此环境中,出于安全原因,root 登录可能默认被禁用。
ssh root@localhost
系统会提示你输入 root 密码。但是,如果 root 登录被禁用,你可能会遇到“Permission denied”(权限被拒绝)的消息:
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
如果 root 登录被禁用,这是预期的行为,也体现了安全最佳实践。你可以按 Ctrl+C 取消连接尝试。
SSH 也可用于在远程系统上执行单个命令,而无需打开交互式 shell。这对于快速检查或自动化非常有用。
让我们以 labex 用户身份在 localhost 上运行 hostname 命令:
ssh labex@localhost hostname
系统会提示你输入 labex 用户的密码。输入 labex 并按 Enter。
labex@localhost's password:
6846375f1c0e35fea6cb03e6
[labex@host ~]$
hostname 命令已通过 SSH 执行,其输出显示在你的本地终端上。你并没有进入交互式 shell。
最后,让我们探讨 SSH 如何管理已知主机。当你连接到新的 SSH 服务器时,其公钥指纹会被添加到你的 ~/.ssh/known_hosts 文件中。此文件有助于你的 SSH 客户端在未来的连接中验证服务器的身份。
你可以查看 ~/.ssh/known_hosts 文件的内容:
cat ~/.ssh/known_hosts
localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHvl7dcZkvMNOr3cjKjlR2/JgFbGpURThT/bHnLZN6gG
localhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCynhy3601o9ZSGZoY0KB/QSonk5ykod2Tb7sCAqVn4ZgTCwd96BhPjJLPNQ6ldNASo1e7EzfT4BUjG5T0ZDRhgaI65qmDwITWipTWUfmYT5XoScyf6NDhcRxYiJwztFEkOvLcPhelS6UXj5Z7HdmYH4Nc5wiF00Wah3Jc0/2CfQsFZCXTn/7Kp8KKbBbPqPzr2R3WIULEacOxx9HKVv+2TvYg/OHZz40hTsr1c68DD7h5PMBNe21YB3HLRRk2LQEC7v7BFD+DCek9GNR66JBjbLDljtwWCaPCY0UntBjjvJ3W2LhX5RDZQHV/iaUSj2tEXnvPt9KSqGfBS91D12dBXyOmWVnTpvvI17BdDkEeefas2Uz4d7Bv/PDxZR6IKkaIGQ/ZnRhSEhBNvfqlBGqkOhRr6jQJK+rQMnsZCT6OEgW7osWzkw5Bs1wY/RNToeQqrRMclqffO9plFI688N2iT86+nxrvBVZg4yMMm2J1lleaBvinXCB8jE6lrtwoAdgk=
localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKYWY8Ty6TrbQS/0fUljBWuUpkyPCS/5P6ZwxhSYsqjRBIprMANI/JQotZqHYq2w3b2X/n8O+J3/WuIB6XMl1f4=
这些条目确认你的客户端已记录了 localhost 的多个公钥(ED25519、RSA 和 ECDSA)。SSH 服务器可能支持多种密钥类型以实现兼容性。如果这些服务器密钥中的任何一个发生意外更改,SSH 将向你发出警告,这是一项至关重要的安全功能。
生成并使用 SSH 密钥对实现免密登录
在这一步中,你将学习如何生成 SSH 密钥对并将其用于免密登录。基于 SSH 密钥的身份验证是密码验证的一种更安全、更便捷的替代方案。你无需每次连接时都输入密码,而是使用一对加密密钥:私钥(保存在本地机器上,必须保密)和公钥(放置在远程服务器上)。
首先,你需要生成一个 SSH 密钥对。为此,你将使用 ssh-keygen 命令。默认情况下,ssh-keygen 会创建一个 RSA 密钥对,并将私钥保存在 ~/.ssh/id_rsa 中,将公钥保存在 ~/.ssh/id_rsa.pub 中。
执行 ssh-keygen 命令:
ssh-keygen
系统会提示你进行一些选择:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/labex/.ssh/id_rsa):
按 Enter 接受默认文件路径(/home/labex/.ssh/id_rsa)。
Enter passphrase (empty for no passphrase):
在本实验中,按两次 Enter 将密码短语留空。虽然在实际场景中建议使用密码短语以增加一层安全保障,但为了简单起见并直接演示免密登录,我们在此跳过它。
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/labex/.ssh/id_rsa
Your public key has been saved in /home/labex/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:QoV7pNBFu1kafGP3VJhpZuIdr1zc+qamJ1C2YAadgNY labex@6846375f1c0e35fea6cb03e6
The key's randomart image is:
+---[RSA 3072]----+
| . *=o . +.|
| . =oE.o . O. |
| o.++.=..*.+.|
| .o .O+o+o. =|
| ..So + o.+ |
| . . . + |
| . . |
| . o o|
| .=.o |
+----[SHA256]-----+
现在,验证密钥文件是否已在 ~/.ssh/ 目录中创建:
ls -l ~/.ssh/
total 16
-rw------- 1 labex labex 2622 Jun 9 01:37 id_rsa
-rw-r--r-- 1 labex labex 584 Jun 9 01:37 id_rsa.pub
-rw------- 1 labex labex 825 Jun 9 01:35 known_hosts
-rw-r--r-- 1 labex labex 91 Jun 9 01:35 known_hosts.old
你应该能看到 id_rsa(你的私钥)和 id_rsa.pub(你的公钥)。请注意权限:id_rsa 的权限为 rw-------(仅所有者可读写),这对安全性至关重要。你可能还会看到 known_hosts.old,它是之前 known_hosts 文件的备份。
接下来,你需要复制你的公钥以启用免密登录。ssh-copy-id 命令就是为此设计的。它会将你的公钥追加到 ~/.ssh/authorized_keys 文件中,从而允许你无需密码即可登录。
执行 ssh-copy-id 命令,指定用户和主机名:
ssh-copy-id labex@localhost
系统会提示你输入 labex 用户的密码。输入 labex 并按 Enter。
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/labex/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
labex@localhost's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'labex@localhost'"
and check to make sure that only the key(s) you wanted were added.
命令输出确认已添加了一个密钥。现在,尝试以 labex 身份登录 localhost,无需提供密码:
ssh labex@localhost
如果配置正确,你应该无需输入密码即可通过 SSH 登录。
Last login: Mon Jun 9 01:37:39 2025 from 47.251.66.143
[labex@host ~]$
你已成功配置了使用密钥对的 SSH 免密登录!
要退出远程会话,请输入 exit:
exit
exit
Connection to localhost closed.
[labex@host ~]$
使用 ssh-agent 管理 SSH 密钥
在这一步中,你将学习如何使用 ssh-agent 管理你的 SSH 密钥。ssh-agent 是一个在后台运行的程序,它将你的私钥保存在内存中。当你的私钥受到密码短语保护时,这特别有用。你无需在每次使用密钥时都输入密码短语,只需在将密钥添加到 ssh-agent 时输入一次,之后代理就会在你的会话期间为你处理身份验证。
尽管你在上一步中生成了一个没有密码短语的密钥,但我们现在将创建一个带有密码短语的新密钥,以演示 ssh-agent 的用途。
首先,生成一个带有密码短语的新 SSH 密钥对。我们将此密钥命名为 id_rsa_passphrase,以将其与默认的 id_rsa 密钥区分开来。
ssh-keygen -f ~/.ssh/id_rsa_passphrase
系统会提示你输入密码短语。在本实验中,请使用 mypassphrase 作为密码短语。
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): mypassphrase
Enter same passphrase again: mypassphrase
Your identification has been saved in /home/labex/.ssh/id_rsa_passphrase
Your public key has been saved in /home/labex/.ssh/id_rsa_passphrase.pub
The key fingerprint is:
SHA256:BuSxVlJb1lsiUFi2I5DAvyL01fJ5d480LT86dgtcHEg labex@6846375f1c0e35fea6cb03e6
The key's randomart image is:
+---[RSA 3072]----+
| ...=o+=*. E |
| .o.*.=..+ o |
| .=.o o. = . |
| . .+... .. . .|
| . . . +S. + |
| . o ..o . o * .|
| . . . . = * |
| oooo|
| ..+.o|
+----[SHA256]-----+
注意: 如果你不小心在没有输入密码短语的情况下按了 Enter,密钥将在没有密码短语的情况下创建。在这种情况下,你可以删除这些文件并再次运行该命令,确保在提示时输入 mypassphrase。
现在,让我们将这个新的公钥复制到 localhost,以便你可以使用它进行身份验证。
ssh-copy-id -i ~/.ssh/id_rsa_passphrase.pub labex@localhost
由于你已经使用默认密钥设置了免密登录,该命令可能不会提示输入密码,而是使用你现有的身份验证:
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/labex/.ssh/id_rsa_passphrase.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'labex@localhost'"
and check to make sure that only the key(s) you wanted were added.
现在,尝试使用此新密钥连接到 localhost。你需要使用 -i 选项指定私钥文件。
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
如果你为密钥设置了密码短语,系统会提示你输入它。但是,如果你不小心在没有密码短语的情况下创建了密钥(如示例输出所示),你将直接登录:
Last login: Mon Jun 9 01:39:25 2025 from 47.251.66.143
[labex@host ~]$
你已登录。现在,退出会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
注意: 如果你的密钥没有密码短语,你仍然可以继续进行 ssh-agent 演示以了解其工作原理,尽管在这种情况下它不会提示输入密码短语。
首先,在当前的 shell 会话中启动 ssh-agent。eval 命令用于正确设置 ssh-agent 输出的环境变量。
eval "$(ssh-agent)"
Agent pid 1024
输出将显示 ssh-agent 的进程 ID (PID)。
接下来,将你的私钥 (id_rsa_passphrase) 添加到 ssh-agent。
ssh-add ~/.ssh/id_rsa_passphrase
如果你的密钥有密码短语,系统会提示你输入它。如果没有,密钥将直接添加:
Identity added: /home/labex/.ssh/id_rsa_passphrase (labex@6846375f1c0e35fea6cb03e6)
现在密钥已添加到 ssh-agent,尝试再次使用相同的密钥连接到 localhost。
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
你应该能够连接而无需输入密码短语(无论你的密钥是否有密码短语,因为它现在由代理管理):
Last login: Mon Jun 9 01:39:49 2025 from 127.0.0.1
[labex@host ~]$
你已成功使用 ssh-agent 管理你的 SSH 密钥。
重要提示: ssh-agent 环境变量仅在启动它的 shell 会话中可用。如果你在 SSH 会话中,则需要退出回到本地 shell 才能使用 ssh-add 命令。
先退出 SSH 会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
现在,要查看当前加载在 ssh-agent 中的密钥,可以使用 ssh-add -l:
ssh-add -l
如果代理正在运行且已加载密钥,你将看到如下输出:
3072 SHA256:BuSxVlJb1lsiUFi2I5DAvyL01fJ5d480LT86dgtcHEg /home/labex/.ssh/id_rsa_passphrase (RSA)
但是,如果你看到类似“Could not open a connection to your authentication agent”的错误消息,则意味着代理环境变量未在当前会话中设置。
要从 ssh-agent 中删除所有身份,请使用 ssh-add -D:
ssh-add -D
如果代理可访问,你将看到:
All identities removed.
但是,如果你看到“Could not open a connection to your authentication agent”,则意味着代理环境在当前会话中不可用。
现在,如果你尝试再次连接且你的密钥有密码短语,系统会提示你输入它,因为密钥已从代理中删除:
ssh -i ~/.ssh/id_rsa_passphrase labex@localhost
如果你的密钥有密码短语,你将看到:
Enter passphrase for key '/home/labex/.ssh/id_rsa_passphrase':
如果你的密钥没有密码短语,你仍然可以直接连接。如果提示输入密码短语,请按 Ctrl+C 取消连接尝试。
最后,要停止 ssh-agent 进程,可以使用 ssh-agent -k:
ssh-agent -k
如果未设置 SSH_AGENT_PID 环境变量,你可能会看到:
SSH_AGENT_PID not set, cannot kill agent
如果代理是在不同的 shell 会话中启动的,或者环境变量未正确导出,这是正常现象。
排查 SSH 连接问题
在这一步中,你将学习如何排查常见的 SSH 连接问题。当 SSH 连接失败时,找出确切的问题可能具有挑战性。ssh 命令提供了详细的输出选项,通过显示连接过程的详细信息,可以帮助诊断问题。
ssh 命令提供三个详细级别:-v、-vv 和 -vvv。每增加一个 v,显示的调试信息量就会增加。
让我们从尝试连接到 localhost 上一个不存在的端口开始,以演示连接失败并查看调试输出。
首先,使用 -v(详细)尝试连接到端口 2222(该端口应该没有运行服务):
ssh -v -p 2222 labex@localhost
你将看到类似以下的输出,表明连接被拒绝:
OpenSSH_8.7p1, OpenSSL 3.0.1 14 Dec 2021
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/01-training.conf
debug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf
debug1: /etc/ssh/ssh_config.d/50-redhat.conf line 3: Applying options for *
debug1: Connecting to localhost [127.0.0.1] port 2222.
ssh: connect to host localhost port 2222: Connection refused
现在,让我们使用 -vv(更详细):
ssh -vv -p 2222 labex@localhost
输出将更加详细,提供额外的调试消息:
OpenSSH_8.7p1, OpenSSL 3.0.1 14 Dec 2021
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/01-training.conf
debug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf
debug1: /etc/ssh/ssh_config.d/50-redhat.conf line 3: Applying options for *
debug2: resolving "localhost" port 2222
debug2: ssh_connect_direct: entering
debug1: Connecting to localhost [127.0.0.1] port 2222.
debug1: connect to address 127.0.0.1 port 2222: Connection refused
ssh: connect to host localhost port 2222: Connection refused
最后,使用 -vvv(最详细):
ssh -vvv -p 2222 labex@localhost
此级别提供最大量的调试信息,虽然可能让人不知所措,但对于复杂问题非常有用。
OpenSSH_8.7p1, OpenSSL 3.0.1 14 Dec 2021
debug3: ssh_connect_internal: entering
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Reading configuration data /etc/ssh/ssh_config.d/01-training.conf
debug1: /etc/ssh/ssh_config.d/01-training.conf line 1: Applying options for *
debug1: Reading configuration data /etc/ssh/ssh_config.d/50-redhat.conf
debug1: /etc/ssh/ssh_config.d/50-redhat.conf line 3: Applying options for *
debug2: resolving "localhost" port 2222
debug2: ssh_connect_direct: entering
debug1: Connecting to localhost [127.0.0.1] port 2222.
debug1: connect to address 127.0.0.1 port 2222: Connection refused
ssh: connect to host localhost port 2222: Connection refused
在这种情况下,错误 Connection refused 清楚地表明端口 2222 上没有运行 SSH 服务器。
现在,让我们模拟一个常见问题:主机密钥已更改。在第一步中,你连接到了 localhost,其公钥被添加到了你的 ~/.ssh/known_hosts 文件中。如果 SSH 服务器密钥发生更改(例如,由于服务器重建或恶意攻击),你的 SSH 客户端将检测到此不匹配并拒绝连接。
为了模拟这一点,我们将故意修改 localhost 的 known_hosts 条目,使其无效。
首先,使用 nano 打开 ~/.ssh/known_hosts 文件:
nano ~/.ssh/known_hosts
你将看到多行具有不同密钥类型的条目:
localhost ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHvl7dcZkvMNOr3cjKjlR2/JgFbGpURThT/bHnLZN6gG
localhost ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCynhy3601o9ZSGZoY0KB/QSonk5ykod2Tb7sCAqVn4ZgTCwd96BhPjJLPNQ6ldNASo1e7EzfT4BUjG5T0ZDRhgaI65qmDwITWipTWUfmYT5XoScyf6NDhcRxYiJwztFEkOvLcPhelS6UXj5Z7HdmYH4Nc5wiF00Wah3Jc0/2CfQsFZCXTn/7Kp8KKbBbPqPzr2R3WIULEacOxx9HKVv+2TvYg/OHZz40hTsr1c68DD7h5PMBNe21YB3HLRRk2LQEC7v7BFD+DCek9GNR66JBjbLDljtwWCaPCY0UntBjjvJ3W2LhX5RDZQHV/iaUSj2tEXnvPt9KSqGfBS91D12dBXyOmWVnTpvvI17BdDkEeefas2Uz4d7Bv/PDxZR6IKkaIGQ/ZnRhSEhBNvfqlBGqkOhRr6jQJK+rQMnsZCT6OEgW7osWzkw5Bs1wY/RNToeQqrRMclqffO9plFI688N2iT86+nxrvBVZg4yMMm2J1lleaBvinXCB8jE6lrtwoAdgk=
localhost ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKYWY8Ty6TrbQS/0fUljBWuUpkyPCS/5P6ZwxhSYsqjRBIprMANI/JQotZqHYq2w3b2X/n8O+J3/WuIB6XMl1f4=
选择其中一行进行修改。在本例中,让我们修改 ED25519 密钥(第一行)。修改长密钥字符串中的几个字符(例如,将最后一个字符从 G 改为 A)。注意不要删除整行或文件的其他部分。
例如,将:
...ZN6gG
改为:
...ZN6gA
按 Ctrl+X 保存文件,然后按 Y 确认保存,按 Enter 确认文件名。
现在,尝试再次连接到 localhost:
ssh labex@localhost
你将收到关于主机密钥已更改的警告:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:h5k1mmPFylpxUCsKx+Mf8rN4wOrk9TmyRfzTvGWRm7A.
Please contact your system administrator.
Add correct host key in /home/labex/.ssh/known_hosts to get rid of this message.
Offending key in /home/labex/.ssh/known_hosts:1
ED25519 host key for localhost has changed and you have requested strict checking.
Host key verification failed.
这是一个严重的安全警告。如果你在现实场景中遇到这种情况,你应该调查主机密钥更改的原因。如果是合法的更改(例如服务器重新安装),你需要从 known_hosts 中删除旧条目。
要解决此问题,你可以手动编辑 ~/.ssh/known_hosts 并删除有问题的行,或者使用 ssh-keygen -R 删除 localhost 的条目。
让我们使用 ssh-keygen -R 删除错误的条目:
ssh-keygen -R localhost
## Host localhost found: line 1
## Host localhost found: line 2
## Host localhost found: line 3
/home/labex/.ssh/known_hosts updated.
Original contents retained as /home/labex/.ssh/known_hosts.old
现在,尝试再次连接到 localhost。系统会提示你确认主机的真实性,就像你第一次连接时一样。
ssh labex@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
ED25519 key fingerprint is SHA256:h5k1mmPFylpxUCsKx+Mf8rN4wOrk9TmyRfzTvGWRm7A.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'localhost' (ED25519) to the list of known hosts.
Last login: Mon Jun 9 01:40:03 2025 from 127.0.0.1
[labex@host ~]$
你现在已成功再次使用基于密钥的身份验证连接。
退出会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
自定义 SSH 客户端配置
在这一步中,你将学习如何使用 ~/.ssh/config 文件自定义你的 SSH 客户端配置。此文件允许你为不同的远程主机定义别名和特定的连接参数,从而简化你的 SSH 命令并使其更加一致。
~/.ssh/config 文件是管理 SSH 连接的强大工具。你可以指定各种选项,例如用户名、要使用的私钥文件、端口号,甚至更高级的设置(如代理命令)。
首先,让我们创建或打开 ~/.ssh/config 文件。如果它不存在,nano 将创建它。
nano ~/.ssh/config
将以下配置添加到文件中。此配置定义了一个别名 localhost_labex,用于以 labex 用户身份连接到 localhost;以及一个别名 localhost_root,用于以 root 用户身份连接。它还明确指定了 labex 用户的 IdentityFile,以使用在之前步骤中生成的 id_rsa 密钥。
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
按 Ctrl+X 保存文件,然后按 Y 确认保存,按 Enter 确认文件名。
现在,让我们尝试使用这些新别名连接到 localhost。
使用 localhost_labex 别名以 labex 身份连接:
ssh localhost_labex
由于你配置了 IdentityFile ~/.ssh/id_rsa 且 id_rsa 没有密码短语,你应该无需输入密码即可登录。
Last login: Mon Jun 9 01:54:16 2025 from 47.251.66.143
[labex@host ~]$
退出会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
现在,使用 localhost_root 别名以 root 身份连接:
ssh localhost_root
系统会提示你输入 root 用户的密码。但是,由于在此环境中禁用了 root 登录,你将收到“Permission denied”消息:
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
按 Ctrl+C 取消连接尝试:
^C
这表明 SSH 配置别名有效,但由于禁用 root 登录的安全策略,连接失败。
如你所见,使用 ~/.ssh/config 文件通过预配置常见的连接参数简化了你的 SSH 命令。
让我们添加另一个条目来演示指定不同的端口。虽然 localhost 使用默认的 SSH 端口 (22),但此示例展示了如果端口不同,你将如何配置它。
再次打开 ~/.ssh/config 文件:
nano ~/.ssh/config
添加以下条目。这创建了一个别名 localhost_port_example,它明确将端口设置为 2222。(注意:localhost 实际上并没有在端口 2222 上监听,因此此连接将失败,但这演示了配置方法。)
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
Host localhost_port_example
HostName localhost
Port 2222
User labex
保存文件。
现在,尝试使用 localhost_port_example 别名连接:
ssh localhost_port_example
此连接将失败,因为 localhost 没有在端口 2222 上监听,但这演示了如何在 SSH 配置中指定自定义端口。
ssh: connect to host localhost port 2222: Cannot assign requested address
You can find some explanations for typical errors at this link:
https://red.ht/support_rhel_ssh
你可以查看当前的 SSH 配置以查看所有定义的别名:
cat ~/.ssh/config
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
Host localhost_port_example
HostName localhost
Port 2222
User labex
最后,让我们通过删除 localhost_port_example 条目来清理 ~/.ssh/config 文件。
打开 ~/.ssh/config 文件:
nano ~/.ssh/config
删除 Host localhost_port_example 块。文件应如下所示:
Host localhost_labex
HostName localhost
User labex
IdentityFile ~/.ssh/id_rsa
Host localhost_root
HostName localhost
User root
保存文件。
理解 OpenSSH 服务器安全配置
在这一步中,你将通过检查当前的安全配置来了解 OpenSSH 服务器的安全最佳实践。你将了解 root 登录限制和密码验证设置如何协同工作,以保护你的服务器免受未经授权的访问。
注意: 在本实验环境中,你将检查当前的 SSH 安全配置并了解不同的安全设置。这一步侧重于理解这些安全措施并学习 SSH 服务器配置的最佳实践。
理解 root 登录安全
通常不建议允许通过 SSH 直接进行 root 登录,因为 root 账户拥有完全的管理员权限。如果攻击者获得了 root 账户的访问权限,他们就拥有了对你系统的完全控制权。以普通用户身份登录,然后使用 sudo 执行管理任务会更安全。
让我们检查当前的 root 登录配置并测试其有效性。
首先,以 labex 用户身份通过 SSH 登录。
ssh labex@localhost
如果之前步骤中的 SSH 密钥设置正确,你应该无需密码即可登录。
Last login: Mon Jun 9 01:57:27 2025 from 47.251.66.143
[labex@host ~]$
现在,让我们检查 SSH 服务器配置文件以了解当前的安全设置:
sudo cat /etc/ssh/sshd_config | grep -E "^PermitRootLogin|^#PermitRootLogin"
此命令将显示当前的 PermitRootLogin 设置。你应该看到类似以下内容:
PermitRootLogin no
此设置意味着通过 SSH 直接进行 root 登录已被禁用,这是一种安全最佳实践。
让我们测试 root 登录是否确实被阻止。首先,退出当前的 SSH 会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
现在,尝试以 root 身份登录 localhost:
ssh root@localhost
你应该会看到“Permission denied”消息,表明不允许直接进行 root 登录(这可能已经在你的环境中配置好了)。
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
Permission denied, please try again.
root@localhost's password:
这确认了在此环境中 root 登录已被禁用,这是理想的安全配置。“Permission denied”消息证明了该安全措施正在有效工作。
理解密码验证安全
禁用密码验证会强制用户依赖更安全的方法,例如基于 SSH 密钥的身份验证。这显著降低了针对你的服务器进行暴力破解攻击的风险。
让我们检查当前的密码验证设置并了解其工作原理。
以 labex 用户身份通过 SSH 登录(使用你的 SSH 密钥):
ssh labex@localhost
Last login: Mon Jun 9 01:57:32 2025 from 127.0.0.1
[labex@host ~]$
首先,让我们检查当前的 PasswordAuthentication 设置:
sudo cat /etc/ssh/sshd_config | grep PasswordAuthentication
PasswordAuthentication yes
## PasswordAuthentication. Depending on your PAM configuration,
## PAM authentication, then enable this but set PasswordAuthentication
如你所见,当前配置为 PasswordAuthentication yes,这意味着密码验证已启用。虽然这允许用户使用密码进行身份验证,但也带来了安全风险,因为它使服务器容易受到暴力破解密码攻击。
输出显示:
PasswordAuthentication yes- 这是启用密码验证的活动设置- 注释行提供了关于 PAM 配置的额外上下文
此配置意味着用户可以使用密码和 SSH 密钥进行身份验证。为了增强安全性,建议禁用密码验证,仅依赖基于 SSH 密钥的身份验证。
退出当前的 SSH 会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
现在,让我们验证在禁用密码验证的同时,基于 SSH 密钥的身份验证是否正常工作:
ssh labex@localhost
这应该无需密码提示即可成功,并使用你的 SSH 密钥:
Last login: Mon Jun 9 02:00:22 2025 from 127.0.0.1
[labex@host ~]$
这演示了几个重要的安全概念:
- 密码验证已启用 (
PasswordAuthentication yes) - 用户可以使用密码和 SSH 密钥登录 - 基于 SSH 密钥的身份验证正常工作 - 更安全的身份验证方法可用
- 服务器允许两种身份验证方法 - 虽然方便,但这可能会带来暴力破解攻击的安全风险
- root 登录已禁用 - 管理访问需要适当的用户权限提升
安全建议: 对于生产环境,请考虑设置 PasswordAuthentication no,通过强制用户仅使用基于 SSH 密钥的身份验证来增强安全性。
退出会话:
exit
exit
Connection to localhost closed.
[labex@host ~]$
你已成功检查并理解了 OpenSSH 服务器安全配置。服务器目前禁用了 root 登录(遵循安全最佳实践),并启用了密码验证(提供了灵活性,但可能需要针对生产环境进行额外的安全考量)。你还验证了基于 SSH 密钥的身份验证作为一种更安全的身份验证方法可以正常工作。
总结
在本实验中,参与者学习了如何使用 SSH 访问系统,从验证 openssh-clients 的安装并连接到 localhost 开始。他们练习了使用密码进行身份验证,并理解了初始的主机真实性检查。
实验进一步引导用户生成并利用 SSH 密钥对实现免密登录,使用 ssh-agent 管理这些密钥,并排查常见的 SSH 连接问题。最后,参与者学习了如何自定义 SSH 客户端配置,并通过禁用 root 登录和密码验证来保护 OpenSSH 服务器,从而增强了他们对安全远程访问实践的理解。



