ARTICLE DETAIL

资讯详情

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

服务器端口测试全攻略:从TCP/UDP原理到防火墙排查实战

服务器端口测试全攻略:从TCP/UDP原理到防火墙排查实战 做运维这些年遇到最多的问题不是服务彻底挂掉而是业务方跑过来说一句“服务器端口不通”。每次我都要从头问一遍你测的是TCP还是UDP从哪台机器测的目标IP和端口到底写的什么这三个问题只要有一个没搞清楚后面所有排查动作都是在撞大运。服务器端口测试听起来是个基础操作但真往深了做里面全是细节。今天我就把这块彻底摊开讲一遍从底层概念到常用工具再从UDP测试的坑到防火墙排查全部按我实际干活的经验来写希望对你有用。1. 端口测试前先把这些底层概念过一遍1.1 端口不是“一个数字”那么简单很多人说起端口测试第一反应就是“测一下某台服务器的某某端口通不通”。但只要你用过一个星期Linux就会知道端口必须和IP、协议放在一起才有意义。一个TCP端口和一个UDP端口即使数字一样也是完全独立的两个通信入口。比如DNS服务同时监听53/tcp和53/udp你只测TCP 53通不代表UDP 53就一定能用。还有一个特别容易忽略的点服务器上的服务监听地址。同样一个8080端口服务可能监听在0.0.0.0:8080也可能只监听在127.0.0.1:8080。前者对局域网内所有机器开放后者只有本机能访问。很多人在服务器上敲curl 127.0.0.1:8080发现正常就告诉别人端口是通的结果外部机器一测就超时——问题往往出在服务绑定了回环地址。所以做端口测试前先得想清楚你要测的是IP:端口加上协议这是一个三元组。目标IP是公网地址还是内网地址端口是服务监听端口的实际数值协议是TCP还是UDP三个要素缺一个测试结果都没法作为依据。1.2 三层连通性和四层端口监听完全是两回事“能ping通”和“端口能连上”是两层不同的事情。ICMP工作在IP层只要网络路由可达、目标主机没禁ping就能收到回应。但TCP端口能不能连上取决于目标主机上是否有进程在这个端口监听以及防火墙是否允许这个端口的报文进入。举一个我真实遇到的例子一台部署了Nginx的服务器从办公网ping它公网IP延迟很低丢包为0但浏览器访问超时。后来排查发现服务器上的Nginx确实在监听80端口但云安全组根本没有放行TCP 80入站。ICMP能通是因为安全组放行了普通协议但TCP 80被挡了。这就是典型的“三层通四层不通”。反过来也一样存在端口通不代表服务可用。TCP握手成功只能说明内核的协议栈把连接建立起来了但如果应用层的Worker进程卡死连接建立后可能立刻断开或者长时间不响应。所以端口测试只能证明“传输层可达”不能证明“应用层正常”。这个边界从一开始就要心里有数。1.3 什么时候该做端口测试端口测试最常见的场景有四个部署验证刚装好一个服务比如MySQL、Redis、Nginx确认端口确实在监听并且能对外提供服务。防火墙变更后改了iptables规则、firewalld配置或者云安全组规则需要验证端口放行是否生效。故障定位业务反馈连接超时或拒连需要逐段判断是服务没起来、网络不可达还是防火墙拦截。安全巡检定期扫描服务器上对外开放的端口确认没有多余端口暴露在公网。注意这种情况必须提前确认你具备授权否则自己扫自己的机器没问题扫别人的就可能踩线。端口测试不是万能的但它是所有网络排查的第一步。把概念捋清楚了后面用什么工具都顺手。2. 我常用的四个端口测试工具telnet、nc、nmap 的真正边界2.1 telnet最朴素但别被“Connecting to”骗了telnet IP 端口是几乎所有运维第一个学会的端口测试命令。Windows和Linux默认都自带telnet客户端Windows上可能需要去“启用或关闭Windows功能”里勾选这个坑很多人踩过。用法很简单telnet 192.168.1.10 3306如果端口开放终端会显示Connected to 192.168.1.10然后进入一个黑框光标在闪。这时候你以为成功了不一定。有些服务比如MySQL在连接建立后会立刻发送一个欢迎报文然后要求客户端走协议你不理它它就一直挂着但有些服务比如普通HTTP服务你连上之后没有任何输出直到超时断掉。还有更坑的情况某些TCP服务会在收到连接后立刻主动关闭连接比如一些只接受特定来源IP的服务。telnet显示Connection closed by foreign host.这并不代表端口不通恰恰相反TCP握手已经完成是服务主动断开的。所以telnet测端口判断标准只有一个是否出现了Connected to这句话。出现就是通没出现就是不通。至于后续报错那是另一回事。2.2 ncnetcatTCP和UDP都能测的瑞士军刀nc比telnet灵活太多我几乎每个服务器上都装。最常用的端口测试命令是nc -zv 192.168.1.10 3306参数-z表示只扫描不发送数据-v是显示详细输出。结果会直接告诉你Connection to 192.168.1.10 3306 port [tcp/mysql] succeeded!比telnet那套黑屏清晰多了。还可以加-w指定超时时间防止目标主机无响应时卡住nc -zv -w 3 192.168.1.10 3306这个-w 3在批量测试时非常重要。没有它如果网络黑洞报文直接丢弃nc可能会卡很久。nc测UDP端口也能做命令是nc -u -z -w 3 IP 端口但这里有个大坑我在后面第3章专门讲。2.3 nmap批量扫描和服务识别如果只测一两个端口nc够了。但如果要给整个网段做端口开放情况摸底或者要确认端口后面的服务类型那还是nmap靠谱。常用命令nmap -sS -p 22,80,443 192.168.1.10-sS是TCP SYN扫描只发包不完成完整握手效率高而且不容易留下大量连接日志。-p可以指定多个端口用逗号分隔想扫一段就用-p 8000-9000。nmap还能做服务识别nmap -sV -p 3306 192.168.1.10它通过指纹匹配来推测目标端口后面跑的是什么服务版本对安全巡检很有用。不过nmap要谨慎使用。我在生产环境遇到过扫描导致服务端日志刷屏甚至触发防火墙封IP的情况。所以用nmap扫内网没问题扫公网目标尤其是别人的服务器必须先确认授权。2.4 工具选型速查表工具支持TCP支持UDP批量服务识别适合场景telnet是否弱否临时快速验证单个TCP端口nc是是中否日常单端口/多端口探测脚本化友好nmap是是强是端口扫描、拓扑梳理、安全巡检ss/netstat本机本机中有限查看服务器本地监听状态3. UDP端口测试比TCP容易让人翻车的地方3.1 为什么UDP端口测试是个老大难TCP端口通不通非常容易判断SYN发出SYN-ACK回来握手完成端口肯定通。UDP就不一样了它是无连接协议你发一个UDP报文过去目标端口如果有服务在监听正常来说不会回任何东西如果目标端口没服务大概率会回一个ICMP Port Unreachable但很多防火墙会过滤这类ICMP。这就导致一个现象UDP端口“看起来通”和“实际能用”之间没有必然关系。我接手过一个案例一套系统依赖内部NTP服务器同步时间业务方说“NTP端口不通”。我远程一看服务器上systemctl status ntpd显示服务正常ss -unlp能看到123端口在监听本机ntpdate -q 127.0.0.1也能正常返回。但跨网段测试时用nc -u -z测123端口永远等不到结果。这不是端口不通而是UDP测试本来就不该用“等回应”的方式来判断。3.2 实测UDP端口的几种可靠办法第一用真实的应用层客户端测。测NTP就用ntpdate -q 目标IP测DNS就用dig 目标IP example.com测RADIUS就用radtest。应用层协议只要正常说明UDP端口和整个服务链路都通。第二在服务器上抓包看ICMP。你可以从客户端发一个UDP包同时在服务器上执行tcpdump -i eth0 udp port 123如果抓到了客户端的请求包说明报文已到达服务器网络路径通畅如果还抓到了服务器进程回给客户端的响应包那更是板上钉钉的“通”。第三看是否有ICMP Port Unreachable回包。从客户端发一个UDP包给目标端口然后立刻抓包tcpdump -i eth0 icmp如果收到Destination Port Unreachable说明目标主机网络可达但这个UDP端口上没有服务监听或者被防火墙给拒了。如果连回包都没有要么是网络黑洞、丢包要么是NAT把报文吞了。第四检查服务器本机监听。ss -unlp能看到哪个进程在监听哪些UDP端口。注意UDP会显示“UNCONN”状态这是正常的UDP本来就是无连接的。只要进程绑定在正确的IP和端口上且防火墙没拦就可以认为服务在监听。3.3 真实案例公网NTP服务器的UDP 123测试很多人想测一台公网NTP服务器通不通最简单的方式是ntpdate -q 120.25.115.20它能拿到服务器的时间差信息就说明UDP 123通了。如果这个命令卡住不输出再用tcpdump抓包看有没有响应。我遇到过一种情况从云服务器上发NTP请求ntpdate -q能拿到结果但从本地办公网发就不行最后排查发现本地网络设备把UDP 123出站方向给禁了。你看端口测试的方向性也很重要——同一台服务器从A网络测通从B网络测不通问题可能不在服务器而在B网络。4. 防火墙和安全组这道隐形墙怎么识别和正确放行4.1 先从服务器本机防火墙看起端口测试不通第一步要查目标服务器本机的防火墙。Linux上常用的是firewalld和ufwCentOS 7以前还有iptables。查看当前开放端口firewall-cmd --list-all看ports那一行有没有你要测的端口。如果没有加上放行规则firewall-cmd --permanent --add-port8080/tcp firewall-cmd --reload如果你用的是iptables那就是iptables -A INPUT -p tcp --dport 8080 -j ACCEPT service iptables saveWindows服务器也一样有防火墙。比如Windows Server 2016入站规则需要在控制台“高级安全Windows防火墙”里新建或者用命令行netsh advfirewall firewall add rule nameOpen8080 dirin actionallow protocolTCP localport8080热词里有人问“windows2016服务器入站出站策略开放指定端口”说的就是这个。注意Windows防火墙的入站和出站是分开的理论上入站放行要测的端口出站默认是放行的但如果之前改过出站策略也要一并检查。4.2 云安全组是“前置防火墙”现在很多人用云服务器除了服务器内部防火墙还有一层更靠前的“安全组”。这层规则是在主机之外、由云平台的SDN实现的效果相当于一台前置防火墙。即使你服务器里iptables全部放行安全组没有放行外部一样连不进来。我见过最典型的坑就是一个人改了半天Linux防火墙怎么测都不通最后发现安全组入站规则压根没加这个端口。所以云服务器端口测试时一定要去云控制台确认安全组入站规则里源地址、协议、端口范围是不是覆盖了你的测试源IP和目的端口。还有个小细节安全组规则是有“优先级”的如果有一条高优先级的拒绝规则挡在你放行规则前面端口仍然不通。检查的时候不要只看有没有放行规则还要看有没有更靠前的拒绝规则。4.3 跨网段和NAT场景下的端口测试如果服务器在NAT后面或者你访问的是映射后的公网IP端口测试的链路就多了一段。比如家里有台NAS做了端口映射公网访问时映射到内网的某个IP和端口。你在公网用nc -zv 公网IP 映射端口即使NAS上服务正常也有可能是路由器上的NAT映射没配对。每一步拆开看内网PC先测NAS内网IP的端口确认服务正常。再测公网IP 映射端口确认NAT转发和路由器防火墙没问题。还要注意运营商可能封了80、443之外的常见端口这个只能靠换高端口测试来排查。所以跨网段端口测试本质上是在测试三个节点源端网络、中间NAT/出口防火墙、目标服务器。任何一个节点出了问题表现都是“端口不通”但处理方式完全不同。5. 一次“端口不通”的排障我从监听一路抓到包5.1 第一步确认服务真的在监听吗有次部署环境业务方反馈“连不上10.10.8.149的8080端口”连VS Code远程开发都报错“未能下载VS Code服务器(failed to fetch)”。我先登录服务器执行ss -tlnp | grep 8080结果没有输出。说明8080端口根本没有进程在监听。再查服务状态发现Tomcat没启动。所以“端口不通”的第一嫌疑人永远是“服务根本没起来”。如果ss -tlnp能看到类似LISTEN 0 100 *:8080 *:*那说明监听地址是*所有网卡基本能对外提供服务了。但如果看到的是127.0.0.1:8080就要去改服务配置让服务监听在内网或公网地址上。5.2 第二步本机回环测试排除服务层故障在服务器本地执行curl -v http://127.0.0.1:8080或者telnet 127.0.0.1 8080本机能通说明服务进程本身是好的问题出在网络层或者防火墙。本机都不能通那还得回头排查服务配置、依赖进程、端口占用冲突。注意本机测试用的是回环地址走的是虚拟网卡不会经过物理网卡所以即使服务器防火墙拦了所有外部请求本机回环通常也是通的。这个特性用于区分“服务层坏”和“网络层坏”特别好用。5.3 第三步跨主机测试区分防火墙与网络从另一台机器执行nc -zv -w 3 10.10.8.149 8080如果超时有三种可能网络路由不通、防火墙丢包、防火墙拒绝。为了快速区分有些人会直接把防火墙停掉再测但这在生产环境很危险。我一般不会上来就关防火墙而是先用telnet再结合抓包判断。还有一种中间测试方式用curl带--connect-timeout参数观察报错是Connection timed out还是Connection refused。后者说明收到了RST服务器防火墙虽然可能拒绝了你的源IP但至少网络链路是通的前者说明报文被静默丢弃网络中间节点或防火墙在DROP。5.4 第四步抓包定位丢包和拒绝如果怀疑防火墙我直接在服务器上抓包tcpdump -i eth0 tcp port 8080 -nn然后从客户端再发起一次连接。重点看TCP握手报文看到SYN发送但没有SYN-ACK返回报文可能在入站时被丢掉要么是云安全组拦了要么是本机防火墙DROP了。看到SYN发送返回RST说明有进程在监听但主动拒绝连接可能是防火墙REJECT或者服务配置了白名单。看到SYN和SYN-ACK都正常说明TCP握手已完成如果业务还报错问题基本不在端口层要去查应用层。我那次排查就是这样tcpdump抓包发现SYN一直发进来但没有SYN-ACK。登录云控制台看一眼安全组8080端口没放行。把端口加上去链接瞬间恢复。很多时候一条抓包命令就能省下半天乱猜的时间。5.5 快速排障对照表现象可能原因下一步动作本机回环通跨主机超时防火墙放行、云安全组、NAT映射查安全组和本机防火墙规则跨主机连接被拒绝Connection refused服务没监听该端口或防火墙REJECTss -tlnp确认监听状态跨主机连接超时Connection timed out网络丢包、防火墙DROP、安全组未放行tcpdump抓包看SYN是否到目标机端口通但应用报错服务进程正常但内部异常检查应用日志做应用层探测6. 批量端口测试与自动化监控6.1 用脚本批量检测多个端口当你需要检查一批服务器上多个端口时手工一条条敲命令根本不现实。我常用一个简单的bash循环配合nc的超时参数#!/bin/bash hosts(192.168.1.10 192.168.1.11 192.168.1.12) ports(22 80 443 3306) for host in ${hosts[]}; do for port in ${ports[]}; do if nc -zv -w 2 $host $port 21 | grep -q succeeded; then echo $host:$port open else echo $host:$port closed fi done done注意nc -zv的输出是写在stderr的所以要21把错误输出重定向过来再grep。这个脚本在机器不多的时候够用但如果你有几百台服务器建议用nmap的-p范围批量扫输出格式也更友好nmap -sT -p 22,80,443 --open 192.168.1.0/24--open只显示开放的端口日志量小很多。6.2 简单定时监控与告警端口测试不只是被动排障更应该做成主动监控。我写过一个最简单的监控脚本放在crontab里每5分钟跑一次发现端口不通就发一条告警消息。核心逻辑是可以自己扩展的#!/bin/bash if ! nc -zv -w 3 127.0.0.1 8080 21 | grep -q succeeded; then echo 8080端口异常 | mail -s 监控告警 opsexample.com fi更完善一点可以把多个端口的状态写到一个日志文件里再交给Prometheus这种监控系统做指标采集。但对我们日常运维来说脚本加crontab已经能解决80%的需求。6.3 真实教训端口测试通过不代表服务正常最后必须强调一个我吃过大亏的教训端口测试永远只是第一层防线。有一次早上业务反馈“订单服务不可用”我远程一看8080端口TCP握手一切正常curl -v虽能建立连接但响应HTTP 502。如果只看端口状态会误以为服务完全正常。后来查明是后端数据库连接池耗尽应用层没法正常处理业务请求。所以端口监控要做但高级一点的监控一定是“应用层探测”HTTP服务要请求一个健康检查接口检查返回码数据库服务要用查询语句测读写消息队列要试着收发一条消息。端口测试的定位是快速发现问题边界而不是做“健康证明”。结合我之前说的UDP测试你会发现一个共同规律凡是只靠系统工具“测通”的都不如直接用业务协议验证来得真实。真正靠谱的端口测试最后都要回归到应用能够正常通信这件事上来。我自己的习惯是无论多忙只要有人报“端口不通”先把“TCP还是UDP、从哪测、目标IP端口”这三件事问清楚再决定下一步用哪个工具。顺序永远是从服务监听查起再走防火墙和安全组最后抓包定量分析。这套方法论帮我解决过上百次连接故障今天分享出来希望你能少走几个弯路。
返回列表