news 2026/10/1 3:40:50

CentOS 7 22端口无法访问?从网络到防火墙的SSH排障全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CentOS 7 22端口无法访问?从网络到防火墙的SSH排障全攻略

先问一句:你现在的状态,到底是“ping 不通 CentOS 7 主机”,还是“ping 得通但 SSH 连不上 22 端口”?这两个问题的排查路径完全不一样,但很多人在提问时报错信息只写了“centos7的22端口无法访问”,这就把故障范围拉得很大。我刚处理过一台 CentOS 7.9 的虚拟机,客户机同网段能 ping 通,但ssh root@一直卡在连接超时,最后定位到是 firewalld 默认 zone 被改成了 drop。这种场景太典型了,值得把整套排查思路完整过一遍。

这篇文章按真实排障顺序展开:网络层判断、端口监听、防火墙、sshd 服务、SELinux、资源问题、客户端干扰以及虚拟机特殊场景。不管你是刚装完 CentOS 7 连不上,还是服务器跑着跑着突然 22 端口进不去,都可以按这个路线逐层定位。

1. 22端口连不上的故障全景与排查路线

1.1 先分清三种截然不同的故障现象

“无法访问”这个词概括了至少三种完全不同的现象,我建议你先把现象确认清楚,后面才不会白忙活。

第一种是连接被拒绝,客户端秒弹Connection refused。说明网络路径是通的,但目标机器的 22 端口没有进程在监听,或者防火墙直接回了 RST。第二种是连接超时,客户端卡在那里直到Connection timed out。说明 SYN 包发出去之后石沉大海,通常是被防火墙 DROP 了,也可能是路由不可达。第三种是认证失败,Permission denied或者密码错,这已经说明 22 端口通了,只是卡在身份验证。

这三种现象对应的排查方向完全不同。遇到过很多新手,明明看到的是Connection refused,还在拼命查防火墙和网络,结果实际是 sshd 服务压根没起来。所以,第一步永远是确认现象,而不是凭经验乱猜。

1.2 一条主线解决90%的问题

对于 CentOS 7 上 22 端口无法访问,核心排查主线就四个字:通、听、挡、验。

通,指网络层是否可达,包括 IP、网关、路由和 ARP。听,指 sshd 有没有监听在 0.0.0.0:22 或者正确的网卡地址上。挡,指 firewalld、iptables、SELinux 这些安全机制有没有把 22 端口拦下来。验,指用客户端工具交叉验证,确认是服务器问题还是客户端这边自己的环境问题。

我在实际排障中习惯按这张表逐步推进。

排查层级核心问题典型命令快速判断
网络层IP和路由通不通ping、ip routeping 不通优先查网络配置
传输层22端口有没有监听ss -tlnp、telnet无监听则查 sshd
安全层防火墙/SELinux 拦没拦firewall-cmd、getenforce规则缺失则放行
应用层sshd 配置和日志sshd -t、/var/log/secure配置错误则修正
客户端软件、代理、known_hostsssh -vvv、换机器测试客户端问题则替换工具

这篇文章后面所有内容,都是围绕这条主线展开的。

2. 先分清三层问题:网络通不通,端口听没听,防火墙挡没挡

2.1 第一板斧:ping 和基础连通性

先看最基本的。在客户端机器上执行:

ping 192.168.31.10

如果 ping 不通,有三种可能。第一种,目标机器根本不在这个网段,或者 IP 配置错了。第二种,中间有防火墙禁 ping,但注意:很多云主机和服务器禁 ICMP 不等于禁 TCP,所以 ping 不通不一定说明 SSH 也不通。第三种,提示“无法访问目标主机”这类报错时,通常是本机 ARP 缓存里找不到目标 MAC 地址,说明目标主机不在当前链路内,或者网关有问题。

接下来看服务端自己:

ip addr ip route

ip addr确认网卡有没有拿到 IP,状态是 UP 还是 DOWN。ip route确认默认路由是否存在。如果发现default via这一行消失了,跨网段访问基本没戏,因为回包找不到路。我见过一台 CentOS 7 重启之后默认路由丢了,外部 ping 不通,SSH 自然也进不去,重启 network 服务才恢复。

