Ubuntu 防火墙导致 Connection refused 的定位与修复
一、先快速判断是否为防火墙问题
- 在服务器本机检查 SSH 是否在监听:sudo ss -tulnp | grep :22(或 sudo netstat -tulnp | grep :22)。若没有输出,通常是 SSH 服务未安装或未启动,先处理服务再谈防火墙。
- 查看防火墙状态与规则:
- UFW:sudo ufw status(应看到 Status: active 且有 22/tcp ALLOW 规则)
- firewalld:sudo firewall-cmd --state(应为 running),sudo firewall-cmd --list-ports(应含 22/tcp)
- 从客户端做连通性验证:
- telnet 目标IP 22 或 nc -vz 目标IP 22,若提示 “Connection refused”,多为目标机端口未监听或被策略直接拒绝;若 “Connection timed out”,更可能是端口未放行或网络不通。
- 虚拟机场景请确认网络模式:桥接(与宿主机同网段直连)或 NAT+端口转发(如宿主机 2222 → 虚拟机 22)。
二、按防火墙类型放行端口
- 使用 UFW(Ubuntu 常见)
- 允许 SSH:sudo ufw allow 22/tcp 或 sudo ufw allow ssh
- 启用防火墙:sudo ufw enable
- 使规则生效:sudo ufw reload
- 核对规则:sudo ufw status(应看到 22/tcp 允许)
- 使用 firewalld
- 放行端口:sudo firewall-cmd --zone=public --add-port=22/tcp --permanent
- 重载:sudo firewall-cmd --reload
- 核对端口:sudo firewall-cmd --list-ports(应含 22/tcp)
- 如需临时排除防火墙干扰做 A/B 测试,可短时关闭后再开启:
- UFW:sudo ufw disable → 测试 → sudo ufw enable
- firewalld:sudo systemctl stop firewalld → 测试 → sudo systemctl start firewalld
- 若系统使用 iptables 直接管理,可查看规则:sudo iptables -L -n;放行示例:sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT(生产环境请谨慎变更并保存规则)。
三、若放行后仍被拒绝,排查 SSH 服务与配置
- 安装并启动 SSH:sudo apt-get update && sudo apt-get install openssh-server;sudo systemctl start ssh;sudo systemctl enable ssh;sudo systemctl status ssh(应为 active/running)。
- 确认监听地址与端口:sudo ss -tulnp | grep :22,正常应见 0.0.0.0:22 或 :::22 处于 LISTEN。
- 检查关键配置(/etc/ssh/sshd_config):确保 Port 22、ListenAddress 0.0.0.0(或注释掉以监听所有地址)、按需设置 PermitRootLogin、PasswordAuthentication yes;修改后重启:sudo systemctl restart ssh。
- 查看认证日志定位问题:sudo tail -f /var/log/auth.log(如 refused、invalid user、pam 等提示能指明方向)。
四、虚拟机与云主机的额外检查
- 获取正确 IP:ip addr;确保与客户端网络可达(同网段或路由可达)。
- 虚拟机网络模式:优先 桥接;若用 NAT,务必在虚拟化软件中配置端口转发(如 宿主机 2222 → 虚拟机 22),客户端连接时使用宿主机的 2222。
- 云服务器安全组/NACL:除系统防火墙外,还需在云平台控制台放行 TCP 22(入站),否则仍会被拒绝。
五、常用命令速查表
| 目的 |
UFW |
firewalld |
说明 |
| 查看状态 |
sudo ufw status |
sudo firewall-cmd --state |
判断是否启用 |
| 放行 SSH |
sudo ufw allow 22/tcp 或 sudo ufw allow ssh |
sudo firewall-cmd --zone=public --add-port=22/tcp --permanent && sudo firewall-cmd --reload |
放行端口并重载 |
| 核对规则 |
sudo ufw status numbered |
sudo firewall-cmd --list-ports |
确认 22/tcp 是否在列 |
| 临时关闭 |
sudo ufw disable |
sudo systemctl stop firewalld |
仅用于排查,用完请开启 |
以上步骤覆盖了最常见的 “被防火墙拦截导致 Connection refused” 的根因与处置路径;优先确保 SSH 服务在监听,再按所用防火墙放行 22/tcp,最后用日志与连通性测试闭环验证。