Debian 服务器默认的 SSH 配置在公网环境中并不安全,尤其是允许密码登录这一点。只要服务器暴露在公网,每天都会有自动化扫描程序尝试用常见用户名和弱密码暴力破解 SSH。禁用密码登录、改用密钥认证,是降低攻击面最直接有效的手段。下面直接讲清楚配置步骤、关键参数含义以及容易忽略的细节。
确认当前 SSH 服务状态先检查 SSH 服务是否在运行,以及当前配置文件的位置。Debian 系统中 SSH 服务端配置文件通常位于 /etc/ssh/sshd_config。执行以下命令查看服务状态:
systemctl status ssh
如果服务未运行,先启动并设置开机自启:
systemctl enable --now ssh
在修改任何配置之前,建议备份原文件:
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)
这样一旦配置出错导致无法登录,还可以通过服务器控制台或救援模式恢复。
生成 SSH 密钥对如果你还没有密钥对,需要先在本地电脑生成。不要使用过时的 RSA 1024 位,推荐使用 Ed25519 算法,安全性和性能都更好。在本地终端执行:
ssh-keygen -t ed25519 -a 100 -C "your-email@example.com"
命令会提示保存路径,默认是 ~/.ssh/id_ed25519。可以设置密码保护私钥,也可以留空。生成后会得到两个文件:id_ed25519(私钥,留在本地)和 id_ed25519.pub(公钥,需要上传到服务器)。
将公钥上传到服务器使用 ssh-copy-id 命令是最简单的方式。如果服务器当前还允许密码登录,执行:
ssh-copy-id -i ~/.ssh/id_ed25519.pub 用户名@服务器IP
系统会提示输入一次用户密码,成功后公钥会被追加到服务器对应用户的 ~/.ssh/authorized_keys 文件中。如果 ssh-copy-id 不可用,也可以手动复制公钥内容,登录服务器后执行:
mkdir -p ~/.ssh && chmod 700 ~/.ssh echo "公钥内容" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
权限设置非常重要。如果 authorized_keys 文件权限过于宽松,SSH 会拒绝使用该公钥认证。
测试密钥登录是否成功在禁用密码登录之前,务必先测试密钥登录是否正常。新开一个终端窗口,执行:
ssh -i ~/.ssh/id_ed25519 用户名@服务器IP
如果能够直接登录而不需要输入密码,说明密钥认证已经生效。如果仍然提示输入密码,检查服务器 /var/log/auth.log 中的错误信息,常见原因包括公钥内容复制不完整、文件权限错误、SELinux 或 AppArmor 限制等。Debian 默认没有 SELinux,但某些定制内核或安全模块可能影响。
修改 SSH 服务端配置禁用密码登录确认密钥登录正常后,开始修改 sshd_config。使用编辑器打开:
nano /etc/ssh/sshd_config
找到以下参数并修改。如果参数被注释,取消注释并设置正确值。如果不存在,就在文件末尾添加。
PasswordAuthentication no ChallengeResponseAuthentication no UsePAM no PermitRootLogin prohibit-password PubkeyAuthentication yes AuthenticationMethods publickey
各参数含义如下:
PasswordAuthentication no:禁止使用密码认证,这是核心配置。
ChallengeResponseAuthentication no:禁用键盘交互认证,防止某些 PAM 模块绕过密码认证限制。
UsePAM no:关闭 PAM 认证模块。这个参数要谨慎,某些系统依赖 PAM 做账户限制。对于纯粹的密钥登录场景,关闭它可以减少攻击面。如果服务器还需要其他 PAM 功能,可以保留为 yes,但必须确保 ChallengeResponseAuthentication 为 no。
PermitRootLogin prohibit-password:允许 root 通过密钥登录,但禁止 root 使用密码。如果你不希望 root 直接登录,可以设置为 no,然后使用普通用户加 sudo。
PubkeyAuthentication yes:显式启用公钥认证,确保密钥登录不会被关闭。
AuthenticationMethods publickey:强制所有登录方式都必须使用公钥认证。这一行可以防止某些组合认证方式绕过密码禁用设置。
检查配置语法并重启服务修改完成后,先检查配置语法是否正确:
sshd -t
如果没有任何输出,说明语法正确。如果有错误,会提示具体行号和问题。确认无误后重启 SSH 服务:
systemctl restart ssh
重启服务不会中断已经建立的连接,所以当前已登录的会话不受影响。但新连接会使用新配置。
验证密码登录已被禁用保持当前会话不要断开,新开一个终端窗口,尝试使用密码登录:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no 用户名@服务器IP
如果配置正确,连接会被拒绝,并显示类似“Permission denied (publickey)”的提示。这说明密码登录已经彻底关闭。
进一步加固 SSH 配置禁用密码登录只是基础安全措施,还可以结合以下配置进一步降低风险。
限制登录用户:只允许特定用户通过 SSH 登录,使用 AllowUsers 参数。
AllowUsers deploy admin
修改默认端口:将 SSH 端口从 22 改为高位端口,可以减少大量自动化扫描流量。在 sshd_config 中设置:
Port 2222
修改后需要同时在防火墙中放行新端口,并更新本地连接命令。注意,修改端口不是真正的安全措施,但能过滤掉大部分无差别扫描。
限制登录尝试频率:Debian 默认没有安装 fail2ban,可以安装并配置 fail2ban 来封禁暴力破解 IP。
apt update && apt install fail2ban -y
安装后默认配置就能对 SSH 进行基本防护。可以创建 /etc/fail2ban/jail.local 文件,设置封禁时间和尝试次数:
[sshd] enabled = true maxretry = 3 bantime = 3600 findtime = 600
重启 fail2ban 服务生效:
systemctl restart fail2ban
关闭 DNS 反向解析:如果服务器不需要根据客户端 IP 反查主机名,可以在 sshd_config 中设置:
UseDNS no
这可以加快连接速度,并减少某些基于 DNS 的探测行为。
设置登录超时:对于已认证但未完成会话建立的连接,设置较短超时时间。
LoginGraceTime 30
限制 root 登录位置:如果必须允许 root 密钥登录,可以通过 authorized_keys 文件中的 from 选项限制来源 IP。
from="203.0.113.10" ssh-ed25519 AAAAC3...
这样即使私钥泄露,攻击者也无法从其他 IP 登录。
常见问题与排查问题一:修改配置后无法登录。这通常是因为密钥文件权限错误或公钥没有正确写入。检查服务器对应用户的 ~/.ssh 目录权限应为 700,authorized_keys 文件权限应为 600。同时确认私钥在本地权限为 600。
问题二:重启 SSH 服务后新连接被拒绝,但旧连接还在。不要关闭旧连接,通过旧连接查看 /var/log/auth.log 日志,定位具体拒绝原因。
问题三:使用 UsePAM no 后某些账户无法登录。如果服务器配置了复杂的 PAM 账户限制,建议将 UsePAM 保持为 yes,只关闭 ChallengeResponseAuthentication 和 PasswordAuthentication。
问题四:自动化部署工具依赖密码登录。需要提前为这些工具生成专用密钥对,并将公钥部署到目标服务器,同时更新部署脚本使用密钥认证。
密钥管理与轮换禁用密码登录后,私钥成为唯一的登录凭证,管理不善会导致无法登录或安全风险。建议为不同用途生成不同密钥对,例如个人管理、自动化部署、备份任务分别使用独立密钥。定期检查 authorized_keys 文件,删除不再使用的公钥。对于多人协作的服务器,要求每个用户使用自己的密钥,不要共享私钥。
如果私钥泄露,立即在服务器上删除对应公钥,并生成新密钥对。同时检查服务器日志,确认是否有异常登录行为。
总结禁用密码登录是 Debian 服务器 SSH 安全加固中最关键的一步。核心操作包括生成并部署密钥、修改 sshd_config 中的 PasswordAuthentication 为 no、测试密钥登录、重启服务并验证密码登录已失效。配合限制登录用户、修改端口、安装 fail2ban、关闭 DNS 反查等措施,可以显著降低服务器被暴力破解的风险。整个过程必须保持至少一个已登录会话,防止配置错误导致无法连接。
