端口是什么意思?端口号的作用、分类与查看方法
端口是传输层协议(TCP、UDP)用来区分同一台主机上不同程序的编号,取值 0–65535。IP 地址负责把数据送到哪台主机,端口号负责交给主机上的哪个程序:访问网站连的是服务器的 443 端口,SSH 登录连的是 22 端口。端口的英文是 port,端口号是 port number。
端口是什么意思?在网络通信里,端口(英文 port)是 TCP 和 UDP 用来区分同一台主机上不同程序的编号,是 0 到 65535 之间的一个整数。一台服务器只有一个或几个 IP 地址,却同时跑着网站、SSH、数据库等多个服务,数据包到达之后要靠端口号决定交给谁:发往 203.0.113.10 的 443 端口,交给网站程序 nginx;发往 22 端口,交给 SSH 服务 sshd。所以常说“IP 找主机,端口找程序”。端口不是一个看得见的接口,而是写在每个 TCP、UDP 报文头里的一个数字。
端口是干什么的:IP 找主机,端口找程序
打个比方:IP 地址像公司的总机号码,端口号像分机号。总机能把电话接进公司,但要找到具体某个人,还得拨分机号。数据包也一样,先按 IP 地址送到服务器,再按端口号交给服务器上的某个程序。
以一台典型的网站服务器为例,上面的程序和端口是这样分工的:
| 程序 | 协议与端口 | 监听在哪个地址 | 谁能连上 |
|---|---|---|---|
| nginx | TCP 80、443 | 0.0.0.0(本机所有 IPv4 地址) | 任何人,前提是防火墙放行 |
| sshd | TCP 22 | 0.0.0.0 | 任何人,应当用防火墙限制来源 |
| mysqld | TCP 3306 | 127.0.0.1 | 只有本机的程序 |
| chronyd | UDP 323 | 127.0.0.1 | 只有本机的 chronyc 管理命令 |
一个发往 203.0.113.10:443 的数据包到达后,系统按下面的顺序处理:
- 网卡收下数据,IP 层确认目的地址是本机;
- 看 IP 报文头里的协议号,6 是 TCP,17 是 UDP,交给对应的协议处理;
- TCP 层读出目的端口 443,找到正在监听 443 的程序 nginx,把数据交给它;
- 如果没有程序监听这个端口,TCP 会回一个 RST,客户端看到的就是“连接被拒绝”;UDP 则通常回一个 ICMP 端口不可达。
平时访问网站感觉不到端口,是因为浏览器替你补上了默认值:http:// 默认 80,https:// 默认 443。服务跑在非默认端口上时,就要在地址里写出来,例如 http://203.0.113.10:8080/admin,冒号后面的 8080 就是端口号。
套接字与五元组:一个端口如何同时服务成千上万个连接
把 IP 地址和端口号放在一起,比如 203.0.113.10:443,就确定了网络上的一个通信端点,叫套接字地址;程序通过操作系统提供的套接字(socket)接口绑定这个地址、收发数据。服务器上的 nginx 先创建一个监听套接字守在 443 端口,每来一个客户端,再为这次连接单独建立一个连接套接字。
一条 TCP 连接由五个要素共同确定,叫五元组:协议、源 IP、源端口、目的 IP、目的端口。只要其中一项不同,就是另一条连接。同一时刻,四个客户端连接访问同一个 443 端口,互不冲突:
| 协议 | 客户端(源 IP:源端口) | 服务器(目的 IP:目的端口) |
|---|---|---|
| TCP | 198.51.100.7:51544 | 203.0.113.10:443 |
| TCP | 198.51.100.7:51546 | 203.0.113.10:443 |
| TCP | 192.0.2.30:40112 | 203.0.113.10:443 |
| TCP | 192.0.2.30:40113 | 203.0.113.10:443 |
前两行是同一台电脑开的两个浏览器连接,靠不同的源端口区分。客户端的源端口通常不是程序自己挑的,而是操作系统从临时端口范围里分配,连接关闭后再回收。所以服务器一侧的端口是固定的、事先约定的,客户端一侧的端口是临时的、每次都不一样。
在服务器上可以直接看到这种情况:
# 统计当前有多少条已建立的连接正在访问本机的 443 端口
ss -Htn state established '( sport = :443 )' | wc -l
# 列出其中几条,看看对端的 IP 和端口
ss -tn state established '( sport = :443 )' | head -5
理解了五元组,防火墙规则就好懂了:入方向放行“目的端口 443”,管的是客户端发来的包;服务器回给客户端的包,目的端口是客户端的临时端口,靠防火墙的连接跟踪自动放行,不需要也不应该去放行一大段高位端口。
端口号的分类:知名、注册、动态三段
端口号字段长 16 位,所以范围是 0–65535,TCP 和 UDP 各有一套,互不相干。IANA 把它分成三段:
| 范围 | 名称 | 由谁使用 | 例子 |
|---|---|---|---|
| 0–1023 | 知名端口(系统端口) | 基础网络服务,Linux 上普通用户的程序默认不能监听 | SSH 22、DNS 53、HTTP 80、HTTPS 443 |
| 1024–49151 | 注册端口 | 各类应用向 IANA 登记的默认端口 | MySQL 3306、RDP 3389、Redis 6379 |
| 49152–65535 | 动态端口(私有端口) | 不分配给固定服务,可用作客户端的临时端口 | Windows 默认从这一段取临时端口;Linux 默认用 32768–60999 |
这只是约定,不是强制:任何程序都可以监听任何空闲端口,低于 1024 的端口只是需要额外权限。所以看到 3306 开着,并不能断定那就是 MySQL,要以实际监听的进程为准;把 SSH 改到 2222,它也照样是 SSH。
对运维来说,比分类更实用的是知道哪些端口该对公网开放、哪些不该:
| 端口 | 服务 | 是否对公网开放 |
|---|---|---|
| TCP 80、443 | 网站 | 开放 |
| TCP 22 | SSH | 只对运维 IP 或跳板机开放 |
| TCP 3389 | Windows 远程桌面 | 只对运维 IP 或跳板机开放 |
| TCP 3306、5432、6379、27017 | MySQL、PostgreSQL、Redis、MongoDB | 不开放,只给本机或内网 |
| UDP 53、TCP 53 | DNS | 只有对外提供解析的 DNS 服务器开放 |
| UDP 161 | SNMP | 只对监控服务器开放 |
| UDP 623、TCP 443(BMC) | IPMI 和 BMC 管理界面 | 不开放,只放在管理网 |
端口号怎么查看:ss -tulnp 与 netstat -ano
Linux 上用 ss 一次列出所有监听中的 TCP、UDP 端口,用 root 执行才能看到每个端口属于哪个进程:
ss -tulnp
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=712,fd=5))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=905,fd=3))
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1320,fd=6))
tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1320,fd=7))
tcp LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=1088,fd=21))
tcp LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=905,fd=4))
五个字母分别是:t 看 TCP,u 看 UDP,l 只看监听状态,n 显示数字端口而不是服务名,p 显示进程。读的时候重点看两列:
- Local Address:Port:冒号后面是端口号,前面是监听地址。
0.0.0.0和[::]表示本机所有地址,127.0.0.1表示只接受本机连接,外面无论如何都连不上。 - Process:占用端口的程序名和进程号。UDP 没有连接状态,显示为 UNCONN,表示已绑定端口、在等数据。
只想知道某个端口被谁占了,加过滤条件即可:ss -lntp 'sport = :80'。老系统没有 ss 时,用 net-tools 里的 netstat -tulnp,参数含义相同。
Windows 上用 netstat,-a 显示全部,-n 显示数字,-o 显示进程号:
netstat -ano | findstr :3389
TCP 0.0.0.0:3389 0.0.0.0:0 LISTENING 1132
TCP 203.0.113.20:3389 198.51.100.7:52011 ESTABLISHED 1132
第一行说明 3389 端口在所有地址上监听,第二行是一个已经连进来的远程桌面会话,最后一列 1132 是进程号。再执行 tasklist /FI "PID eq 1132" 查出程序名;用管理员身份运行 netstat -anb 可以直接显示程序名。PowerShell 里也可以写成 Get-NetTCPConnection -LocalPort 3389。
本机能看到监听,不代表外面连得上。从另一台机器测试时,Linux 用 nc -zv -w 3 203.0.113.10 443,Windows 用 Test-NetConnection 203.0.113.10 -Port 443。
开放端口、防火墙放行、改 SSH 端口:端口在日常操作里的意义
日常说的“开放端口”,其实是同时满足三个条件:有程序在一个外部能到达的地址上监听这个端口;本机防火墙放行了这个协议和端口;上游的安全组或机房 ACL 也放行了它。少一个都连不上。下面几种常见操作,换成端口的视角来理解:
| 操作 | 在端口层面做了什么 | 命令示例 |
|---|---|---|
| 对外开放 8080 | 程序监听 0.0.0.0:8080,防火墙允许目的端口为 TCP 8080 的入方向包 | firewall-cmd --permanent --add-port=8080/tcp && firewall-cmd --reload,或 ufw allow 8080/tcp |
| Windows 放行端口 | 同上,规则写在 Windows 防火墙里 | New-NetFirewallRule -DisplayName "Web 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow |
| 关闭一个端口 | 让程序不再监听:停掉服务,或改成只监听 127.0.0.1 | systemctl disable --now 服务名 |
| 改 SSH 端口 | 让 sshd 改为监听另一个号码,客户端连接时指定新号码 | 配置文件里的 Port 改为 2222,客户端用 ssh -p 2222 [email protected] |
| 端口映射 | 路由器或防火墙把公网 IP 某端口收到的包,转给内网某台机器的某个端口 | 公网 IP:8443 转到 192.168.1.10:443 |
几点经验:
- 防火墙规则必须写协议。端口号在 TCP 和 UDP 里各算各的,只放行 TCP 53 的 DNS 服务器,绝大多数走 UDP 的查询照样进不来。
- 改 SSH 端口要按顺序来。先在防火墙上放行新端口,再改 sshd 配置并重载,保持当前会话不断开,另开一个窗口用新端口登录成功后,才删除 22 的放行规则;启用了 SELinux 的系统还要把新端口登记为 SSH 端口。顺序反了,很容易把自己锁在门外。
- “Address already in use”就是端口被占了。例如 nginx 启动时报
bind() to 0.0.0.0:80 failed (98: Address already in use),说明已经有程序在监听 80,先用ss -lntp 'sport = :80'查出是谁,再决定停掉它还是换端口。 - 端口映射后,外部看到的端口和程序实际监听的端口可以不同。排查时要分清楚,外面访问的是 8443,服务器上的 nginx 监听的却是 443。
在管理系统里怎么落地
改端口、改防火墙是租用服务器的客户最常自己动手、也最容易把自己锁在外面的操作:SSH 端口改了却没放行,或者防火墙规则一保存,远程连接立刻断开。这时不必提工单等机房处理,在客户自助端里打开 VNC 控制台,画面走 BMC 带外通道,不依赖服务器上的任何端口,登录进去把配置改回来即可;系统彻底进不去时,还可以进入救援模式修复,不动硬盘数据。
服务商这一侧,哪些地址上的端口可以对外开放,取决于地址属于哪个网络。Toplink DCIM 的 IP 地址管理把地址段按公网 IP、IPMI、客户内网、内网 IP 等类型分别登记,一个地址属于公网段、客户内网还是 IPMI 管理段,一查便知,决定哪些端口可以对外放行时就有了依据。
常见问题
端口和网口是一回事吗?
不是。网口是看得见的物理接口,比如服务器背后的 RJ45 电口、交换机面板上的光口;端口号是软件层面的编号,写在 TCP、UDP 报文头里。交换机的“端口”通常指物理口,和这里说的端口号是两个概念。
一个程序可以同时占用多个端口吗?
可以。nginx 常同时监听 80 和 443,一些数据库还会另开管理端口。反过来,在同一个 IP 上,同一协议的同一个端口同一时间只能被一个程序监听,除非程序专门开启了端口复用。
怎么知道自己的服务器有哪些端口暴露在公网上?
ss 只能看到本机在监听什么,看不出防火墙和上游 ACL 的效果。可以从外部另一台机器对自己的公网 IP 做一次端口扫描,例如 nmap -Pn 203.0.113.10(默认扫常用的 1000 个 TCP 端口,加 -p- 扫全部),显示 open 的才是外面真正连得上的。只扫描自己有权管理的地址。