📚 第六章 TCP与UDP
📄 一句话概括

端口号是「应用的号码」:80 上跑的是网页,22 上跑的是远程登录。 但它只能识别「哪种应用」,识别不了「哪个程序」——同一个端口可能被不同的软件占着。

📝 本节和前面几节的关系

6.2.1 讲了端口怎么分段,这一节讲「分段之后怎么用号码认人」。 6.2.4 会讲「号码怎么定」,这一节先讲「号码告诉了我们什么」。

一、端口就是应用的号码

客户端要访问某个服务,必须知道「目的端口」:因为它不知道对面那个程序在哪个端口上等着。 所以「知名端口」存在的意义就是「事先约定」——你不用查,直接连 443 就是网页服务。 最有用的几个必须背下来:

端口 应用 备注
22 SSH 远程登录
25 SMTP 发邮件
53 DNS TCP 和 UDP 都用
80 HTTP 明文网页
443 HTTPS 加密网页
3306 MySQL 数据库

第三行的「两个都用」值得记一下:它说明「端口号」不是唯一的标识,「协议加端口」才是。 这一点 6.2.5 会专门讲。

二、端口能认出什么,认不出什么

它能认出「这是哪种服务」:看到 443 就知道是加密网页,看到 22 就知道是远程登录。 这是排查时最有用的一条线索:「本机为什么在监听 3389」比「本机有个进程在跑」有用得多。 它认不出「这是哪个程序」:同样是 443,可能是 nginx、可能是某个代理、也可能是个测试脚本。 端口是「约定」,不是「强制」—— 你完全可以让自己的程序监听 443,系统不会拦你(1024 以下要管理员)。 所以完整的判断顺序是三段:先看端口猜服务,再看进程名确认,最后看进程路径。 只做第一步会误判,因为「有人故意把后门放在 443 上」这种事是真实存在的。

三、怎么查本机在监听什么

命令行最常用的是两个:Windows 用 netstat -ano,Linux 用 ss -lntup。 两者都能给出「协议、地址、端口、进程号」四样。 但「端口对应哪个进程」这个信息,各系统的给法不一样: Linux 直接把进程名带上,Windows 只给 PID,要再查一次。 所以脚本里常用「先拿 PID 再查进程名」这两步——D177 就是这样做的。 这里有个容易踩的坑:同一个端口在 IPv4 和 IPv6 上是两条记录, 所以「数出来 36 个端口」和「看到 47 条 LISTEN」并不矛盾, 因为有的端口在两个协议族上各监听一次。

四、动手 Demo:本机在哪些端口上等人来连

列出本机 LISTEN 的前 12 个端口,并统计它们绑在哪个地址上。 「未登记」会很多,这是正常的。

import psutil

seen = {}
for c in psutil.net_connections(kind='inet'):
    if c.status == 'LISTEN':
        seen[c.laddr.port] = seen.get(c.laddr.port, 0) + 1
for p in sorted(seen)[:12]:
    print(p, seen[p])

实跑输出:

--------------------------------------------------------------------
本机在哪些端口上等人来连
--------------------------------------------------------------------
**LISTEN 状态的端口就是「开着的门」**,**每一个背后都是一个在跑的服务。**

  端口     常见用途     监听条数
  -------------------------------
  135      RPC          2
  139      NetBIOS      1
  445      SMB          2
  1971     未登记       1
  1981     未登记       1
  1991     未登记       1
  5040     未登记       1
  5283     未登记       1
  8890     未登记       1
  8901     未登记       1
  8990     未登记       1
  9901     未登记       3

**本机一共 36 个端口在 LISTEN**:
  监听地址              条数
  ---------------------------
  只给本机              25
  全网卡(0.0.0.0)     21
  绑具体网卡            1

**第二行才是「外面连得进来」的那些**:**绑 0.0.0.0 表示「本机所有网卡都收」**,
**而「只给本机」的那些,外面再怎么连也连不上。**
**这一点在排查「服务起了但连不上」时最有用**:**先看它绑的是 127.0.0.1 还是 0.0.0.0。**

**「未登记」那一列会很多,这很正常**:**注册端口是「登记过」的,不是「必须用」的**,
**大量程序自己挑一个高位端口就开张了。**

表里出现「未登记」很正常:注册端口是「登记过」的,不是「必须用登记的号码」。 大量程序自己挑一个高位端口就开张了,所以「端口号认应用」这件事只对知名端口有效。 第二张表更能说明安全问题:「只给本机」的那些,外面再怎么连也连不上; 只有绑 0.0.0.0 的才对外。 所以「我的服务起了但别人连不上」的第一检查项,就是「它绑的是 127.0.0.1 还是 0.0.0.0」。 「绑具体网卡」那一行最少,但最值得注意:它意味着「只在这个网段提供服务」, 这通常是刻意配置的,不是随手写的。

30 秒实验

  1. 想一下:为什么 443 上跑的也可能不是网页服务?
  2. 算一下:本机 LISTEN 的条数和端口数为什么不一样?
  3. 想一下:「绑 127.0.0.1」和「绑 0.0.0.0」在安全上差在哪?

常见误区

  1. 以为「端口能认出具体程序」。 只能认出「哪种服务」,同一个端口可能被不同软件占着。
  2. 以为「未登记的端口就是可疑的」。 大量正常程序用高位端口,登记只是「报备」, 不是「强制」。
  3. 以为「服务起了就一定连得上」。 绑 127.0.0.1 时外面连不上,这是最常见的原因。
自测三问(点开对答案) 1. 443 和 80 分别是什么服务? —— **443 是 HTTPS(加密网页),80 是 HTTP(明文网页)。** 2. 端口能识别出「哪个程序」吗? —— **不能**,只能识别「哪种服务」;要知道具体程序,得看进程名和路径。 3. 为什么 LISTEN 的条数比端口数多? —— **同一个端口可能在 IPv4 和 IPv6 上各监听一次**,算两条记录。

下一节把「五个要素」凑齐,看一条连接到底靠什么认出来。

相关笔记