FAQ-3:网络与连接常见问题
预计阅读时间:12 分钟
📖 目录
FAQ-3:网络与连接常见问题(Q29-Q43)
问题速查表
| 问题 | 章节 |
|---|---|
| Q29: 如何查看哪些进程在监听端口? | Q29 |
| Q30: 端口被占用怎么办? | Q30 |
| Q31: 如何测试远程端口是否开放? | Q31 |
| Q32: 如何查看网卡速率? | Q32 |
| Q33: curl SSL 证书错误? | Q33 |
| Q34: 如何配置静态 IP(Netplan)? | Q34 |
| Q35: 如何查看当前连接数? | Q35 |
| Q36: SSH 连接自动断开? | Q36 |
| Q37: 如何实现 SSH 免密登录? | Q37 |
| Q38: 如何查看 DNS 解析过程? | Q38 |
| Q39: 如何限制某 IP 访问? | Q39 |
| Q40: 为什么 ping 不通但端口是通的? | Q40 |
| Q41: 如何设置 HTTP 代理? | Q41 |
| Q42: 如何抓取 HTTP 请求响应? | Q42 |
| Q43: scp 传输中断了怎么办? | Q43 |
Q29: 如何查看哪些进程在监听端口?
当服务启动失败或端口冲突时,第一步是确认哪些进程占用了端口。
# ss -tlnp:查看 TCP 监听端口
# -t:TCP -l:listening(监听中) -n:数字显示(不解析域名) -p:显示进程
ss -tlnp
# ss -tulnp:同时查看 TCP 和 UDP
ss -tulnp
# lsof -i :80:查看占用 80 端口的进程
lsof -i :80
# 预期输出示例:
# State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
# LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
Q30: 端口被占用怎么办?
启动服务时提示 Address already in use,说明端口已被其他进程占用。
# 第一步:找到占用端口的进程
ss -tlnp | grep :8080
# 输出:LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=5678,...))
# 第二步:终止占用进程(或修改自己的应用端口)
sudo kill 5678 # 发送 SIGTERM(优雅终止)
sudo kill -9 5678 # 强制终止(仅在 SIGTERM 无效时使用)
# 或者修改应用配置,使用其他端口
Q31: 如何测试远程端口是否开放?
# nc(netcat):网络瑞士军刀
# -z:只扫描不发送数据
# -v:详细输出
nc -zv 192.168.1.100 80
# Bash 内置方式(无需安装额外工具)
# /dev/tcp 是 Bash 的特殊设备,成功连接会返回 0
timeout 3 bash -c "
Q32: 如何查看网卡速率?
# ethtool:查看网卡物理参数(速率、双工模式等)
ethtool eth0 | grep Speed
# 输出:Speed: 1000Mb/s
# ip -s link:查看网卡统计信息(收发包数、错误数)
ip -s link show eth0
Q33: curl SSL 证书错误?
SSL 证书错误常见原因:自签名证书、证书过期、系统时间不正确、证书链不完整。
# 跳过证书验证(仅用于测试,生产环境不要用)
curl -k https://example.com
# 查看证书详细信息
curl -vI https://example.com 2>&1 | grep -E "expire|subject|issuer"
# 检查系统时间(证书验证依赖时间)
date
Q34: 如何配置静态 IP(Netplan)?
Netplan 是 Ubuntu 18.04+ 的网络配置工具,通过 YAML 文件定义网络参数。
# 编辑配置文件(注意 YAML 缩进,用空格不用 Tab)
sudo vim /etc/netplan/01-netcfg.yaml
# 示例配置:
network:
version: 2
ethernets:
eth0:
addresses:
- 192.168.1.100/24 # 静态 IP 地址
routes:
- to: default
via: 192.168.1.1 # 默认网关
nameservers:
addresses:
- 8.8.8.8 # DNS 服务器
- 114.114.114.114
# 应用配置(会短暂断开网络连接)
sudo netplan apply
# 调试语法错误
sudo netplan --debug generate
Q35: 如何查看当前连接数?
# ss -s:连接状态汇总
ss -s
# 统计已建立的 TCP 连接数
ss -tan state established | wc -l
# 按状态统计
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn
# 输出示例:
# 150 ESTAB
# 20 TIME-WAIT
# 5 LISTEN
Q36: SSH 连接自动断开?
长时间空闲的 SSH 连接会被防火墙或 NAT 网关中断。通过 keepalive 机制保持连接。
# 服务端配置(/etc/ssh/sshd_config)
# 每 60 秒向客户端发送 keepalive 探测
ClientAliveInterval 60
ClientAliveCountMax 3 # 3 次无响应才断开
# 客户端配置(~/.ssh/config)
# 每 60 秒向服务端发送 keepalive
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# 修改后重启 SSH 服务(仅服务端需要)
sudo systemctl restart sshd
Q37: 如何实现 SSH 免密登录?
基于密钥的 SSH 认证比密码更安全且更方便。
# 1. 生成密钥对(ed25519 是当前推荐算法)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 默认保存到 ~/.ssh/id_ed25519(私钥)和 ~/.ssh/id_ed25519.pub(公钥)
# 2. 将公钥复制到目标服务器
ssh-copy-id user@host
# 会自动将公钥追加到目标服务器的 ~/.ssh/authorized_keys
# 3. 测试免密登录
ssh user@host # 不再需要输入密码
Q38: 如何查看 DNS 解析过程?
# dig +trace:显示完整的 DNS 解析链路
# 从根服务器开始,逐级查询到最终结果
dig +trace example.com
# 简单查询
dig example.com
# 指定 DNS 服务器查询
dig @8.8.8.8 example.com
Q39: 如何限制某 IP 访问?
# ufw(Ubuntu 默认防火墙)
sudo ufw deny from 1.2.3.4
# iptables(通用方式)
# -A INPUT:追加到 INPUT 链
# -s 1.2.3.4:源地址
# -j DROP:直接丢弃(不回复)
sudo iptables -A INPUT -s 1.2.3.4 -j DROP
# nftables(iptables 的继任者,推荐)
sudo nft add rule inet filter input ip saddr 1.2.3.4 drop
Q40: 为什么 ping 不通但端口是通的?
ping 使用 ICMP 协议,而端口连接使用 TCP/UDP 协议。防火墙可以单独禁 ICMP 而放行 TCP。ICMP 和 TCP 是网络协议栈中不同层级的协议,防火墙规则可以独立控制每一层。
# ping 使用 ICMP 协议(第 3 层)
# curl/nc 使用 TCP 协议(第 4 层)
# 两者互不影响
# 验证:用 TCP 方式测试
nc -zv 192.168.1.100 80
curl http://192.168.1.100:80
# 如果需要允许 ping(ICMP)
sudo ufw allow icmp
# 或 iptables:
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
Q41: 如何设置 HTTP 代理?
# 临时设置(仅当前终端生效)
export http_proxy=http://proxy.example.com:8080
export https_proxy=http://proxy.example.com:8080
export no_proxy=localhost,127.0.0.1 # 不走代理的地址
# 永久设置(写入 ~/.bashrc)
echo 'export http_proxy=http://proxy.example.com:8080' >> ~/.bashrc
echo 'export https_proxy=http://proxy.example.com:8080' >> ~/.bashrc
Q42: 如何抓取 HTTP 请求响应?
# tcpdump:底层抓包工具
# -i any:监听所有网卡
# -A:以 ASCII 显示包内容
# port 80:只抓 80 端口
sudo tcpdump -i any -A port 80
# curl -v:显示详细的请求/响应头信息
curl -v https://example.com
Q43: scp 传输中断了怎么办?
scp 不支持断点续传,中断后只能重传。rsync 支持断点续传和增量同步。
# rsync 替代 scp(支持断点续传)
# -a:归档模式(保留权限、时间戳)
# -v:详细输出
# -z:传输时压缩
# --partial:保留部分传输的文件(断点续传的关键)
# --progress:显示传输进度
rsync -avz --partial --progress large_file user@host:/path/
真实案例
案例 A:服务绑定 127.0.0.1 导致外部无法访问
现象:Node.js 应用在服务器上 curl localhost:3080 正常,但浏览器访问 http://服务器IP:3080 始终连接超时。
# 服务器本机测试正常
$ curl http://localhost:3080
{"status":"ok"}
# 远程客户端测试失败
$ curl -v http://10.0.0.5:3080
* connect to 10.0.0.5 port 3080 failed: Connection refused
# 查看监听地址
$ ss -tlnp | grep 3080
LISTEN 0 128 127.0.0.1:3080 0.0.0.0:* users:(("node",pid=1823,...))
根因:应用监听地址为 127.0.0.1(回环接口),只有本机能访问。
修复:将监听地址改为 0.0.0.0(所有接口)或具体网卡 IP。
案例 B:防火墙 REJECT 与服务未启动的 Connection refused 区分
现象:两台服务器 A 访问 B 的 3306 端口报 Connection refused,但原因不同——一个是防火墙拒绝,一个是服务没启动。
# 测试一:服务在监听,但防火墙 REJECT
$ nc -zv 10.0.0.11 3306
Connection refused
$ ss -tlnp | grep 3306
LISTEN 0 70 0.0.0.0:3306 ... # 服务活着
# 测试二:服务根本没启动
$ nc -zv 10.0.0.11 3306
Connection refused
$ ss -tlnp | grep 3306 # 无输出
区分方法:Connection refused 只说明"被拒绝",可能是服务未启动,也可能是防火墙 REJECT。必须先在服务端执行 ss -tlnp 确认端口是否在监听,再查防火墙规则。Connection timed out 才表示被 DROP(丢弃)。
案例 C:Netplan YAML 缩进错误导致网络断连
现象:修改 Netplan 配置后执行 sudo netplan apply,SSH 立即断开,无法重新连接。
# 错误配置(用 Tab 缩进而非空格)
network:
ethernets: # ← Tab 缩进,Netplan 不识别
eth0:
addresses: [192.168.1.100/24]
根因:Netplan 使用 YAML 格式,YAML 严格要求用空格缩进(不能用 Tab)。Tab 缩进导致语法解析失败,网络配置应用失败,网卡未获得 IP。
修复:连接控制台(或物理访问),将 Tab 替换为空格,重新 netplan apply。预防:Netplan 修改前用 sudo netplan --debug generate 验证语法。
预防措施
- 部署服务后立即用
ss -tlnp | grep 端口号确认监听地址是否正确 - 配置 SSH keepalive(ServerAliveInterval 60)避免长时间空闲连接被中断
- 大文件传输用
rsync --partial替代 scp,支持断点续传 - Netplan 修改前先用
netplan --debug generate检查语法,避免网络配置错误导致无法 SSH - DNS 解析异常时先用
dig +trace排查,确认是本地 DNS 还是上游服务器问题 - 防火墙规则变更前用
nc -zv做连通性测试,变更后立即验证 - 生产环境 SSH 配置
MaxAuthTries 3防暴力破解,配合 fail2ban 自动封禁 - 大文件传输优先用
rsync --partial --progress,支持断点续传和进度显示 - Netplan 修改前用
sudo netplan try测试配置,超时自动回滚避免网络断连 - DNS 解析异常时先用
dig +trace排查,确认是本地 DNS 还是上游服务器问题
案例 D:服务只监听 IPv6 导致 IPv4 客户端无法连接
现象:新安装的 Nginx 默认只监听 IPv6 地址,IPv4 客户端访问报 Connection refused。
# 查看监听地址
$ ss -tlnp | grep :80
LISTEN 0 511 [::]:80 *:* users:(("nginx",pid=1234,fd=6))
# [::]:80 表示只监听 IPv6
# 修复:在 nginx.conf 中添加 IPv4 监听
server {
listen 80; # 监听所有 IPv4 地址
listen [::]:80; # 监听所有 IPv6 地址
...
}
根因:某些发行版默认配置优先使用 IPv6,而客户端通过 IPv4 连接时无法匹配。Nginx 的 listen 指令决定了绑定的地址族,只配置 [::]:80 会忽略所有 IPv4 请求。
修复:在配置文件中同时添加 listen 80(IPv4)和 listen [::]:80(IPv6),或仅 listen 80 监听所有地址。修改后用 nginx -t 测试配置语法,sudo systemctl reload nginx 重载配置。
案例 E:DNS 缓存导致域名解析不更新
现象:域名 A 记录已修改为新 IP,但服务器仍解析到旧 IP。
# 查看本地 DNS 缓存
$ resolvectl statistics
# 或
$ systemd-resolve --statistics
# 清除 systemd-resolved 缓存
$ sudo resolvectl flush-caches
# 验证解析结果
$ dig +short example.com
1.2.3.4 ← 已更新
# 如果使用 nscd 缓存
$ sudo systemctl restart nscd
# 临时禁用 DNS 缓存(调试用)
$ sudo systemd-resolve --set-dns=8.8.8.8 --set-domain=~.
根因:systemd-resolved 或 nscd 缓存了旧的 DNS 记录,TTL(Time To Live)未过期前不会重新查询。本地 DNS 缓存与上游 DNS 记录不同步。
修复:sudo resolvectl flush-caches 清除缓存。长期方案:降低 DNS 记录的 TTL 值(如 300 秒),便于快速切换。检查 /etc/resolv.conf 确认 DNS 服务器配置正确。
案例 F:iptables 规则顺序导致端口放行失效
现象:执行 iptables -A INPUT -p tcp --dport 80 -j ACCEPT 放行 80 端口,但外部仍然无法访问。
# 查看规则顺序
$ sudo iptables -L INPUT -n --line-numbers
num target prot opt source destination
1 DROP all -- 0.0.0.0/0 0.0.0.0/0 ← 先匹配 DROP
2 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
# iptables 按顺序匹配,第一条 DROP 就丢弃了所有流量
根因:-A(Append)将规则追加到链末尾,但前面已存在 DROP all 规则,所有流量在到达 ACCEPT 之前就被丢弃。iptables 按顺序匹配规则,第一条匹配的规则决定流量命运。
修复:用 -I INPUT 1(Insert)将规则插入到链的第一条位置:sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT。也可以先删除旧规则再添加:sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT。建议用 ufw/nftables 替代原生 iptables,语法更清晰且不易出错。生产环境防火墙规则变更前务必做好备份和测试。
案例 G:SSH 端口修改后旧连接残留导致端口冲突
现象:修改 SSH 端口从 22 改为 2222 后重启 sshd,报 Address already in use。
# 查看端口占用
$ ss -tlnp | grep :22
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1234,fd=4))
# 原因:旧的 sshd 进程仍在监听 22 端口
# 新配置要求同时监听 22 和 2222,但旧进程持有 22 端口
# 解决:先停止旧服务,再启动新配置
$ sudo systemctl stop sshd
$ sudo systemctl start sshd
# 验证
$ ss -tlnp | grep sshd
LISTEN 0 128 0.0.0.0:2222 0.0.0.0:* users:(("sshd",pid=5678,fd=3))
根因:systemctl restart 在某些情况下会先启动新进程再停止旧进程,导致短暂的端口冲突。修改端口时尤其容易出现此问题。
修复:先 stop 再 start,避免 restart 的竞争条件。修改 SSH 端口前确保新端口已放行防火墙,否则会把自己锁在外面。
案例 H:systemd-resolved 导致 DNS 解析异常
现象:Ubuntu 24.04 上 ping google.com 正常但 curl https://api.example.com 报 Could not resolve host。
# 检查 DNS 解析
$ dig api.example.com
# 无输出——解析失败
$ dig @8.8.8.8 api.example.com
;; ANSWER SECTION:
api.example.com. 300 IN A 1.2.3.4 ← 手动指定 DNS 可以解析
# 检查 systemd-resolved 状态
$ resolvectl status
Global
Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
# 问题:systemd-resolved 的 stub 监听异常
$ sudo systemctl restart systemd-resolved
# 验证
$ dig api.example.com
;; ANSWER SECTION:
api.example.com. 300 IN A 1.2.3.4 ← 修复
根因:Ubuntu 默认使用 systemd-resolved 管理 DNS,/etc/resolv.conf 指向 127.0.0.53(stub 转发器)。systemd-resolved 异常时会导致部分域名解析失败。传统 resolv.conf 方式配置的 DNS 服务器在此场景下不生效。
修复:sudo systemctl restart systemd-resolved 重启解析服务。长期方案检查 /etc/resolv.conf 是否正确指向 stub 监听地址,或手动配置 /etc/systemd/resolved.conf 中的上游 DNS 服务器。
案例 I:tcp_tw_recycle 导致高并发下连接被随机丢弃
现象:服务器在高并发场景下出现大量 SYN timeout,部分客户端连接失败,但服务器 CPU 和内存正常。
# 检查 TIME_WAIT 状态连接数
$ ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn
8500 TIME-WAIT
1200 ESTAB
50 LISTEN
# 检查 tcp_tw_recycle 设置
$ sysctl net.ipv4.tcp_tw_recycle
net.ipv4.tcp_tw_recycle = 1 ← 已开启(危险!)
# 关闭 tcp_tw_recycle
$ sudo sysctl -w net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_recycle = 0
# 永久生效
$ echo "net.ipv4.tcp_tw_recycle=0" | sudo tee -a /etc/sysctl.conf
# 调优建议
$ sudo sysctl -w net.ipv4.tcp_tw_reuse=1 ← 复用 TIME_WAIT
$ sudo sysctl -w net.ipv4.tcp_max_tw_buckets=5000
根因:tcp_tw_recycle 在 NAT 环境下会导致问题——同一 NAT 出口的不同客户端共享 IP,但时间戳不同,内核会随机丢弃连接。Linux 4.12+ 已移除此选项。
修复:sysctl -w net.ipv4.tcp_tw_recycle=0 关闭。改用 tcp_tw_reuse=1 允许复用 TIME_WAIT 连接。高并发服务器调整 tcp_max_tw_buckets 控制 TIME_WAIT 数量上限。
延伸阅读
- 4.5:网络故障排查 网络故障排查——ip 配置、ping/traceroute 排错与 SSH 密钥认证
- 4.5:网络故障排查 网络故障排查——从物理层到应用层的逐层排查方法论
- 3.4:Nginx Web服务器 Nginx Web 服务器——Web 服务端口、访问控制与反向代理
- 5.5:防火墙实战 防火墙实战——ufw/nftables 规则、端口放行与 NAT 配置
- 5.9:DNS 服务搭建 DNS 服务搭建——DNS 原理、BIND/Unbound 配置与排错
- 2.11:SSH 深入 SSH 深入——SSH 隧道、端口转发与安全加固
- 1.4:基本文件操作命令 基本文件操作命令——scp 和 rsync 传输文件的基础