编写Cron定时脚本:保留localhost的同时终止其他SSH连接进程
我来帮你搞定这个问题——之前的命令一刀切杀掉所有带ssh的进程确实会误杀本地连接,咱们得精准定位那些外部主机的SSH连接进程才行。这里有两个靠谱的方案,你可以按需选:
方案1:通过环境变量筛选远程SSH进程
当远程主机通过SSH连接到你的机器时,对应的sshd子进程会携带SSH_CLIENT环境变量,值就是远程主机的IP和端口;而本地连接(比如localhost)或者sshd主进程要么没有这个变量,要么变量值是127.0.0.1。利用这个特性就能精准筛选:
# 筛选非本地的远程SSH连接进程并终止 ps -ef e | grep '[s]shd' | grep -v 'SSH_CLIENT=127.0.0.1' | awk '{print $2}' | xargs --no-run-if-empty kill -9
各部分的作用:
ps -ef e:列出所有进程并显示它们的环境变量grep '[s]shd':精准匹配sshd进程(避免grep自身被误匹配)grep -v 'SSH_CLIENT=127.0.0.1':排除本地连接的进程awk '{print $2}':提取进程ID(PID)xargs --no-run-if-empty kill -9:只有存在要杀的进程时才执行kill,避免无进程时报错
如果需要保留多个本地/内网IP,比如192.168.1.100,只要修改排除规则就行:
ps -ef e | grep '[s]shd' | grep -v -E 'SSH_CLIENT=(127.0.0.1|192.168.1.100)' | awk '{print $2}' | xargs --no-run-if-empty kill -9
方案2:通过网络连接状态筛选
另一种思路是直接查看SSH的网络连接,找出远程IP不是本地回环的连接,再定位对应的进程ID:
# 找出远程SSH连接的进程ID并终止 ss -tulpn | grep 'sshd' | grep -v '127.0.0.1' | awk '{split($7, pid_part, "pid="); split(pid_part[2], pid, ","); print pid[1]}' | xargs --no-run-if-empty kill -9
各部分的作用:
ss -tulpn:列出所有TCP/UDP连接,显示进程名称和PIDgrep 'sshd':筛选sshd相关的连接grep -v '127.0.0.1':排除本地回环的连接awk ...:从输出中拆分出PID(输出格式类似pid=1234,fd=5,所以提取出1234)xargs --no-run-if-empty kill -9:安全执行kill,避免空输入报错
写成Cron定时脚本的注意事项
- 用绝对路径:Cron的PATH环境变量非常有限,为了避免命令找不到,最好把所有命令换成绝对路径(可以用
which ps查看命令路径)。 - 加日志记录:方便排查问题,比如记录执行时间和错误信息。
- 先手动测试:确保脚本不会误杀本地进程后再加入Cron。
这里给你一个完整的脚本示例:
#!/bin/bash # 远程SSH连接清理脚本 LOG_FILE="/var/log/ssh_cleanup.log" # 记录开始时间 echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting SSH cleanup..." >> $LOG_FILE # 执行清理(这里用方案1的命令,换成绝对路径) /usr/bin/ps -ef e | /usr/bin/grep '[s]shd' | /usr/bin/grep -v 'SSH_CLIENT=127.0.0.1' | /usr/bin/awk '{print $2}' | /usr/bin/xargs --no-run-if-empty /usr/bin/kill -9 2>> $LOG_FILE # 记录结束时间 echo "[$(date '+%Y-%m-%d %H:%M:%S')] Cleanup completed." >> $LOG_FILE
接下来添加Cron任务:
- 执行
crontab -e编辑定时任务 - 比如要每天凌晨2点执行,添加一行:
0 2 * * * /path/to/your/ssh_cleanup.sh
(把/path/to/your/换成你的脚本实际路径)
内容的提问来源于stack exchange,提问作者jintek
相关产品推荐
相关产品推荐

