Esse script executa o desligamento remoto (shutdown) de servidores Windows ou Linux através da execução remota de comandos via SSH. O desligamento pode ser feito em um servidor ou em todos os servidores cadastrados no arquivo de configuração.
READ-ME
RemoteOff ========= Shutdown remoto de servidores. SERVIDORES LINUX ================ Preparando servidores --------------------- * Permitir que usuários não root façam shutdown - Adicionar o grupo shutdown: $ sudo groupadd shutdown - Adicionar usuário ao grupo shutdown: $ sudo usermod -a -G shutdown - Configurar o 'sudo' para dar permissão aos usuários do grupo 'shutdown': $ sudo visudo - Adicionar ao final do arquivo aberto pelo 'visudo', as linhas abaixo: %shutdown ALL=(root) NOPASSWD: /sbin/reboot %shutdown ALL=(root) NOPASSWD: /sbin/poweroff %shutdown ALL=(root) NOPASSWD: /sbin/shutdown - No RedHat, comentar a linha que contém "Defaults requiretty" no mesmo arquivo. * OBS: Para que o faça shutdown, ele deve usar 'sudo', mas não será pedida nenhuma senha: $ sudo shutdown -h now SERVIDORES WINDOWS ================== Preparando servidores --------------------- * Instalar servidor SSH: OpenSSH ou freeSSHd - freeSSHd: http://www.freesshd.com/?ctt=download (mais simples de configurar) - OpenSSH: http://sshwindows.sourceforge.net/download/ (OpenSSH portado com Cygwin mínimo) ARQUIVO DE CONFIGURAÇÃO ======================= * Criar ou editar o arquivo "remoteoff.conf", uma linha por servidor, com as seguintes informações: # IP.........: Endereço IP do servidor remoto # PORT.......: Número da porta do ssh no serv. remoto # USER.......: Login do usuário ssh no serv. remoto # PASSWD.....: Senha do usuário ssh no serv. remoto # DELAY......: Tempo de espera em segundos antes de exec. o comando. # CMD........: Comando a ser executado no serv. remoto. * Exemplo de arq. de configuração (10.0.0.1 -> Linux; 10.0.0.2 -> Windows): # IP PORT USER PASSWD DELAY CMD # ------------ ----- -------- --------- ----- ------------------- 10.0.0.1 22 user user 0 sudo poweroff 10.0.0.2 22 suporte suporte 0 shutdown -s -t 0 * IMPORTANTE: chmod 700 remoteoff.conf ^^^^^^^^^^ EXECUTANDO SCRIPT ================= * Para executar shutdown em todos os servidores: $ ./remoteoff -s all * Para executar shutdown em um servidor somente: $ ./remoteoff -s 10.0.0.1
CÓDIGO
#!/usr/bin/python # -*- coding: UTF-8 -*- # Programa: remoteoff # Função: Realiza shutdown em todos os servidores. VERSION = "1.0" # # Arquivo de configuração: arquivo texto contendo as seguintes # informações para cada servidor, um servidor por linha. # IP.........: Endereço IP do servidor remoto # PORT.......: Número da porta do ssh no serv. remoto # USER.......: Login do usuário ssh no serv. remoto # PASSWD.....: Senha do usuário ssh no serv. remoto # DELAY......: Tempo de espera em segundos antes de exec. o comando. # CMD........: Comando a ser executado no serv. remoto. # # OBS1: SUDO deve ser configurado para executar "shutdown" ou "poweroff" # sem pedir senha. # # OBS2: Pode ser adicionado um comentário no final de cada linha # usando caracter "#". # # IMPORTANTE: chmod 700 remoteoff.conf # # Exemplo de arq. de configuração ## IP PORT USER PASSWD DELAY CMD ## --------- ---- -------- -------- ----- ------------------- # 10.0.0.1 22 user user 0 sudo poweroff # 10.0.0.2 22 suporte suporte 0 shutdown -s -t 0 import os, sys, time import getopt import paramiko # apt-get install python-paramiko #Variáveis globais CONF_FILE = "remoteoff.conf" # Nome do arquivo conf TEST = False SERVER = None # Para debug... # paramiko.util.log_to_file('remoteoff.log') def main(): global TEST, SERVER #Obtem argumentos getArgs() #Início #printLogMsg("Inicio de execucao.") #Remove arquivos antigos shutdownServers(TEST, SERVER, CONF_FILE) #Fim #printLogMsg("Fim de execucao.") #end main def getArgs(): """Obtem e faz consistência dos argumentos""" global TEST, SERVER #Captura parâmetros try: opts, args = getopt.getopt(sys.argv[1:], "hts:", \ ["help", "test", "server="]) except getopt.GetoptError, err: # Exibe ajuda e encerra: print str(err) # exibe algo como "option -a not recognized" usage() sys.exit(2) #endTry #Trata opções SERVER = None for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() elif o in ("-t", "--test"): TEST = True elif o in ("-s", "--server"): SERVER = a else: assert False, "unhandled option" #endfor #Verifica argumentos errmsg = "" if (opts == []): #Se não houver parametro nenhum... errmsg = "missing options" else: if (SERVER == None): errmsg = "missing option: -s" #endIf #endIf if (errmsg != ""): print errmsg usage() sys.exit(2) #endIf #endDef def usage(): """Exibe help""" global VERSION print print "RemonteOff v", VERSION print print "Uso: remoteoff [-h]|[[-t] -s {IP}|all]" print print "Realiza shutdown em um ou todos servidores remotos, " print "conforme especificado no arquivo remoteoff.conf" print print "Opções:" print "-h, --help Exibe o help de comandos." print "-s, --server Endereço IP do servidor desejado ou 'all' para todos." print "-t, --test Exibe os comandos que serão executados." print print "Exemplo:" print 'remoteoff -s all' print #endDef def shutdownServers(test, server, confFile): """Realiza shutdown do servidor especificado.""" serverFound = False # Abre arquivo de configuração conf = os.path.dirname(sys.argv[0]) + "/" + confFile fconf = open(conf) # Cria objeto SSH ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #Processa lista de servidores for line in fconf: # Linha do arquivo conf: # IP, PORT, USER, PASSWD, DELAY, CMD ln = line.split() if (len(ln) > 0) and (ln[0] != "#"): ip = ln[0] # host remoto dport = int(ln[1]) # porta ssh usr = ln[2] # usuario ssh pwd = ln[3] # senha do usuario ssh dly = float(ln[4]) # retardo para execução cmd = " ".join(ln[5:len(ln)]) # junta texto do comando cmd = cmd[0:cmd.find("#")] # remove comentários do final # Processa servidor da lista if (server == 'all') or (server == ip): serverFound = True print # Aguarda delay especificado if (dly > 0): printLogMsg("Aguardando %s seg..." % (dly)) time.sleep(dly) #endIf # Executa comando if (test == True): printLogMsg("Teste: %s" % (ip)) else: printLogMsg("Executando em %s: %s" % (ip, cmd)) try: ssh.connect(ip, port=dport, username=usr, password=pwd) except: printLogMsg("Erro ao conectar em %s!!" % (ip)) continue #endTry try: # Executa comando stdin, stdout, stderr = ssh.exec_command(cmd) except: printLogMsg("Erro ao executar comando %s" % (cmd)) pass #endTry # Mostra saída. for l in stdout.readlines(): print l.replace("\n", " ") #endFor ssh.close() #endIf #endIf #endIf #endFor if (serverFound == False): printLogMsg("Servidor %s nao configurado." % (server)) #endIf fconf.close() print #end shutdownServers #----- Funções Genericas ----------------------------------------------------- def printLogMsg(msg): """Imprime mensagem de log com data e hora correntes.""" t = time.localtime(time.time()) lmsg = "%02d/%02d/%d %02d:%02d - %s" % (t[2], t[1], t[0], t[3], t[4], msg) print lmsg sys.stdout.flush() return #end printLogMsg if __name__ == "__main__": main()
remoteoff.conf (exemplo)
# IP PORT USER PASSWD DELAY CMD # -------------- ----- --------- ----------- ----- -------------------------------- 10.0.0.1 22 user user 0 sudo poweroff 10.0.0.2 22 suporte suporte 0 shutdown -s -t 0