服务器SSH安全加固:禁用Root、密钥认证与端口修改实战指南

📅 2026/6/29 23:57:50
服务器SSH安全加固:禁用Root、密钥认证与端口修改实战指南
1. 项目概述为什么你的服务器需要一次SSH“体检”最近帮朋友处理了一台被暴力破解的服务器登录日志里密密麻麻全是来自全球各地的失败尝试目标直指root账户和默认的22端口。这让我意识到很多朋友在拿到一台云服务器或VPS后往往只做了基础的环境部署却忽略了最外层的“大门”——SSH服务的安全加固。今天要聊的就是一次标准的服务器SSH登录优化“三板斧”禁用root直接登录、强制使用密钥认证、修改默认SSH端口。这不仅仅是安全最佳实践更是运维工程师的“肌肉记忆”。你可能觉得我的服务器没什么重要数据或者有云厂商的安全组挡着没必要这么麻烦。但安全从来不是“亡羊补牢”而是“未雨绸缪”。一个弱密码的root账户加上默认端口就像把家门钥匙藏在脚垫下面攻击者用自动化脚本扫一遍你的服务器就可能沦为“肉鸡”。这次优化操作不涉及复杂的网络架构或昂贵的硬件只需要你有一台Linux服务器CentOS、Ubuntu等主流发行版均可和基本的命令行操作知识。整个过程大约30分钟但带来的安全提升是指数级的。无论你是个人开发者、学生还是初创公司的运维这套组合拳都值得你花时间配置一次。2. 核心思路与方案选型理解每一招背后的安全逻辑在动手之前我们先拆解一下这三个措施各自解决了什么问题以及为什么它们组合起来效果最佳。单独使用任何一项都有其局限性但三者叠加能构建一个坚固的纵深防御体系。2.1 禁用Root直接登录切断最高权限的“直通车”Root是Linux系统的超级管理员拥有至高无上的权限。允许直接以root身份通过SSH登录意味着攻击者一旦破解了root密码就能长驱直入为所欲为。禁用直接登录并不是抛弃root用户而是强制所有管理员先以一个普通用户身份登录然后再通过su或sudo命令切换或提权到root。这样做有两个核心好处增加攻击门槛攻击者需要连续破解两个账户普通用户和root的密码难度大大增加。普通用户的用户名还可以自定义避免了被针对“root”这个固定用户名进行爆破。留下审计痕迹通过sudo执行的命令会被详细记录在日志中通常是/var/log/auth.log或/var/log/secure谁在什么时间执行了什么命令一目了然便于事后追溯和审计。如果直接root登录很多操作日志的关联性会变弱。注意在禁用前你必须确保已经创建好了一个具有sudo权限的替代管理账户并且测试过能用该账户正常登录和提权。否则你可能会把自己锁在服务器外面。2.2 密钥认证替代密码认证从“你知道什么”到“你拥有什么”密码认证Password Authentication依赖于“你知道什么”Something you know即密码。密码可能被猜解、被撞库、被键盘记录。而密钥认证Public Key Authentication依赖于“你拥有什么”Something you have即一对非对称加密的密钥私钥和公钥。工作原理简述你在本地生成一对密钥。将公钥好比一把公开的锁上传到服务器的~/.ssh/authorized_keys文件中。当你尝试连接时服务器用这把“锁”加密一个随机挑战字符串发送给你的客户端。你的客户端用本地保存的私钥唯一的钥匙解密并回应这个挑战。服务器验证回应正确即认证通过。私钥从不离开你的本地机器。优势极高的安全性私钥通常是一长串随机字符暴力破解在现有算力下几乎不可能。避免密码泄露风险网络上传输的只有加密的挑战和回应没有密码明文。支持免密登录可以为私钥设置一个“通行短语”passphrase来加密私钥文件本身提供二次保护。也可以不设置实现真正的免密登录但建议设置以防私钥文件被盗。2.3 修改默认SSH端口躲开自动化扫描的“第一波浪潮”SSH默认监听22端口这是尽人皆知的事实。全球有无数的僵尸网络和扫描器24小时不间断地对公网IP的22端口进行密码爆破尝试。修改为一个非标准的高位端口如 2022, 3522等可以立即过滤掉99%的自动化、无差别的扫描流量。这就像把你的家门从热闹的主街1号搬到了小巷子里的10086号那些挨家挨户试门锁的小偷可能根本不会走到这里来。需要注意这不是银弹。定向攻击者或全端口扫描依然能找到你的服务。因此它必须与前两项措施结合使用。修改端口后你每次连接都需要显式指定端口号例如ssh -p 3522 userserver_ip。务必在防火墙如firewalld、iptables或云服务商的安全组中同时放行新端口并考虑关闭旧端口的访问。方案选型总结我们选择按“创建新用户 → 配置密钥 → 修改配置 → 重启服务 → 测试验证”的顺序进行。这个顺序是安全的先准备好“备用钥匙”新用户和密钥再更换“门锁”修改配置最后测试新钥匙能否开门并确保旧钥匙密码登录和root直接登录已经失效。绝对不要反过来先禁用密码或root结果发现自己没配置好密钥那就真的“家”门难入了。3. 实操前的核心准备打造你的“备用钥匙”在修改任何SSH服务器配置之前我们必须先做好万全准备确保有一条可靠的备用登录路径。这步错了后续操作就可能变成“自杀”。3.1 创建具备sudo权限的替代管理用户首先我们需要登录到你的服务器目前还是用root或者已有账户通过密码登录。然后执行以下步骤添加新用户我们创建一个名为admin的用户你可以用任何喜欢的名字但避免使用admin、test等常见名增加猜解难度。adduser admin系统会提示你设置密码及一些个人信息密码请设置一个强密码即使后续用密钥密码作为备用手段也应足够强。赋予sudo权限这是关键一步让admin用户能够执行管理员命令。在Ubuntu/Debian系统将用户加入sudo组。usermod -aG sudo admin在CentOS/RHEL系统将用户加入wheel组通常wheel组默认有sudo权限。usermod -aG wheel admin你可以检查/etc/sudoers文件确认%wheel组是否有ALL(ALL) ALL这样的配置。验证新用户打开一个新的终端窗口或标签页尝试用新用户登录ssh admin你的服务器IP登录成功后尝试切换为root或执行需要特权的命令sudo su - # 或者执行一个命令 sudo ls /root系统会提示你输入admin用户的密码即刚才设置的密码。输入正确后命令应该成功执行。这一步至关重要它证明了你的新用户具备管理权限是可靠的“备用钥匙”。3.2 在本地生成并部署SSH密钥对现在我们在你本地的电脑上比如你的Windows/Mac/Linux开发机生成密钥对。生成密钥对打开你本地的终端Windows可用PowerShell或Git Bash。ssh-keygen -t rsa -b 4096 -C your_emailexample.com -f ~/.ssh/id_rsa_admin_server-t rsa: 指定密钥类型为RSAEd25519也是很好的选择更安全更快但某些老旧系统可能不支持。-b 4096: 指定密钥长度为4096位安全性更高。-C: 添加一个注释通常用邮箱便于识别这把钥匙是给哪台服务器用的。-f: 指定密钥文件的保存路径和名称。这里我们指定了一个自定义名称id_rsa_admin_server避免覆盖可能已存在的默认密钥id_rsa。执行命令后会提示你输入“通行短语”passphrase。强烈建议设置一个这相当于给你的私钥文件本身加了一把密码锁。即使私钥文件不慎泄露没有通行短语也无法使用。当然如果你追求极致的便利性例如用于CI/CD自动化可以不设直接回车两次。将公钥上传到服务器生成后你会得到两个文件私钥id_rsa_admin_server和公钥id_rsa_admin_server.pub。我们需要把公钥上传到服务器上admin用户的家目录下。方法一使用ssh-copy-id最方便但需要当前支持密码登录ssh-copy-id -i ~/.ssh/id_rsa_admin_server.pub -p 22 admin你的服务器IP输入admin用户的密码即可自动完成部署。方法二手动复制通用方法先查看你的公钥内容cat ~/.ssh/id_rsa_admin_server.pub全选复制。登录服务器用admin用户密码登录ssh admin你的服务器IP。在服务器上确保~/.ssh目录存在且权限正确mkdir -p ~/.ssh chmod 700 ~/.ssh将复制的公钥内容追加到authorized_keys文件echo “你复制的公钥内容” ~/.ssh/authorized_keys设置authorized_keys文件的权限权限不对会导致认证失败chmod 600 ~/.ssh/authorized_keys测试密钥登录在本地新开一个终端尝试使用密钥登录注意此时要指定我们刚生成的私钥文件ssh -i ~/.ssh/id_rsa_admin_server -p 22 admin你的服务器IP如果你设置了通行短语此时会提示你输入。如果成功登录且没有要求输入密码恭喜你密钥认证配置成功这是你未来最主要的登录方式。实操心得在测试密钥登录时我强烈建议保持原来的密码登录会话窗口不要关闭。在新窗口测试密钥登录成功并确认一切正常后再回到旧窗口进行后续的危险配置修改。这相当于系上了“安全绳”。4. 深入SSH服务端配置动刀前的谨慎与精确完成上述准备后我们终于可以开始修改SSH服务端sshd的配置文件了。这个文件通常位于/etc/ssh/sshd_config。修改前务必先备份sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak现在用你喜欢的文本编辑器如vim、nano打开配置文件sudo vim /etc/ssh/sshd_config我们将找到并修改以下几个关键参数。注意配置文件中以#开头的行是注释要修改的是去掉#后的实际参数行。4.1 禁用Root直接登录找到关于PermitRootLogin的配置行。它可能有几种状态被注释掉默认行为因发行版而异、设为yes、prohibit-password等。我们将其修改为PermitRootLogin no这明确禁止了任何形式的root直接登录包括密码和密钥。4.2 启用并强制密钥认证禁用密码认证找到PubkeyAuthentication和PasswordAuthentication参数。确保公钥认证开启通常默认是开启的PubkeyAuthentication yes将密码认证关闭PasswordAuthentication no重要提醒在确认密钥登录100%工作正常之前不要先将此选项设为no。一个安全的操作顺序是先设为yes测试密钥登录成功后再回来改为no。或者更稳妥的做法是在本次修改中先保持yes等所有修改完成并重启服务后用密钥登录测试确认无误再在同一个会话中第二次修改配置文件将其改为no并再次重启。这能最大程度避免被锁在外面。4.3 修改SSH服务监听端口找到#Port 22这一行。默认是被注释的SSD服务实际监听22端口。我们做两件事取消Port 22的注释即保留22端口作为一个监听选项但这不是必须的有些教程建议直接删除22我更倾向于先保留作为备份。在它下面新增一行指定一个新端口。端口号选择1024到65535之间且未被系统其他服务占用的数字。例如Port 22 Port 3522这样配置表示sshd会同时监听22和3522两个端口。在我们测试新端口成功之前旧端口是重要的逃生通道。4.4 其他推荐的安全加固选项你可以顺便调整这些参数进一步提升安全性ChallengeResponseAuthentication no禁用挑战应答认证通常与密码认证相关。UsePAM yes保持PAM启用但因为我们关了密码认证它的相关模块影响不大。有些系统需要它为yes才能正常使用某些功能如AllowUsers。AllowUsers admin这是一个白名单机制只允许列出的用户如admin通过SSH登录。即使有其他用户账户存在也无法SSH登录。配置此项要格外小心确保你列出的用户admin绝对正确并且该用户已经配置好密钥。语法是AllowUsers user1 user2。ClientAliveInterval 300和ClientAliveCountMax 2设置客户端活跃检测如果300秒内没有收到客户端的任何数据服务器会发送一条加密的“保活”消息最多发送2次。如果客户端均无响应则断开连接。这可以防止连接因网络问题长时间挂起。修改完成后保存并退出编辑器。5. 防火墙配置与服务重启让新规则生效修改了sshd_config只是改变了服务的配置还需要让服务重新加载配置并且确保防火墙允许新的端口通过。5.1 配置系统防火墙这里以最常见的firewalldCentOS 7/8, RHEL, Fedora和ufwUbuntu, Debian为例。对于使用 firewalld 的系统# 添加新端口到永久规则并重载防火墙 sudo firewall-cmd --permanent --add-port3522/tcp sudo firewall-cmd --reload # 查看端口是否添加成功 sudo firewall-cmd --list-ports对于使用 ufw 的系统# 允许新端口 sudo ufw allow 3522/tcp # 启用UFW如果尚未启用 sudo ufw enable # 查看规则 sudo ufw status numbered对于云服务器重要你必须登录云服务商的管理控制台如阿里云、腾讯云、AWS的安全组找到你服务器实例关联的安全组规则添加入站规则允许TCP协议访问你新设置的端口如3522。云服务器的安全组是独立于系统防火墙的另一道关卡两者都需要配置。5.2 谨慎重启SSH服务并测试这是最紧张的一步。我们分阶段测试确保退路。首次重启双端口运行因为我们配置了Port 22和Port 3522所以先以此配置重启。sudo systemctl restart sshd # 或者对于某些系统 sudo systemctl restart ssh检查服务状态确保没有报错sudo systemctl status sshd测试新端口密钥登录不要关闭当前的服务器连接窗口在你本地机器上打开一个新的终端尝试使用新端口和密钥登录。ssh -i ~/.ssh/id_rsa_admin_server -p 3522 admin你的服务器IP如果成功登录说明新端口和密钥认证工作正常。太好了如果失败检查错误信息。常见问题防火墙没开、安全组没设、sshd_config中端口号写错、密钥路径或权限不对。根据错误信息在当前保持的连接窗口里进行修复。测试旧端口密码登录应失败在本地再开一个终端尝试用密码登录旧端口此时应该被拒绝因为我们还没关密码但用了密钥所以可能提示密钥方式被拒然后才问密码实际上如果客户端提供了密钥服务器会优先尝试密钥。我们可以强制不用密钥来测试密码ssh -o PreferredAuthenticationspassword -o PubkeyAuthenticationno -p 22 admin你的服务器IP此时应该提示“Permission denied”。这验证了密钥认证优先。最终加固禁用密码并移除旧端口在通过新端口登录的会话中或者你一直没断开的那个原始会话再次编辑/etc/ssh/sshd_config将PasswordAuthentication的值从yes改为no。将Port 22这一行注释掉行首加#或直接删除。只保留Port 3522。保存退出。第二次重启SSH服务sudo systemctl restart sshd最终验证验证1尝试用新端口密钥登录应该成功。验证2尝试用新端口密码登录强制密码方式应该立即被拒绝提示“Permission denied (publickey)”这表明密码认证已关闭。验证3尝试连接旧端口22应该连接超时或被拒绝因为服务不再监听22端口且防火墙可能也没开22云安全组也可以考虑关闭22端口入站。至此核心的“三板斧”加固已经完成。你的服务器SSH入口已经从“不设防的广场”变成了“需要特定钥匙、走特定小巷后门”的隐蔽通道。6. 客户端连接优化与高级配置服务端配置好了客户端用起来也别太别扭。每次连接都要输入-i -p太麻烦我们可以通过SSH客户端配置文件来简化。在你本地电脑的~/.ssh/config文件如果没有就创建一个中添加如下配置Host myserver # 一个别名方便记忆 HostName 你的服务器IP地址 Port 3522 # 你修改后的端口 User admin # 登录用户名 IdentityFile ~/.ssh/id_rsa_admin_server # 私钥路径 # 可选配置 ServerAliveInterval 60 # 每60秒发送一次保活包防止连接断开 TCPKeepAlive yes # 启用TCP保活保存后以后连接服务器只需要一句命令ssh myserver所有参数都会自动应用极大提升了日常使用的便利性。7. 常见问题与故障排查实录即使按照步骤操作也可能会遇到问题。这里记录几个我踩过的坑和解决方法。7.1 连接被拒绝 (Connection refused)现象ssh -p 3522 adminip后立刻返回Connection refused。排查思路服务未监听端口在服务器上执行sudo netstat -tlnp | grep sshd或sudo ss -tlnp | grep sshd查看sshd进程是否在监听你设置的端口如3522。如果没有说明sshd配置未生效或重启失败。检查sshd_config语法sudo sshd -t。如果有错误根据提示修正。防火墙/安全组阻拦这是最常见的原因。确保系统防火墙和云平台安全组都正确放行了新端口。在服务器上可以临时关闭防火墙测试sudo systemctl stop firewalld或sudo ufw disable但测试后务必重新开启并配置好规则。IP地址或端口号写错再检查一遍命令。7.2 权限太开放 (Permissions are too open)现象密钥登录失败客户端提示WARNING: UNPROTECTED PRIVATE KEY FILE!或Permissions 0644 for ‘.ssh/id_rsa‘ are too open.原因你的私钥文件id_rsa_admin_server的权限过于宽松SSH出于安全考虑拒绝使用。解决在本地电脑上执行chmod 600 ~/.ssh/id_rsa_admin_server同样服务器上的~/.ssh目录权限应为700authorized_keys文件权限应为600。7.3 认证失败 (Permission denied, please try again)现象提示输入密码但输入正确密码后仍被拒绝在禁用密码前或直接提示Permission denied (publickey)。排查思路服务器端authorized_keys问题确认公钥内容已正确无误地追加到服务器上admin用户的~/.ssh/authorized_keys文件末尾。检查文件权限必须为600。sshd_config配置确认PubkeyAuthentication yes和AuthorizedKeysFile .ssh/authorized_keys默认已设置。SELinux仅限RHEL/CentOSSELinux可能会阻止非标准家目录或.ssh目录的访问。可以尝试暂时将SELinux设为宽容模式测试sudo setenforce 0。如果问题解决需要为SSH设置正确的SELinux上下文restorecon -Rv ~/.ssh。生产环境请谨慎操作SELinux。用户家目录权限admin用户的家目录权限不能对组或其他人有写权限如755是可以的但777就不安全可能导致SSH拒绝使用该目录下的密钥。建议设置为750或755。7.4 修改配置后重启sshd失败现象执行sudo systemctl restart sshd后服务状态为failed。解决立即查看日志获取错误详情sudo journalctl -xe -u sshd --no-pager | tail -50最常见的错误是sshd_config文件中有语法错误比如参数拼写错误、值格式不对。根据日志提示的行号去修正配置文件。在修正前如果你还有活跃的SSH连接千万不要断开如果所有连接都断了而服务又起不来你可能需要通过云服务商的VNC控制台或物理服务器的本地控制台登录进行修复。8. 维护与监控安全是一个持续的过程配置完成并非一劳永逸。你需要定期查看认证日志经常检查/var/log/secureRHEL系或/var/log/auth.logDebian系关注失败的登录尝试。命令如sudo grep “Failed password” /var/log/secure或使用fail2ban这类工具自动封禁暴力破解IP。更新密钥定期如每半年或一年更换一次密钥对就像更换密码一样。管理授权密钥定期检查服务器上~/.ssh/authorized_keys文件移除不再需要的公钥。关注SSH漏洞关注CVE公告及时更新系统和OpenSSH软件包。我个人在管理多台服务器时会为每台服务器生成独立的密钥对并使用一个本地的密码管理器来管理这些私钥的通行短语和对应的服务器信息。同时所有sshd_config的修改都会通过Ansible等自动化工具进行并纳入版本控制确保配置的一致性和可追溯性。这套“禁用root密钥登录改端口”的组合是我给每一台新服务器上线时必做的“标准动作”它用极低的成本构筑了应对自动化攻击的第一道也是极其有效的防线。