机器概况
1
2
3
4
5
6
7
8
| hostname
whoami
pwd
date
uptime
uname -a
cat /etc/os-release
nproc
|
1
2
3
4
| free -h
df -h
df -i
top
|
服务状态
1
2
3
4
| systemctl status nginx
systemctl status docker
systemctl list-units --failed
systemctl list-unit-files | grep enabled
|
1
2
3
4
| journalctl -u nginx -n 100 --no-pager
journalctl -u nginx -f
journalctl -n 200 --no-pager
journalctl -b -n 200 --no-pager
|
1
2
3
| systemctl restart 服务名
systemctl reload 服务名
systemctl enable --now 服务名
|
进程
1
2
3
4
| ps aux
ps aux | grep nginx
pgrep -a nginx
pidof nginx
|
1
2
| ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head
|
1
2
| kill -TERM <pid>
kill -KILL <pid>
|
端口
1
2
3
| ss -lntp
ss -lnup
ss -antp
|
1
2
3
| sudo lsof -i :80
sudo lsof -iTCP:3000 -sTCP:LISTEN
sudo fuser -v 80/tcp
|
1
2
| netstat -lntp
netstat -lnup
|
1
2
3
| 127.0.0.1:3000 只监听本机
0.0.0.0:3000 监听所有 IPv4
[::]:3000 监听 IPv6
|
网络
1
2
3
4
5
| ip addr
ip route
ip neigh
resolvectl status
cat /etc/resolv.conf
|
1
2
3
4
| ping 1.1.1.1
ping example.com
traceroute example.com
mtr example.com
|
1
2
3
4
| nc -vz example.com 80
nc -vz example.com 443
nc -vz 1.2.3.4 25565
telnet example.com 443
|
代理设置
临时设置当前 Shell 的代理:
1
2
3
| export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export all_proxy=socks5://127.0.0.1:7890
|
1
2
3
| export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5://127.0.0.1:7890
|
取消当前 Shell 的代理:
1
2
3
4
5
6
| unset http_proxy
unset https_proxy
unset all_proxy
unset HTTP_PROXY
unset HTTPS_PROXY
unset ALL_PROXY
|
测试代理是否生效:
1
2
| curl -I https://example.com
curl -x http://127.0.0.1:7890 -I https://example.com
|
Git 设置代理:
1
2
| git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
|
Git 取消代理:
1
2
| git config --global --unset http.proxy
git config --global --unset https.proxy
|
Docker 服务设置代理,适合拉镜像慢或拉不下来时排查:
1
2
| sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/proxy.conf
|
1
2
3
4
| [Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1"
|
1
2
3
| sudo systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl show --property=Environment docker
|
抓包
1
2
3
| sudo tcpdump -ni any port 443
sudo tcpdump -ni any host 1.2.3.4
sudo tcpdump -ni eth0 port 80
|
1
2
3
| sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
sudo tcpdump -ni any 'icmp'
sudo tcpdump -ni any 'udp port 53'
|
1
| sudo tcpdump -ni any -w capture.pcap port 443
|
DNS
1
2
3
4
5
6
7
8
| dig example.com
dig example.com A
dig example.com AAAA
dig example.com CNAME
dig example.com MX
dig example.com TXT
dig example.com NS
dig example.com SOA
|
1
2
3
4
| dig @1.1.1.1 example.com
dig @8.8.8.8 example.com
dig @223.5.5.5 example.com
dig @ns1.example-dns.com example.com
|
1
2
3
| dig +trace example.com
dig +short example.com
dig +nocmd example.com any +multiline +noall +answer
|
1
2
3
| nslookup example.com
ipconfig /displaydns
ipconfig /flushdns
|
HTTP / HTTPS
1
2
3
4
| curl -I https://example.com
curl -IL https://example.com
curl -v https://example.com
curl -vk https://example.com
|
1
2
3
| curl -v -H 'Host: example.com' http://1.2.3.4
curl -v --resolve example.com:443:1.2.3.4 https://example.com
curl -v --connect-to example.com:443:1.2.3.4:443 https://example.com
|
1
| curl -iv https://example.com --connect-to example.com:443:12.34.56.78:443
|
1
2
3
| --connect-to 会保持 URL 和 SNI 还是 example.com,
但实际 TCP 连接会打到 12.34.56.78:443。
适合排查 DNS、CDN、源站差异。
|
1
2
| curl -X POST https://example.com/api
curl -H 'Content-Type: application/json' -d '{"hello":"world"}' https://example.com/api
|
1
2
3
4
| openssl s_client -connect example.com:443 -servername example.com
openssl s_client -connect 1.2.3.4:443 -servername example.com -brief
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -subject
|
1
2
3
| -connect 1.2.3.4:443 实际连接的 IP 和端口
-servername example.com TLS SNI 使用的域名
-brief 输出简洁结果
|
Nginx
1
2
3
4
| sudo nginx -t
sudo nginx -T
sudo systemctl status nginx
sudo systemctl reload nginx
|
1
2
| tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
|
1
2
3
4
| sudo nginx -T | grep -n "server_name"
sudo nginx -T | grep -n "proxy_pass"
sudo nginx -T | grep -n "client_max_body_size"
sudo nginx -T | grep -n "listen"
|
1
| nginx -T | grep -A 5 -i "proxy_pass"
|
1
2
| -A 5 表示匹配到 proxy_pass 后,再额外显示后面 5 行。
适合快速确认 proxy_set_header、proxy_http_version 等反代配置。
|
1
| nginx -T > /tmp/full_nginx.conf && less /tmp/full_nginx.conf
|
1
2
| nginx -T 会输出主配置和所有 include 进来的配置。
导出到 /tmp/full_nginx.conf 后更方便搜索和分页查看。
|
1
2
| awk '$9 ~ /^5[0-9][0-9]$/' /var/log/nginx/access.log | tail -n 50
grep -E '(connect\(\) failed|no live upstreams)' /var/log/nginx/error.log | tail -n 20
|
1
2
3
4
| access.log 默认第 9 列通常是 HTTP 状态码。
/^5[0-9][0-9]$/ 匹配 500 到 599。
connect() failed 表示 Nginx 连不上后端 upstream。
no live upstreams 表示 upstream 里没有可用后端。
|
1
2
3
4
| proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
|
1
2
3
| proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
|
防火墙
1
2
3
| sudo ufw status verbose
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
|
1
2
3
4
| sudo firewall-cmd --list-all
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --add-port=443/tcp --permanent
sudo firewall-cmd --reload
|
1
2
3
4
| sudo iptables -S
sudo iptables -L -n -v
sudo iptables -t nat -S
sudo nft list ruleset
|
磁盘
1
2
3
4
| df -h
df -i
lsblk
mount
|
1
| find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n
|
1
2
3
4
5
| / 从根目录开始
-xdev 不跨文件系统, 避免扫到挂载盘、proc、sys 等
-type f 只统计普通文件
cut -d "/" -f 2 取一级目录名
sort | uniq -c | sort -n 统计数量并排序
|
1
2
3
| du -sh *
du -h --max-depth=1
find /var -type f -size +500M -print
|
1
2
3
| sudo lsof | grep deleted
sudo lsof +L1
sudo truncate -s 0 /var/log/big.log
|
1
2
| lsof +L1 用来查看已经删除但仍被进程占用的文件。
常见场景是日志文件被删了, 但进程还开着文件句柄, 磁盘空间不会释放。
|
查看大于 10 MB 的已删除占用文件:
1
| sudo lsof | grep -E '(deleted|COMMAND)' | awk '{if($7 > 10485760) print $0}'
|
1
2
3
| $7 通常是文件大小字段, 单位是字节。
10485760 = 10 MB。
deleted 表示文件已经从目录中删除, 但仍被进程持有。
|
更清晰地列出大于 10 MB 的 deleted 文件:
1
| sudo lsof +L1 | awk 'NR==1 || $7 > 10485760'
|
如果只是想分页查看:
清空进程仍持有的文件描述符:
1
| true > /proc/<PID>/fd/<FD>
|
1
2
3
| <PID> 是占用文件的进程 ID。
<FD> 是 lsof 输出里的文件描述符编号。
这个操作会把进程打开的那个文件句柄清空。
|
让进程关闭指定 FD:
1
| sudo gdb -p <PID> -ex 'p close(4)' -ex 'quit'
|
1
2
3
| close(4) 表示关闭 FD 4, 需要换成实际 FD 编号。
这个方法会 attach 到进程, 可能导致进程短暂停顿。
生产环境谨慎使用。
|
内存 / CPU / IO
1
2
3
4
| free -h
top
htop
uptime
|
1
2
| ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head
|
1
2
| vmstat 1
iostat -xz 1
|
1
2
| dmesg | grep -i oom
journalctl -k | grep -i oom
|
查看当前最容易被 OOM Killer 杀掉的进程:
1
| printf "PID\tOOM Score\tCommand\n" && printf "%s\n" /proc/[0-9]* | awk -F/ '{print $3}' | while read pid; do if [ -f /proc/$pid/oom_score ]; then echo -e "$pid\t$(cat /proc/$pid/oom_score)\t$(cat /proc/$pid/cmdline | tr '\0' ' ')"; fi; done | sort -k2 -nr | head -n 10
|
1
2
3
4
5
| /proc/<PID>/oom_score 当前进程被 OOM Killer 选中的倾向
分数越高, 越容易在内存不足时被杀
cmdline 进程启动命令
sort -k2 -nr 按 OOM Score 从高到低排序
head -n 10 只看前 10 个
|
Docker
1
2
3
4
5
| docker ps
docker ps -a
docker images
docker volume ls
docker network ls
|
1
2
3
4
5
6
| docker logs -f container_name
docker logs --tail 100 container_name
docker inspect container_name
docker port container_name
docker stats
docker system df
|
1
2
3
| docker exec -it container_name sh
docker exec -it container_name bash
docker restart container_name
|
查看所有正在运行容器的容器名、容器 IP 和网络 ID:
1
| docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}} ({{.NetworkID}}){{end}}' $(docker ps -q)
|
1
2
3
4
| .Name 容器名
.NetworkSettings.Networks 容器加入的 Docker 网络
.IPAddress 容器在该网络内的 IP
.NetworkID Docker 网络 ID
|
进入容器网络命名空间抓包:
1
2
| PID=$(docker inspect -f '{{.State.Pid}}' <容器名>)
sudo nsenter -t $PID -n tcpdump -ni any port 80
|
1
2
3
| docker inspect 取出容器对应的宿主机进程 PID。
nsenter -t $PID -n 进入该进程的 network namespace。
tcpdump -ni any port 80 在容器网络视角下抓 80 端口流量。
|
如果 tcpdump 版本支持按容器 ID 抓包:
1
| sudo tcpdump --container-id <容器名或ID> -ni any
|
1
2
| --container-id 不是所有系统的 tcpdump 都支持。
如果报 unknown option, 改用 nsenter 方法。
|
Docker Compose
1
2
3
| docker compose ps
docker compose logs -f
docker compose logs --tail 100 service_name
|
1
2
3
4
| docker compose up -d
docker compose pull
docker compose restart service_name
docker compose down
|
1
2
3
| docker compose config
docker compose exec service_name sh
docker compose exec service_name bash
|
1
2
3
| docker compose config 会合并 compose.yaml、override、
环境变量替换后的最终配置。
适合排查 ports、volumes、environment、networks 是否写错。
|
Git
1
2
3
4
5
| git status --short
git status --short --ignored
git diff
git diff --stat
git diff --cached
|
1
2
3
4
| git log --oneline -10
git log --graph --oneline --decorate --all
git show <commit>
git blame path/to/file
|
1
2
3
4
5
| git reflog
git stash push -m "debug temp"
git stash list
git stash show -p stash@{0}
git stash pop stash@{0}
|
1
2
3
4
| git restore path/to/file
git restore --staged path/to/file
git clean -nd
git clean -fd
|
Windows 网络
1
2
3
| ipconfig /all
ipconfig /displaydns
ipconfig /flushdns
|
1
2
3
| ping example.com
tracert example.com
route print
|
1
2
| Test-NetConnection example.com -Port 443
Test-NetConnection 1.2.3.4 -Port 25565
|
1
2
| netstat -ano | findstr :443
tasklist | findstr 1234
|
Windows 端口转发
1
2
3
| netsh interface portproxy show all
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=192.168.1.10 connectport=80
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8080
|
1
2
| netsh advfirewall firewall add rule name="PortProxy 8080" dir=in action=allow protocol=TCP localport=8080
netsh advfirewall firewall delete rule name="PortProxy 8080"
|
常用组合
服务打不开:
1
2
3
4
| systemctl status 服务名
journalctl -u 服务名 -n 100 --no-pager
ss -lntp
curl -v http://127.0.0.1:端口
|
网站打不开:
1
2
3
4
| dig 域名
curl -IL https://域名
sudo nginx -t
tail -f /var/log/nginx/error.log
|
端口不通:
1
2
3
4
| ss -lntp
sudo ufw status
sudo tcpdump -ni any port 端口
nc -vz 主机 端口
|
服务器变慢:
1
2
3
4
5
6
| uptime
top
free -h
df -h
ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head
|
Docker 异常:
1
2
3
4
5
| docker compose ps
docker compose logs --tail 100 服务名
docker compose config
docker port 容器名
docker inspect 容器名
|
Git 状态奇怪:
1
2
3
4
| git status --short --ignored
git diff --stat
git log --oneline -10
git reflog
|
磁盘满但看不出哪里占用:
1
2
3
4
| df -h
du -h --max-depth=1 /
sudo lsof +L1
sudo lsof +L1 | awk 'NR==1 || $7 > 10485760'
|
Nginx 反代异常:
1
2
3
4
| sudo nginx -t
nginx -T | grep -A 5 -i "proxy_pass"
grep -E '(connect\(\) failed|no live upstreams)' /var/log/nginx/error.log | tail -n 20
awk '$9 ~ /^5[0-9][0-9]$/' /var/log/nginx/access.log | tail -n 50
|
容器网络异常:
1
2
3
4
5
| docker ps
docker port 容器名
docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}} ({{.NetworkID}}){{end}}' $(docker ps -q)
PID=$(docker inspect -f '{{.State.Pid}}' <容器名>)
sudo nsenter -t $PID -n tcpdump -ni any port 80
|
疑似 OOM:
1
2
3
4
5
| free -h
ps aux --sort=-%mem | head
dmesg | grep -i oom
journalctl -k | grep -i oom
printf "PID\tOOM Score\tCommand\n" && printf "%s\n" /proc/[0-9]* | awk -F/ '{print $3}' | while read pid; do if [ -f /proc/$pid/oom_score ]; then echo -e "$pid\t$(cat /proc/$pid/oom_score)\t$(cat /proc/$pid/cmdline | tr '\0' ' ')"; fi; done | sort -k2 -nr | head -n 10
|