网络调试指南:curl / DNS / 代理 / SSH
适用场景:调试 API 请求、排查 DNS 问题、配置代理、SSH 连接远程服务器。
适用版本:curl 7.82+、OpenSSH 8+、PowerShell 7+;Windows PowerShell 5.1 差异单独标注。
最后核对:2026-07-30
30 秒快速路径
curl --fail-with-body --connect-timeout 5 https://api.example.com/health
nslookup example.com
ssh -v user@example.com
目录
curl — HTTP 请求调试
curl 是命令行 HTTP 客户端,调试 API 必备。
基础请求
# GET 请求
curl https://api.example.com/users
curl -sS https://api.example.com/users # 静默进度条,但仍显示错误
# 只看响应头
curl -I https://example.com # HEAD 请求
curl -i https://example.com # 响应头 + body 一起看
# 只看 HTTP 状态码
curl -sS -o /dev/null -w "%{http_code}\n" https://example.com
# 输出:200
# 让 HTTP 4xx/5xx 返回非零退出码,同时保留错误正文
curl --fail-with-body https://api.example.com/users
# 查看详细的请求/响应过程
curl -v https://example.com # 显示 TLS 握手、请求头、响应头等
# 跟随重定向
curl -L https://short.url/abc # -L = follow redirects
# 超时设置
curl --connect-timeout 5 --max-time 10 https://slow-api.com
# 对 curl 判断为临时故障的请求最多重试 3 次,并限制整体重试时间
curl --retry 3 --retry-max-time 20 https://api.example.com/health
--retry-all-errors 会扩大重试范围,但配合管道、重定向或非幂等请求可能造成重复数据或重复操作,不应作为默认模板。
POST / PUT / DELETE
# POST JSON(curl 7.82+;自动设置 Content-Type 与 Accept)
curl --json '{"name":"Example User","email":"user@example.com"}' \
https://api.example.com/users
# 从文件读取 JSON
curl --json @request.json https://api.example.com/users
# POST 表单数据
curl https://example.com/login \
--data-urlencode "username=example-user" \
--data-urlencode "password=REPLACE_ME"
# PUT
curl -X PUT https://api.example.com/users/1 \
-H "Content-Type: application/json" \
-d '{"name":"Updated"}'
# DELETE
curl -X DELETE https://api.example.com/users/1
# 上传文件
curl -X POST https://api.example.com/upload \
-F "file=@./photo.jpg"
请求头与认证
# 不要把真实 Token、密码或 Cookie 写进会被保存的命令历史。
# 以下值仅为占位符;长期凭据应使用权限受控的配置文件或密钥管理器。
# 自定义请求头
curl -H "Authorization: Bearer REPLACE_WITH_TOKEN" \
-H "Accept: application/json" \
https://api.example.com/me
# Basic Auth:只写用户名,让 curl 交互提示密码
curl -u username https://api.example.com/admin
# Cookie
curl -b "session=abc123" https://example.com/dashboard
curl -c cookies.txt https://example.com/login # 保存 cookie
chmod 600 cookies.txt # Cookie 文件按敏感信息保护
curl -b cookies.txt https://example.com/dashboard # 使用 cookie
输出与保存
# 保存到文件
curl -o output.html https://example.com # 自定义文件名
curl -O https://example.com/file.zip # 用 URL 中的文件名
# 格式化 JSON(配合 jq)
curl -s https://api.example.com/users | jq .
curl -s https://api.example.com/users | jq '.[0].name'
# 测量响应时间
curl -s -o /dev/null -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://example.com
PowerShell 的 curl
# Windows PowerShell 5.1 中 curl 是 Invoke-WebRequest 的别名;
# PowerShell 7+ 通常没有该别名。需要原生 curl 时显式使用 curl.exe
curl.exe -s https://api.example.com/users
# 或者用 PowerShell 原生:
Invoke-RestMethod -Uri "https://api.example.com/users" -Method Get
Invoke-RestMethod -Uri "https://api.example.com/users" -Method Post -Body '{"name":"Example User"}' -ContentType "application/json"
# 只看头
Invoke-WebRequest -Uri "https://example.com" -Method Head | Select-Object StatusCode, Headers
DNS 排查
查询 DNS 解析
# nslookup(所有平台)
nslookup example.com
nslookup example.com 8.8.8.8 # 指定 DNS 服务器
# dig(Linux/macOS,更详细)
dig example.com
dig example.com +short # 只看 IP
dig example.com MX # 查 MX 记录
dig example.com NS # 查 NS 记录
dig @8.8.8.8 example.com # 用 Google DNS 查
# host(Linux 简洁工具)
host example.com
常见 DNS 问题
# 清除本地 DNS 缓存
# Windows:
ipconfig /flushdns
# macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Linux:命令取决于实际启用的解析服务
sudo resolvectl flush-caches # systemd-resolved
sudo systemctl restart NetworkManager # 使用 NetworkManager 时的另一种方式
hosts 文件
手动把域名指向特定 IP(优先级高于 DNS):
# 文件位置:
# Windows: C:\Windows\System32\drivers\etc\hosts
# Linux/macOS: /etc/hosts
# 格式:IP 域名
127.0.0.1 myapp.local
127.0.0.1 api.myapp.local
# 用途:本地开发时模拟域名
连通性测试
# ping — 测试 ICMP;失败也可能只是对方或防火墙屏蔽 ICMP
ping google.com # 持续 ping
ping -c 4 google.com # 只 ping 4 次(Linux/macOS)
ping -n 4 google.com # Windows
# traceroute — 追踪路由路径
traceroute google.com # Linux/macOS
tracert google.com # Windows
# telnet — 测试 TCP 端口
telnet example.com 443
# nc (netcat) — 更好用
nc -zv example.com 443 # 测试端口
for port in 80 443 8080; do nc -zv example.com "$port"; done
代理配置
终端代理设置
# Linux/macOS — 当前会话
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export no_proxy="localhost,127.0.0.1,.local"
# 取消
unset http_proxy https_proxy no_proxy
# 写入 ~/.bashrc 持久化(如果代理一直开着)
# PowerShell
$env:http_proxy = "http://127.0.0.1:7890"
$env:https_proxy = "http://127.0.0.1:7890"
# 取消
Remove-Item Env:http_proxy, Env:https_proxy -ErrorAction SilentlyContinue
Git 代理
# 给所有仓库设置代理前先确认这是你的长期需求
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
# 只给 GitHub 设代理
git config --global http.https://github.com.proxy http://127.0.0.1:7890
# 取消
git config --global --unset http.proxy
git config --global --unset https.proxy
npm 代理
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
# 取消
npm config delete proxy
npm config delete https-proxy
SSH 基础
生成密钥
# 生成 Ed25519 密钥(推荐)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 生成文件:~/.ssh/id_ed25519(私钥)和 ~/.ssh/id_ed25519.pub(公钥)
chmod 600 ~/.ssh/id_ed25519
# 查看公钥(复制到 GitHub/服务器)
cat ~/.ssh/id_ed25519.pub
连接远程
ssh user@hostname # 基础连接
ssh -p 2222 user@hostname # 指定端口
ssh -i ~/.ssh/mykey user@host # 指定密钥文件
首次连接前应通过可信渠道核对服务器主机密钥指纹,不要在不确认的情况下接受发生变化的 host key。
SSH Config(免记 IP 和参数)
# ~/.ssh/config
Host myserver
HostName 192.168.1.100
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519
Host github
HostName github.com
User git
IdentityFile ~/.ssh/github_key
# 使用:
ssh myserver # 等价于 ssh -i ... deploy@192.168.1.100
git clone github:user/repo # 使用 github 配置
端口转发(隧道)
# 本地转发:把远程端口映射到本地
ssh -o ExitOnForwardFailure=yes -L 127.0.0.1:8080:127.0.0.1:3000 user@server
# 访问本地 8080 → 实际访问 server 上的 3000
# 远程转发:把本地端口暴露到远程
ssh -o ExitOnForwardFailure=yes -R 127.0.0.1:9090:127.0.0.1:4321 user@server
# 默认只允许远程服务器本机访问 127.0.0.1:9090;
# 是否允许其他主机访问取决于 sshd 的 GatewayPorts 配置
# 后台运行隧道
ssh -fN -o ExitOnForwardFailure=yes -L 127.0.0.1:8080:127.0.0.1:3000 user@server
# -f 后台运行 -N 不开 shell
文件传输
# scp — 简单拷贝
scp file.txt user@server:/home/user/ # 上传
scp user@server:/var/log/app.log ./ # 下载
scp -r ./dist user@server:/var/www/ # 上传目录
# rsync — 增量同步(更快)
rsync -avz ./dist/ user@server:/var/www/ # 上传(只传有变化的)
rsync -avzn --delete ./dist/ user@server:/var/www/ # 先 dry-run
rsync -avz --delete ./dist/ user@server:/var/www/ # 确认后执行;会删除远端多余文件
rsync 源路径末尾的 / 会改变复制层级;使用 --delete 前必须核对源、目标和 dry-run 输出。
常见网络问题排查
API 请求失败排查流程
# 1. 确认域名能解析
nslookup api.example.com
# 2. 辅助检查 ICMP;ping 失败不能单独证明服务不可达
ping api.example.com
# 3. 确认端口通
nc -zv api.example.com 443
# 4. 确认 HTTP 层
curl -v https://api.example.com/health
# 5. 确认不是代理问题
curl --noproxy '*' https://api.example.com/health
CORS 问题
# 模拟带 Origin 的实际 GET
curl -i -H "Origin: http://localhost:3000" https://api.example.com/data
# 模拟浏览器 OPTIONS 预检
curl -i -X OPTIONS \
-H "Origin: http://localhost:3000" \
-H "Access-Control-Request-Method: POST" \
https://api.example.com/data
# 检查 Allow-Origin、Allow-Methods、Allow-Headers 和凭据策略
SSL/TLS 证书问题
# 查看证书信息
curl -vI https://example.com 2>&1 | grep -A 5 "Server certificate"
# 跳过证书验证(仅调试用!)
curl -k https://self-signed.example.com
# 查看证书详情
openssl s_client -connect example.com:443 -servername example.com </dev/null
慢请求定位
curl -s -o /dev/null -w "\
DNS查询: %{time_namelookup}s\n\
TCP连接: %{time_connect}s\n\
TLS握手: %{time_appconnect}s\n\
首字节(TTFB): %{time_starttransfer}s\n\
总时间: %{time_total}s\n" https://example.com