'2018/05'에 해당되는 글 1건

  1. 2018.05.18 Python]paramiko 모듈에서 su 명령어로 계정 전환

Python]paramiko 모듈에서 su 명령어로 계정 전환

python에서 ssh에 연결 후 command를 실행하기 위해 사용하는 paramiko 모듈에서 간단하게 command를 실행하는 코드는 다음과 같다.

import paramiko

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # host keys 관련 설정
ssh_client.connect('127.0.0.1', username='lahuman', password='pass')

stdin, stdout, stderr = ssh_client.exec_command('ls')
stdin.flush()
time.sleep(1)
print stdout.read()

## 결과
lahuman
  • host kyes 관련 설정은 ssh로 다른 서버로 접근시, key 값을 저장할 지에 대한 처리 이다. paramiko.AutoAddPolicy() 로 설정시 자동으로 yes 처리 된다.

ssh_client.exec_command(cmd)를 이용할 경우 매 명령어 마다 새로운 세션이 부여되어, 다른 계정으로 전환 후 작업을 진행 할 수 없다.

하나의 세션에서 작업을 연속되게 진행하고 싶다면 channel = ssh_client.invoke_shell()를 이용하면 된다.

import paramiko

def main():
    ssh_client = None
    recv_size = 9999
    try:
		ssh_client = paramiko.SSHClient()
		ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # host keys 관련 설정
		ssh_client.connect('127.0.0.1', username='lahuman', password='pass')

        channel = ssh_client.invoke_shell()
        channel.send('su -\n')
        outdata, errdata = waitStrems(channel)
        print outdata

        channel.send('pass\n')
        outdata, errdata = waitStrems(channel)
        print outdata

        channel.send('whoami\n')
        outdata, errdata = waitStrems(channel)
        print outdata

    finally:
        if ssh_client is not None:
            ssh_client.close()


def waitStrems(chan):
    time.sleep(1)
    outdata=errdata = ""

    while chan.recv_ready():
        outdata += chan.recv(1000)
    while chan.recv_stderr_ready():
        errdata += chan.recv_stderr(1000)

    return outdata, errdata

if __name__ == "__main__":
    main()


## 결과
Last login: Thu May 17 01:34:37 2018 from 10.0.2.2
su -
[lahuman@localhost ~]$ su -
Password: 

Last login: Thu May 17 01:35:10 EDT 2018
[root@localhost ~]# 
whoami
root
[root@localhost ~]# 

세션을 유지한 상태로 명령어를 실행하기 위해서는 channel을 가져오고 channel을 계속 유지 해야 한다.

각 명령의 결과가 문제 없이 종료 되었는지는

 while chan.recv_ready():
        outdata += chan.recv(1000)
    while chan.recv_stderr_ready():
        errdata += chan.recv_stderr(1000)

를 통해서 확인 한다.

참고 자료


Posted by lahuman