ping 通是基础,但很多人忽略了一个关键:ping 通只代表 ICMP 可达,不能代表 22 端口 TCP 可达。所以下一步必须直接测端口。

2.2 第二板斧:telnet/nc/nmap 探测22端口

端口探测最直观的方式是 telnet:

telnet 192.168.31.10 22

如果出现Connected to 192.168.31.10并显示SSH-2.0-OpenSSH_7.4之类的 banner,说明 22 端口已经通了,问题可能出在认证环节或客户端自身。如果出现Connection refused,说明端口没监听或被 REJECT。如果一直卡住直到超时,说明数据包被丢弃。

在不方便装 telnet 的机器上,可以用 nc:

nc -vz -w 3 192.168.31.10 22

-v显示详细信息,-z只扫描不发送数据,-w 3设置 3 秒超时。有 nmap 的话更简单:

nmap -p 22 192.168.31.10

nmap 会明确显示open、closed、filtered三种状态。其中filtered基本就是防火墙把包丢了,这个信息和Connection timed out相互印证。

我实测过一个很典型的案例:同网段 ping 通,telnet超时,服务端ss -tlnp显示 sshd 正常监听 0.0.0.0:22,最后发现是 firewalld 默认 zone 被设置成了drop。所有入站连接都被静默丢弃,表现就是“看起来一切都正常,但就是连不上”。

2.3 第三板斧:在服务端抓包确认是被丢还是没回包

如果客户端探测超时,下一步我建议直接在 CentOS 7 服务器上抓包,这一步能区分“防火墙丢弃”和“回程路由不通”。

tcpdump -i ens33 tcp port 22 -nn

观察几秒钟。如果只看到SYN发进来,但服务器没有回SYN-ACK,那基本可以确定是防火墙拦了,因为协议栈本身没有回包。如果看到服务器回了SYN-ACK,但客户端依然超时,那就是回程路由或客户端侧的问题。

抓包这个操作看起来多余,但在复杂网络里真的能救命。有一次我排查一台双网卡服务器,发现抓包能看到请求进来,但服务器从错误网卡回包,客户端自然收不到。这个问题如果不抓包,光靠看防火墙规则,永远定位不到。

3. 网卡与IP配置:那些一眼看不出来的老坑

3.1 ifcfg-xxx 和 ONBOOT=no 这个经典问题

CentOS 7 的网络配置文件和 CentOS 6 相比变化不大,但坑一点都不少。最常见的是/etc/sysconfig/network-scripts/ifcfg-ens33里ONBOOT=no,导致开机后网卡没有自动启动,IP 没配上去,外部自然无法访问。

修改方式很简单:

vi /etc/sysconfig/network-scripts/ifcfg-ens33

确保以下几项正确:

TYPE=Ethernet BOOTPROTO=static ONBOOT=yes IPADDR=192.168.31.10 NETMASK=255.255.255.0 GATEWAY=192.168.31.1 DNS1=223.5.5.5

改完执行:

systemctl restart network

或者用 NetworkManager 的方式:

nmcli con reload nmcli con up ens33

这里有个配置差异:CentOS 7 同时存在 network 和 NetworkManager 两套管理工具。如果你改了配置文件但发现不生效,检查一下 NetworkManager 是不是接管了这块网卡。我见过用户在/etc/sysconfig/network-scripts/下改了 IP,结果 NM 自动覆盖了配置,最后两条命令很快解决:

systemctl disable NetworkManager systemctl enable network systemctl restart network

另外提醒一句,很多从 CentOS 6 时代过来的老文档还在教改eth0,但 CentOS 7 默认用ens33或ens192这类网卡命名。如果写的网卡名不对,文档改得再对也等于白改。可以用ip addr先确认实际网卡名。

3.2 路由表与多网卡的干扰

单网卡配置不当导致问题,相对好查。真正头疼的是多网卡服务器。

