当前位置:首页 > 时尚

shell脚本加密后可执行

我在生产环境里干过一件蠢事:把数据库密码明文写在shell脚本里,本加然后chmod 755扔到服务器上。密后后来安全扫描报告出来,可执红字标得刺眼。本加改吧,密后可脚本还得跑,可执密码还得用。本加于是密后我开始琢磨怎么给shell脚本加密——不是混淆,是可执真正的加密,但加密后还得能执行。本加

先说结论:shell脚本没有官方加密方案,密后但有三条野路子能走通。可执第一条,本加用gzexe,密后系统自带的可执家伙。它把脚本压缩后塞进一个自解压的壳里,执行时自动解压到临时目录跑。缺点?解压出来的临时文件是明文,root用户能直接读。但对付普通运维足够了,毕竟大多数人不会去翻/tmp。

第二条路,用openssl做对称加密,然后写个包装器。思路很简单:把真正的脚本用AES加密成二进制文件,再写一个几十行的启动器,运行时解密到内存管道里执行。关键在细节——解密后的内容不能落盘,得直接喂给bash。我试过用命名管道,但进程管理麻烦;最后用进程替换,bash <(openssl enc -d -aes-256-cbc -in script.enc -pass pass:xxxx),干净利落。

第三条路最硬核,用shc把脚本编译成C源码再gcc。这东西会把脚本内容转成C字符串常量,然后编译进二进制。执行时,二进制内部会解密还原脚本内容。但shc有个致命伤——它用的是异或加密,密钥藏在二进制里,有人用strings就能翻出来。我做过测试,一个十行的脚本,shc编译后二进制里能直接看到关键变量名。所以shc适合防君子不防小人,适合内部系统防误看,不适合对抗恶意逆向。

选哪条路,取决于你的威胁模型。如果你只是不想让同事一眼看到密码,gzexe够了。如果脚本里有云厂商的API密钥,而且服务器可能被横向渗透,那必须用openssl方案,密钥单独放在只有root能读的文件里。至于shc,我建议只用来处理那些需要分发给客户、但不想暴露实现细节的脚本——毕竟客户不会闲到去逆向你的部署脚本。

实际操作中还有个坑——加密后脚本的调试。明文脚本能加set -x看执行过程,加密后这招废了。我的土办法是留一个带详细日志的明文版本在开发机,线上只放加密版。每次改逻辑,先在开发机跑通,再加密上线。麻烦是麻烦点,但总比裸奔强。

最后提醒一句:加密不是安全边界。真正的秘密应该放在密钥管理系统或环境变量里,脚本里只留引用。我见过有人费劲加密了整个脚本,结果脚本开头就export AWS_SECRET_KEY="xxx"——加密了个寂寞。脚本加密只是增加读取成本,别指望它挡住铁了心的攻击者。你的目标应该是让90%的同事不会顺手看到密码,让10%的恶意者需要花半小时才能拿到——这就够了。

分享到: