情况
Ubuntu20.04 live
服务器启动了一个Nginx
服务,服务使用80
端口,服务器有2
个网卡。经过公司H3C
路由器NAT
转发,将内部服务器的80
端口映射到公网5088
端口。通过内网的主机可以服务Nginx
服务,通过公网IP+5088
端口,无法访问Nginx
服务。
现象
在Ubuntu20.04
服务器通过tcpdump
转包,发现通过公网IP
访问的请求,在Server
可以收到第一个TCP
的SYN
包,收到SYN
包之后,Server
不向Client
返回SYN+ACK
包。
解决办法
Server
的网关信息配置错误(下图网关配置错误)
上图中多个网卡时,配置的网关是错误的配置。yaml
文件中不允许配置多个gateway4
将yaml
中gateway4
注释掉,然后netplan apply
。至此问题解决,下面是解决这个问题的过程。仅供参考。
解决过程
致谢
我们的运维在n
个月之前将一套服务部署在公司内网服务器上面,从裸服务器到安装Ubuntu20.04 live
系统,配置服务器静态网络,再到安装项目环境,运行环境。都是运维凭借一己之力完成。
序言
就在昨天,客户要求通过公网访问服务,运维请网络工程师将服务映射到公网。网管也给他映射好了,但是客户通过公网却一直不能访问服务,急的客户都快骂娘了。
第一章 与网管的爱恨情仇
但是内网可以访问该服务。我确定我写的服务肯定没问题,然后把锅丢给网管。网管当然也不接这个锅,通过我映射的其他服务你试试在公网可以访问吗?我试了一下,果真可以访问。
第二章 Ubuntu 抓包
那问题出在哪里了?我问运维,运维也不知道。然后就是我替运维找问题的过程。首先怀疑NAT
丢弃了来自公网的请求,无奈不好向网管开口在路由器中抓包查看请求。只好在Server中
通过tcpdump
抓包分析,使用tcpdump -i <网卡> -vnn port 80
,开始抓取所有请求Server 80
端口的请求。
第三章 发现
Server劈腿
通过抓包发现:Client
通过内网请求Server
的80
端口,在tcpdump
记录中可以看到有SYN
,然后Server
回复ACK
…然后握手就建立了,开始请求接口,内网一切正常;Client
通过公网请求Server
映射的端口,在tcpdump
记录中只能看到Client
的SYN
,因为Client
没有收到ACK
,所以Client
在短时间内一直在尝试向Server
发送SYN
。但是Server
不回复ACK
,此时的Server
真实王八吃秤砣,铁了心不给Client
回复。
分析内网和外网请求第一次握手的SYN
包时,发现内网的SYN
报头中没有TS Val(时间戳)
,而通过外网请求的第一次握手SYN
报头中有TS Val(时间戳)
,然后一番询问ChatGPT
,得知TS Val
是报头请求时客户端的时间戳,而且这个tcp
数据包中timestamps
的value
是系统开机时间到现在时间的(毫秒级)时间戳。
第四章 毛利小五郎探(渣男)
Server
然后开始搜索服务端收到syn但是不回复ack
。
一通搜索,无一例外都是说Ubuntu
内核修改了,要检查设置net.ipv4.tcp_timestamps
或设置net.ipv4.tcp_tw_recycle
,我也都设置了,然而Server
这个渣男还是不给Client
回复ACK
。
第五章 工藤新一探(渣男)
Server
慢慢分析,慢慢秃头。就在我快绝望的时候看到一篇文章,奉上文章链接内网PC通过NAT server公网地址访问内部服务器时TCP三次握手不成功,TMD
这不就跟我现在的情况一样吗,为什么Server
向Client
回复的消息发不出去呢?
第六章 真相大白
我一度怀疑是Server
的DNS
配置有问题。可是Server
网络是运维小哥配置的,应该没有问题,确定不是Server
网络的问题,我开始查看Nginx
的配置文件,检查映射端口(如果这些配置错误了,内网也不能访问,只是自己寻找心里安慰罢了)。上面冤枉Server
这个渣男了。
第七章 洗脱冤屈
当我运行netplan apply
时,有一个Warning
和一个Error
,报错了,解决问题的关键就在此刻。
** (generate:26873): WARNING **: 21:44:53.561: Problem encountered while validating default route consistency.Please set up multiple routing tables and use `routing-policy` instead.
Error: Conflicting default route declarations for IPv4 (table: main, metric: default), first declared in eno2 but also in veth3146213** (process:26871): WARNING **: 21:44:53.916: Problem encountered while validating default route consistency.Please set up multiple routing tables and use `routing-policy` instead.
Error: Conflicting default route declarations for IPv4 (table: main, metric: default), first declared in eno2 but also in veth3146213
然后去修改Server
网络,果然,果然,下面是网络配置
我将eno2
和veth3146213
网卡(虚拟网卡为什么还这么配置)的gateway4
注释掉,然后netplan apply
后,没有报错,浏览器通过公网打开了服务端口。当初运维小哥配置好网络后,apply
时,那么大的两个Error
就直接忽略了。直到这次映射公网不能访问服务才发现这两个Error
。