有一次我在一台双网卡 CentOS 7 上部署服务,外网网卡和内网网卡都配置了默认网关。重启后系统把默认路由指向了内网网卡,结果从外网 SSH 22 端口进来的包,回包却从内网网卡发出去了。客户端那边看到的全是连接超时。

排查命令:

ip route

正常情况下输出里应该只有一条default via。如果出现了多条默认路由,或者默认网关指向了错误的网卡,处理方式通常是把不需要的 GATEWAY 注释掉,或者用策略路由(ip rule)控制源地址路由。

对于只有一张网卡的读者,这里也不可掉以轻心。CentOS 7 里 NetworkManager 有时候会动态修改路由表,尤其是虚拟机环境里 DHCP 和静态配置混用的时候。配置完 IP 之后,再执行一次ip route确认默认路由存在且指向正确,这是成本最低的保险。

4. firewalld 是 22 端口访问失败的头号嫌疑人

4.1 先确认防火墙到底开没开

CentOS 7 默认使用 firewalld,但在很多装机教程和自定义镜像里,可能同时存在 iptables 服务。所以排查时要先确认到底是谁在拦。

systemctl status firewalld firewall-cmd --state

如果输出running,那防火墙就是主要嫌疑人。接着查看当前 zone 和已有规则:

firewall-cmd --get-default-zone firewall-cmd --list-all

--get-default-zone输出通常是public,但如果被改成了drop,那所有入站流量都会被直接丢弃,SSH 无论如何都连不上。--list-all里能看到当前 zone 放行了哪些服务和端口,如果services: ssh不在列表里,22 端口默认就被挡在外面。

这里有个关键概念:firewalld 的 zone 机制类似“不同信任级别的区域”。public区域默认只放行少量服务,drop区域默认丢弃所有入站请求,trusted区域默认接受所有流量。CentOS 7 安装完成后默认是public,本来应当放行 ssh,但很多人在配置过程中误改了默认 zone,或者执行过一些第三方脚本导致 zone 变成了 drop。检查这一步一定要做。

4.2 正确放行22端口的命令

如果防火墙开着但规则里没有 ssh,执行以下命令放行:

firewall-cmd --permanent --add-port=22/tcp firewall-cmd --reload

这里加不加--permanent是新手最容易踩的坑。--permanent表示写入永久配置,重启后依然生效;不带这个参数的话,规则只对当前运行环境生效,重启 firewalld 或重启机器后就没了。

如果你想指定来源 IP,而不是对所有 IP 开放,可以用 rich rule:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.31.0/24" port protocol="tcp" port="22" accept' firewall-cmd --reload

执行完以后,一定要复查:

firewall-cmd --list-all

确认ports: 22/tcp或对应的 rich rule 已经出现。如果复查发现规则不在,多半是刚才的命令没加--permanent,重启后丢了。

4.3 “重启失效”和 DOCKER 链的坑

说一个很典型的现场故事。有人执行了firewall-cmd --add-port=22/tcp,当时测试 SSH 可以连接,很高兴。结果第二天重启机器后又连不上了,还非常困惑“我明明放行了”。

原因就是上面说的:--add-port没有加--permanent,规则只存在于运行时配置里。重启后 firewalld 加载永久配置,临时规则自然消失。正确的操作流程是:先加--permanent,再--reload,最后用--list-all复核。

另一个更隐蔽的坑和 Docker 有关。CentOS 7 上装了 Docker 之后,Docker 会在 iptables 的 FORWARD 链中插入 DOCKER 规则。如果firewalld和 Docker 的启动顺序不对,或者做了防火墙操作后没有重新初始化 Docker 链,可能会导致整个网络转发异常,表现之一就是 22 端口访问失败。

排查方法:

iptables -L -n | grep 22 iptables -L FORWARD -n

看到 DOCKER 链的规则覆盖了 FORWARD 行为,但又不确定是不是它导致的,可以临时验证:

systemctl stop firewalld

