ABOUT ME

lahuman 과 jabsiri가 함께 쓰는 공개 노트 입니다. 유용한 정보를 많이 기입하려고 노력 중입니다. 감사합니다.

Today
Yesterday
Total
  • Python]paramiko 모듈에서 su 명령어로 계정 전환
    Python 2018. 5. 18. 10:12
    728x90

    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)
    

    를 통해서 확인 한다.

    참고 자료


    728x90
Designed by Tistory.