728x90
반응형

파이썬 expect 스크립트 실행 

리눅스에서는 expect 스크립트 언어를 통해 ftp 나 ssh 로 접속 하여 업무를 자동화 할 수 있습니다. 

* expect
CLI 상호작용 자동화 프로그램의로 특정 명령을 수행후 정해진 응답을 기대하면서 다음 작업 처리를 대기하는 방식으로 

코드를 작성합니다. 

 

파이썬에서도 해당 언어와 마찬가지로 pexpect 라이브러리를 활용해 보다 다양한 업무를 자동화 할수 있습니다. 

Python 프로그램을 통해 리눅스 사용자 계정을 일괄 변경 하는 테스트를 코드를 공유 합니다. 

Python2.7 환경에서 테스트 되었습니다. 

 

패스워드 변경할 사용자 파일(UserList.txt )

$cat UserList.txt 
testuser1
testuser2
testuser3
testuser4
testuser5

Python 코드

#!/usr/bin/python
# -*- coding:utf-8 -*-

import sys
import pexpect  
import subprocess
import tarfile
import sys
import re
import os
import getopt
import traceback
import shutil
import sys
reload(sys)
PROMPT = ['\# ','>>> ','> ','\$ ', '\] ']

USER_LIST_FILE='UserList.txt'
ROOT_ID = 'root'

class PsshConn:

    def __init__(self , ip , id , passwd, timeout):
        self.ip = ip
        self.id = id
        self.passwd = passwd
        self.timeout = timeout

    def show(self):
        print "ip : %s " % self.ip
        print "id : %s  passwd : %s" % (self.id, self.passwd)

    def sshconn(self):
        ssh_newkey = 'Are you sure you want to continue connecting'
        conn = 'ssh %s@%s' % (self.id , self.ip)
        print "conn : " + conn
        child = pexpect.spawn(conn ,timeout=self.timeout)
        ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword: '] )

        if ret == 0:
            print '[-] Error Connecting : 0 '
            return
        if ret == 1:
            child.sendline('yes')
            ret = child.expect([pexpect.TIMEOUT, \
                '[P|p]assword:'])
            if ret == 0:
                print '[-] Error Connecting : 1'
                return
        child.sendline( self.passwd )
        child.expect(PROMPT)
        return child


def usage():
    print "user password change Test [options]  "
    print "-h : help"
    print "-u : User List "
    print "-i : SERVER IP "
    print "-P : Root Password "
    print "-p : User Password "
    print "ex:User List get) ./ChangePassword.py -i localhost -P test -u  "
    print "ex:Change passwd) ./changepassd.py  -i localhost -P test  -p test  "


def userList() :
    with open(USER_LIST_FILE) as f:
        lines = f.read().split()
    #for line in lines:
    #    print(line)
    return lines


def mkUserList():

    conn = PsshConn(IP_ADDRESS , ROOT_ID , ROOT_PASSWD, 60).sshconn()
    conn.sendline('export LANG=en_US.UTF-8')
    conn.expect(PROMPT)
    conn.sendline('grep /bin/bash /etc/passwd | cut -f1 -d: ')
    conn.expect(PROMPT)

    #print "RECOMAND :<< %s >>" % conn.before
    users = conn.before

    with open(USER_LIST_FILE+'_tmp','w') as wfile:
        wfile.writelines(users)
    wfile.close()
 
    #file line count
    lineCnt = len(open(USER_LIST_FILE+'_tmp','r').readlines())   
     
    with open(USER_LIST_FILE+'_tmp','r') as rfile:
        with open(USER_LIST_FILE,'w') as rwfile:
            for i, line in enumerate(rfile):
                if (i > 1) & (i < lineCnt - 1) :
                    print "User :%s" % line.replace("\n","")
                    rwfile.writelines(line)
        rwfile.close()
    rfile.close()                           
    os.remove(USER_LIST_FILE+'_tmp')
                
                    

    
if __name__=="__main__":

    try:
        opts, args = getopt.getopt(sys.argv[1:],"i:P:p:hu")

    except IOError as e:
        usage()
        print ("[-] Error : "  + e)
        sys.exit(2)


    for o, a in opts:
        if o == "-h":
            print "======= options ========"
            usage()
            sys.exit(0)
        elif o == "-i":
            IP_ADDRESS = a
            print 'IP: %s' % [ IP_ADDRESS ]      
        elif o == "-P":
            ROOT_PASSWD = a
            print 'ROOT_PASSWD : %s' % [ ROOT_PASSWD ]
        elif o == "-p":
            USER_PASSWD = a
            print 'USER_PASSWD : %s' % [ USER_PASSWD ]
        elif o == "-u":
            mkUserList()
            print '[User List Search]'    
            sys.exit(0)             

    try:
        print " ==== change password  ==== "

        try:
            ssh = PsshConn(IP_ADDRESS , ROOT_ID , ROOT_PASSWD,60).sshconn()
            ssh.sendline('cd ')
            ssh.sendline('export LANG=en_US.UTF-8')

            for user in userList():
                print "USER : %s" % user
                ssh.sendline('passwd ' + user )
                ssh.expect("password:")
                ssh.sendline(USER_PASSWD )
                ssh.expect("password:")
                ssh.sendline(USER_PASSWD )
                ssh.expect(PROMPT)
        except Exception ,e:
             print "[-] Error       : %s " % e

    except Exception, e:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        print "[-] Error       : %s " % e
        print "[-] line number :  " , exc_traceback.tb_lineno

실행

  • UserList.txt 파일에 등록된 testuser1~testuser5 까지 test 패스워드로 일괄 변경 합니다. 
  • 변경된 패스워드로(test) 로 변경 되었는지 확인하기 위해 SSH 로 접속 테스트를 진행 합니다.

728x90
반응형

+ Recent posts