然后立刻用客户端测试 22 端口。如果能连接了,说明一定是 firewalld 的规则问题。确认后再把防火墙启动回来,用最小化放行规则代替“一关了之”。

5. sshd 服务本身与 SELinux 的隐形坑

5.1 检查 sshd 是否在听、监听在哪

当网络层和防火墙都排除后,就要看 sshd 自己了。先检查服务状态:

systemctl status sshd

如果显示active (running),再看监听地址:

ss -tlnp | grep :22

正常情况应该看到类似下面的输出:

LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))

注意0.0.0.0:22表示监听在所有 IPv4 地址上。如果看到的是127.0.0.1:22,那问题就大了:sshd 只监听在回环地址上,外部流量根本无法到达。这种情况通常是因为/etc/ssh/sshd_config里配置了ListenAddress 127.0.0.1,或者系统里其他配置文件覆盖了默认监听行为。

解决方法,把配置改为:

ListenAddress 0.0.0.0

然后重启 sshd。这是“端口通但连不上”的经典原因之一,排查时通过ss -tlnp一眼就能看出来。

5.2 sshd_config 改错导致远程回不来

另一种情况是服务端 sshd 没有在运行,或者启动失败。看状态和日志:

systemctl status sshd journalctl -u sshd -n 50 tail -n 50 /var/log/secure

如果有Failed to start OpenSSH server daemon之类的报错,大概率是配置文件写错了。最稳的操作是执行配置语法检查:

sshd -t

如果语法有误,这里会直接报错。这个命令在远程维护场景下简直是救命绳。我自己的习惯是:每次改完/etc/ssh/sshd_config,先sshd -t通过,再systemctl restart sshd。千万别直接 restart,一旦语法错误,服务起不来,远程会话直接断开,如果手头没有其他访问通道,就只能去机房或者靠 IPMI 了。

另外,配置里几个常见项值得留意:

  • PermitRootLogin:如果设为no,root 用户无法登录。
  • PasswordAuthentication:如果设为no,密码登录会被拒绝。
  • AllowUsers/DenyUsers:指定用户白名单或黑名单,如果配错了会把你自己挡在门外。
  • UseDNS:如果设为yes,客户端连接时服务端会做反向 DNS 解析,表现为连接建立很慢但最终能连上。对多数场景建议设置为no。

排障时结合/var/log/secure最有效。看到Failed password是认证失败,看到Connection closed by authenticating user说明认证流程被中断,看到error: maximum authentication attempts exceeded说明客户端尝试认证次数太多被服务端断开。

5.3 SELinux 拦截了 SSH 流量

很多人在排查 22 端口时会把 SELinux 直接忽略,但它确实会拦截 SSH,而且表现形式很迷惑:防火墙开了,sshd 也在监听,可外部就是连不上。

先看状态:

getenforce

输出Enforcing说明 SELinux 正在强制模式。为了快速定位,可以临时关掉验证:

setenforce 0

这时候如果客户端能连上了,那基本可以确定是 SELinux 拦截。但注意,setenforce 0只对当前运行环境生效,重启后恢复 Enforcing,不能作为长期解决方案。

长期方案是用 semanage 命令放行对应端口。比如你把 sshd 改到了 9022 端口,SELinux 默认只允许 22,就需要执行:

semanage port -a -t ssh_port_t -p tcp 9022

查看当前 SELinux 允许的 SSH 端口:

semanage port -l | grep ssh

如果看到ssh_port_t tcp 22只有 22,而你实际监听的是其他端口,那 SELinux 一定会拦。新增放行后重启 sshd 即可。

有人会问,为什么只改了端口就要动 SELinux?因为 SELinux 的端口类型标签和进程策略是绑定的,sshd 进程被标记为ssh_t,它只允许绑定到带有ssh_port_t标签的端口。你改了配置但没通知 SELinux,它当然继续按旧策略拦截。这个逻辑理解透了,以后遇到类似问题就不会一头雾水。

6. 资源耗尽、客户端干扰与虚拟机场景

6.1 磁盘满、日志刷爆、连接数耗尽

