半夜收到一条告警,负载阈值直接超标,我揉着眼睛坐起来的第一件事不是看监控大屏,而是熟练地敲下一行uptime。干运维这些年,我电脑里一直维护着一个服务器运维操作命令速查手册,说是手册,其实更像一堆按场景叠起来的真实经验记录。这类东西不是背出来的,是在各种“疑似要挂但还没挂”“挂了但不知道哪挂”的现场里一次一次攒出来的。我把它整理成一份可以直接照用的速查体系,送给刚上手服务器运维的朋友,也送给那些明明会敲命令、但一到故障现场就不知道先看什么的老同事。这篇内容适合所有需要管理 Linux 生产环境的人,也适合准备把运维工作系统化梳理一遍的团队,少走弯路,少做无用操作。
1. 服务器异常时的第一屏操作:别急着抓瞎,先按顺序看四个维度
故障现场最忌乱。很多新人和部分老手都会有同一个毛病:一上来就free -g看一眼,再df -h瞄一下,然后就开始怀疑是代码问题还是网络问题,来回切换上下文,最后半小时过去了还没定位到根因。我自己的经验是,不管客户报什么现象,先把第一屏命令跑完,四个维度全部扫一遍,再决定下一步。这四个维度就是负载、CPU、内存、磁盘。
1.1 负载与 CPU 瓶颈的三板斧
第一板斧是uptime。它会把当前时间、开机时长、在线用户数和 load average 一起打出来,通常长这样:
$ uptime 03:42:11 up 88 days, 6:17, 3 users, load average: 12.87, 8.65, 5.32load average 后面的三个数字分别是 1 分钟、5 分钟、15 分钟的平均负载。这块有个特别容易误读的点:load average 不只是 CPU 使用率,它包含正在运行的任务和不可中断睡眠的任务。如果 1 分钟和 15 分钟相差很大,说明负载是突然冲上来的;如果三个数都长期很高,说明系统已经持续满负荷运转很久,不是瞬时的波动。判断基准也不是看数字小于几,而是结合 CPU 核数来看。8 核机器 load 到 8 上下已经是临界状态,16 核机器 load 到 15 还有余量。这里我说的是经验值,更严谨的应该配合后面的 vmstat 一起确认。
第二板斧是top。直接跑top会进入交互界面,按下P按 CPU 排序,按下M按内存排序。但我更推荐在排查时直接使用批处理模式,一次性抓几屏快照:
top -b -n 1 -o %CPU | head -20-b是批处理模式,-n 1只输出一次,-o %CPU按 CPU 使用率排序。这一步的目标是找到到底哪个进程在消耗 CPU。另外注意看top里面的%Cpu(s)那行:us 表示用户态时间,sy 表示系统态时间,wa 表示等待 I/O 的时间。如果 wa 长期偏高,说明瓶颈不在 CPU 而在磁盘或文件系统,这时候盯着进程看半天反而跑偏了。
第三板斧是vmstat,它弥补了 top 只看瞬间的缺点。跑一次vmstat 2 5,意思是每两秒采样一次,连续采五次:
vmstat 2 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 4 2 123456 45678 1024 99810 0 0 120 130 478 1024 35 10 45 10 0重点关注 r 列和 b 列。r 是运行队列中的进程数,如果长期大于 CPU 核数,说明 CPU 肯定不够用;b 是阻塞在 I/O 上的进程数,b 越大越要往磁盘方向查。wa 高加上 b 列有值,基本可以锁定存储层的性能问题。
1.2 内存到底够不够,free 的细节很多人忽略了
free -h大概是每个运维一天里敲得最多的命令之一,但也是误读最多的命令。以前内存小,free那一列的数字还有点参考意义;现在内存普遍做了缓存管理,直接看 free 那行基本没有判断价值。正确的做法是看 available 那一列,它才是真正“还能给新进程用的内存”。我见过有人看到 free 只有几百兆就紧张得不行,实际上 cache 一直在正常回收,系统稳得很。
$ free -h total used free shared buff/cache available Mem: 125Gi 98Gi 2.1Gi 24Mi 25Gi 26Gi如果想要进一步确认内存到底被谁吃了,top里按 M 排序后看 RES 列,或者用一段组合命令把进程内存占用排个序:
ps aux --sort=-%mem | head -15这里要留意一个细节:ps aux里的 RSS 是进程实际驻留内存,VSZ 是虚拟内存,虚拟内存大并不一定真的占用物理内存。排查内存泄漏时,我更习惯隔一段时间记一次同一进程的 RSS,看看是不是只涨不降。如果缓存占比一直很大,可以稍等再观察,不用急着清理;如果担心内存回收出问题,sysctl vm.drop_caches确实能清缓存,但能不动就别动,生产环境里手动 drop cache 有时会带来额外抖动。
1.3 磁盘快满时,df 和 du 怎么配合定位
磁盘问题的标准套路是先df -h看整体,再看df -i看 inode。这两个必须同时看。我碰到过好几次诡异的现象:df -h显示还有 20% 空间,但服务就是报“No space left on device”,结果一查df -i,inode 早就满了,全是上千个小碎文件捣的鬼。
df -h df -i确认哪个分区有问题之后,用du从根上逐层定位。找大目录有一个很快的办法:
du -h --max-depth=1 /路径 | sort -rh | head -20--max-depth=1只看一层,sort -rh按大小倒序。不要去全盘du -sh /,生产环境大磁盘跑这个命令能把 I/O 拖垮。如果某个目录删了文件但空间没释放,基本可以确定有进程还在占着这个文件的删除后的句柄,这种情况lsof | grep deleted能帮你找到元凶,找到后重启或重载对应的进程就好。这个坑非常典型,值得单独记一笔,属于“排查链路完整才能收工”的经典案例。第一屏检查做完,基本就能把问题收敛到 CPU、内存、磁盘、网络中的某个方向,接下来的章节会逐个方向给出完整命令链。
2. 进程与服务治理:systemd 时代照样离不开那一组老伙计
现在主流 Linux 发行版都跑 systemd,日常操作服务确实比以前简洁,但命令背后的状态语义如果搞不清楚,很容易在不该重启的时候重启,或者以为自己禁用了服务结果一开机又自动起来了。
2.1 systemctl 状态与启停命令的正确理解
常用的一组命令其实很固定:
systemctl status myservice systemctl start myservice systemctl stop myservice systemctl restart myservice systemctl enable myservice systemctl disable myservice systemctl mask myservice这里最容易被忽略的是 enable 和 disable 本身不影响当前运行状态,只控制开机是否自动启动。另一个更隐蔽的是 mask。disable 只是取消开机自启,如果服务被依赖它被调起时照样还能启动;mask 会把服务彻底屏蔽,软链到/dev/null,任何方式都拉不起来。所以当你想要某个服务完全不能起来时,用 mask 而不是简单 disable。遇到“改完配置不生效”之类的问题,先跑systemctl daemon-reload再 restart,这个动作虽然简单,但漏掉它会让不少改动白白浪费。
看服务状态时,systemctl status开头几行会给出 active、exited、failed 这类状态。需要区分的是:active 代表服务进程在跑或处于预期状态,exited 一般用于 oneshot 类型的服务,它执行完正常退出不代表出错;failed 就很直白了,进程异常退出,而且 systemd 通常会带上退出码和最近的日志片段。
2.2 进程异常的完整排查链条
systemctl 能管理的服务之外,还有大量直接跑在后台的进程、临时脚本、调试进程。这时候要快速找进程,我一般按这样的顺序来:
pgrep -l -f "进程特征名" pidof 进程名 pstree -p PID ps -ef | grep 进程特征名 | grep -v greppgrep 用-f匹配完整命令行比单纯匹配进程名更实用,因为很多程序的名字一样但参数不同。找到 PID 之后,想看它的运行参数就用ps -fp PID,想看它的父进程关系就用pstree -p PID。定位到具体进程后,很多问题的下一步是看系统调用。这里有一个很多人平时不太用、但关键时刻特别管用的工具:strace。
strace -p PID -e trace=network -f -t附加到一个异常进程上,看它卡住的时候在干什么网络调用,或者干脆采集一段时间内的文件访问和系统调用,能快速判断是“它在等什么”还是“它本身在空转”。注意 strace 附加生产进程会带来一定的性能开销,操作前确认允许的窗口期,不要在所有进程上滥用。
杀进程是另一个需要小心的地方。kill -9不是第一选择,默认的kill发的是 TERM 信号,让进程有清理资源、保存状态的机会。只有进程对 TERM 无响应,或者确实需要立刻断掉某个失控任务时才考虑kill -9。一个相对稳妥的升级流程是:先kill PID,等三到五秒,确认没退再考虑kill -9 PID。另外,如果进程变成了僵尸,父进程一直不回收,需要处理的是父进程,杀僵尸本身没有意义,这一点很多新手会反复踩坑。
2.3 定时任务和长驻任务的保活思路
后台任务的经典组合是 nohup 加重定向,这个大家应该都见过:
nohup sh /opt/scripts/job.sh > /var/log/job.log 2>&1 &nohup 能让进程忽略挂断信号,&把它放到后台,输出统一接到日志文件。还有个容易被忽略的参数是disown,进程已经启动后才想起来要脱离当前会话,可以用这个命令把它从 shell 的作业表里摘出去。不过现在生产环境跑定时任务的习惯已经慢慢从 crontab 迁移到 systemd timer 了,原因很简单:systemd timer 能配置开机后多久再执行,能避免服务没起来脚本先跑的尴尬,还能配合日志统一收集。同等的定时任务用 systemd 需要写一个 service 文件和一个 timer 文件,虽然初看多两步,但可维护性和可靠性的提升明显。
关于定时任务,我提一个实际教训:在 crontab 里写脚本时,几乎必须把关键日志重定向到文件,否则一旦脚本输出内容,crontab 会把它作为邮件内容尝试发信,有时还会触发大量的 sendmail 进程堆积。看到机器上一堆 sendmail 或 postfix 进程卡着不动,先查一下是不是有没加重定向的 cron 任务在刷屏。服务治理这一层做完,下一个重灾区就是网络,网络排查没有固定顺序就特别容易绕圈。
3. 网络层排查:从连通性到端口到流量的递进打法
网络相关的命令不少,但最核心的排查思路是分层的:先确认链路通不通,再确认端口开没开,最后才是看内容、看流量。这个顺序颠倒了,很容易被表象带偏。
3.1 连通性与路径排查:ping、traceroute 的适用边界
ping是连通性测试的第一选择,但不是唯一选择。很多公网环境出于安全考虑禁了 ICMP,这时候 ping 不通不代表服务不通,需要用 TCP 层的探测来验证,比如用nc或curl直接测端口。管理员自己排查时,我习惯把 ping 的回复时间和丢包率作为第一判断依据,如果延迟突然抬高、丢包明显,再飞过来一个traceroute看路径上哪一跳有问题。
ping -c 10 -i 0.2 目标IP traceroute -n -T -p 目标端口 目标IPtraceroute -n不解析域名,速度快很多;-T -p用 TCP 协议探测指定端口,能绕过 ICMP 限制。需要注意,traceroute 对中间设备路径的反映存在一定误差,运营商路由器经常不处理或不回超时包,看到星号不要急着判断网络断了,重点看最后一跳的延迟和丢包。
DNS 层面也是网络排查的高频卡点。先明确解析本身是否正常,再排查是不是本地缓存的问题:
dig 域名 +short dig @8.8.8.8 域名 +short nslookup 域名 cat /etc/resolv.confdig +short只看解析结果,干净利落;换一个公共 DNS 做对比能快速判断是递归 DNS 的缓存问题还是域名解析本身配置异常。生产环境还会遇到读不到正确的 resolver 导致内外网都慢的情况,这时候cat /etc/resolv.conf和系统 network configuration 都要检查一遍,特别是有些云主机网络配置经常被自动改写。
3.2 端口、连接与会话状态怎么看
老一代运维习惯用 netstat,新一代更推荐 ss。ss 的优势是性能好、输出更细。这里列一下最常用的几种场景:
ss -lntp ss -anp | head -50 ss -state established '( dport = :80 or sport = :80 )'ss -lntp查看所有监听端口和对应进程,这是排查“端口被谁占了”的标准命令。ss -anp会列出所有连接,配合管道过滤出需要关注的远端地址。如果只想看某个服务的连接数,有一种很实用的统计方式:
ss -tan state established | wc -l ss -tan | awk '/ESTAB/ {print $4}' | awk -F: '{print $(NF-1)}' | sort | uniq -c | sort -rn第二行能统计出本机各监听端口当前的连接数分布,排第一的那个端口基本就是流量主要入口。连接队列也需要常看,ss -lntp中的 Send-Q 其实有讲究:如果监听端口的 Send-Q 数值巨大,说明 accept 队列已经积压,背后往往是应用处理不过来。专门看连接队列可以留意ss -lnt | awk 'NR>1 {print $2}',这个值反映了积压深度,是判断服务过载的一个重要信号。
会话状态里最值得盯的是 TIME_WAIT 和 CLOSE_WAIT。TIME_WAIT 大量堆积在短连接场景下很常见,一般不会立刻致命,但如果整体连接数逼近上限,就需要审视系统参数或改造连接复用。CLOSE_WAIT 是指对端关闭了连接,本地进程一直没调用 close,一旦数量持续上涨,基本可以断定应用代码有缺陷或者线程池卡死,是典型的应用层问题。
3.3 用抓包定位真相:tcpdump 的使用纪律
当 ping、端口、连接状态都没问题,但业务就是表现异常时,就该上 tcpdump 了。很多人不敢用 tcpdump 是因为怕流量太大把磁盘写满,其实加几个关键参数就能控制住:
tcpdump -i eth0 -n -s 96 port 8080 -w /tmp/trace.pcap -c 2000-i指定网卡,-n不做 IP 和端口解析以减少干扰,-s 96只抓每个包的前 96 字节,这叫 snaplen,对大多数排查来说够用了;-c 2000抓满 2000 个包自动停止,既控制了文件大小,又给抓包一个明确边界。抓下来的 pcap 文件可以拉回本地用工具慢慢分析。
如果只是看图字符内容,可以配合-A直接看 ASCII:
tcpdump -i eth0 -n port 80 -A | grep -i "host\|GET\|POST"还有一种高频排查场景:确认特定 IP 是否在大量连接本机。命令也很简单:
tcpdump -i eth0 -n src host 1.2.3.4 -c 100抓包这事的关键控制是“抓到够判断的量就停”,而不是丢在那里无限跑。抓完在网卡层面确认没问题后,才轮到应用层和日志层,这也正好过渡到下一章的主题:日志检索与文本处理。网络和文本这两块是运维日常干得最多的杂活,也是最讲究方法的两块。
4. 日志检索与文本处理:从大海捞针到逐层定位的日常战斗
日志文件多到爆炸,命令就那么几条,但同样的命令,为什么有人三分钟定位问题,有人半小时还在翻屏?差别在于组合方式和细节思路。这一章讲的不是单个命令的文档,而是把它们怎么组合起来解决真实场景。
4.1 日志时间窗口与 grep 的检索组合
先确认日志文件位置和时间窗口是第一步。常见的系统日志和服务日志路径各有不同,但思路一致:先用 tail 看最新的写入情况,再往前翻指定时间范围。我常用的一个组合命令是:
tail -n 100 /var/log/messages | grep -i error grep -n "2025-06-11 03:" /var/log/app.log | grep -i "error\|exception" | head -50grep 本身的基础逻辑不复杂,复杂的是如何快速定位到需要聚焦的行。日志行里一般都有时间戳、级别、请求 ID,这些字段用awk抽取之后再做统计,效果极佳。最典型的场景是统计某段时间内在某一台机器上某个错误出现的次数:
awk '/2025-06-11/ && /ERROR/ {count[$5]++} END {for (err in count) print count[err], err}' /var/log/app.log | sort -rn | head这里我按第五列(通常是等级或模块名)做了一次聚合,把所有 ERROR 分类统计,再把出现次数最多的错误类型列出来。这个思路比一屏一屏翻日志高效得多,适合对未知问题做初步盘面。
如果日志量非常大,先想办法排除干扰项比试图更精确地正则匹配更实际。比如只关心某一接口的请求,就先按请求路径过滤一遍再统计;只关心某一段时间,就先用sed -n截一个时间段,再做后续操作。每多一次过滤,后续命令的负担就小一截。
4.2 awk 和 sed 在统计与清洗中的妙用
awk 和 sed 是文本处理的双剑之一。awk 擅长大规模字段统计,sed 擅长大批量替换和行处理。运维里最常见的 awk 场景是“从混合日志里取出某个字段并计算平均值”。比如服务日志记录每次请求耗时的方式是“cost=123ms”,要先提取数字再求平均值,可以这样:
grep -oP 'cost=\K[0-9]+' /var/log/app.log | awk '{sum += $1; count++} END {print sum/count}'grep -oP提取目标字符,差异在于它只输出匹配部分而不是整行,配合\K跳过前缀,很好用。求完平均值还可以再配合排序函数看 P95 或者最大值,这比直接翻日志更接近量化定位。
sed 的经典用法是日志脱敏、批量替换、按时间段截取。比如需要把某个测试环境的对外 IP 统一替换成内网 IP:
sed -i 's/203.0.113.10/10.0.0.10/g' /etc/hosts另一个很实用的是日志去重和计数。sort | uniq -c | sort -rn这个管道组合是所有日志统计的万能底座,我听不少同事把它称作“运维三兄弟”。要统计某个页面 PV 量、统计来源 IP 数、统计用户 ID 去重数,基本都能套:
cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -204.3 journalctl 与日志轮转的日常维护
systemd 时代的日志统一交给 journald 管理,journalctl 的检索语法比 grep 日志文件更直接。最常用的几个参数:
journalctl -u myservice --since "2025-06-10 00:00:00" --until "2025-06-10 12:00:00" journalctl -u myservice -f -n 200 journalctl -k -b 0-u指定 unit,-f是实时跟踪,-k只看内核日志,-b 0表示本次开机以来的日志。生产环境最省心的是把时间窗口直接写在命令里,一次性拉出来再分析。如果发现日志文件越来越占空间,要检查 journald 的存储上限和轮转策略,配置文件在/etc/systemd/journald.conf,字段通常是 SystemMaxUse 和 RuntimeMaxUse。改完配置记得重启 journald 让它生效。
日志轮转方面,传统做法是 logrotate。它的原理是定期把当前日志改名、压缩、清理旧日志,避免单个日志文件无限增大。运维中最容易漏的不是配置 logrotate,而是在排障前忘了先确认日志有没有被轮转过。如果排查的是“凌晨三点的问题”,但日志文件从头到尾只有今天白天的内容,那多半是要去旧日志的 .gz 文件里找。查历史日志时用命令zgrep直接查 gzip 压缩文件,不用先解压再查。这个小小的区别,能把排障时间缩短一大截。
日志查得再熟,前面说的磁盘和文件系统问题还会卷土重来。尤其是磁盘扩容,很多人只在初始化机器时做一次,真正遇到容量不足时手生得厉害,所以下一章单独拿出来过一遍。
5. 磁盘扩容与文件系统维护:生产环境的扩容操作要按教科书来
磁盘相关操作最怕的是过程不可逆。某个生产分区满了,不是直接把新盘挂上去就完事,需要先分清楚当前磁盘用的是哪套体系:传统分区、LVM,还是文件系统直接挂整块盘。这里我用最常见的 LVM 场景来讲,因为它的灵活性最高,操作流也最完整。
5.1 先看清当前的盘面结构再动手
动手扩容前,先用命令看一遍当前磁盘和分区状况:
lsblk blkid pvdisplay vgdisplay lvdisplay dmesg | grep -i "sd.*new" | taillsblk用树状结构显示出磁盘、分区、卷组和逻辑卷的关系,一眼看清新增的盘叫什么名字,以及它有没有被加入卷组。pvdisplay、vgdisplay、lvdisplay三连是 LVM 体系的盘面总览,分别显示物理卷、卷组和逻辑卷的状态。新增磁盘正常情况下它在/dev/下面会出现一个新的盘符,但还没被纳入 LVM。判断新盘是否被内核识别还可以用ls /dev/sd*对比前后的设备列表,或者用上面的 dmesg 来确认。
5.2 LVM 扩容的一个完整操作流
假设我们已经有了一块新盘,名字叫/dev/sdb,要把现有卷组 vgdata 的逻辑卷 lvdata 扩容。完整的操作流程拆成这几步:
- 创建物理卷:
pvcreate /dev/sdb这一步是把裸盘初始化为 LVM 物理卷,会往磁盘头部写入元数据。如果磁盘上本来有旧分区或文件系统,先确认不是误操作。
- 加入卷组:
vgextend vgdata /dev/sdb卷组空间不足时这里会报错,报错就说明先前的 pvcreate 没成功,回查一下盘符对不对。
- 扩展逻辑卷并刷新文件系统:
lvextend -L +50G /dev/vgdata/lvdata resize2fs /dev/vgdata/lvdata如果文件系统是 xfs,命令要换成xfs_growfs /挂载点。这是两类文件系统最容易踩的坑:resize2fs 和 xfs_growfs 不能混用。建议在扩容前先执行df -T看清楚文件系统类型。xfs 不支持缩容,这一点尤其重要,规划的时候就要留足余量。
- 最后用
df -h和vgdisplay验证结果,确认容量已经体现,整个过程是可以在线完成的,不需要重启。但前面每一步都要谨慎核对盘符,因为pvcreate /dev/sdb一旦打错盘符,造成的后果很可能是灾难性的。
5.3 文件系统异常与磁盘硬件的自查思路
日常若怀疑文件系统出问题,常见现象包括:读写报 I/O error、目录卡顿、dmesg刷出大量异常块设备日志。先把 dmesg 内核日志拉出来看:
dmesg -T | grep -i "error\|i/o\|blk" | tail -30文件系统检查工具方面,ext4 系是 fsck,xfs 是 xfs_repair,但运行 fsck 前必须先卸载文件系统或者进入只读模式。生产环境直接对已挂载分区执行 fsck 会带来数据风险,这个技能点务必记牢。一个更轻量的做法是先用只读挂载的方式评估:
mount -o ro,remount /data如果分区本身已经读不到内容再考虑卸载检查,操作顺序和风险评估都要提前写在变更方案里。
磁盘硬件层面的健康监测我习惯部署 smartmontools,用 smartctl 读取 S.M.A.R.T. 数据。重点看几个属性,像 Reallocated_Sector_Ct、Current_Pending_Sector、Offline_Uncorrectable,这些数值一旦出现非零,基本说明盘在物理层就有坏道或者已有重映射,应该尽快安排数据迁移和换盘。查的时候直接跑:
smartctl -a /dev/sda smartctl -H /dev/sda-H是健康状态快检,-a是完整属性表。容量和硬件本身都没问题,还有一种容易被忽略的慢,是文件系统层单个目录文件数量爆炸,比如一个目录塞了几十万个静态文件,任何读取操作都会被拖垮。遇到这种情况就不是命令能解决的,基本要改造存储结构或引入分片目录方案。盘面问题处理完,平时没有故障时也不能放松,安全基线自查是运维里最容易欠账的一块,最后一章专门聊它。
6. 安全基线自查:这台服务器是不是已经被人动过
安全的日常工作不只是一年一次“等保检查”式的突击检查,而是在每次变更、每次异常发生前后都顺手过一遍。很多入侵迹象其实早就写在日志里、写在登录记录里,只是平时没人去看。
6.1 登录痕迹与异常账号排查
最先看的是最近登录成功的记录和失败的记录:
last | head -30 lastb | head -30 lastloglast读/var/log/wtmp,能看到最近谁从哪个 IP 登录、登录多久、是否还登着。lastb读/var/log/btmp,记录的是失败的登录尝试。如果发现大量来自陌生 IP 的失败尝试,就说明机器正在被扫描或者被暴力猜解,接下来要做的是临时屏蔽来源 IP、调整 SSH 配置。
登录当前在线用户用w或者who:
w who -uw会显示每个登录用户当前正在执行的命令,这是发现异常会话最直接的途径。再往下,排查系统里是否存在不该存在的账号,我习惯用这条命令看一眼所有能登录的账号:
awk -F: '$7 ~ /bash|sh$/ {print $1}' /etc/passwd如果一个普通业务机的 passwd 里多了个奇怪的 shell 账号,就要怀疑是不是被人留了后门。还可以定期核对 uid 为 0 的账号,理论上除了 root 之外不应该有第二个 uid 0 的账号:
awk -F: '$3==0 {print $1}' /etc/passwd6.2 端口暴露与防火墙规则的核对
查看端口是安全自查的另一条线。用 ss 把所有监听端口拉出来,逐个核对哪些端口是业务需要的、哪些根本不应该暴露:
ss -lntp iptables -L -n -v --line-numbers firewall-cmd --list-alliptables 查看时-n不做域名解析,-v显示详细计数,--line-numbers给规则编号方便后面删除或插入操作。现在很多机器用 firewalld 或自研网络策略,规则展示方式不同,但最终答案只有一个:对外只开放业务必须的端口,其余策略全部禁止。
这里有一个经常被忽略的细节:防火墙规则看的时候,除了看通配协议和端口,还要看每条规则的计数。如果一条规则从来没有命中过任何包,它很可能已经失去意义;如果按顺序匹配的规则顺序不对,后规则也可能永远不生效。规则顺序是防火墙的灵魂,调试时一定要先看--line-numbers,确定 insert 到哪一行,而不是随便追加到最后。
6.3 系统快照收集的注意事项
怀疑系统被入侵时,最忌讳在可疑机器上漫无目的地东点一下西点一下,那样会破坏现场、污染时间线。专业做法是第一时间做一次主机信息快照收集,能导出的尽量导出,再离线去分析。一个最基础的信息收集命令集大概包括这几类:
history lsof -i ss -a -n ss -lntp cat /etc/passwd cat /etc/crontab ls -la /tmp /var/tmp find / -name "*.so" -newer /tmp 2>/dev/null | head历史命令history要看,但也要意识到 history 是可以被修改的。检查 crontab 计划和系统定时任务,看有没有计划任务在拉取外部的可疑文件;查看 /tmp 和 /var/tmp 有没有异常的可执行文件。更完整的做法是借助文件指纹系统或审计工具,这里不展开。
安全自查做完整之后,还有一个更重要的环节:把这些排查动作沉淀成自动化脚本或者定期巡检任务。一周跑一次,输出给固定接收人,而不是每次都靠人去手工敲命令。自动化巡检不需要做得多重,先把最核心的登录异常、监听端口、关键文件时间戳这三样覆盖掉,就已经能挡住相当一部分隐患。
这一路下来,从第一屏异常诊断,到进程服务治理,再到网络排查、日志处理和磁盘扩容,最后到安全自查,几乎覆盖了一个 Linux 服务器运维日常可能遇到的八成场景。我自己这些年最深的一个体会是:命令本身背不住没关系,但要清楚每一类命令在什么场景下应该出现、按什么顺序出现。手册不是用来收藏的,是用来在故障现场迅速找到下一个动作的。最后再分享一个我长期受用的小细节:把那些“容易记混但极关键”的命令组合存到 shell 的 alias 或自己的笔记文件里,比如alias ports='ss -lntp'、alias topcpu='top -b -n 1 -o %CPU | head -20',减少紧急状态下手忙脚乱翻历史记录的概率。真正靠谱的运维,不是脑子里装了所有命令,而是知道在哪一刻该取出哪一把工具。