如何使用sshpass两次传递密码完成SSH登录及远程sudo操作
问题原因
原命令执行失败的核心问题有四个:
- 端口参数
-p 234放在了远程主机地址之后,SSH会把它识别为远程执行的命令参数,不会作为连接端口配置,默认会走22端口发起连接,大概率连不上目标服务器 - 管道后的
'sudo cat > /etc/apt/apt.conf'被单引号包裹,本地shell会把整段字符串当做可执行文件名,属于非法命令语法 - 即使去掉单引号,
sudo cat > /etc/apt/apt.conf也是在本地shell执行,没有被发送到远程服务器,本地普通用户无权限写入系统路径才会报Permission denied - 没有在远程SSH会话内触发sudo提权逻辑,根本不可能对远程的
/etc/apt/apt.conf执行写入操作
实现方法
通过sudo的-S参数即可实现非交互式密码传递:该参数会让sudo从标准输入流读取密码,不需要手动交互输入,配合sshpass就能同时完成SSH登录、sudo提权两次密码校验。
场景1:SSH登录密码与远程sudo密码一致(示例中均为pass123)
直接执行以下命令即可完成配置写入:
sshpass -p pass123 ssh -oStrictHostKeyChecking=no -p 234 user@10.10.4.4 'sudo -S tee /etc/apt/apt.conf > /dev/null' <<'EOL' Acquire::http::proxy "http://proxy.my.org.com:80"; Acquire::https::proxy "http://proxy.my.org.com:80/"; EOL
参数说明:
- 单引号包裹的整段内容会作为远程命令发送到服务器执行,避免重定向、通配符等特殊符号被本地shell提前解析
sudo -S会从SSH会话的标准输入读取密码,sshpass建立SSH连接时会自动填充登录密码,同密码场景下sudo可直接读取到密码完成提权- 用
tee代替cat >执行文件写入,解决sudo场景下重定向符权限不足的问题,> /dev/null用于屏蔽tee默认输出到终端的文件内容 - here-doc的分界符EOL加单引号,避免配置内容里的特殊符号被本地/远程shell展开
场景2:SSH登录密码与远程sudo密码不一致
如果SSH登录密码为pass123,sudo密码为独立值(示例为sudopass456),将密码传递逻辑放到远程会话内即可,命令如下:
sshpass -p pass123 ssh -oStrictHostKeyChecking=no -p 234 user@10.10.4.4 'echo "sudopass456" | sudo -S tee /etc/apt/apt.conf > /dev/null' <<'EOL' Acquire::http::proxy "http://proxy.my.org.com:80"; Acquire::https::proxy "http://proxy.my.org.com:80/"; EOL
安全提示:明文写密码的方式仅建议在临时测试、内网隔离环境使用,生产环境推荐配置SSH密钥登录+sudo免密白名单,避免密码明文泄露。
内容的提问来源于stack exchange,提问作者Chel MS
相关产品推荐
相关产品推荐