有些 22 端口“无法访问”其实和设备资源有关,这类问题表现得比较隐蔽,因为看起来配置文件都对。

第一个常见场景是根分区磁盘写满。用df -h看/的使用率,如果 100%,sshd 在写入 utmp、读取 authorized_keys、创建 session 文件时都会失败。表现可能是客户端输入密码后卡死,或者连接直接被拒。处理方式就是清理磁盘,通常先找/var/log下的大文件,再用journalctl --vacuum-size=200M收缩日志。

第二个场景是/var/log/secure被刷爆。如果服务器暴露在公网,被扫描器暴力破解,日志文件可能涨到几个 GB。日志写不进去时,sshd 的认证流程可能异常缓慢甚至无响应。处理方式是删掉旧日志并重启 rsyslog,同时建议启用 fail2ban 或修改 SSH 端口降低被扫概率。

第三个场景是文件描述符耗尽或进程数达到上限。查看:

ulimit -n cat /proc/sys/fs/file-nr

如果已分配文件描述符接近系统上限,sshd 无法 accept 新连接。表现是连接立即被拒或极慢。这种问题通常需要通过调大fs.file-max和进程的ulimit来解决,但更重要的是先找到为什么会有这么多文件描述符被占。曾经遇到过 coredump 文件堆积把inode耗尽的案例,df -i一看发现 inode 满,删除大量临时文件后才恢复。

6.2 客户端侧也有“假故障”

有一种情况很气人:服务器完全正常,问题出在客户端自己身上。

最常见的是 known_hosts 冲突。换过服务器系统或者恢复过快照后,客户端的~/.ssh/known_hosts里还存着旧的指纹,连接时会报:

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

这时候很多人会不知所措,实际上删除对应的 known_hosts 条目即可:

ssh-keygen -R 192.168.31.10

另外一个隐蔽因素是客户端开了全局代理。我用 Windows 上某些 SSH 工具连接内网 Linux 服务器时,只要系统代理开着,连接就失败,关了代理立刻恢复正常。这个原因在文档里很少被提及,但真实场景遇到概率不小。

多角度验证也很有用。如果服务器连不上,拿另一台电脑、手机上的 Termius、或者换个网络环境试一试。如果其他设备能连,只有你这台机器不能连,那问题的范围基本锁定在客户端,不必再折腾服务器。

6.3 VMware 虚拟机网络模式的影响

很多新手是在 VMware 里装的 CentOS 7,然后发现 22 端口连不上。这时候要先看虚拟机的网络模式,因为不同的模式决定了谁能访问这台虚拟机。

VMware 三种网络模式的区别整理如下。

模式虚拟机 IP 特征宿主机能否访问局域网其他机器能否访问
NAT192.168.x.x,由 VMnet8 分配能默认不能,需端口转发
桥接与宿主机同网段能能,前提是 IP 配置正确
仅主机192.168.x.x,由 VMnet1 分配能不能

最常见的坑是选 NAT 模式,然后局域网里另一台电脑想 SSH 连这台虚拟机,怎么都连不上。这不是 CentOS 7 的问题,而是 NAT 模式本身就不允许外部主动访问。解决方式有两种,要么改用桥接模式,要么在 VMware 的 NAT 设置里添加端口转发,把宿主机的某个端口转发到虚拟机的 22 端口。

此外,虚拟机内部网卡可能没有“已连接”。编辑虚拟机设置,确认网络适配器那里已勾选“已连接”和“启动时连接”。我遇到过一台虚拟机关机后再次开机,网卡连接状态丢失,导致ip addr里根本没有 IP 地址,这类问题不到虚拟机设置里看一眼很难发现。

7. 排障速查表与几条实战体会

7.1 常用排障命令速查表

把多年积累的排查命令整理成一张表,遇到问题可以按顺序来。

