3

サーバーとパスワードのリストを繰り返し処理して、サーバーのグループの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', 'user@192.168.1.1', '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はかなり新しいので、アドバイスをいただければ幸いです。ありがとう。

4

2 に答える 2

3

COMMAND2を二重引用符で囲み、埋め込まれた二重引用符を正しくエスケープしますが、すでにエスケープされている二重引用符も二重引用符で囲む必要があります。言い換えれば、実際にはPythonの問題ではありません。ただし、最も外側の引用符をPythonの三重引用符に切り替えることもできます。読みやすくなります。

編集:実際には、引用の適切な曖昧性解消が可能です。シェルは一重引用符も提供するため、一重引用符を使用したソリューションで問題ありません。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)
于 2012-02-03T06:26:40.873 に答える
1

二重引用符をエスケープする方法を理解しようとする代わりに、一重引用符を使用することになりました。

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)
于 2012-02-03T21:33:50.147 に答える