8080 打不开的四层定位:监听地址、ufw、DOCKER 链、安全组

周二早上八点四十,客户在群里发了一句「8080 打不开」,后面跟一张 ERR_CONNECTION_TIMED_OUT 的截图。

机器是上周新买的 2C2G,跑一个 Java 服务,监听 8080。他自己在控制台把安全组入方向改成 0.0.0.0/0、协议端口写 ALL,还是不通。到这一步一般人会继续在安全组里翻,我习惯反过来,从机器里面往外查。

一、先分清「连不上」是哪一种

ssh 上去,本机先测一次:

bash 复制代码
SCHEME=http 
curl -sS -m 3 -o /dev/null -w '%{http_code}\n' "$SCHEME://127.0.0.1:8080/"

返回 200,说明服务活着,参数也没问题。再换一台外网机器测:

yaml 复制代码
nc -vz -w 3 203.0.113.10 8080

两种结果的含义完全不同:

  • Connection refused:对端回了 RST。包到了机器,但那个端口上没有进程在等,或者被 REJECT 拒了。
  • 一直卡到超时:包被 DROP 了,或者根本没到机器。安全组、本机的 DROP 规则、路由,都在这条线上。

这一步能砍掉一半工作量。refused 往机器里查,timeout 往机器外查。客户是后者。

二、第一层:监听地址可能只听了回环

netstat -tlnp 扫一眼「在听」,不等于外部能连:

shell 复制代码
ss -lntp 'sport = :8080' 
# LISTEN 0 128 127.0.0.1:8080 0.0.0.0:* users:(("java",pid=1731,fd=98))

127.0.0.1:8080 意思是只有本机能连。外面来的包目标是公网 IP,内核找不到匹配的监听,直接 RST。安全组开到 ALL 也没用,因为包压根没被交给应用。

要的是 0.0.0.0:8080 或 *:8080。另外留意 [::]:8080------只写了 IPv6 的监听。net.ipv6.bindv6only=0 时它顺带接 IPv4,设成 1 就只接 v6,症状和只听回环一模一样。

那次客户的服务配置文件里写着 server.address=127.0.0.1,是半年前为了「安全」改的,一直没出问题,因为一直没人从外网连过。

三、第二层:本机防火墙

Ubuntu 上多半是 ufw:

lua 复制代码
ufw status verbose

看两行就够:Default: deny (incoming),以及规则里有没有 8080。加规则时别省协议:

bash 复制代码
ufw allow 8080/tcp

不写 /tcp 时 ufw 会同时放 tcp 和 udp。看着能用,实际是多开了一个不需要的口子。

CentOS 系是 firewalld,注意两步:

css 复制代码
firewall-cmd --add-port=8080/tcp --permanent 
firewall-cmd --reload 
firewall-cmd --list-ports

只敲第一条不 reload,规则没进运行时,--list-ports 里也看不到。这个我漏过两次,第二次是在客户面前。

如果机器上直接用的是 iptables 或 nft,先确认有没有被别的规则集接管:

css 复制代码
iptables -S | grep -i 8080 
nft list ruleset | grep -i 8080

Ubuntu 22.04 默认是 nft 后端,iptables -L 看到的是兼容层翻译过的内容。写规则时一半用 iptables、一半用 nft,很容易出现「规则在、行为不对」,因为两套工具动的是不同表的视图。

四、Docker 发布端口会绕过 ufw

如果服务在容器里,ufw deny 8080 之后外面照样能连。docker -p 的端口发布走 nat 表的 DOCKER 链做 DNAT,包在 FORWARD 链被放行,不经过 INPUT;而 ufw 的规则主要挂在 INPUT。

arduino 复制代码
iptables -t nat -L DOCKER -n --line-numbers

看到这样一行,就是 docker 开的口子:

lua 复制代码
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:8080

要收回,在 DOCKER-USER 链最前面插规则,或者发布时只绑回环:

arduino 复制代码
docker run -p 127.0.0.1:8080:8080 ...

前面挂个 nginx 反代,对外只留 80/443。

顺带说一句 DOCKER-USER 的位置:它是留给使用者的链,docker 重启不会清空,但顺序在 FORWARD 之前。写 -I 插到最前面,别用 -A,否则会被后面的放行规则先命中。

查这类问题,几台机器的监听列表我会并排放着看,一般开极目Linux桌面一起连过去,省掉来回切窗口。也谈不上多省事,规则该改还是回控制台,它不替我做判断。

五、第三层:云安全组

到这一步才轮到控制台。四个地方按顺序看:

  1. 绑定对象。规则写对了,但绑在另一台实例上,或者绑的是默认安全组而实例早就换组了。
  1. 方向。要改的是入方向,不是出方向。
  1. 优先级 。多数云厂商的拒绝优先于允许,一条 0.0.0.0/0 全部拒绝 排前面,后面放行 8080 是无效的。
  1. 源地址 。10.0.0.0/8 和 0.0.0.0/0 是两件事,内网通不代表公网通。

还有个隐性的:大陆的云主机上 80/443 要备案才放行,25 端口默认封,换端口绕不过去,只能提工单。

