套接字与端口诊断
目标
区分监听套接字的绑定范围,并通过 ss 与 /proc/net/tcp 两条路径验证同一事实。
为什么重要
‘服务器内部 curl 正常,但外部无法访问’这类报告,大多数不是防火墙问题,而是绑定问题。绑定到 127.0.0.1:8080 的套接字只接受来自同一主机的连接,外部数据包根本不会被内核转交。这种区分也是一种安全设计——故意把管理端口只绑定到回环地址是标准做法。还要注意,监听套接字的 Send-Q 表示 backlog 最大值,Recv-Q 表示当前 accept 等待队列长度。它们在已建立连接中的含义不同,因此经常被误读。
步骤
在 /root/net 目录中工作。
- 在后台启动
python3 -m http.server 8080 --bind 127.0.0.1,并把 PID 写入/root/net/http_pid.txt。 - 在后台启动
python3 -m http.server 8081 --bind 0.0.0.0,并把 PID 写入/root/net/all_pid.txt。8080 必须继续保持仅回环可用。 - 将两个端口的绑定范围按以下两行写入
/root/net/binding.txt。值为loopback或all。8080=<값>8081=<값>
- 启动一个进程,打开到 8081 的连接并保持不关闭,把 PID 写入
/root/net/client_pid.txt。 - 将十进制 8080 转换为 4 位十六进制大写字母,写入
/root/net/hexport.txt。 - 只把 8080 监听套接字的 backlog 最大值写入
/root/net/backlog.txt。 - 使用
ss确认占用 8080 的进程 PID,并写入/root/net/owner.txt。 - 创建
/root/net/portcheck.sh <포트>。如果该端口正在监听,输出port=<포트> state=listen pid=<PID>并返回退出码 0;如果无人监听,输出port=<포트> state=free并返回退出码 1。没有参数时必须返回非 0。
提示
ss -ltnH不显示表头,只显示监听中的 TCP 套接字。列顺序为Recv-Q Send-Q Local Peer。/proc/net/tcp的local_address中,IP:PORT都采用十六进制,状态0A表示 LISTEN。- 使用
python3 -c "import socket,time; s=socket.create_connection(('127.0.0.1',8081)); time.sleep(9999)" &可以保持连接。 - 常见错误 1:第 4 步打开连接后立即关闭,ESTABLISHED 状态就会消失。
- 常见错误 2:第 7 步不加
-p而只用ss -ltn,不会显示进程信息。
启动仅绑定回环地址的服务器
在后台启动 python3 -m http.server 8080 --bind 127.0.0.1,并把 PID 写入 /root/net/http_pid.txt。
python3 -m http.server 提供 --bind 选项。请在后台启动并记录 PID。
绑定所有地址并启动
在后台启动 python3 -m http.server 8081 --bind 0.0.0.0,并把 PID 写入 /root/net/all_pid.txt。8080 必须继续保持仅回环可用。
绑定到 0.0.0.0 后,会接受来自任何接口的连接。8080 必须继续绑定回环地址。
记录绑定范围
将两个端口的绑定范围按以下两行写入 /root/net/binding.txt。值为 loopback 或 all。
8080=<값>8081=<값>
查看 ss -ltn 的 Local Address 列,记录两个端口有何不同。
保持连接不关闭
启动一个进程,打开到 8081 的连接并保持不关闭,把 PID 写入 /root/net/client_pid.txt。
必须打开连接后保持不关闭。可以用 python3 执行 create_connection 后 sleep。
直接读取 /proc/net/tcp
将十进制 8080 转换为 4 位十六进制大写字母,写入 /root/net/hexport.txt。
端口以十六进制记录。请把 8080 转换为 4 位大写十六进制。
读取 backlog 最大值
只把 8080 监听套接字的 backlog 最大值写入 /root/net/backlog.txt。
对于监听套接字,Send-Q 表示 backlog 最大值,也就是 ss -ltn 的第二列。
找出端口所有者
使用 ss 确认占用 8080 的进程 PID,并写入 /root/net/owner.txt。
ss 有一个显示进程信息的选项。请从输出中提取 pid= 部分。
端口占用检查脚本
创建 /root/net/portcheck.sh <포트>。如果该端口正在监听,输出 port=<포트> state=listen pid=<PID> 并返回退出码 0;如果无人监听,输出 port=<포트> state=free 并返回退出码 1。没有参数时必须返回非 0。
正在监听时连同 pid 一起报告并返回 0;空闲时输出 free 并返回 1。