2012-02-03 6 views
3

サーバのリストを繰り返して、サーバのグループのsshd configを変更するパスワードを&に変更しようとしています。パスワードなしのSSHキーを使用してルート経由でpexpectとssh:su - rootの後にコマンドの文字列をフォーマットする方法-c

私はこれをbashで簡単に行うことができますが、私は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 %[email protected]%s:/tmp/" % (USER, HOST) 

COMMAND2="ssh -o StrictHostKeyChecking=no -t %[email protected]%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:

scp ~/.ssh/id_rsa.pub /etc/ssh/sshd_config [email protected]:/tmp/ 

ssh -o StrictHostKeyChecking=no -t [email protected] "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でこれを行うに近い得ている:ここで

は、私が何をしたいのはbashです) 正常に動作します。 しかしCOMMAND2は失敗します。私は、スクリプトを実行する前に、リモートサーバ上の/ 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  

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]', '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 

は私が取得:

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にはまったく新しいので、どんなアドバイスも感謝しています。おかげさまで

+0

適切なセキュリティを確保するために、リモートホストの '/ tmp'に制限付きのディレクトリを作成してから、何かをコピーしてください。悪意のあるユーザーが '/ tmp'に' id_rsa.pub'という名前でシンボリックリンクを作成した場合、悪質なことが起こる可能性があります。セキュリティを少し向上させるために、ファイルをホームディレクトリにコピーします。おそらく攻撃者は権限を持ちません。 – tripleee

答えて

3

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

編集:実際には、引用の適切な曖昧さ回避が行います。シェルはシングルクォートも提供しているので、一重引用符を使用したソリューションは問題ありません。 Pythonでは、一重引用符や他の多くの引用機能を使用することができます。問題をまだ解決していない場合は推奨します(文字列自体に変更を必要としない引用符を選択できるため、エラーの場合)。

ので、これらのいずれかが問題ないはず:私は、隣接する二重引用符を明確にするために、三重引用符にスペースを追加するために必要な

COMMAND2='ssh -o StrictHostKeyChecking=no -t %[email protected]%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 %[email protected]%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 %[email protected]%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 %[email protected]%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) 
+0

ありがとう@トライプルー。あなたは文字列の例をコピーすることができますか?私は二重エスケープと三重引用符の外側の引用符のいくつかのバージョンを試してきましたが、まだCOMMAND2を正しく解釈していません。間違いなくPythonの問題ではなく、私の脳の問題です。 :) –

+0

わかりやすく説明してくれてありがとう。 –

1

私は単一引用符のために行く代わりに二重引用符をエスケープする方法を把握しよう終わった:

COMMAND2="ssh -o StrictHostKeyChecking=no -t %[email protected]%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) 
関連する問題