传输层端口与五元组

IP 地址负责把数据包送到目标服务器,但一台服务器上往往同时跑着好几个网络程序:Web 网站、SSH 远程登录、数据库、邮件服务等。操作系统收到数据包后,靠传输层的端口号(Port Number)来区分这个包该交给本机的哪个进程。

通信端点与五元组

用浏览器访问网站时,连接是在两个通信端点(Socket)之间建立的:

客户端端点                         服务器端点
192.168.12.170:51842   →   192.168.20.10:80

服务器端的 80 是固定监听的端口(HTTP 服务);客户端的 51842 则是操作系统临时挑的短暂端口(Ephemeral Port)。服务器把网页内容回传给客户端时,源和目的刚好对调(192.168.20.10:80 → 192.168.12.170:51842),客户端内核看到目的端口是 51842,就知道该把数据交还给对应的浏览器进程。

两条 TCP 连接使用不同的客户端端口,连接到同一服务器的网站服务

服务器之所以能同时服务成千上万个客户端,是因为每条网络连接都由 “源 IP、源端口、目的 IP、目的端口、传输层协议” 这个五元组(5-tuple)唯一标识。就算所有人都在访问服务器的 80 端口,只要客户端 IP 或客户端临时端口不同,内核协议栈就能分清每条连接。

常见默认端口

端口号是一个 16 位无符号整数,范围是 0 到 65535(1~1023 通常叫知名端口)。日常最常碰到的默认端口有:

协议默认端口用途与安全特点
FTPTCP 20(数据)/ 21(控制)传统明文文件传输,命令和账号密码都是明文
SSHTCP 22加密的远程终端登录与文件传输(SCP/SFTP)
TelnetTCP 23早期明文远程终端登录,已被 SSH 取代
SMTPTCP 25客户端发信及邮件服务器之间中继投递邮件
WHOISTCP 43查询域名注册商、持有人、到期时间及权威 DNS
DNSUDP 53 / TCP 53域名解析(常规查询走 UDP,区域传送或超长响应走 TCP)
DHCPUDP 67(服务端)/ 68(客户端)局域网动态分配 IP、掩码、网关和 DNS
HTTPTCP 80明文网页传输
POP3TCP 110从邮件服务器把邮件下载到本地
IMAPTCP 143与邮件服务器双向同步邮件状态,支持多端同时管收件箱
HTTPSTCP 443(HTTP/3 用 UDP 443)经 TLS 加密的网页与 API 传输
SMBTCP 445Windows 局域网文件共享与打印共享
MySQLTCP 3306MySQL 数据库默认监听端口
RDPTCP 3389Windows 远程桌面

注意

默认端口只是约定,管理员完全可以把 Web 服务改到 8080、把 SSH 改到 2222。排查或做安全测试时,不能光看端口号猜服务,得看连上去之后的协议响应。

明文应用层协议长什么样?

互联网早期设计的很多应用层协议(WHOIS、HTTP、FTP、SMTP、POP3、IMAP)直接用可读的 ASCII 纯文本对话。连上对应的 TCP 端口后,客户端和服务器就是一问一答地发文本行。

比如查域名注册信息的 WHOIS(TCP 43),连上去直接发一行域名加回车,服务器就会回一段纯文本档案:

客户端 → 服务器:example.com\r\n
服务器 → 客户端:Domain Name: EXAMPLE.COM
                Registry Domain ID: 2336799_DOMAIN_COM-VRSN
                Registrar: Reserved-Internet Assigned Numbers Authority
                Creation Date: 1995-08-14T04:00:00Z

浏览网页用的 HTTP(TCP 80) 也是纯文本问答。客户端发请求方法(如 GET)、路径和请求头,服务器回三位状态码(如 200 OK)、响应头和 HTML 正文:

客户端 → 服务器:GET /index.html HTTP/1.1
                Host: www.example.com
                User-Agent: Mozilla/5.0

服务器 → 客户端:HTTP/1.1 200 OK
                Content-Type: text/html; charset=utf-8
                Content-Length: 45

                <html><body><h1>Hello World</h1></body></html>

因为 HTTP 全程明文,沿途的中间设备能直接看到访问的页面和提交的表单。HTTPS(TCP 443) 则在 TCP 握手之后加了一层 TLS 加密握手,双方协商出对称密钥后,再把上面这段 HTTP 报文放进加密隧道里传输。

同理,FTP(TCP 21 控制通道) 和 Telnet(TCP 23) 也是直接用明文指令发账号密码(比如 FTP 的 USER alice / PASS Secret123!),在局域网里一抓包就能看见口令,所以现在远程运维和传文件基本都换成了加密的 SSH(TCP 22)。

收发电子邮件则由两类协议配合:SMTP(TCP 25) 负责发信和中继投递(通过 HELO、MAIL FROM、RCPT TO、DATA 等文本指令把信推给邮件服务器),POP3(TCP 110) 和 IMAP(TCP 143) 负责让收件人把信从服务器上拉下来。现在的邮件服务同样会套上 TLS 加密(发信 465/587、POP3S 995、IMAPS 993)。

查看本机监听端口

在 Linux 终端里可以用 ss -ltn 查看当前正在监听的 TCP 端口(-l 只看监听状态,-t 只看 TCP,-n 直接显示数字地址和端口):

crow@server:~$ ss -ltn
State   Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN  0      128    0.0.0.0:80        0.0.0.0:*
LISTEN  0      128    127.0.0.1:3306    0.0.0.0:*
  • 0.0.0.0:80:绑定了本机所有 IPv4 网卡接口,只要路由可达、防火墙放行,外部机器就能连上来。
  • 127.0.0.1:3306:只绑定了本地回环地址,只有本机内部的进程能连这个 MySQL,外部网卡发来的连接请求会被内核直接拒绝。

当有客户端连上 80 端口后,用 ss -tn 就能看到一条状态为 ESTAB(ESTABLISHED)的活动连接:

ESTAB  0  0  192.168.12.170:51842  192.168.20.10:80

本章阅读

阅读标记