bssh

Esse script possibilita a execução de comandos remotamente utilizando o protocolo SSH. Os comandos podem ser executados individualmente ou em lote para um ou mais servidores.

O script foi desenvolvido em Python para Windows e utilizando paramiko e pycrypto para instalar o SSH nesse sistema. As versões citadas no READ-ME abaixo certamente estão desatualizadas. Para executar a partir de uma máquina Linux não deve ter qualquer problema.

READ.ME

bssh - ver. 0.3

Bulk SSH (bssh) is a python script written to provide remote command 
submission to one or more servers/hosts using ssh protocol. Written to run
on Win32 environment, should run on Linux with minor or no modification.

VERSION HISTORY:
0.1: Simple command execution 
0.2: Support to input response to programs running on remote host.
0.3: Added username and password parameters.
 
INSTALATION: 
Download and run the following installers:
http://www.python.org/ftp/python/2.7.1/python-2.7.1.msi
http://bialix.com/python/paramiko-1.7.3-ctypes.win32.exe
http://www.serenethinking.com/bitlift/tl_files/pycrypto-2.3.win32-py2.7.msi

USAGE: 
bssh <options>

OPTIONS:
-h, --help
      Show this help.
-d, --debug
      Show debug messages.
-c, --command=<command>
      Single command to be executed on remote server.
-f, --commandfile=<command file name>
      Name of the file containing all commands that will run on remote 
      server. (See below for details)
-s, --server=<server name>
      Single target server name or IP address.
-l, --serverlist=<server list file name>
      Name of the file containing all target servers names or IP address,
      one per line.
-o, --output=<file name>
      Sends output text to a file.
-u, --username=<user id>
      User id to ssh sign-on.
-p, --password=<password>
      User password to ssh sign-on.
 
COMMAND FILE:
Text file containing one command per line to be executed on the remote 
host/server. Each command is preceded of a meta command to be interpreted 
by bssh script as follows.

Meta commands:
 $C <command>
    Executes a command on remote host and catches it's stdout
 $R <command>
    Run a program and feeds to it's prompts with "input text" ($I)
    provided right below.
 $I <input text>
    Text to be provided to programa executed with "run" ($R) command.
    For consecutive responses, use $I for each program prompt.
 # <comment>
    The trailing text will not be executed and will be considered as
    a comment.

Additionaly to meta commands there are some meta data that can be used
in a command line.

Meta data:
 $user$
    Replaced by username provided as credential to SSH login.
 $pass$
    Replaced by password provided as credential to SSH authentication.

CÓDIGO

#
# bssh - Bulk SSH
# Description: Submit a single command or a command sequence to remote 
#              host(s) using SSH protocol.
# Author.....: Megumi K. Jr.
# Date.......: Sep, 12 2011
# Version history:
#    0.3: Added user and password parameter option
#
scriptname = "bssh"         # Script Name 
scriptver  = "0.3"          # Version
#

import os, re, sys
import string
import getpass
import getopt
import time
import paramiko

from types import *  # http://docs.python.org/library/types.html#module-types

def main():
    global username
    global password
    global debug
    
    command = None
    cmdfile = None
    server = None
    serverlist = None
    username = None
    password = None
    debug = False
    
    # Check if options were informed
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hdc:f:s:l:o:u:p:", \
            ["help", "debug", "command=", "commandfile=", "server=", "serverlist=", "output=", "username=", "password="])
    except getopt.GetoptError, err:
        # print help information and exit:
        print str(err)
        print
        Usage()
        sys.exit(2)
        
    # Get all options
    for o, a in opts:
        if o in ("-h", "--help"):
            Usage()
            sys.exit()
        elif o in ("-d", "--debug"):
            debug = True
        elif o in ("-c", "--command"):
            command = a
        elif o in ("-f", "--commandfile"):
            cmdfile = a
        elif o in ("-s", "--server"):
            server = a
        elif o in ("-l", "--serverlist"):
            serverlist = a
        elif o in ("-o", "--output"):
            sys.stdout = Logger(a)
        elif o in ("-u", "--username"):
            username = a
        elif o in ("-p", "--password"):
            password = a
        else:
            Usage()
            sys.exit(2)
 
    # Check if is only one command to be executed
    if command != None:
        # only one command to be run
        cmd = command # var "cmd" will have the command
    else:
        if cmdfile != None:
            try:
                # var "cmd" will have file handler
                cmd = open(cmdfile)
            except IOError as e:
                print("{0}".format(e))
                sys.exit(2)
        else:
            Usage()
            sys.exit(2)
    
    # Check if is only one server
    if server != None:
        # will run commands only on one server
        srv = server # var "srv" will have server name
    else:
        if serverlist != None:
            # Open server list file
            try:
                # var "srv" will have file handler
                srv = open(serverlist)
            except IOError as e:
                print("{0}".format(e))
                sys.exit(2)
        else:
            Usage()
            sys.exit(2)
            
    # Get user credentials
    print
    print "%s - ver. %s" % (scriptname, scriptver)
    if username == None:
        print "Logon credentials"
        username = raw_input('Username: ')
        password = getpass.getpass("Password: ")

    ProcServer(srv, cmd)

    return
