从零构建Linux进程级安全防线
目录导读
- 第一章:为什么需要进程黑名单?——安全运维的最后一公里
- 第二章:核心设计思路——白名单、黑名单与动态策略
- 第三章:手把手编写脚本——基于PID与进程名的双重过滤
- 第四章:进阶技巧——结合systemd与crontab实现持久化防护
- 第五章:常见问题FAQ——kill不掉、误杀、权限不足怎么办?
第一章:为什么需要进程黑名单?——安全运维的最后一公里
在服务器安全体系中,防火墙(网络层)、文件权限(存储层)往往被重点部署,但进程层的管控常被忽略,设想一个场景:攻击者通过WebShell上传了xmrig挖矿程序,传统杀软未及时更新,此时唯一能阻止其占用CPU挖矿的手段,就是实时监测并强制终止该进程,进程黑名单脚本正是为了填补这一空白——它不是防御所有攻击,而是针对已知恶意进程、僵尸进程、或违规运行的业务进程(如开发环境下误启动的生产数据库)提供“秒级清理”能力。

核心价值:轻量、可控、不依赖云端病毒库,完全由运维人员自定义拦截规则,在谷歌SEO中,这类实操型内容常被检索为“linux kill process script”“process blacklist bash”,我们需覆盖这些长尾词。
第二章:核心设计思路——白名单、黑名单与动态策略
一个健壮的黑名单脚本不应只是pkill -9的简陋封装,而应具备三种模式:
- 静态黑名单:硬编码进程名(如
xmrig,cryptonight)。 - 动态黑名单:从外部文件(
/etc/blacklist.conf)读取列表,便于运维即时增删。 - 白名单保护:避免误杀核心服务(如
sshd,systemd),脚本逻辑应先去匹配白名单过滤,再匹配黑名单。
推荐策略:优先匹配进程名精确匹配,其次匹配命令行包含特定字符串(如-pool、--donate-level),最后匹配CPU使用率超阈值(如超过80%持续3秒),这种多级过滤可大幅降低误杀概率。
第三章:手把手编写脚本——基于PID与进程名的双重过滤
以下是一个进阶版Bash脚本示例(保存为process_guard.sh):
#!/bin/bash
# 进程黑名单守护脚本 v2.0
BLACKLIST_FILE="/etc/blacklist.conf"
WHITELIST=("sshd" "systemd" "nginx")
CPU_THRESHOLD=80
# 读取黑名单文件(每行一个进程名)
mapfile -t BLACKLIST < "$BLACKLIST_FILE"
# 遍历所有非内核进程
for pid in $(ps -eo pid,comm --no-headers | awk '$2 != "kthreadd" {print $1}'); do
if [ -d "/proc/$pid" ]; then
proc_name=$(cat /proc/$pid/comm 2>/dev/null)
proc_cmdline=$(tr '\0' ' ' < /proc/$pid/cmdline 2>/dev/null)
cpu_usage=$(ps -p $pid -o %cpu --no-headers | awk -F. '{print $1}')
# 白名单保护检查
skip=false
for wname in "${WHITELIST[@]}"; do
if [[ "$proc_name" == "$wname" ]]; then skip=true; fi
done
if $skip; then continue; fi
# 黑名单匹配:进程名或命令行
matched=false
for bname in "${BLACKLIST[@]}"; do
if [[ "$proc_name" == "$bname" ]]; then matched=true; fi
if [[ "$proc_cmdline" == *"$bname"* ]]; then matched=true; fi
done
# 动态条件:CPU超阈值且非白名单
if [[ "$cpu_usage" -gt $CPU_THRESHOLD ]]; then matched=true; fi
if $matched; then
echo "$(date +%F_%T) Killing $proc_name (PID:$pid) CPU:$cpu_usage"
kill -9 $pid
# 可选:记录日志到syslog
logger -t process_guard "Blocked process: $proc_name (PID:$pid)"
fi
fi
done
关键点说明:使用/proc文件系统而非ps grep可以避免误匹配(如grep自身被匹配),CPU阈值判断需注意取整问题,否则会频繁触发。
第四章:进阶技巧——结合systemd与crontab实现持久化防护
-
定时任务:在crontab中添加
*/1 * * * * /root/process_guard.sh实现每分钟扫描。 -
systemd服务(更稳健):
[Unit] Description=Process Guard [Service] ExecStart=/root/process_guard.sh WorkingDirectory=/root Restart=always RestartSec=10 [Install] WantedBy=multi-user.target
启用:
systemctl enable process_guard。 -
日志轮转:避免日志膨胀,可在脚本中追加
>> /var/log/process_guard.log,并使用logrotate管理。
第五章:常见问题FAQ——kill不掉、误杀、权限不足怎么办?
Q1:为什么我的黑名单脚本杀不掉"僵尸进程"?
A:僵尸进程(Z状态)已无法被kill -9终止,其父进程需释放资源,脚本应额外检测状态:
stat=$(cat /proc/$pid/stat | awk '{print $3}'),若为Z,则记录并通知父进程(ps -o ppid= -p $pid)让其处理。
Q2:误杀合法进程如何快速恢复?
A:在脚本中加入--dry-run模式(仅打印不执行),先测试规则再启用到生产,同时在白名单中严格放行数据库、核心业务程序。
Q3:执行kill报"Operation not permitted"?
A:检查当前用户权限,脚本需以root运行,或用setcap cap_kill=ep赋予特定二进制,若是容器环境,需确保宿主机权限足够。
Q4:黑名单文件格式对空格敏感吗?
A:是的,推荐每行一个进程名,不要有尾随空格,如果进程名含空格(如Java Web Start),建议在脚本中用精确匹配$(cat /proc/$pid/comm),该接口不会包含空格截断问题。
编写进程黑名单脚本的核心在于灵活的匹配规则与防御性编程,从简单的pkill到结合CPU、命令行、白名单的三维过滤,每一步都降低误杀风险,配合systemd守护,能形成一套闭环的进程级安全防护体系,这在恶意挖矿、反弹Shell等攻击频发的当下,是一项性价比极高的运维技能,请务必先在测试环境运行--dry-run,再逐步推向生产。