有人为了少登录几次,会在机器上装个 Web 面板看端口和监听。代价是面板自己就占一个对外端口,还多一个要打补丁的服务。另一条路是本地渲染型客户端:界面在本地渲染、只走现成的 SSH 通道,服务器侧不装 Web 服务、也不新增端口。要不要让工具进服务器,判断只有一条------看它是否在服务器上新增对外端口。

六、用 tcpdump 定死在哪一层

前面都看完还不通,就别猜了,抓包:

arduino 复制代码
tcpdump -i any -nn 'tcp port 8080' -c 20

在服务端挂着,同时从外网 nc -vz 打一次。三种结果对应三个位置:

抓到的包 结论 下一步
只有 SYN,没有 SYN-ACK 包到了机器,本机在丢 查 iptables/nft
连 SYN 都没有 包没到 查安全组、路由、NAT
SYN 和 SYN-ACK 都有 网络通 问题在应用层,不是端口

客户那台抓到的是第二种,一条 SYN 都没有。最后发现安全组规则加在了默认组,而实例两星期前被换到了另一个组。前面所有放行操作都做在了错的对象上。

抓包还有一个细节:别只跑三秒就下结论。-c 20 是抓满二十个包退出,如果对方一直没连,命令会一直挂着,看着像"没输出"。想给命令加个时限,用 timeout 20 tcpdump -i any -nn 'tcp port 8080' -c 5,命令结束就是观察期结束。

七、开完记得收

临时排查时放行的 0.0.0.0/0,问题解决后要收回到具体来源 IP,能限源就限源。端口这件事上,多开一个就是多一个长期要盯的面。

FAQ

Q1:ss 显示在听,外面还是不通,最先看哪一列?

看 Local Address 那一列。127.0.0.1:端口 表示只监听回环,外部连接会在内核层被 RST,任何防火墙放行都无效。0.0.0.0:端口 才是全地址监听,[::]:端口 要额外确认 bindv6only 的取值,否则只接 IPv6。

Q2:安全组放行了、本机 ufw 也放行了,为什么还是 timeout?

三个常见原因:规则绑错对象(绑在默认安全组而非实例当前所在组)、拒绝规则优先级更高、以及容器发布端口走的是 FORWARD 链,绕开了以 INPUT 为主的 ufw 规则。逐个排除最快的方法是在服务端抓包,看 SYN 有没有到。

Q3:Connection refused 和"卡住不动"能说明什么?

refused 是对端回了 RST,说明包到达了对端主机,但端口没有监听进程,或被 REJECT 显式拒绝,问题在机器内部。卡住是包被静默丢弃,问题在路径上------安全组、DROP 规则、NAT 都可能。前者查进程和本机规则,后者查网络链路。

Q4:把服务换到 8080 之外的端口,能绕开运营商的限制吗?

对 25 端口这类策略无效。多数云厂商对 25 出方向做统一封禁,换端口仍然被拦,需要提交工单申请解封。80/443 在大陆主机上受备案约束,换高位端口可以临时访问,但对外提供 Web 服务仍然要备案。

Q5:不装 Web 面板的话,端口和监听状态还能怎么看?

通过 SSH 直接读系统状态就够:ss 拿监听、iptables -S 或 nft list ruleset 拿规则、ps 拿进程。这类本地渲染型客户端的界面在本地渲染、只走现成的 SSH 通道,服务器侧不装 Web 服务、也不新增端口,所以「看」这件事本身不增加对外暴露面。边界也要说清:它适合看状态和临时改一处,批量下发配置、多人协作、留审计日志仍然要做在别处。要不要让一个工具进服务器,判断标准就一句------看它是否在服务器上新增对外端口。

Q6:云上配了安全组,是不是就可以把本机防火墙关掉?

不建议。安全组管的是云网络边界,本机规则管的是主机内部,两者失效条件不同:安全组配错、实例换组、同 VPC 内互访,都会绕过前者。关掉本机防火墙等于把最后一层兜底也去掉,而且这种改动往往没人记得改回来。

相关推荐
程序开发阿元6 分钟前
swappiness 60 和 10 差在哪:一台 1C1G 的三轮对比
linux·ssh
无足鸟ICT29 分钟前
【RHCA+】mpstat命令(监控CPU)
linux
GeW2 小时前
新质生产力Linux和数据库为啥这么关键
linux
番茄啊2 小时前
linux 开启xftp连接
linux·运维·服务器
CodeYp20192 小时前
第1讲:Linux 基础指令
linux·指令
李松桃3 小时前
基于端口号的服务配置
linux·nginx-核心模块配置
CodeYp20197 小时前
第14讲:mmap 实现文件 LRU 缓存
linux·lru·mmap
程序开发阿元8 小时前
一台 20G 的 VPS 被日志吃掉一半:我按这个顺序查了二十分钟
linux·ssh
.冰块.8 小时前
流量大了自动加 Pod!K8s HPA 扩缩容与 ResourceQuota/LimitRange 资源管控实战
linux·云原生·容器·kubernetes·hpa·quota·limitrange