遇到一个需求,要求 a 切换到 b 用户执行一些操作,但是 b 用户的目录等不能授权给 a 访问。探索一番具体有下列方式。
第一次尝试
方案
在 b 用户下建立脚本 target.sh
,a 用户下建立一个中间脚本脚本 helper.sh
,在 helper.sh 中通过 su 命令切换用户过去,而 su 命令需要输入密码的过程,当然,b 用户的密码是不能暴露给 a 的。
编写 helper.sh 内容如下:
1 | !/bin/bash |
利用 expect 去为我们输入密码,所以脚本中调用了 helper.exp,内容如下:
1 | !/usr/bin/expect -f |
要将用户密码传入 expect 的执行脚本内,由于无法对 expect 文件进行二进制加密,所以将密码保存在 helper.sh 内,在执行时通过参数传入 expect 内。
随后通过 shc 进行加密,helper.sh 被编译为二进制执行文件,保存其中的明文密码无法被查看。
问题
通过这种方式乍看很完美,但是在实际的执行过程中发现,在运行脚本的过程中输入 ctrl+z
发出中断信号,执行会停止,停留在 a 用户的执行环境中。这样 b 用户就获得了 a 用户的环境,前功尽弃了。
后来尝试在脚本中捕获中断信号,在 shell script 中添加:
1 | trap "" SIGINT |
仍无法解决,它只能忽略 shell 中的中断信号,而我们调用了 expect,无法处理。
查询 expect 的用法,发现了类似的语法:
1 | trap SIG_IGN { SIGINT SIGHUP SIGQUIT} |
但是在 exp 中配置 trap SIG_IGN SIGINT
无效果,不知原因,因而此方案废弃,改用第二种方案。
第二次尝试
方案
既然 expect 会有中断的问题,那么就只能避免使用 expect,想到使用 ssh 来进行登陆和验证。
添加 b 用户的公钥到 a 用户认证文件,这样 b 用户可以使用密钥登陆 a 用户。为了保证 b 用户无法在脚本外登陆到 a 用户,所以这里的密钥生成过程中需要密码。密码保留,这样就可以避免此问题。
这里又回到了交互式输入密码的问题上,既然 expect 是不可行的,那就只能寻找其它方案。查找资料发现了 sshpass 这个工具,它能帮助我们在 ssh 登陆中输入明文密码。
用法:
1 | sshpass -p password ssh a@localhost |
不过我这里输入后无响应,随后发现 sshpass 只能响应密码输入,无法响应加密密钥的密码输入。
回到原点,撤销密钥登陆,仍旧使用密码登陆。随意 helper.sh 可以这样写:
1 | !/bin/bash |
使用 shc 加密,密码同样可以被保护。
不足
这里为了实现功能引入了额外的软件 sshpass,网上不建议将该软件用于生产环境,容易引发安全问题。所以尽可能使用 Linux 自带的命令来实现,就有了第三次尝试。
第三次尝试
方案
思路同第二种方法一样,都是将密码传入保留,不同的是这里用到了内置的 sudo 命令而不需要安装 sshpass。
将第二种方案最后一行改写一下:
1 | !/bin/bash |
sudo 命令的 -S 选项可以接受一个标准输入作为密码传递,同样的可以被加密,实现功能。
有一个不足是自带的 sudo 命令会有一个默认的超时时间,在该事件内使用 sudo 命令无需输入密码,使用者第一次执行后在一段时间内是可以用 sudo 去执行任何操作的,这是危险的。所以要配置为每次执行 sudo 命令都输入密码。
用 root 用户执行 visudo
,找到下列行:
1 | Defaults env_reset |
将其修改为:
1 | Defaults env_reset,timestamp_timeout=0 |
这样每次执行 sudo 都需要输入密码了,保证了安全。
不足
这种方式的不足在于更改了 sudo 的默认行为,每次都需要输入密码,对其它用户来讲操作不便。
第二个不足就是在输出结果时,返回的结果会同密码输入提示在同一行:
1 | [b@localhost ~]$ ./helper test test |
显示效果不美观,待解决。
SHC 加密的注意事项
在某一平台上通过 shc 加密生成的二进制文件是动态链接形式,因而在其它平台无法运行。在其它平台运行可能导致服务器宕机。
可以通过下面的方法生成静态链接的二进制可执行文件:
1 | CFLAGs=-static shc -r -f helper.sh |
参考
- http://blog.csdn.net/boyishachang/article/details/8677936
- http://blog.csdn.net/xushx_bigbear/article/details/12966625
- https://sourceforge.net/projects/sshpass/
- https://www.cnblogs.com/yuzhoushenqi/p/6950425.html
- http://www.datsi.fi.upm.es/~frosal/sources/
-EOF-