SSH 服务器加固的 10 个必备最佳实践
安全外壳 (SSH) 是远程服务器管理的核心,它提供了一个加密网络协议,用于安全的数据通信、远程命令执行和其他网络服务。然而,它的普遍性也使其成为攻击者的首要目标。一个安全不足的 SSH 服务器可能成为关键漏洞,导致未经授权的访问、数据泄露和系统被攻陷。保护您的远程访问环境不仅仅是良好实践;它是必需的。
本文概述了加固 SSH 服务器配置的 10 个必备最佳实践。通过实施这些关键的配置指令、推荐的权限设置和安全技巧,您可以显著增强服务器抵御未经授权访问和常见攻击向量(如暴力破解尝试和凭据填充)的能力。遵循这些指南将有助于确保您的远程管理保持安全,并保护您的服务器基础设施。
1. 更改默认 SSH 端口
默认的 SSH 端口是 22。这是自动化机器人寻找易受攻击服务器时普遍知晓并持续扫描的端口。更改默认端口提供了一个简单但有效的混淆层。虽然它本身不是一种安全措施,但它能显著减少自动化扫描的噪音,并有助于避免许多机会主义攻击。
要更改端口,请编辑 sshd_config 文件,通常位于 /etc/ssh/sshd_config。
sudo nano /etc/ssh/sshd_config
找到 Port 22 行(如果不存在则添加),并将 22 更改为一个非标准、未分配的端口号(例如,2222,49152-65535 是用户/动态端口)。
#Port 22
Port 2222
保存文件后,重启 SSH 服务。请记住更新您的防火墙规则,允许在新端口上进行流量,并阻止旧端口。
sudo systemctl restart sshd
# 对于 UFW (Uncomplicated Firewall):
sudo ufw allow 2222/tcp
sudo ufw deny 22/tcp
sudo ufw reload
# 对于 Firewalld:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --remove-port=22/tcp
sudo firewall-cmd --reload
技巧: 在测试配置更改时,始终保持至少一个 SSH 会话打开。如果您被锁定,可以在活动会话中恢复更改。
2. 禁用 Root 登录
强烈不建议通过 SSH 直接进行 root 登录。root 用户拥有不受限制的特权,使其成为攻击者的首要目标。如果攻击者获得 root 访问权限,他们将完全控制您的系统。相反,请以普通、非特权用户身份登录,然后使用 sudo 执行管理任务。
在 sshd_config 中,找到 PermitRootLogin 指令并将其设置为 no。
PermitRootLogin no
保存并重启 SSH 服务:
sudo systemctl restart sshd
3. 使用基于密钥的身份验证
基于密码的身份验证容易受到暴力破解攻击和字典攻击,尤其是当用户选择弱密码时。SSH 基于密钥的身份验证是一种更安全的替代方案。它使用一对加密密钥:存储在服务器上的公钥和保存在您本地机器上的私钥。只有拥有匹配私钥的客户端才能进行身份验证。
实现基于密钥的身份验证的步骤(简述):
- 在您的本地机器上生成密钥对:
bash ssh-keygen -t ed25519 -b 4096 -C "[email protected]"ed25519是一种现代、安全的算法。rsa也常用,通常使用-b 4096指定密钥强度。
- 将公钥复制到您的服务器:
bash ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your_server_ip
或者,手动将~/.ssh/id_ed25519.pub的内容追加到服务器上您希望登录的用户的~/.ssh/authorized_keys文件中。 -
确保服务器上的正确权限:
~/.ssh目录:700(仅所有者可读写执行)~/.ssh/authorized_keys文件:600(仅所有者可读写)
bash chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys
4. 禁用密码身份验证
一旦您成功为所有必要的用户设置并测试了基于密钥的身份验证,就应该完全禁用密码身份验证。通过使暴力破解密码攻击成为不可能,消除了 SSH 安全中最薄弱的环节。
在 sshd_config 中,将 PasswordAuthentication 设置为 no。
PasswordAuthentication no
保存并重启 SSH 服务:
sudo systemctl restart sshd
警告: 切勿 在验证基于密钥的身份验证对所有需要访问的用户都能正常工作之前禁用密码身份验证。否则,您将面临将自己锁定在服务器之外的风险。
5. 限制用户访问
默认情况下,服务器上的任何用户帐户都可以尝试通过 SSH 登录。您可以将 SSH 访问限制为仅限于特定用户或组,从而最小化攻击面。
在 sshd_config 中使用 AllowUsers 或 AllowGroups 指令。
仅允许特定用户(例如 adminuser、devuser)登录:
AllowUsers adminuser devuser
仅允许特定组(例如 sshusers)的成员登录:
AllowGroups sshusers
技巧: 如果您有多个用户,通常最好使用 AllowGroups。创建一个专用的 SSH 访问组,并将授权用户添加到其中。
sudo groupadd sshusers
sudo usermod -aG sshusers adminuser
sudo usermod -aG sshusers devuser
进行更改后,保存并重启 SSH。
6. 为 SSH 密钥使用强密码短语
虽然基于密钥的身份验证很强大,但您的私钥仍然是关键资产。如果攻击者获得了对您本地机器的访问权限,他们可能会窃取您的私钥。一个强密码短语可以加密您的私钥,在使用之前需要输入密码短语才能解锁。这增加了另一层安全性,即使您的密钥落入他人之手也能提供保护。
在生成 SSH 密钥时(如步骤 3 所示),系统会提示您输入密码短语。选择一个长而复杂且容易记住的密码短语,并且与您使用的任何其他密码都不同。
7. 实施连接速率限制 (Fail2Ban)
即使有了基于密钥的身份验证,SSH 服务器仍然可能面临连接尝试。像 Fail2Ban 这样的工具可以主动监控 SSH 日志,查找来自同一 IP 地址的重复登录失败尝试,并自动使用防火墙规则将该 IP 地址暂时封禁。
安装(Debian/Ubuntu 示例):
sudo apt update
sudo apt install fail2ban
Fail2Ban 在默认 SSH 规则下即可工作,但您可以通过将 jail.conf 复制到 jail.local 并进行编辑来定制其配置。
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local
在 jail.local 中,您可以调整 [sshd] 部分的 bantime、findtime 和 maxretry。
[sshd]
enabled = true
port = 2222 # 您的新 SSH 端口
logpath = %(sshd_log)s
maxretry = 3
bantime = 1h # 封禁 1 小时
findtime = 10m # 在 10 分钟内查找 3 次失败
配置更改后重启 Fail2Ban:
sudo systemctl restart fail2ban
8. 保持 SSH 服务器软件更新
软件漏洞不断被发现和修补。运行过时的 SSH 守护程序软件 (OpenSSH) 意味着您可能会暴露在已知漏洞之下。定期更新服务器软件,包括 OpenSSH 服务器包,对于修补安全漏洞至关重要。
# 对于 Debian/Ubuntu:
sudo apt update && sudo apt upgrade
# 对于 CentOS/RHEL:
sudo yum update
# 或
sudo dnf update
在适当的情况下配置您的系统以自动应用安全更新,或建立手动更新的例程。
9. 监控 SSH 日志以发现可疑活动
即使采取了强有力的预防措施,警惕性仍然是关键。定期查看 SSH 身份验证日志,以检测异常模式、登录失败尝试或未经授权的访问尝试。这有助于您识别潜在的泄露或正在进行的攻击。
SSH 日志通常位于:
/var/log/auth.log(Debian/Ubuntu)/var/log/secure(CentOS/RHEL)- 使用
journalctl(systemd 系统):
bash sudo journalctl -u sshd -f
查找重复的身份验证失败尝试、来自不寻常 IP 地址的登录,或不熟悉用户的成功登录。像 Logwatch 或 Elastic Stack (ELK) 这样的工具可以为大型环境自动化日志分析和警报。
10. 配置防火墙规则以限制访问
防火墙是您的第一道防线。默认情况下,它应该阻止所有传入流量,除了您明确需要公开的服务。对于 SSH,这意味着仅允许连接到您选择的端口(例如 2222),并且理想情况下,仅允许来自特定受信任 IP 地址或网络的连接。
使用 UFW (Uncomplicated Firewall) 的示例:
允许来自特定 IP 地址 192.168.1.100 在端口 2222 上的 SSH 连接:
sudo ufw allow from 192.168.1.100 to any port 2222
允许来自特定子网 192.168.1.0/24 的 SSH 连接:
sudo ufw allow from 192.168.1.0/24 to any port 2222
使用 Firewalld (CentOS/RHEL) 的示例:
允许来自特定 IP 地址 192.168.1.100 在端口 2222 上的 SSH 连接:
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port=2222 protocol="tcp" accept'
sudo firewall-cmd --reload
警告: 如果您正在从动态 IP 地址管理服务器,请谨慎使用严格的防火墙规则。您可能需要允许更广泛范围的访问或使用 VPN。
其他加固技巧
除了必备的 10 条,还可以考虑以下指令以获得更高级别的安全性:
MaxAuthTries:限制每个连接的身份验证尝试次数。默认为 6。降低它(例如3)可以减少暴力破解的机会。在sshd_config中设置。
config MaxAuthTries 3LoginGraceTime:限制用户进行身份验证的时间。默认为 2 分钟。降低它(例如30s)可以缩短慢速攻击的窗口期。
config LoginGraceTime 30sClientAliveInterval和ClientAliveCountMax:防止空闲的 SSH 会话无限期地保持打开状态。ClientAliveInterval每 X 秒发送一个空数据包。如果错过ClientAliveCountMax(默认为 3)次响应,连接将被终止。
config ClientAliveInterval 300 ClientAliveCountMax 0 # 如果您希望会话无限期持续,则禁用客户端存活检查Banner:在身份验证之前显示警告消息。这为潜在的未经授权的用户提供了法律通知。
config Banner /etc/issue.net
创建/etc/issue.net文件并包含您想要的警告消息。
结论
加固您的 SSH 服务器是一个持续的过程,而不是一次性设置。通过实施这 10 个必备的最佳实践——从更改默认端口、禁用 root 登录到强制执行基于密钥的身份验证和部署防火墙——您可以为您的远程访问建立强大的安全态势。始终牢记要仔细测试更改,保持系统更新,并定期监控日志以发现任何可疑活动。持续的警惕是维护安全可靠的远程管理环境的关键。
这些实践是任何服务器管理员的基础,并将大大降低您暴露于常见网络威胁的可能性,保护您的服务器基础设施免受未经授权的访问和潜在的风险。