{"id":294,"date":"2017-11-07T11:06:09","date_gmt":"2017-11-07T13:06:09","guid":{"rendered":"http:\/\/megumijr.com\/blog\/?page_id=294"},"modified":"2017-11-07T14:56:35","modified_gmt":"2017-11-07T16:56:35","slug":"bssh","status":"publish","type":"page","link":"https:\/\/megumijr.com\/blog\/biblioteca-de-scripts\/bssh\/","title":{"rendered":"bssh"},"content":{"rendered":"<p>Esse script possibilita a execu\u00e7\u00e3o de comandos remotamente utilizando o protocolo SSH. Os comandos podem ser executados individualmente ou em lote para um ou mais servidores.<\/p>\n<p>O script foi desenvolvido em Python para Windows e utilizando <em>paramiko<\/em> e <em>pycrypto<\/em> para instalar o SSH nesse sistema. As vers\u00f5es citadas no READ-ME abaixo certamente est\u00e3o desatualizadas. Para executar a partir de uma m\u00e1quina Linux n\u00e3o deve ter qualquer problema.<\/p>\n<h3>READ.ME<\/h3>\n<pre>bssh - ver. 0.3\r\n\r\nBulk SSH (bssh) is a python script written to provide remote command \r\nsubmission to one or more servers\/hosts using ssh protocol. Written to run\r\non Win32 environment, should run on Linux with minor or no modification.\r\n\r\nVERSION HISTORY:\r\n0.1: Simple command execution \r\n0.2: Support to input response to programs running on remote host.\r\n0.3: Added username and password parameters.\r\n \r\nINSTALATION: \r\nDownload and run the following installers:\r\nhttp:\/\/www.python.org\/ftp\/python\/2.7.1\/python-2.7.1.msi\r\nhttp:\/\/bialix.com\/python\/paramiko-1.7.3-ctypes.win32.exe\r\nhttp:\/\/www.serenethinking.com\/bitlift\/tl_files\/pycrypto-2.3.win32-py2.7.msi\r\n\r\nUSAGE: \r\nbssh &lt;options&gt;\r\n\r\nOPTIONS:\r\n-h, --help\r\n      Show this help.\r\n-d, --debug\r\n      Show debug messages.\r\n-c, --command=&lt;command&gt;\r\n      Single command to be executed on remote server.\r\n-f, --commandfile=&lt;command file name&gt;\r\n      Name of the file containing all commands that will run on remote \r\n      server. (See below for details)\r\n-s, --server=&lt;server name&gt;\r\n      Single target server name or IP address.\r\n-l, --serverlist=&lt;server list file name&gt;\r\n      Name of the file containing all target servers names or IP address,\r\n      one per line.\r\n-o, --output=&lt;file name&gt;\r\n      Sends output text to a file.\r\n-u, --username=&lt;user id&gt;\r\n      User id to ssh sign-on.\r\n-p, --password=&lt;password&gt;\r\n      User password to ssh sign-on.\r\n \r\nCOMMAND FILE:\r\nText file containing one command per line to be executed on the remote \r\nhost\/server. Each command is preceded of a meta command to be interpreted \r\nby bssh script as follows.\r\n\r\nMeta commands:\r\n $C &lt;command&gt;\r\n    Executes a command on remote host and catches it's stdout\r\n $R &lt;command&gt;\r\n    Run a program and feeds to it's prompts with \"input text\" ($I)\r\n    provided right below.\r\n $I &lt;input text&gt;\r\n    Text to be provided to programa executed with \"run\" ($R) command.\r\n    For consecutive responses, use $I for each program prompt.\r\n # &lt;comment&gt;\r\n    The trailing text will not be executed and will be considered as\r\n    a comment.\r\n\r\nAdditionaly to meta commands there are some meta data that can be used\r\nin a command line.\r\n\r\nMeta data:\r\n $user$\r\n    Replaced by username provided as credential to SSH login.\r\n $pass$\r\n    Replaced by password provided as credential to SSH authentication.<\/pre>\n<hr \/>\n<h3>C\u00d3DIGO<\/h3>\n<pre>#\r\n# bssh - Bulk SSH\r\n# Description: Submit a single command or a command sequence to remote \r\n#              host(s) using SSH protocol.\r\n# Author.....: Megumi K. Jr.\r\n# Date.......: Sep, 12 2011\r\n# Version history:\r\n#    0.3: Added user and password parameter option\r\n#\r\nscriptname = \"bssh\"         # Script Name \r\nscriptver  = \"0.3\"          # Version\r\n#\r\n\r\nimport os, re, sys\r\nimport string\r\nimport getpass\r\nimport getopt\r\nimport time\r\nimport paramiko\r\n\r\nfrom types import *  # http:\/\/docs.python.org\/library\/types.html#module-types\r\n\r\ndef main():\r\n    global username\r\n    global password\r\n    global debug\r\n    \r\n    command = None\r\n    cmdfile = None\r\n    server = None\r\n    serverlist = None\r\n    username = None\r\n    password = None\r\n    debug = False\r\n    \r\n    # Check if options were informed\r\n    try:\r\n        opts, args = getopt.getopt(sys.argv[1:], \"hdc:f:s:l:o:u:p:\", \\\r\n            [\"help\", \"debug\", \"command=\", \"commandfile=\", \"server=\", \"serverlist=\", \"output=\", \"username=\", \"password=\"])\r\n    except getopt.GetoptError, err:\r\n        # print help information and exit:\r\n        print str(err)\r\n        print\r\n        Usage()\r\n        sys.exit(2)\r\n        \r\n    # Get all options\r\n    for o, a in opts:\r\n        if o in (\"-h\", \"--help\"):\r\n            Usage()\r\n            sys.exit()\r\n        elif o in (\"-d\", \"--debug\"):\r\n            debug = True\r\n        elif o in (\"-c\", \"--command\"):\r\n            command = a\r\n        elif o in (\"-f\", \"--commandfile\"):\r\n            cmdfile = a\r\n        elif o in (\"-s\", \"--server\"):\r\n            server = a\r\n        elif o in (\"-l\", \"--serverlist\"):\r\n            serverlist = a\r\n        elif o in (\"-o\", \"--output\"):\r\n            sys.stdout = Logger(a)\r\n        elif o in (\"-u\", \"--username\"):\r\n            username = a\r\n        elif o in (\"-p\", \"--password\"):\r\n            password = a\r\n        else:\r\n            Usage()\r\n            sys.exit(2)\r\n \r\n    # Check if is only one command to be executed\r\n    if command != None:\r\n        # only one command to be run\r\n        cmd = command # var \"cmd\" will have the command\r\n    else:\r\n        if cmdfile != None:\r\n            try:\r\n                # var \"cmd\" will have file handler\r\n                cmd = open(cmdfile)\r\n            except IOError as e:\r\n                print(\"{0}\".format(e))\r\n                sys.exit(2)\r\n        else:\r\n            Usage()\r\n            sys.exit(2)\r\n    \r\n    # Check if is only one server\r\n    if server != None:\r\n        # will run commands only on one server\r\n        srv = server # var \"srv\" will have server name\r\n    else:\r\n        if serverlist != None:\r\n            # Open server list file\r\n            try:\r\n                # var \"srv\" will have file handler\r\n                srv = open(serverlist)\r\n            except IOError as e:\r\n                print(\"{0}\".format(e))\r\n                sys.exit(2)\r\n        else:\r\n            Usage()\r\n            sys.exit(2)\r\n            \r\n    # Get user credentials\r\n    print\r\n    print \"%s - ver. %s\" % (scriptname, scriptver)\r\n    if username == None:\r\n        print \"Logon credentials\"\r\n        username = raw_input('Username: ')\r\n        password = getpass.getpass(\"Password: \")\r\n\r\n    ProcServer(srv, cmd)\r\n\r\n    return\r\n# endDef\r\n\r\ndef Usage():\r\n    try:\r\n        helpfile = sys.path[0] + \"\\\\READ.ME\"\r\n        help = open(helpfile)\r\n    except IOError as e:\r\n        print 'Error reading \"%s\" file.' % helpfile\r\n        print(\"{0}\".format(e))\r\n        sys.exit(2)\r\n    help.close()\r\n    cmd = 'more \"%s\"' % helpfile\r\n    os.system(cmd)\r\n    print\r\n    sys.exit(0)\r\n# endDef\r\n\r\ndef ProcServer(srv, cmd):\r\n    # Process a server or servers list\r\n    if type(srv) == StringType:  # If srv is StringType, contains server name\r\n        ProcCommand(srv, cmd)    #    proc single server\r\n    else:\r\n        for servername in srv.read().splitlines():  # loop into server file\r\n            if servername.strip() == \"\":            # Skip empty lines\r\n                continue\r\n            elif servername.strip()[0] == \"#\":      # Skip comments\r\n                continue\r\n            else:\r\n                ProcCommand(servername, cmd)\r\n#endDef    \r\n    \r\ndef ProcCommand(srv, cmd):\r\n    print\r\n    print \"Host: %s\" % srv\r\n    print \"-----------------------------------------------------------------------\"\r\n\r\n    ssh = OpenConnection(srv)\r\n    if type(cmd) == StringType: # If cmd is StringType, contains single command\r\n        ExecCmd(ssh, cmd)\r\n    else:\r\n        cmd.seek(0)                                 # Point to file beginning\r\n        ParseCmdFile(ssh, cmd)\r\n#endDef\r\n\r\ndef ParseCmdFile(ssh, cmd):\r\n    cmdList = []\r\n    for command in cmd.read().splitlines():\r\n        # Ignore empty lines or comments\r\n        if command.strip() == \"\":               # Skip empty lines\r\n            continue\r\n        elif command.strip()[0] == \"#\":         # Skip comments\r\n            continue\r\n        \r\n        command = NormalizeString(command)\r\n        \r\n        if command.strip()[:2].upper() == \"$C\":\r\n            if len(cmdList) &gt; 0:                # If there's a pending program\r\n                ExecCmd(ssh, cmdList)           #     execution, do it before\r\n                cmdList = []                    #     the next command.\r\n            command = command[2:].strip()\r\n            ExecCmd(ssh, command)\r\n        elif command.strip()[:2].upper() == \"$R\"\\\r\n            or command.strip()[:2].upper() == \"$I\":\r\n            cmdList.append(command[2:].strip())\r\n            continue\r\n \r\n    if len(cmdList) &gt; 0:                # If there's a pending program\r\n        ExecCmd(ssh, cmdList)           #     execution, do it before exit\r\n           \r\n    return\r\n# endDef\r\n\r\ndef OpenConnection(server):\r\n    if debug:                           # Turn on debug messages\r\n        paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)\r\n        \r\n    ssh = paramiko.SSHClient()\r\n    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())\r\n    try:\r\n        ssh.connect(server, username=username, password=password)\r\n    except Exception, e:\r\n        print(\"({0})\".format(e))\r\n        sys.exit(2)\r\n    return ssh\r\n# endDef\r\n\r\ndef ExecCmd(ssh, command):\r\n    if type(command) == ListType:       # If it is a list of commands\r\n        cmd = command[0]                #   get 1st cmd.\r\n    else:\r\n        cmd = command   \r\n        \r\n    print \"$&gt; %s\" % (cmd)\r\n    stdin, stdout, stderr = ssh.exec_command(cmd)\r\n    \r\n    if type(command) == ListType:       # If it is a list of commands\r\n        for cmd in command[1:]:         #   continue sending next on\r\n            stdin.write(cmd+\"\\n\")       #   the list\r\n            stdin.flush()\r\n    stdin.close()\r\n\r\n    for line in stdout.read().splitlines():\r\n        print line\r\n    print\r\n    return stdout, stderr\r\n# endDef\r\n\r\ndef NormalizeString(string):\r\n    string = re.sub(r'(\\$user\\$)', username, string) # Replace meta var \"username\"\r\n    string = re.sub(r'(\\$pass\\$)', password, string) # Replace meta var \"password\"\r\n\r\n    # Removes\/fixes leading\/trailing newlines\/whitespace and escapes double quotes with double quotes \r\n    string = re.sub(r'(\\r\\n|\\r|\\n)', '\\n', string) # Convert all newlines to unix newlines\r\n    string = string.strip() # Remove leading\/trailing whitespace\/blank lines\r\n    # string = re.sub(r'(\")', '\"\"', string) # Convert double quotes to double double quotes (e.g. 'foo \"bar\" blah' becomes 'foo \"\"bar\"\" blah')\r\n    return string\r\n# endDef\r\n\r\nclass Logger(object):\r\n    # Duplicate \"print\" output to a file.\r\n    def __init__(self, object):\r\n        self.terminal = sys.stdout\r\n        self.log = open(object, \"a\")\r\n\r\n    def write(self, message):\r\n        self.terminal.write(message)\r\n        self.log.write(message)  \r\n        \r\nif __name__ == \"__main__\":\r\n    main()\r\n<\/pre>\n<p>&nbsp;<\/p>\n<hr \/>\n<h3>ARQUIVO DE COMANDOS (exemplo)<\/h3>\n<pre># Ver 0.3 Command File\r\n$C hostname\r\n$C date<\/pre>\n<hr \/>\n<h3>ARQUIVO DE SERVIDORES (exemplo)<\/h3>\n<pre># Host name or ip address\r\nqaectlvbosapp503<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Esse script possibilita a execu\u00e7\u00e3o 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\u00f5es citadas no READ-ME \u2026 <a class=\"continue-reading-link\" href=\"https:\/\/megumijr.com\/blog\/biblioteca-de-scripts\/bssh\/\">Continue lendo <span class=\"meta-nav\">&rarr; <\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":292,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/pages\/294"}],"collection":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/comments?post=294"}],"version-history":[{"count":7,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/pages\/294\/revisions"}],"predecessor-version":[{"id":307,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/pages\/294\/revisions\/307"}],"up":[{"embeddable":true,"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/pages\/292"}],"wp:attachment":[{"href":"https:\/\/megumijr.com\/blog\/wp-json\/wp\/v2\/media?parent=294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}