支持通配符SSL证书、多域名证书、IP证书。适配ACME接口, 支持Zerossl、Let's Encrypt和Google等渠道。登录已有账号
2026-10-04 04:00:44 Linux auditd inotify 运维排障 安全审计 conda
早上到公司,好几个人反馈 conda 用不了,报 command not found。
第一反应是 PATH 没加载上去,结果去 /home/software/anaconda3/etc/profile.d/ 看了一眼,conda.sh 没了。
文件确实没了,但 Linux 不会主动告诉你谁删的。这不算设计缺陷,内核默认的审计规则只覆盖登录、提权、权限变更那一类安全事件,unlink 这种文件系统操作默认不记。想追责就得自己提前把监控铺好,事后现装工具是一点用没有的。
ls -l /home/software/anaconda3/etc/profile.d/conda.sh
返回 No such file or directory 只能证明现在不存在。判断是删除、移动、还是整个目录被替换,三种情况排查方向完全不一样。
看一下父目录的状态:
stat /home/software/anaconda3/etc/profile.d/
目录的 mtime 变了,说明这里面确实发生过增删。如果文件没了但目录 mtime 纹丝不动,那大概率不是简单删除,可能是挂载覆盖。
这种情况我碰到过一次,有人把空目录 bind mount 到目标路径,ls 看着是空的,实际文件还在底层躺着:
findmnt | grep profile
真撞上了就 umount 掉,东西直接回来了。概率不高,但花十秒钟排除一下不亏。
inotify 和日志都做不到这一点。auditd 是唯一能落到系统调用层面、并且带上 uid 的方案。
先确认在不在:
systemctl status auditd
auditctl -s
auditctl -s 输出里的 enabled 字段,0 是没开,1 是开着,2 是开着且锁定不允许改规则。
没装就装上:
sudo apt-get install auditd # Debian / Ubuntu
sudo yum install audit # CentOS / RHEL
加监控规则:
sudo auditctl -w /home/software/anaconda3/etc/profile.d/ -p wa -k conda_file_delete
-w 跟路径,-p wa 里的 w 是写入、a 是属性变更,删除行为会落在这两类里。-k 是打关键字,后面靠它检索。
这里有个坑很容易绕进去:-w 监控的是 inode,不是路径字符串。文件已经被删的情况下你现在加规则,只能监控到"将来在这个目录里新建的同名文件"。已经发生的事,auditd 补不回来。
所以这条规则的价值全在"下一次"。
想要更精准,直接抓系统调用:
sudo auditctl -a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat \
-F dir=/home/software/anaconda3/etc/profile.d/ -k conda_del
只抓删除和改名,不抓普通写入,日志量小一个数量级。
代价是 -F dir 只匹配当前这一层,子目录里的动作抓不到。要覆盖子目录就把 -F dir 去掉,噪音会大很多。
我一般两条换着用:定位阶段用 -w 广撒网,范围摸清之后换成 syscall 规则长期挂着。
sudo ausearch -k conda_file_delete
输出里几行是关键:
time->Sun Sep 13 09:41:22 2026
uid=0 auid=1003
exe="/usr/bin/rm"
name="/home/software/anaconda3/etc/profile.d/conda.sh"
auid 是登录时的原始 uid,uid 是执行时的实际 uid。有人 su 到 root 再删,uid 会显示 0,但 auid 还是他自己的账号。查人只看 auid。
auid 是 4294967295(也就是 -1)的话,说明这个进程不是从登录会话发起的,cron 任务、systemd service、容器里的进程都会是这个值。
这种情况得换个方向,去翻 crontab 和服务单元文件。
exe 字段告诉你用什么删的。/usr/bin/rm 是命令行直接删;如果是 python 或者某个脚本路径,就顺着 ppid 往上追,父进程才是真正的问题来源。
排查时加上时间范围能省不少事:
sudo ausearch -k conda_file_delete -ts yesterday
sudo ausearch -k conda_file_delete -ts 09/10/2026 08:00:00 -te 09/13/2026 20:00:00
auditctl 加的都在内存里,重启即失效。持久规则写到 /etc/audit/rules.d/audit.rules,然后:
sudo augenrules --load
这里有个反直觉的地方:systemctl restart auditd 经常报 refused。auditd 本身就被设计成不能随便停,改规则用 augenrules 加载就行,不用动进程。
auditd 常驻但很多机器默认没有。临时蹲一次,inotify 上手快得多。
sudo apt-get install inotify-tools
inotifywait -m /home/software/anaconda3/etc/profile.d/ --format '%w%f %e' --event delete
-m 是持续监听,不加的话抓到一次就退出。
--event 建议把 delete、delete_self、moved_from、moved_to 都写上,只写 delete 的话,文件被 mv 走这种情况就漏了,而 mv 在用户看来同样是"文件没了"。
inotify 的局限得很清楚:只看到启动之后的事,没有任何追溯能力,输出里也没有 uid,只有路径和事件类型。
它适合"这个文件老是被删,我蹲在这儿等下一次",不适合事后追责。
还有个报错挺坑的:监听的目录树一大,会报 No space left on device,跟磁盘一点关系没有,实际是 /proc/sys/fs/inotify/max_user_watches 打满了,默认通常 8192。调大就行:
echo 'fs.inotify.max_user_watches=524288' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
sudo grep -i "conda.sh\|profile.d" /var/log/syslog /var/log/auth.log
sudo journalctl _COMM=sudo --since "2026-09-10" | grep rm
删系统目录基本绕不开 sudo,所以 auth.log 里的提权记录通常能锁定时间段和人。
bash history 只能当辅助证据。
它默认不带时间戳(除非设了 HISTTIMEFORMAT),用户自己一条 history -c 就清掉了,而且是退出终端时才写盘,非正常退出的会话会整段丢。就算翻到 rm 记录,也得跟日志时间对得上才算数。
再说一层:如果审计日志本身就在同一台机器上,能删文件的人同样能删 /var/log/audit/audit.log。所以稍微认真一点的做法是把日志外送,auditd 自带的 audisp-remote 可以直连集中日志服务器,简单点就用 rsyslog 转发。
顺带提一句我们踩过的坑。日志外发一开始走的内网 HTTP,后来挪到公网入口改成 HTTPS。证书这块我现在用 lcjmSSL,免费申请,多域名、泛域名和 IP 证书都支持,底层是 Let's Encrypt、Google Trust Services、ZeroSSL 这几家,API 对接 ACME 做自动续期,基本不用管。之前手动管证书吃过一次亏,半夜三点服务全挂,排查半小时才发现是证书过期。
日志链路上任何一环断掉,前面审计规则配得再全也是白搭,这块值得单独花点时间做稳。
conda.sh 比较好办,它是 conda 初始化时生成的脚本,内容跟 conda 版本绑定。同版本的另一台机器 scp 一份过来最省事,或者让 conda 自己重新生成:
/home/software/anaconda3/bin/conda init bash
如果整个 anaconda3 目录都残缺了,conda init 也不顶用,那就重装 miniconda 到同一路径再 init 一次。
没备份也没同环境机器的话别硬找了。conda.sh 不在 conda 的包缓存里,pkgs 目录下翻不到的,它是安装时生成的,只能靠 init 重建。
权限收紧是最基本的:
sudo chmod 644 /home/software/anaconda3/etc/profile.d/conda.sh
sudo chown root:root /home/software/anaconda3/etc/profile.d/conda.sh
但这招挡不住大多数情况——只要目录本身可写,文件照样能删。真要防死,得用不可变属性:
sudo chattr +i /home/software/anaconda3/etc/profile.d/conda.sh
sudo lsattr /home/software/anaconda3/etc/profile.d/conda.sh
加了 i 之后 root 也删不掉,得先 chattr -i 解除。代价是 conda 更新时也会失败,升级前记得手动解一下。
另外容器里 chattr 不一定生效,部分 overlayfs 不支持 i 属性,上线前先测。
多人共享的服务器上,更实际的做法是把这类目录纳入配置管理,用 ansible 或者一个 git 仓库做基线,删了自动恢复,顺带触发一条告警。
追责终究是事后手段,让文件删了能自己长回来,才是真正省心的状态。
分享三种查看Linux系统用户列表的方法,包括读/etc/passwd、用getent以及bash内建的compgen,附踩坑提醒和场景选择建议。
碰到 ./ndt: error while loading shared libraries 这种报错,从确认库文件是否存在、配置 LD_LIBRARY_PATH,到装包、ldd 查依赖、ldconfig 重建缓存,一次说清排查顺序。
本文深入探讨Linux系统下多种包管理工具(如APT、YUM、DNF、RPM)的软件卸载命令与最佳实践。从命令语法到配置文件处理,再到手动安装软件的清理技巧,提供一站式解决方案,确保系统纯净高效。
手把手教你如何在Linux环境下,为知行之桥(CData Arc)设置HTTPS,并通过自动化脚本和`cron`定时更新SSL证书,告别证书过期噩梦。