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