pexpect 和 ssh:如何在 su - root -c 之后格式化一串命令

2024-05-04

我正在尝试迭代服务器和密码列表来更改一组服务器上的 sshd 配置,以便我可以使用无密码 SSH 密钥通过 root 登录/运行命令。

我可以在 bash 中轻松完成此操作,但我正在尝试学习 Python 并且(显然)希望放弃手动输入密码。

这是我想做的事情:

scp ~/.ssh/id_rsa.pub /etc/ssh/sshd_config USER@IP:/tmp/

ssh -o StrictHostKeyChecking=no -t USER@IP "su - root -c \"chown root:root /tmp/id_rsa.pub; chmod 600 /tmp/id_rsa.pub; chown root:root /tmp/sshd_config; mkdir /root/.ssh; chown root:root /root/.ssh; chmod 700 /root/.ssh; mv /tmp/id_rsa.pub /root/.ssh/authorized_keys; mv /tmp/sshd_config /etc/ssh/; service sshd reload\""

我已经接近用 pexpect 在 Python 中做到这一点:

import pexpect

USER="user"
HOST="192.168.1.1"
USERPASS="userpass" 
ROOTPASS="rootpass"

COMMAND1="scp /Users/user/.ssh/id_rsa.pub /Users/user/github/ssh-pexpect/sshd_config %s@%s:/tmp/" % (USER, HOST)

COMMAND2="ssh -o StrictHostKeyChecking=no -t %s@%s \"su - root -c \"chown root:root /tmp/id_rsa.pub; chmod 600 /tmp/id_rsa.pub; chown root:root /tmp/sshd_config; mkdir /root/.ssh; chown root:root /root/.ssh; chmod 700 /root/.ssh; mv /tmp/id_rsa.pub /root/.ssh/authorized_keys; mv /tmp/sshd_config /etc/ssh/; service sshd reload\"\"" % (USER, HOST)

child = pexpect.spawn(COMMAND1)
child.expect('password:')
child.sendline(USERPASS)
child.expect(pexpect.EOF)
print child.before

child = pexpect.spawn(COMMAND2)
child.expect('password:')
child.sendline(USERPASS)
child.expect('Password:')
child.sendline(ROOTPASS)
child.expect(pexpect.EOF)
print child.before

当我运行 COMMAND1 (scp'ing) 时工作​​正常。 但 COMMAND2 失败:

server1:ssh-pexpect user$ python test4.py 

id_rsa.pub                                    100%  410     0.4KB/s   00:00    
sshd_config                                   100% 3498     3.4KB/s   00:00    

Traceback (most recent call last):
  File "test4.py", line 25, in <module>
    child.expect(pexpect.EOF)
  File "/Library/Python/2.7/site-packages/pexpect.py", line 1316, in expect
    return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
  File "/Library/Python/2.7/site-packages/pexpect.py", line 1330, in expect_list
    return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize)
  File "/Library/Python/2.7/site-packages/pexpect.py", line 1414, in expect_loop
    raise TIMEOUT (str(e) + '\n' + str(self))
pexpect.TIMEOUT: Timeout exceeded in read_nonblocking().
<pexpect.spawn object at 0x102b796d0>
version: 2.4 ($Revision: 516 $)
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '-o', 'StrictHostKeyChecking=no', '-t', '[email protected] /cdn-cgi/l/email-protection', 'su - root -c chown', 'root:root', '/tmp/id_rsa.pub;', 'chmod', '600', '/tmp/id_rsa.pub;', 'chown', 'root:root', '/tmp/sshd_config;', 'mkdir', '/root/.ssh;', 'chown', 'root:root', '/root/.ssh;', 'chmod', '700', '/root/.ssh;', 'mv', '/tmp/id_rsa.pub', '/root/.ssh/authorized_keys;', 'mv', '/tmp/sshd_config', '/etc/ssh/;', 'service', 'sshd', 'reload']
searcher: searcher_re:
    0: EOF
buffer (last 100 chars): : Permission denied
mv: try to overwrite `/etc/ssh/sshd_config', overriding mode 0600 (rw-------)? 
before (last 100 chars): : Permission denied
mv: try to overwrite `/etc/ssh/sshd_config', overriding mode 0600 (rw-------)? 
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 3612
child_fd: 4
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

如果我在运行脚本之前删除远程服务器上的 /etc/ssh/sshd_config 文件,我会得到:

server1:ssh-pexpect user$ python test4.py  
id_rsa.pub                                    100%  410     0.4KB/s   00:00    
sshd_config                                   100% 3498     3.4KB/s   00:00    


