port
约 1706 字大约 6 分钟
2025-10-12
我们常说的网络端口是指软件服务监听的端口,也即是逻辑端口(Logical Port)。它不像物理端口(如网卡接口)那样有实物实体,而是由操作系统分配的虚拟通道,用于标识特定进程或服务。
如果计算机中的某个软件应用或服务需要与其他终端进行网络通信,就需要暴露一个端口出来。网络端口由传输层(Transport Layer)使用,主要被UDP或TCP协议控制。这些协议负责数据包的可靠传输和端口的绑定。
端口号是什么?
端口号(Port Number)是网络端口的唯一编号,它是一个16位无符号整数,取值范围为0 到 65535(即2^16 - 1)。这个范围由**互联网号码分配机构(IANA,Internet Assigned Numbers Authority)**负责管理和分配,以避免端口冲突。
- 为什么是16位? 因为TCP/IP协议栈的标准设计中,端口字段占用16位空间,这决定了最大端口数为65536个(包括0)。
- 端口0的特殊性: 端口0通常保留,不推荐使用。它有时用于表示“任意端口”或动态分配。
- IANA的作用: IANA维护官方端口列表,确保标准服务(如HTTP)使用固定端口,便于全球互操作。
端口号分类
根据IANA的规范,端口号一般分为三类,以便于管理和标准化使用:
系统端口(Well-Known Ports)
- 范围: 0 - 1023
- 说明: 这些端口由IANA严格分配给系统级服务,通常需要root/管理员权限绑定。它们是最常用的标准服务端口,确保全球网络的兼容性。
- 常见示例:
- HTTP(超文本传输协议):80 – 用于网页传输。
- HTTPS(安全HTTP):443 – 用于加密网页传输。
- DNS(域名系统):53 – 用于域名解析。
- BGP(边界网关协议):179 – 用于路由器间路由交换。
- RIP(路由信息协议):520 – 用于小型网络路由更新。
注册端口(Registered Ports)
- 范围: 1024 - 49151
- 说明: 这些端口可以由应用程序开发者向IANA注册,但不强制要求root权限。它们常用于自定义服务或特定软件的默认端口,便于用户配置和记忆。
- 常见示例:
- MySQL(关系型数据库):3306 – 默认数据库服务器端口。
- PostgreSQL(开源数据库):5432 – 另一个流行数据库的默认端口。
- L2TP(第二层隧道协议):1701 – 用于VPN隧道。
- 自定义端口:如8080(备选HTTP)、9090(Web管理)、9999/8888(开发测试) – 这些是开发者常用的高端口,避免与系统端口冲突。
专用端口(Dynamic/Private Ports)
- 范围: 49152 - 65535
- 说明: 也称为非保留端口(Ephemeral Ports)或动态端口。这些端口未被IANA正式注册,常用于临时目的,如客户端临时连接服务器时操作系统自动分配的源端口。适合私人应用或客户端临时使用,避免与已注册服务冲突。
- 使用场景: 浏览器发起HTTP请求时,会动态分配一个高端口作为源端口。
查看本机监听的端口
在Linux/Unix系统中,可以使用netstat命令查看当前监听的端口和服务状态。常用命令:
netstat -tuln- 参数解释:
-t:显示TCP连接。-u:显示UDP连接。-l:仅显示监听(LISTEN)状态的端口。-n:以数字形式显示地址和端口(不解析主机名)。
示例输出:
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 10.255.255.254:53 0.0.0.0:* LISTEN
udp 0 0 127.0.0.53:53 0.0.0.0:*
udp6 0 0 ::1:323 :::*- 字段解释:
- Proto:协议类型(tcp/udp/udp6)。
- Recv-Q (Receive Queue):接收队列中的数据量(字节)。这是内核缓冲区中本地程序尚未读取的数据。如果长期不为0,表明本地进程处理不及时,导致数据堆积,可能引发性能瓶颈。
- Send-Q (Send Queue):发送队列中的数据量(字节)。这是尚未发送到对端的数据。如果数值持续不为0,可能表示对端未及时接收、网络拥塞或连接中断,导致数据卡在本地缓冲区。
- Local Address:本地监听地址和端口(e.g., 10.255.255.254:53 表示在IP 10.255.255.254的53端口监听)。
- Foreign Address:远程地址(* 表示任意)。
- State:连接状态(LISTEN 表示监听中)。
提示: 最近,netstat可能被ss命令取代(ss -tuln),netstat已经停止维护了, 并且ss的读取速度更快,显示界面更全面。
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:*
udp UNCONN 0 0 10.255.255.254:53 0.0.0.0:*iptables 对端口的选择性封禁
同一个端口可以同时接受TCP协议和UDP协议,在实际工作中,有时候会遇到使用iptables对端口进行选择性封禁和放通的情况,所以这里以DNS协议扩展说一下。
iptables 是Linux内核的防火墙工具,用于控制数据包过滤。TCP和UDP协议都可以使用端口53进行DNS(域名系统)查询,但默认行为有差异:
- DNS默认协议: UDP/53 – 因为UDP无连接、开销小、查询简单,适合快速域名解析。
- TCP/53的使用场景: 当UDP查询失败(e.g., 数据包过大、丢包)或需要大响应(如区域传送AXFR)时,DNS客户端会自动回退(fallback)到TCP/53。
如果仅封禁UDP/53,可能会留下绕过漏洞:
| 协议 | 端口 | 是否被封禁 | 结果 |
|---|---|---|---|
| UDP | 53 | ✅ 被封 | 普通DNS查询不通(大多数客户端默认UDP)。 |
| TCP | 53 | ❌ 未封 | 仍可进行DNS查询(如手动指定TCP或自动fallback)。 |
绕过风险: 用户可以通过工具(如dig +tcp example.com)或配置DNS客户端强制使用TCP/53,绕过UDP封禁,继续解析域名获取IP地址。
实际防护建议
要彻底封禁DNS外联流量或控制DNS解析,应同时针对UDP和TCP端口53添加规则(假设在OUTPUT链上,针对出站流量):
# 封禁UDP/53(默认DNS)
iptables -A OUTPUT -p udp --dport 53 -j REJECT
# 封禁TCP/53(回退或手动DNS)
iptables -A OUTPUT -p tcp --dport 53 -j REJECT- -A OUTPUT:追加规则到输出链(控制本地发出的包)。
- -p udp/tcp:指定协议。
- --dport 53:目标端口53。
- -j REJECT:拒绝并发送ICMP不可达响应(比DROP更友好,避免超时)。
注意:
- 这仅影响出站DNS;入站需在INPUT链配置。
- 保存规则:使用
iptables-save或工具如ufw/firewalld。 - 测试:用
nslookup或dig验证封禁效果。 - 高级:若需允许内部DNS,可添加白名单(如
--dport 53 -s 内部IP -j ACCEPT)。
