核心是源头杜绝明文密码:禁写死密码,改用权限严格(0400/0600)的独立凭据文件、环境变量临时传递、交互式关闭回显输入、历史与进程隔离控制,并优先以ssh密钥替代密码认证。

运维脚本中过滤敏感信息、防止密码泄露,核心不是“事后擦除”,而是“从源头杜绝明文出现”。关键在于让密码不落地、不入命令行、不进历史、不被进程窥见。
密码绝不写死或拼接在命令里
禁止在脚本中直接写 ssh -p 'mypass' user@host 或 mysql -uroot -pmypass。这类写法会让密码暴露在 ps aux、bash_history、系统日志甚至脚本备份中。
- 用
sshpass -f /path/.pass:密码存独立文件,创建后立即执行chmod 0400 /path/.pass - 用
SSHPASS="xxx" sshpass -e ssh ...; unset SSHPASS:环境变量仅临时存在,且执行完立刻清空 - 数据库连接改用配置文件,如
~/.my.cnf,权限同样设为0600,内容含[client] password=xxx
交互式输入必须关闭回显
若需人工输入密码(如调试或临时场景),不能用 read PASSWORD——它会在终端显示输入内容。
- 先执行
stty -echo关闭终端回显 - 再用
read -s -p "Password: " PASSWORD - 最后务必恢复:
stty echo,否则终端会“失声” - 输入完成后,不打印、不记录、不拼接到命令字符串中,直接传给 expect 或 sshpass 的 stdin
历史记录与进程可见性要主动控制
即使密码没写进脚本,也可能意外留在 shell 历史或进程参数里。
- 在
~/.bashrc中设置HISTCONTROL=ignorespace,之后所有以空格开头的命令(如mysql -u root -p)不会记入 history - 用
history -d $(history 1 | awk '{print $1}')删除上一条命令(适合误输后立即补救) - 批量操作时加
setsid启动脚本,使其脱离当前终端会话,降低被ps --forest关联识别的风险
优先用密钥替代密码认证
这是最根本的防护手段——没有密码,就不存在泄露问题。
- 生成密钥:
ssh-keygen -t ed25519 -f ~/.ssh/opkey -N "" - 部署公钥:
ssh-copy-id -i ~/.ssh/opkey.pub opuser@host - 启用 agent:
eval $(ssh-agent); ssh-add ~/.ssh/opkey(可配合keychain持久化) - 后续脚本直接调用
ssh opuser@host cmd,无需任何密码处理逻辑