chown: missing operand
Try `chown --help' for more information.
chown: changing ownership of `/tmp/sshd_config': Operation not permitted
mkdir: cannot create directory `/root/.ssh': Permission denied
chown: cannot access `/root/.ssh': Permission denied
chmod: cannot access `/root/.ssh': Permission denied
mv: accessing `/root/.ssh/authorized_keys': Permission denied
mv: cannot move `/tmp/sshd_config' to `/etc/ssh/sshd_config': Permission denied
bash: service: command not found
Connection to 192.168.1.1 closed.

我什至不知道如何调试它以查看它哪里出了问题。不过,我认为它没有正确解析 COMMAND2 。 对 Python 来说还很陌生,所以任何建议都会受到赞赏。 谢谢。


您将 COMMAND2 放在双引号中,并正确转义任何嵌入的双引号,但您还需要对任何已转义的双引号进行双转义。换句话说,这并不是真正的 Python 问题。不过,您可以将最外面的引号切换为 Python 三引号。它也会更容易阅读。

Edit:实际上,对引用进行任何适当的消歧就可以了。由于 shell 也提供单引号,因此使用单引号的解决方案就很好。 Python 允许您使用单引号或许多其他引用工具,如果您还没有解决问题,我会建议您使用单引号(因为这样您就可以选择不需要对字符串本身进行任何更改的引号;更少的空间)错误)。

所以,其中任何一个都应该没问题:

COMMAND2='ssh -o StrictHostKeyChecking=no -t %s@%s "su - root -c \"chown root:root /tmp/id_rsa.pub; chmod 600 /tmp/id_rsa.pub; chown root:root /tmp/sshd_config; mkdir /root/.ssh; chown root:root /root/.ssh; chmod 700 /root/.ssh; mv /tmp/id_rsa.pub /root/.ssh/authorized_keys; mv /tmp/sshd_config /etc/ssh/; service sshd reload\""' % (USER, HOST)

COMMAND2="""ssh -o StrictHostKeyChecking=no -t %s@%s "su - root -c \"chown root:root /tmp/id_rsa.pub; chmod 600 /tmp/id_rsa.pub; chown root:root /tmp/sshd_config; mkdir /root/.ssh; chown root:root /root/.ssh; chmod 700 /root/.ssh; mv /tmp/id_rsa.pub /root/.ssh/authorized_keys; mv /tmp/sshd_config /etc/ssh/; service sshd reload\"" """ % (USER, HOST)

COMMAND2="ssh -o StrictHostKeyChecking=no -t %s@%s 'su - root -c \"chown root:root /tmp/id_rsa.pub; chmod 600 /tmp/id_rsa.pub; chown root:root /tmp/sshd_config; mkdir /root/.ssh; chown root:root /root/.ssh; chmod 700 /root/.ssh; mv /tmp/id_rsa.pub /root/.ssh/authorized_keys; mv /tmp/sshd_config /etc/ssh/; service sshd reload\"'" % (USER, HOST)

我需要在三引号中添加一个空格,以便消除相邻双引号的歧义。但您可以使用三个单引号代替。此外,三引号(单引号或双引号)允许您嵌入换行符,从而显着提高易读性:

COMMAND2='''ssh -o StrictHostKeyChecking=no -t %s@%s "su - root -c '
    chown root:root /tmp/id_rsa.pub
    chmod 600 /tmp/id_rsa.pub
    chown root:root /tmp/sshd_config
    mkdir /root/.ssh
    chown root:root /root/.ssh
    chmod 700 /root/.ssh
    mv /tmp/id_rsa.pub /root/.ssh/authorized_keys
    mv /tmp/sshd_config /etc/ssh/
    service sshd reload'"''' % (USER, HOST)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pexpect 和 ssh:如何在 su - root -c 之后格式化一串命令 的相关文章

