ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu SSH端口修改实战:从sshd_config到防火墙与故障排查

Ubuntu SSH端口修改实战:从sshd_config到防火墙与故障排查 1. 修改 SSH 端口到底解决什么问题——动机评估与适用场景聊到 Ubuntu 系统改 SSH 端口这件事我得先给各位泼一盆冷水如果你以为改了端口就能一劳永逸地解决服务器安全问题那你多半要失望。但它依然是一件值得做的事前提是你搞清楚它到底解决什么、不解决什么。SSH 服务默认监听 22 端口这几乎是所有运维人员、脚本扫描器和恶意爬虫的“共识”。互联网上每天有大量的自动化扫描程序在全网扫 IPv4 地址段遇到 22 端口开放就会尝试常见的用户名密码组合进行暴力破解。我托管过一台公网 Ubuntu 服务器装好系统不到 24 小时/var/log/auth.log里就能看到源源不断的 Failed password 记录来源 IP 遍布全球。这不是个例几乎每台公网服务器都会面临同样的处境。把 SSH 从 22 端口改到高位端口比如 22222 或 50022这些无差别扫描的大部分流量就直接扫不到了因为它们的扫描清单里默认只写了 22 端口。但要注意这属于“降低暴露面”而非“绝对安全”。一个专注针对你的攻击者用nmap -p 1-65535全端口扫描照样能找到你的 SSH 服务。所以改端口通常配合密钥登录、禁用密码登录、Fail2ban 等方案一起使用形成纵深防御。这篇文章聚焦在“怎么把端口改好、改稳”其他安全加固手段我们会在涉及的地方顺带提一句但不展开。适用场景很清晰你是 Ubuntu 服务器管理员想把 SSH 从默认的 22 端口迁到自定义端口或者你所在的内网环境有端口冲突本机或者其他服务占用了 22 端口又或者你的安全审计要求明确指出“不得使用默认 SSH 端口”。这几种情况都适合按照本文的流程操作。需要特别提醒的是如果你是通过远程 SSH 连接服务器来执行这次修改请一定先确保自己理解了每一步的含义而且最好准备一个备用连接方案比如云服务商控制台提供的 VNC、管理终端或者干脆是同一网络里的另一台跳板机。因为一旦配置写错、防火墙没放行、sshd 服务没重启成功你可能会把自己锁在门外而这时云控制台的救援通道就是你唯一的救命稻草。我在后面的故障处理章节会专门展开这个场景。2. 动手前的环境检查——配置备份、端口冲突与防火墙现状排查很多人改端口失败、把服务搞挂问题不是出在改端口这一步而是出在准备工作没做扎实。我见过太多反面教材直接编辑sshd_config把Port 22改成Port 22333然后迫不及待地重启 sshd结果一重启就发现连接直接断开怎么也连不回去了。原因无非是以下几种新端口被其他进程占用、防火墙没放行新端口、SELinux 或 AppArmor 策略拦截、sshd 配置语法有误。这些坑全部可以在动手之前用几分钟排查干净。2.1 确认当前 SSH 服务状态与现有配置先登录目标 Ubuntu 服务器执行sudo systemctl status ssh正常情况下你会看到 ssh.service 处于 active (running) 状态。如果输出显示的是ssh.socket说明你用的可能是 socket 激活模式新版 systemd 的特性这种模式下手动改sshd_config的端口不一定生效还要处理 socket 单元的配置后面我会专门说明。确认服务正常后再看看当前实际监听的端口sudo ss -tlnp | grep sshd一般会输出类似LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:((sshd,pid1234,fd3)) LISTEN 0 128 [::]:22 [::]:* users:((sshd,pid1234,fd4))注意看 IPv4 和 IPv6 两条监听记录都有说明 sshd 在双栈环境正常工作。接下来看一眼现在的配置文件全貌sudo grep -n ^ /etc/ssh/sshd_config | grep -v ^# | grep -v ^$这样能看到所有未被注释的行快速了解当前生效的配置项。特别留意有没有多个Port指令——sshd_config 的规则是如果有多个 Port 行sshd 会同时监听所有列出的端口这其实是一个可用于平滑迁移的技巧后面细说。2.2 备份这个动作不能跳过在改任何系统级配置文件之前养成备份习惯是基本功。改 SSH 配置尤其如此因为你可能因为一个多余的空格、一个写错的指令名而把整个服务搞挂。备份命令很简单sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date %Y%m%d%H%M%S)这样生成带时间戳的备份文件出问题可以精确回滚到改动前的那一刻。顺便建议把原来的 sshd 二进制和服务状态也做记录sudo sshd -T | head -20sshd -T是 sshd 的“测试模式”只输出根据当前配置计算出的生效参数不实际启动服务。改动配置后可以用它来快速对比前后差异。2.3 检查新端口是否被占用端口冲突是改端口失败的头号原因。你选一个新端口比如 22222得先确认没有被其他服务占用sudo ss -tlnp | grep -E 22222|:22222没有任何输出说明端口是空闲的。如果你想更细致一点直接用ss -tln | awk {print $4}列出所有监听端口目测一下自己想用的端口不在其中。提示端口范围要注意1-1024 是特权端口1024-49151 是注册端口49152-65535 是动态/私有端口。sshd 以 root 启动理论上可以监听任何端口但为了避免和其他服务冲突建议选 1024 以上的高位端口且避开常见服务端口和临时端口范围。另外不要选别人常用的替代端口比如 2222 是很多教程里推荐的“标准替代”实际上也成了扫描器的重点关注对象——我见过不少扫描流量专门扫 2222。挑一个不那么“热门”的高位端口比如 32122、44555 这类效果更好。2.4 检查防火墙现状Ubuntu 系统最常见的防火墙是 ufwUncomplicated Firewall也有不少人直接操作 iptables/nftables。先看看当前状态sudo ufw status verbose如果输出显示Status: inactive说明 ufw 根本没启用任何端口都对外可达那防火墙不用管。如果显示Status: active注意看当前放行的规则里有没有 22/tcp。通常云服务器镜像默认会放行 22但你自己改端口后必须手动添加新规则——这是最容易遗漏的一步。如果你用的不是 ufw 而是云平台安全组阿里云安全组、腾讯云防火墙、AWS Security Group 等对应的放行规则要先去云控制台改服务器内部的防火墙只是第二层。很多人在云服务器上改了端口却连不上就是漏了安全组的入方向规则。这一步现在记在心里后面操作完一起处理。如果你用 iptables 直接管理规则检查一下当前规则sudo iptables -L -n | grep 22或者用 nftablessudo nft list ruleset | grep 22搞清楚了现状我们才进入真正改配置的环节。3. sshd_config 修改实操——命令行修改、语法校验与服务重启准备工作做完了开始动配置。这部分看起来很简单——改一行字的事——但细节决定成败几个原则必须先在脑子里过一遍。3.1 直接编辑 vs 追加覆盖我的习惯是直接用编辑器打开主配置文件修改sudo vim /etc/ssh/sshd_config找到这一行#Port 22去掉注释并改成你自己的端口Port 32122如果你不改Port 22那行而是想在文件末尾追加一行Port 32122会出现什么情况sshd_config 的规则是配置文件中同一个指令出现多次时取第一个出现的值不是最后一个。前半句是几乎所有教程都告诉你的但很多人忽略了一个关键细节如果你保留了Port 22那行带#注释然后在末尾加一行Port 32122那没问题生效的只有32122。但如果Port 22是没有注释的生效指令末尾再追加Port 32122结果是 sshd同时监听 22 和 32122两个端口——因为Port指令比较特殊它不像PermitRootLogin那样“第一个生效后续忽略”而是“每个 Port 值都会被加入监听列表”。我之前迁移端口就利用过这个特性先在末尾追加新端口的Port行重启 sshd确认新端口能连接再把老端口那行注释掉再重启一次整个过程平滑无感。3.2 不仅仅是端口——连接数限制和监听地址除了Port我建议你顺手检查另外几个配置项这些不直接决定端口对不对但影响改完之后的稳定性和安全性ListenAddress 0.0.0.0默认监听所有网卡的 IPv4 地址。如果你只想让内网某个 IP 连 SSH可以写成ListenAddress 192.168.1.10。PermitRootLogin强烈建议no然后用普通用户登录再sudo su -提权。这个和改端口是黄金搭档。PasswordAuthentication能改成no就改成no然后只允许密钥登录。大部分针对 22 端口的暴力破解都依赖密码认证关了这扇门配合改了端口攻击面小很多。MaxAuthTries默认 6可以调小到 3。这个决定了单条连接里最多允许几次认证失败。ClientAliveInterval和ClientAliveCountMax设置空闲超时防止一些僵尸连接长期占用。这些配置一句话带过但每一项展开都是安全课题。这篇的重点还是端口其他配置我建议你按需逐项搜索研究。3.3 语法校验重启前的最后一道闸门改完配置别急着重启先让 sshd 自己检查一下语法sudo sshd -t没有任何输出说明配置语法正确。如果输出了类似/etc/ssh/sshd_config line 5: Bad port number.那就是端口值写错了检查是不是敲了非数字字符或者超出 1-65535 范围。语法校验没报错再看一眼计算出的生效配置sudo sshd -T | grep -E ^port|^listenaddress确认port 32122和listenaddress 0.0.0.0符合预期。这一步能直观看到 sshd 实际会用到哪些值比直接猜靠谱得多。3.4 重启服务并保持连接不中断远程操作最关键的一步来了。重启 sshd 时千万不要使用下面的命令sudo systemctl restart ssh # 危险为什么不建议因为如果配置有误或者 SSH 服务重启后监听失败systemd 可能会杀掉当前连接对应的 sshd 进程你的 SSH 会话会直接断掉。更稳妥的姿势是使用reloadsudo systemctl reload sshreload 会加载新配置但不中断现有连接——严格来说你当前这个会话所用的 sshd 进程是旧的它继续监听旧端口直到会话结束新连接才会走新配置。不过 reload 也不是完全没有风险如果配置错误sshd 会拒绝重载并保持旧配置运行所以你的现有连接安全。这是远程操作 SSH 时最推荐的优雅方式。注意2022 年以后的 Ubuntu 版本22.04 及更新ssh.service和ssh.socket的体系发生了变化。如果你执行systemctl status ssh发现输出里出现Triggered by: ssh.socket那么你还需要处理 socket 单元。此时检查一下sudo systemctl status ssh.socket确认它监听的端口是否还是 22。如果确实以 socket 方式激活重启 ssh 的正确方式是sudo systemctl restart ssh.socket这个细节是很多 Ubuntu 用户改完端口发现“没生效”的隐藏原因后面故障排查还会再提。reload 或者 restart 执行后立刻在新终端窗口测试ssh -p 32122 useryour-server-ip如果新连接能建立恭喜核心操作完成了。如果新端口连不上别慌下一步按流程排查。3.5 平滑迁移到新端口如果你追求零中断可以按这个顺序操作在sshd_config追加一行Port 32122保留原来的Port 22。sudo systemctl reload ssh此时 22 和 32122 同时可连。新窗口测试ssh -p 32122能正常连上。确认连接稳定后注释掉Port 22再次 reload。测试旧端口应该无法连接新端口正常。这个流程特别适合生产环境。每一步都有验证每一步都可以回退不存在“一刀切”把自己关在门外的尴尬。4. 防火墙规则更新——ufw 和 iptables 两套方案别漏了云安全组配置改完了服务也重载了如果新端口还是连不上十有八九是防火墙在拦。这一节把防火墙的几种情况全部过一遍。4.1 ufw最常见的 Ubuntu 防火墙如果你的 ufw 是 active 状态执行sudo ufw allow 32122/tcp如果之前只允许了 22这个新规则加上后应该能直接放行新端口。可以用以下命令确认sudo ufw status numbered输出里应该能看到[ 1] 22/tcp ALLOW IN Anywhere [ 2] 32122/tcp ALLOW IN Anywhere看到新的规则在列说明放行成功。很多人问“要不要把 22 的规则也删掉”。我的建议是在确认新端口稳定运行一段时间之前先别急着删。你可以改端口后保留 22 的放行规则但 SSH 服务本身已经不再监听 22规则留着也不会有流量进来。等你在新端口上跑了几天确定没有异常再删掉旧规则不迟sudo ufw delete allow 22/tcp4.2 iptables/nftablesiptables 场景在默认 INPUT 链里加一条sudo iptables -I INPUT -p tcp --dport 32122 -j ACCEPT这条规则插到第一条让后面的规则在评估时直接匹配放行。如果想让它重启后依然生效别忘了保存规则sudo netfilter-persistent save # 或 sudo iptables-save /etc/iptables/rules.v4nftables 场景先看当前表结构sudo nft list ruleset然后按你的表结构添加规则以inet filter表为例sudo nft add rule inet filter input tcp dport 32122 accept4.3 云安全组最容易被忽略的一层如果你用的是云服务器服务器内部的 ufw 只是第二层防线。云平台的安全组Security Group才是第一层。以达梦云、某云、某翼云为例安全组的入方向规则通常要手动添加端口段常见默认规则是22/22 源 0.0.0.0/0。你要去云控制台的网络与安全组配置页面加一条32122/32122的入方向 TCP 规则源地址按需填0.0.0.0/0公网开放或特定 IP 段只允许内网。这一步不做即使服务器内部防火墙全放行外网照样连不上新端口。很多“教程说改了端口就连不上”的案例最后查出来都是这里漏了。4.4 内网还有没有其他防火墙如果服务器在公司内网或者前面还有硬件防火墙、路由器 ACL那也得确认这些中间设备是否允许高位端口的入站流量。有些公司网络策略只开放特定端口比如 80、443、22这种情况改端口之前最好先跟网络管理员确认否则改完连不上还得回头沟通。5. 连接测试的完整链路——从本机检测到公网穿透测试配置改完、防火墙放完最后一步是完整的连接测试。这一步的目的不是“哦能连了”而是“确认新端口真的工作、旧端口真的关闭、修改没有引入其他问题”。我习惯分三层测试。5.1 本机验证监听状态回到服务器上检查 sshd 监听状态sudo ss -tlnp | grep sshd预期输出LISTEN 0 128 0.0.0.0:32122 0.0.0.0:* users:((sshd,pid1234,fd3)) LISTEN 0 128 [::]:32122 [::]:* users:((sshd,pid1234,fd4))我只能看到 32122看不到 22说明老端口确实关闭了。如果 22 和 32122 同时出现在列表里说明你还有一行生效的Port 22没注释干净回配置里查一遍。5.2 本机回环测试在服务器本机执行ssh -p 32122 localhost这一步能确认 sshd 本身工作正常、端口可以接受连接。如果本机都连不上那不是防火墙的问题是 sshd 配置或服务状态的问题先排查服务。5.3 局域网测试换一台同一局域网的机器执行ssh -p 32122 userserver-lan-ip这步验证局域网内的连通性如果不行重点查服务器内部的防火墙ufw/iptables和监听地址是否绑定了内网 IP。5.4 公网测试与端口连通性检测如果你操作的是公网服务器最后一步用外部环境测。最简单的方法是用手机流量热点开一台笔记本或者找另一台公网机器nc -vz your-server-ip 32122或nmap -p 32122 your-server-ip端口状态显示 open说明公网可达。显示 filtered 或 closed说明大概率被云安全组或外部防火墙拦了。这里提一句测试完新端口后建议顺手把 SSH 配置里的旧端口行注释掉并删除防火墙旧的 22 端口入站规则。很多管理员改完新端口后旧的 22 端口规则还留着服务虽然不监听 22但安全组和防火墙规则一直挂着等于是给攻击者留了一个“看起来没用但随时可能被重新启用”的口子。干净利落地清掉旧规则才算真正完成迁移。6. 常见故障与回滚方案——连接超时、权限拒绝、配置没生效的完整排查链路这一节是重点中的重点。我相信每个改过 SSH 端口的人都至少踩过其中一个坑而最常见的结果就是把自己锁在门外。下面我把故障排查链路完整拆开手把手教你一步步定位和修复。6.1 改完端口后完全连不上——先分清“拒绝连接”和“超时”连接失败时错误信息很重要不要忽略它直接瞎猜。Connection refused目标端口没有服务在监听或者防火墙直接回了 RST。说明 sshd 没监听新端口或者防火墙 DROP 之前先 REJECT。优先检查 sshd 状态和监听地址。Connection timed out数据包被静默丢弃一般是防火墙 DROP 规则或者云安全组没放行。优先检查安全组和内部防火墙。No route to host三层不通检查网络配置和路由跟这次改动关系通常不大。用这条规律先缩小范围就能省掉大量无效排查。6.2 服务重启失败——查看日志是第一步如果sudo systemctl reload ssh或restart ssh报错立刻看日志sudo journalctl -u ssh -n 50最常见的错误是配置语法问题比如端口范围写错、指令拼错、引号不匹配。日志里会明确提示第几行配置有问题/etc/ssh/sshd_config line 8: Bad port abc需要系统恢复的话直接把配置恢复到备份版本sudo cp /etc/ssh/sshd_config.bak.20240101120000 /etc/ssh/sshd_config sudo systemctl start ssh6.3 配置改对了但连接仍然走 22 端口——检查 ssh.socket这是 Ubuntu 22.04 用户最常撞见的怪问题配置里写了Port 32122sshd -T也显示 port 32122但实际连接 22 端口照样能建立 SSH 会话。原因在于新版 systemd 的 socket 激活机制。用下面的命令确认sudo systemctl status ssh.socket如果 socket 是 active 且监听端口是 22那么 ssh 连接是由 socket 单元接管压根不会完全走你 sshd_config 里的端口配置。处理方式sudo systemctl stop ssh.socket sudo systemctl disable ssh.socket sudo systemctl restart ssh把 socket 停掉禁用让 sshd 服务以 standalone 模式直接监听配置里的端口。这样Port 32122才能真正生效。提示改 socket 配置的另一种方法是直接修改/lib/systemd/system/ssh.socket里的ListenStream行但我觉得更干净的方式是禁用 socket 激活让 SSH 回到传统 daemon 模式行为更容易预测也方便排查。6.4 密钥登录失效——端口改了和它没关系但坑还是踩得到有些场景是端口改完了密码登录可以密钥登录却报Permission denied (publickey)。这跟端口本身没关系但很容易在改动过程中不小心踩到。检查思路服务端sshd_config里有没有显式设置PubkeyAuthentication no。有些教程在加固时会把密码登录和密钥登录一起调改完后把行为搞乱了。客户端用了-i ~/.ssh/id_rsa吗没有指定私钥文件的话会默认尝试~/.ssh/id_rsa文件名不匹配就登录不了。服务端的~/.ssh/authorized_keys权限对吗必须是600.ssh目录必须是700。权限不对会导致服务端拒绝读取密钥。chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys6.5 把旧连接挤掉、新连接也断——MaxStartups 和连接数限制改端口后如果遇到“能连上但马上就断”或者“连接一多就踢人”的症状查一下MaxStartups配置。默认值是10:30:100含义是未认证连接数达到 10 后以 30% 的概率拒绝新连接直到达到 100 全部拒绝。如果你同时有很多连接在排队就可能触发这个机制。可以适当调大MaxStartups 50:30:100这个和端口改动没有直接关系但迁移端口后很多人会顺便做压力测试或批量推密钥就容易撞上这个参数。6.6 最终手段通过云控制台救援通道恢复如果上述所有排查都做完了你依然被锁在门外别慌还有最后的自救通道。几乎所有主流云平台都提供 VNC 或者 Web Shell 登录入口。登录到系统后你可以直接修改配置文件sudo vi /etc/ssh/sshd_config # 把端口改回 22或者改回正确的端口 sudo systemctl restart ssh哪怕是 socket 激活的状态在救援通道里都能直接操作。这也是我为什么在前面强调“操作之前先确认自己有没有备用通道”——这句话关键时刻真的能救命。7. 改完端口后的习惯建议——密钥登录、Fail2ban 与定期检查最后再多聊几句“改完端口之后的事”。端口改对了只是第一步整个 SSH 安全策略的升级才是长远之计。7.1 配合密钥登录关闭密码认证如果你现在还用密码登录我强烈建议这次改端口的同时把密钥登录一并配上。操作流程本地生成密钥对如果有就不用了ssh-keygen -t ed25519 -C your-comment上传公钥到服务器ssh-copy-id -p 32122 userserver-ip确认密钥登录正常后禁用密码认证sudo sed -i s/^#PasswordAuthentication yes/PasswordAuthentication no/ /etc/ssh/sshd_config sudo systemctl reload ssh改完后密码登录这条路就断了暴力破解也就失去意义。7.2 Fail2ban 做第二层拦截即使改了高位端口针对性扫描依然可能发生。Fail2ban 能监控 SSH 的认证日志自动封禁短时间内连续失败多次的 IP。安装很简单sudo apt install fail2ban sudo systemctl enable fail2ban默认配置就能工作但建议把ignoreip填上自己的固定 IP免得哪天误伤自己。7.3 每月检查一次 auth.log一条很土但有效的习惯定期看一眼认证日志。sudo grep Failed password /var/log/auth.log | awk {print $(NF-3)} | sort | uniq -c | sort -nr | head -20这个命令能列出过去所有认证失败次数最多的 20 个 IP。如果你的新端口真的是“安静”的这条命令跑出来应该是空的结果。如果还有大量失败记录说明你的端口已经被人盯上了考虑再加上 Fail2ban 或者改用密钥登录。在多次和 SSH 安全问题打交道之后我更确信一件事改端口不是银弹但它是一个成本极低、效果明显的安全习惯。配合密钥认证、Fail2ban、定期审计日志这套组合拳能让你的 Ubuntu 服务器在公网环境里安静很多。最后再分享一个小技巧改完端口后把~/.ssh/config里对应主机的Port字段更新一下再也不会出现“换台电脑就忘了端口”的尴尬。这些经验都是踩坑踩出来的希望各位一次就能顺利改完不用经历被锁在门外的惊魂时刻。
返回列表