要彻底禁用Ubuntu的密码认证并强制使用SSH密钥登录,你需要修改SSH服务端配置、正确部署密钥文件、并严格测试连接。以下是具体操作步骤和注意事项。
为什么必须禁用SSH密码登录?
SSH密码登录存在被暴力破解的风险,尤其是暴露在公网的服务器。攻击者可以使用自动化工具不断尝试常见密码组合。相比之下,SSH密钥登录使用非对称加密,私钥本地保存且可设置密码短语,公钥存放在服务器,即使公钥泄露也无法反向推导私钥,安全性远高于密码。对于生产服务器或存有敏感数据的系统,禁用密码认证是基本的安全加固措施。
第一步:生成SSH密钥对
在本地客户端机器(例如你的个人电脑)上生成密钥对。打开终端,执行以下命令。如果你已有密钥对(通常位于~/.ssh/id_rsa和~/.ssh/id_rsa.pub),可以跳过此步。
ssh-keygen -t rsa -b 4096
命令解释:-t rsa指定密钥类型为RSA,-b 4096指定密钥长度为4096位(更安全)。执行过程中会提示你选择密钥保存路径(直接回车使用默认路径即可)和设置一个可选的密码短语(passphrase)。设置密码短语能为私钥再加一层保护,即使私钥文件被盗,没有短语也无法使用。
第二步:将公钥上传到Ubuntu服务器
你需要将生成的公钥文件(默认为id_rsa.pub)内容添加到服务器对应用户的~/.ssh/authorized_keys文件中。最简便的方法是使用ssh-copy-id命令。
ssh-copy-id username@your_server_ip
将username替换为你的服务器用户名,your_server_ip替换为服务器IP地址。此命令会自动将你的公钥追加到服务器用户的authorized_keys文件末尾。如果命令不可用,可以手动操作:首先在本地查看公钥内容cat ~/.ssh/id_rsa.pub,复制输出结果;然后登录服务器,确保~/.ssh目录存在(权限应为700),编辑(或创建)~/.ssh/authorized_keys文件(权限应为600),将复制的公钥内容粘贴进去。
第三步:测试SSH密钥登录
在修改SSH配置前,必须先测试密钥登录是否成功。保持当前的密码登录会话开启,并开启一个新的终端窗口尝试使用密钥登录。
ssh username@your_server_ip
如果配置正确,你将无需输入用户密码(但如果你为私钥设置了密码短语,则需要输入)即可登录。如果失败,请检查服务器上authorized_keys文件的权限、内容是否正确,以及~/.ssh目录的权限。
第四步:修改SSH服务端配置以禁用密码认证
密钥登录测试成功后,登录服务器,使用sudo权限编辑SSH服务端的主配置文件/etc/ssh/sshd_config。
sudo nano /etc/ssh/sshd_config
找到并修改以下关键参数,确保它们的状态如下:
PubkeyAuthentication yes PasswordAuthentication no ChallengeResponseAuthentication no UsePAM no
参数详解:
PubkeyAuthentication yes:启用公钥认证,这是密钥登录的基础。
PasswordAuthentication no:核心设置,禁用所有通过密码的认证方式。
ChallengeResponseAuthentication no:禁用质询-应答认证,它通常也涉及密码。
UsePAM no:禁用可插拔认证模块(PAM),PAM可能绕开上述设置启用密码认证。但请注意,在某些发行版或特定配置(如某些SFTP设置)下,禁用PAM可能导致问题。如果你后续遇到其他服务认证问题,可以尝试将其设为yes,但前两个设置已足以禁用密码登录。
你还可以考虑修改PermitRootLogin参数,将其设置为prohibit-password或no,以禁止root用户直接使用密码登录(甚至完全禁止root登录),进一步加固系统。
第五步:重启SSH服务并创建“逃生”会话
在应用配置前,这是最关键的安全步骤。由于配置错误可能导致你被锁在服务器外,务必提前做好预防。
1. 开启一个持久的SSH连接会话:在重启SSH服务前,保持一个当前有效的SSH登录会话不要关闭。这个会话将作为你的“逃生通道”。
2. 在新窗口中测试配置语法:在“逃生”会话中,运行sudo sshd -t来检查配置文件是否有语法错误。无输出则表示语法正确。
3. 小心地重启SSH服务:在“逃生”会话中,执行重启命令。
sudo systemctl restart sshd
4. 使用新会话测试连接:打开第三个终端窗口,尝试用SSH密钥登录服务器。确保登录成功,并且输入密码的环节被跳过(或仅需私钥密码短语)。
5. 验证密码登录已失效:你可以故意使用一个错误的私钥或指定不使用密钥来测试,命令如下:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no username@your_server_ip
此时,服务器应该直接拒绝连接,或提示“Permission denied (publickey)”,而不会给你输入密码的机会。只有在新会话测试完全成功后,你才能安全地关闭最初的“逃生”会话。
高级配置与故障排除
针对特定用户或用户组进行限制:你可以在sshd_config文件中使用Match块进行更精细的控制。例如,允许内网特定IP段使用密码,而其他全部禁用:
Match Address 192.168.1.0/24
PasswordAuthentication yes密钥文件权限问题:这是最常见的失败原因。服务器上相关文件和目录的权限必须严格:~/.ssh目录权限应为700 (drwx------),authorized_keys文件权限应为600 (-rw-------)。权限过宽,SSH守护进程出于安全考虑会拒绝使用它们。
SELinux/AppArmor的影响:如果你在服务器上启用了强制访问控制框架如SELinux,可能需要调整上下文。如果密钥登录在权限正确的情况下仍失败,可以暂时将SELinux设置为宽容模式测试:sudo setenforce 0。如果问题解决,你需要为.ssh目录设置正确的上下文:sudo restorecon -Rv ~/.ssh。
彻底禁用后的管理建议
1. 密钥管理:妥善备份你的私钥,并考虑为团队使用密钥管理系统。不要将私钥通过网络传输或存储在云盘。
2. 备用访问通道:对于物理服务器或云服务器,确保你保留了控制台访问权限(如云服务商的VNC、串行控制台等)。这是配置出错被锁在外的最后补救手段。
3. 审计与监控:定期检查/var/log/auth.log文件,查看失败的登录尝试。你会看到大量针对密码登录的失败尝试被拒绝,这证明了你的配置正在生效。
sudo grep "Failed password" /var/log/auth.log | tail -20
4. 考虑使用Fail2ban:虽然禁用了密码登录,但SSH端口仍然会收到大量探测。使用Fail2ban等工具可以监控日志,将多次尝试连接(即使是尝试密钥)的IP地址临时加入防火墙黑名单,减少日志噪音和潜在骚扰。
遵循上述步骤,你可以系统性地将Ubuntu服务器的SSH认证方式从脆弱的口令密码升级为坚固的密钥体系,并彻底关闭密码登录这道“后门”,从根本上消除一类最常见的安全威胁。整个过程的核心在于:测试先行,保留退路,逐步推进。