随机推荐

  • 为什么这个 C++ STL 分配器不分配?

    我正在尝试编写一个派生自的自定义 STL 分配器std allocator 但不知何故所有的电话allocate 去基础班 我已将范围缩小到以下代码 template
  • 创建持久身份验证 cookie 时出现问题:ASP.NET MVC

    好的 这是我创建身份验证 cookie 的代码 get user s role List
  • 找出右键单击的 DOM 元素

    我使用以下代码片段来构建自定义上下文菜单
  • AudioTrack 可以播放 MIDI 文件吗?

    我想知道AudioTrack Android可以播放MIDI文件吗 如果没有的话哪个库可以 因为我想要 Android 库 可以为我的应用程序播放和控制 MIDI 文件的速度 从这里检查 Android 支持的媒体格式Android 媒体支
  • NodeJS + Express + Mongo 会话存储

    我目前在尝试在 MongoDb 中存储会话时遇到了很大的麻烦 我尝试过express session mongo和connect mongodb 当我尝试加载登录页面时 两者都给出了相同的 500内部服务器错误 这让我觉得也许在某个地方与
  • 使用 Poppler Qt4 C++

    我需要在我的应用程序中使用 pdf 查看器库 我使用 C 和 QT 我下载了Poppler http poppler freedesktop org 和代码示例Poppler Qt4 界面库 http people freedesktop
  • 从应用程序访问 iCloud Drive 文件

    我希望我的应用程序支持 iCloud 以便我可以存储和获取 PDF 文件 我的问题是 如何在不使用 iCloud 的情况下访问 iCloud 驱动器文件UIDocumentPickerViewController 实际上我想在我的应用程序中
  • 如何以编程方式检测我的应用程序是否在 ASP.NET 页面中以 IIS 7.0 集成模式运行

    一般来说 我们应该控制我们的 AppPools 并能够强制使用托管管道模式 就我而言 我没有控制权 并且希望根据托管管道模式 集成与经典 以稍微不同的方式实现代码背后的代码 我只是不知道如何检测到这一点 有没有一种简单的方法可以从代码隐藏页
  • 使用 MapBox GL JS 无需访问令牌

    有没有办法使用MapBox GL JS没有访问令牌 我在文档中找不到任何提示MapBox GL JS https docs mapbox com mapbox gl js api 然而 Uber建议是可以通过他们的图书馆 https ube
  • 如何设置 MPEG-4 文件的“媒体创建”日期

    我有许多从各种数码相机格式转码的 MPEG 4 文件 其文件系统修改日期是正确的 我想设置 媒体创建 标签来匹配 这可以通过 属性 窗口的 详细信息 选项卡在 Windows 资源管理器中手动完成 设置 媒体创建 非常有用 因为 Windo
  • 强制 WcfSvcHost.exe 使用我的自定义服务主机

    是否可以强制 WcfSvcHost 当我执行 F5 或在解决方案中调试另一个项目时自动执行 使用自定义 ustom 服务 通过使用服务工厂 我的自定义服务主机在我的 asp net 主机容器中运行良好 该服务工厂又调用自定义服务库 但是当
  • 使用 ExecuteSqlCommand 调用存储过程(需要未提供的参数)

    我正在尝试使用 EF 调用存储过程context Database ExecuteSqlCommand因为我的参数之一是数据表 以下是该过程的参数 ALTER PROCEDURE mySchema myProc customerId INT
  • 由于 MSVCR110.dll,MS Visual Studio 2012 Ultimate 无法启动

    当我尝试运行 MVS 2012 时 我总是收到错误 在库 DLL MSVCR110 dll 中找不到过程 crtCreateSymbolicLinkW 的入口点 我已经从我的另一台计算机复制了这个 dll 文件 一切正常 但没有帮助0 o
  • 实现自己的“工厂”以重用 WPF 中的视图

    我目前正在使用WAF WPF 应用程序框架 http waf codeplex com discussions 361216用于 WPF 编程 我真的很喜欢为我的应用程序中的每个小视图单元拥有一个自己的 ViewModel 的想法 我随后以
  • 内置方法读取couchdb文件大小?

    我正在尝试使用 couchdb 作为消息存储 并想报告消息大小 理想情况下 读取 size 属性会很好 最坏的情况是我可以检查整个文档 JSON 的字符串长度 我什至可能想使用尺寸作为查看键 您认为记录文档大小的最佳方法是什么 为什么您认为
  • 使用 varargin (...) 时如何显示不同的函数用法?

    当您输入 Matlab 函数名称并打开大括号时 例如sum 在命令窗口中 将打开一个工具提示 显示此函数的所有可能用法 当我编写自己的接受函数时varargin 工具提示仅显示一个选项 而不是varargin puts e g myfunc
  • 如何将 OpenCV 等待键与 Chaquopy 一起使用

    我正在尝试使用 Chaquopy 将计算机视觉应用程序移植到 Android 当我尝试运行脚本时 以下行中出现以下错误 cv2 waitKey 100 打印到嵌入式 python 控制台的错误是 java chaquopy CQPEnv c
  • 带有 API 21 的 Snackbar

    我正在尝试在我的应用程序中实现新的 Snackbars 但我做不到 首先 我从以下位置下载了 zip 文件这个 SnackBarSampleActivity https github com nispok snackbar blob mas
  • 如何测试包含应用程序是否授予“允许完全访问”权限?

    我正在开发一个键盘扩展项目 在应用程序代码的某些点 我需要测试用户是否已授予键盘扩展的 允许完全访问 权限 协议是我需要从应用程序端进行这些测试 并在此基础上让用户访问键盘设置或在未授予权限的情况下提醒他 问题是这里提供的方法如下 func
  • pexpect 和 ssh:如何在 su - root -c 之后格式化一串命令

    我正在尝试迭代服务器和密码列表来更改一组服务器上的 sshd 配置 以便我可以使用无密码 SSH 密钥通过 root 登录 运行命令 我可以在 bash 中轻松完成此操作 但我正在尝试学习 Python 并且 显然 希望放弃手动输入密码 这