# endDef

def Usage():
    try:
        helpfile = sys.path[0] + "\\READ.ME"
        help = open(helpfile)
    except IOError as e:
        print 'Error reading "%s" file.' % helpfile
        print("{0}".format(e))
        sys.exit(2)
    help.close()
    cmd = 'more "%s"' % helpfile
    os.system(cmd)
    print
    sys.exit(0)
# endDef

def ProcServer(srv, cmd):
    # Process a server or servers list
    if type(srv) == StringType:  # If srv is StringType, contains server name
        ProcCommand(srv, cmd)    #    proc single server
    else:
        for servername in srv.read().splitlines():  # loop into server file
            if servername.strip() == "":            # Skip empty lines
                continue
            elif servername.strip()[0] == "#":      # Skip comments
                continue
            else:
                ProcCommand(servername, cmd)
#endDef    
    
def ProcCommand(srv, cmd):
    print
    print "Host: %s" % srv
    print "-----------------------------------------------------------------------"

    ssh = OpenConnection(srv)
    if type(cmd) == StringType: # If cmd is StringType, contains single command
        ExecCmd(ssh, cmd)
    else:
        cmd.seek(0)                                 # Point to file beginning
        ParseCmdFile(ssh, cmd)
#endDef

def ParseCmdFile(ssh, cmd):
    cmdList = []
    for command in cmd.read().splitlines():
        # Ignore empty lines or comments
        if command.strip() == "":               # Skip empty lines
            continue
        elif command.strip()[0] == "#":         # Skip comments
            continue
        
        command = NormalizeString(command)
        
        if command.strip()[:2].upper() == "$C":
            if len(cmdList) > 0:                # If there's a pending program
                ExecCmd(ssh, cmdList)           #     execution, do it before
                cmdList = []                    #     the next command.
            command = command[2:].strip()
            ExecCmd(ssh, command)
        elif command.strip()[:2].upper() == "$R"\
            or command.strip()[:2].upper() == "$I":
            cmdList.append(command[2:].strip())
            continue
 
    if len(cmdList) > 0:                # If there's a pending program
        ExecCmd(ssh, cmdList)           #     execution, do it before exit
           
    return
# endDef

def OpenConnection(server):
    if debug:                           # Turn on debug messages
        paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
        
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        ssh.connect(server, username=username, password=password)
    except Exception, e:
        print("({0})".format(e))
        sys.exit(2)
    return ssh
# endDef

def ExecCmd(ssh, command):
    if type(command) == ListType:       # If it is a list of commands
        cmd = command[0]                #   get 1st cmd.
    else:
        cmd = command   
        
    print "$> %s" % (cmd)
    stdin, stdout, stderr = ssh.exec_command(cmd)
    
    if type(command) == ListType:       # If it is a list of commands
        for cmd in command[1:]:         #   continue sending next on
            stdin.write(cmd+"\n")       #   the list
            stdin.flush()
    stdin.close()

    for line in stdout.read().splitlines():
        print line
    print
    return stdout, stderr
# endDef

def NormalizeString(string):
    string = re.sub(r'(\$user\$)', username, string) # Replace meta var "username"
    string = re.sub(r'(\$pass\$)', password, string) # Replace meta var "password"

    # Removes/fixes leading/trailing newlines/whitespace and escapes double quotes with double quotes 
    string = re.sub(r'(\r\n|\r|\n)', '\n', string) # Convert all newlines to unix newlines
    string = string.strip() # Remove leading/trailing whitespace/blank lines
    # string = re.sub(r'(")', '""', string) # Convert double quotes to double double quotes (e.g. 'foo "bar" blah' becomes 'foo ""bar"" blah')
    return string
# endDef

class Logger(object):
    # Duplicate "print" output to a file.
    def __init__(self, object):
        self.terminal = sys.stdout
        self.log = open(object, "a")

    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)  
        
if __name__ == "__main__":
    main()

 


ARQUIVO DE COMANDOS (exemplo)

# Ver 0.3 Command File
$C hostname
$C date

ARQUIVO DE SERVIDORES (exemplo)

# Host name or ip address
qaectlvbosapp503

 

Os comentários estão desativados.