Goals for this year.

January 25, 2013

This year I have been teaching a continuing education class at the Pacific Northwest College or Art called Physical Computing for Artists named by the school after Dan O’sullivan and   Tom Igoe’s excellent but dated Physical Computing: Sensing and Controlling the Physical World with Computers, last quarter my students complained that the code samples were hard to translate but agreed that the books coverage of the material was worth it regardless. While teaching this winter my goal is to translate as much of the code in physical computing to the Arduino, Wiring and if possible Maple platforms.

This should be doable. A code fragment and sample project per day.

 

 

Paramiko: python driven ssh.

January 4, 2013

As the only unix person available over the holidays the task I was given was to take a list of over a hundred servers and a login (belonging to our manager, a windows sysadmin) that was supposed to have ssh and sudo access and learn as much as I could before the other admin got back from Christmas vacation. Since I have been working primarily in python I started looking at ssh and python and found paramiko which is an ssh implementation built in python. http://www.lag.net/paramiko/docs/paramiko-module.html  I was able to use this to determine which servers actually were accessible and which were virtual. Once the other admin was available to fix the accounts that didn’t have access I set about getting a login and password on them. Apparently in the past this took months.

"""
quick script to add my account to the 100+ servers using the my managers login credentials
"""

import paramiko
import getpass
import socket

uname='myboss'
pwd=getpass.getpass()
hosts=["host1",...,"host130"]
for host in hosts:
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host,username=uname,password=pwd,timeout=3.0)
        stdin,stdout,stderr=ssh.exec_command('/usr/local/bin/sudo /usr/sbin/useradd -u 1119 -g 14 -G"ssh-allow" -c"Donald Davis" -m -d /export/home/ddavis -s /bin/bash ddavis')
        stdin.write(pwd+'\n')
        stdin.flush()
        outlines=stdout.readlines()
        if len(outlines):
            lastout=outlines[0].rstrip('\r\n')
            lastuser=lastout.split(' ',1)[0]
        stdin,stdout,stderr=ssh.exec_command("/usr/bin/grep ddavis /etc/passwd")
        outlines=stdout.readlines()
        if len(outlines):
           print "USER_ADDED::"+host+","+outlines[0].rstrip('\r\n')
        else:
            outlines=stderr.readlines()
            for line in outlines:
                print " ERROR::"+host+","+line.rstrip('\r\n')

        stdin,stdout,stderr=ssh.exec_command("/usr/bin/grep ddavis /etc/passwd")
        if len(outlines):
           print "GRP_CHANGE::"+host+","+outlines[0].rstrip('\r\n')
        else:
            outlines=stderr.readlines()
            for line in outlines:
                print " ERROR::"+host+","+line.rstrip('\r\n')

    except paramiko.AuthenticationException:
        print " AUTHFAIL::"+host+","+uname
    except Exception as e:
        if "Name or service not known" in str(e):
            print " AWOL::"+host
        elif "timed out" in str(e):
            print " TIMEDOUT::"+host
        else:
            print " UNKNOWN::"+host+",", str(e)

Getting the password set was a little more tricky since password actually requires a tty/shell context.

import paramiko
import getpass
import socket
import time

authissues=[]
unknown=[]
awol=[]

uname='myboss'
pwd=getpass.getpass()

hosts=[...listofhosts...]

mypwd=getpass.getpass(0)
for host in hosts:
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host,username=uname,password=pwd,timeout=1.5)
        chan=ssh.invoke_shell()
        chan.set_combine_stderr(True)
        time.sleep(.6)
        print chan.recv(9999)

        chan.sendall("/usr/local/bin/sudo /usr/bin/passwd ddavis\n")
        time.sleep(.3)
        buff=''
        while 'assword' not in buff:
            resp = chan.recv(9999)
            buff += resp
            print(resp)
            if 'unknown' in buff:
                raise #hell
            if 'denied' in buff:
                raise #hell
            if 'o such file' in buff:
                raise #hell
            if 'not in the sudoers' in buff:
                raise #hell
        chan.send(pwd+'\n')
        time.sleep(.2)

        buff='' 
        while 'assword' not in buff:
            resp = chan.recv(9999)
            buff += resp
            print(resp)
            if 'unknown' in buff:
                raise #hell
            if 'denied' in buff:
                raise #hell
            if 'o such file' in buff:
                raise #hell
            if 'not in the sudoers' in buff:
                raise #hell

        chan.send(mypwd+'\n')
        time.sleep(.2)

        buff=''
        while 'assword' not in buff:
            resp = chan.recv(9999)
            buff += resp
            print(resp)
        chan.send(mypwd+'\n')
        time.sleep(.2)

        print chan.recv(2000)
        chan.close()
    except paramiko.AuthenticationException:
        print " AUTHFAIL::"+host+","+uname
        authissues.append(host)
    except Exception as e:
        if "Name or service not known" in str(e):
            print " AWOL::"+host
            awol.append(host)
        elif "timed out" in str(e):
            print " TIMEDOUT::"+host
            awol.append(host)

        else:   
            print "UNKNOWN::"+host+",", str(e)
            unknown.append(host)

print "AUTHFAIL", authissues
print "AWOL", awol
print "UNKNOWN",unknown

Finally I can then get rid of the need for passwords altogether with this snippet stolen from the internets.

#!/usr/bin/python
import os
import getpass

authissues=[]
unknown=[]
awol=[]
hosts=[...list of hostnamed ]
import paramiko

def deploy_key(key, server, username, password):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(server, username=username, password=password)
    client.exec_command('mkdir -p ~/.ssh/')
    client.exec_command('echo "%s" > ~/.ssh/authorized_keys' % key)
    client.exec_command('chmod 644 ~/.ssh/authorized_keys')
    client.exec_command('chmod 700 ~/.ssh/')

key = open(os.path.expanduser('~/.ssh/id_rsa.pub')).read()
username = os.getlogin()
password = getpass.getpass()

for host in hosts:
    try:
        deploy_key(key, host, username, password)
    except paramiko.AuthenticationException:
        print " AUTHFAIL::"+host
        authissues.append(host)
    except Exception as e:
        if "Name or service not known" in str(e):
            print " AWOL::"+host
            awol.append(host)
        elif "timed out" in str(e):
            print " TIMEDOUT::"+host
            awol.append(host)

        else:   
            print "UNKNOWN::"+host+",", str(e)
            unknown.append(host)

print "AUTHFAIL", authissues
print "AWOL", awol
print "UNKNOWN",unknown

.

This all may move.

January 4, 2013

After a 3+ year hiatus from system administration I have been offered one of those short sweet contracts.  Keep the wheels on the road, find and train your replacement.

Its an oracle/sun house mostly about 50 real servers and another 50 or so virtual suns running in zones on 6 m series machines. And and exadata2. Outside of the virtualization not much has changed.

So I am needing a place to put the things I am learning while I come up to speed. Also finding myself with an entirely new set of tools due to my excursions into cross platform python.