Just small script for toying around with python….
There is always a first time… now this is it.. in English coi…. ![]()
It happened during administrating servers in detik. Every time doing login to the servers, it always ask the password. There’s mechanism by copying public key into remote server in order to login automatically without entering the password. Application like ssh-copy-id do the job.
So, my concern is how to do login automatically without having explicitly launch ssh-copy-id before ssh to the server. I’ve written a script to handle that. This script requires pexpect library. Here it is :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | """ USAGE: go user@host This script is used as One Time Password SSH login """ import os, pexpect, getpass, sys, socket def gethomedir(): for user in open('/etc/passwd'): cols = user.split(':') if cols[0] == os.getlogin(): return cols[5] def knownhost(user_host): for line in open(homedir + '/.ssh/hosts', 'a+'): if line.strip() == user_host: return True return False def updateknownhost(user_host): fd = open(homedir + '/.ssh/hosts','a+') fd.write(user_host + '\n') fd.close() if __name__ == "__main__": homedir = gethomedir() if not len(sys.argv) > 1 or sys.argv[1].find('@') < 0: print __doc__ sys.exit(1) user,host = sys.argv[1].split('@') try: host = socket.gethostbyname(host) except socket.gaierror: print 'Error resolving host' sys.exit(1) if not knownhost(user + '@' + host): # ssh-copy-id and update info print 'Hostname %s | User %s' % (host, user) result = 0 exp = pexpect.spawn('ssh-copy-id ' + sys.argv[1]) while result != 2: result = exp.expect(['password', 'publickey,password', 'expecting', pexpect.EOF]) if result == 0: # try again passwd = getpass.getpass('Enter Password:') exp.sendline(passwd) elif result == 1 or result == 3: # failed to input password correctly print 'Failed.' sys.exit(1) # update info updateknownhost(user + '@' + host) exp.close() os.system('ssh ' + ' '.join(sys.argv[1:])) |
And also I’ve created small script to manipulate /etc/hosts, because sometime I don’t remember IP address of some servers, so I just need to create an alias in /etc/hosts. Here is the script :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | """ USAGE: hosts add address hostname... | del [address|hostname]... This script adds/deletes hostname alias in /etc/hosts """ import os, getpass, sys, socket lineread={} linewrite={} def addhosts(address, hostname): global linewrite, lineread notFound = True for idx, line in linewrite.iteritems(): cols = filter(lambda x:not x == '', line.split()) if cols[0] == address: notFound = False for host in hostname: if not host in cols: cols.append(host) linewrite[idx] = ' '.join(cols) + "\n" if notFound: lineread[len(lineread)] = address + ' ' + ' '.join(hostname) + "\n" def delhosts(addr_host): global linewrite, lineread lw = linewrite.copy() isAddr = False for idx, line in lw.iteritems(): cols = filter(lambda x:not x == '', line.split()) for item in addr_host: if item in cols: if cols[0] == item: isAddr = True del linewrite[idx] del lineread[idx] else: i = 1 for col in cols[1:]: if col == item: del cols[i] i+=1 if len(cols) == 1: isAddr = True del linewrite[idx] del lineread[idx] if not isAddr: linewrite[idx] = ' '.join(cols) + "\n" if __name__ == "__main__": if not len(sys.argv) > 2 or not sys.argv[1] in ['add','del']: print __doc__ sys.exit(1) idx=0 try: for line in open('/etc/hosts'): lineread[idx]=line if not (line.strip().startswith('#')) and not (line.strip() == ''): linewrite[idx]=line idx+=1 except IOError: print 'Error opening /etc/hosts' sys.exit(1) if sys.argv[1] == 'add': addhosts(sys.argv[2],sys.argv[3:]) else: delhosts(sys.argv[2:]) hosts = open('/etc/hosts','w') for idx, line in lineread.iteritems(): if linewrite.has_key(idx): hosts.write(linewrite[idx]) else: hosts.write(lineread[idx]) |