现象可能原因先执行什么
ping 报“无法访问目标主机”ARP 不通、目标不在链路内ip neigh、检查网段
ping 超时ICMP 被禁或路由问题用nc -vz IP 22验证 TCP
telnet 显示 Connection refusedsshd 没监听或防火墙 REJECTsystemctl status sshd
telnet 超时防火墙 DROP 或回程路由错误firewall-cmd --list-all、tcpdump
防火墙规则里有 22 端口仍连不上SELinux 拦截或 sshd 监听错误地址getenforce、ss -tlnp
密码正确但认证失败磁盘满、authorized_keys 权限错、UseDNSdf -h、tail /var/log/secure
换网络环境能连,原网络不行客户端代理、IP 冲突、宿主机防火墙关闭代理、换 IP 测试

这张表不能覆盖所有情况,但能覆盖八成以上“22端口无法访问”的问题。剩下的就需要结合日志和抓包深入分析了。

7.2 三条实战体会

第一个体会是:先用nc或telnet测端口,别急着改服务器。命令结果直接告诉你问题是“拒绝”还是“超时”,方向完全不一样。拒绝查服务和防火墙 REJECT,超时查防火墙 DROP 和路由。

第二个体会,也是踩过坑才明白的:不要为了方便直接永久关闭防火墙。见过太多人systemctl disable firewalld然后服务器被扫描爆破,SSH 被塞满垃圾日志。正确做法是只放行必要端口,能用 rich rule 限制来源 IP 就尽量限制。22 端口是登录入口,安全等级本来就该比普通服务高。

第三个体会和配置安全相关:改 sshd 配置前先备份,改完先sshd -t自检,再重启服务。我唯一一次被锁在云主机外面就是深夜手滑把 Port 写错,重启后 sshd 直接起不来。从那以后所有涉及 SSH 的改动,都必须先跑语法检查。这个习惯救了我很多次,也希望这次分享能帮到你。

CentOS 7 已经服役多年,这类端口访问问题本质都不难,难的是被各种环境变量干扰。希望这篇排障记录能让你下次面对 22 端口问题时,少走几步弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 3:38:36

LeetCode每日一题:基本计算器与栈的边界处理实战

说实话,LeetCode的每日一题这个日历,我从 2021 年就开始跟了,中间断断续续,真正坚持下来也就是最近这大半年。昨天 1 月 22 号的这道题,难度不算顶天,但背后的套路特别典型,做完之后我想了很久&…

作者头像 李华
网站建设 2026/10/1 3:38:35

C# WinForm 人脸卡通化工程实战:ONNX Runtime 与 OpenCvSharp 集成

简介:本资源是一套基于C#与WinForm框架、结合PhotoCartoon算法实现人物卡通化效果的完整源码工程,面向具备一定C#基础、希望学习图像风格化处理与深度学习模型部署的开发者。工程在VS2019、.NET Framework 4.7.2、OpenCVSharp 4.8.0与ONNX Runtime 1.16.…

作者头像 李华
网站建设 2026/10/1 3:37:54

Chinese-CLIP中文图文检索实战:从零部署可答辩的双塔系统

简介:本资源是一套基于Python实现的Chinese-CLIP图文跨模态检索系统,面向计算机视觉方向的学习者与实践者,特别适合作为课程设计、毕设选题或工程实训项目。系统完整复现了中文图文匹配的核心流程,涵盖预训练模型加载、多模态特征…

作者头像 李华
网站建设 2026/10/1 3:37:54

MES系统是什么?一文讲透制造执行系统的核心功能与落地实践

做了十多年产线信息化,我经手过的MES系统没有三十套也有二十套。从汽车零部件到电子装配,从注塑车间到机加工线,几乎每个制造业老板都会问我同一个问题:MES到底能帮我干什么?这个问题看似基础,但真能用一句…

作者头像 李华
网站建设 2026/10/1 3:37:54

ByteTrack实战:从VOC数据集训练到实时多目标跟踪

简介:ByteTrack超详细教程配套资源包,面向目标检测与多目标跟踪方向的算法学习者与开发者,帮助解决自定义VOC格式数据集训练、摄像头实时检测与跟踪两大核心问题。包内共250个文件,以Python脚本(145个py)和…

作者头像 李华