| Tipo: | Script |
| Função: | Automatizar o envio de mensagens do sistema |
| Linguagens: | BASH Script, C, AWK, SED |
| Ferramentas: | msmtp, gmail, daemon, cron, mail2sms |
Resumo
Hoje vou lhes mostrar uma técnica para enviar mensagens de seu Linux e recebê-las via e-mail e/ou SMS, vulgo torpedo.
A função básica é receber mensagens relevantes do sistema, por exemplo, data e hora do boot, sucessivas tentativas de acesso remoto, execução de comandos não-autorizados... Como exemplo, o sistema deverá nos informar toda vez que obtivermos um novo IP externo para que possamos acessar remotamente o servidor de casa, transferir uns arquivos, etc; tivessem os IPs estáticos preços decentes aqui no Brasil isso seria irrelevante, mas o fato é que a grande maioria dos usuários domiciliares utilizam IPs dinâmicos e estes podem facilmente mudar por perda de sinal do modem, falta de energia, problemas no provedor de acesso... precisamos de algum modo simples e transparente de obtê-lo.
É, eu sei, existe o NoIP e o DynDNS, mas esta mesma solução pode resolver outros problemas para outros usuários, que simplesmente não consigo prever.
Então, mãos à obra pessoal.
Nossa tarefa será dividida em 3 partes:
- Instalar o software de envio de e-mails;
- Criar os scripts para ler automaticamente os e-mails;
- Criar um script para ser executado pelo boot e pelo cron.
Índice
1 - Enviando os e-mails: msmtp + gmail
O msmtp é um cliente capaz de enviar e-mails para qualquer servidor SMTP, é um bom substituto simplificado para o sendmail. Sua documentação pode ser lida aqui: < http://msmtp.sourceforge.net/doc/msmtp.html > O código-fonte pode ser baixado aqui: < http://sourceforge.net/projects/msmtp/>
Instalação
$ wget sourceforge.net/projects/msmtp/files/msmtp/1.4.23/msmtp-1.4.23.tar.bz2
$ tar xjvf msmtp-1.4.23.tar.bz2
$ cd msmtp-1.4.23
$ ./configure
$ make
# make install
Se você estiver no Debian ou algum variante rode:
Para configurar o msmtp eu me baseei neste ótimo artigo do Andrew's Corner. Como agora o gmail só permite POP e SMTP via conexão SSL, precisaremos gerar dois certificados PEM (Privacy-enhanced Electronic Mail). Vamos lá.
1.1 - Gerando os certificados PEM
O Andrew criou um script em Perl para gerarmos localmente os certificados e só me levou meia hora para configurar todas os módulos que o Perl necessitava no Slack. Então, por caridade, pus o código abaixo, basta copiar e colar:
-----BEGIN CERTIFICATE----- MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf 8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t UCemDaYj+bvLpgcUQg== -----END CERTIFICATE----- FIM
$ cat > $HOME/.certs/Thawte_Premium_Server_CA.pem << FIM-----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW 8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 70+sB3c4 -----END CERTIFICATE----- FIM
Hora de dizer ao openssl que temos os certificados:
OK, tudo pronto para configurar o .msmtprc.
1.2 - Configurando o .msmtprc
Bom, criados os certificados, é hora de fazer nosso arquivo de configuração. Para evitar confusão entre o que é variável, função, comando e dados a serem preenchidos, o arquivo será configurado para o Zé abaixo. Mude para seus próprios dados. Eis, aí o Zé:
| Endereço no gmail: | zeh@gmail.com |
| Senha do gmail: | 53nH* |
| USER: | zeh |
| HOSTNAME: | NAVI |
E seu arquivo de configuração:
$ cat > $HOME/.msmtprc << FIM account default host smtp.gmail.com port 587 from zeh@gmail.com tls on tls_starttls on #tls_trust_file /home/zeh/.certs/Thawte_Premium_Server_CA.pem tls_trust_file /home/zeh/.certs/Equifax_Secure_CA.pem auth on user zeh@gmail.com password 53nH* logfile ~/.msmtp.log FIM $ chmod 600 $HOME/.msmtprc
Note que o chmod é muito importante já que não queremos que outros usuários possam ler nossa senha. Vamos testar para ver se deu tudo certo:
Veja em sua caixa de entrada se o e-mail chegou. Em casa ele leva pouco mais de 4 segundos para enviar o e-mail. Agora que já podemos enviar os e-mails, vamos ver como lê-los.
2 - Lendo e-mails com o wget
Há muitas formas diferentes de ler e-mails pelo bash, eu vou usar uma função pouco explorada do gmail, são os Atom Feeds. Eles podem ser naturalmente acessados via https através de seu login e senha. No caso do Zé é só jogar a URL abaixo no navegador:
O mesmo efeito pode ser obtido sem um navegador através do auxílio do wget:
Reparou que a saída está em XML? Se o e-mail enviado for bem padronizado será fácil analisá-lo. Nosso objetivo é fazer algo como:
NAVI has booted at 2010-09-12 23:51:15
NAVI IP=207.135.111.25
Um grep 'IP=' no comando acima bastaria para retornar
Mas este sed consumirá muito menos processos:
Ele se divide em quatro partes:
| /NAVI\ IP/!d | Não apague a linha que contiver o padrão NAVI(espaço)IP |
| s/.*=//g | Apague tudo do 'igual' para trás |
| s/<.*//g | Apague tudo do início da tag '<' para frente |
| q | Pegue apenas a primeira linha (o e-mail recente) e saia (quit) |
Por fim, para não ficar com a senha em um script, simplemente compilei a chamada em C em um arquivo naviip.c:
Compile assim:
Teste o programa:
De preferência jogue-o em algum lugar do seu PATH.
Um dos diretórios abaixo:
No Slackware o diretório $HOME está incluído. Pessoalmente gosto de:
$ echo -e 'PATH=$PATH:$HOME/bin\nexport PATH' >> $HOME/.bashrc
$ source $HOME/.bashrc
e vou supô-lo de agora em diante.
2.1 - Acessando o servidor remoto
É claro que não queremos manipular o endereço nós mesmos, um código deve fazer isso. É mais rápido, é mais fácil. Este script deve lhe ajudar:
Repare que por muita ou pouca paranóia eu configurei meu SSH para escutar atrás de uma porta não-padrão. Normalmente usamos a porta 22, escolhi outra aleatória, a 2247.
Seria interessante fazer um script no servidor para alterar aleatoriamente esta porta e informá-la no e-mail, melhor ainda seria usar o iptables para fazer um Port-Knocking, ou apenas permitir acesso remoto vindo de 143.107.45.30 ;^)!
Repare também que o cliente só tentará se conectar no servidor se realmente houver um SSH escutando atrás daquela porta, o que evita a tentativa infrutífera de acesso a outra máquina que, pelos motivos mais diversos, está agora com nosso antigo IP.
ATENÇÃO: se você tiver um roteador na frente do servidor precisará abrir a porta correspondente e/ou fazer um port fowarding.
3 - Criando o script de checagem e envio
Vamos agora criar um script chamado rc.mailMyIp que deverá rodar no boot e em certo intervalo de tempo (cron). No Slackware para que um script seja executado ao final do boot, duas coisas são necessárias:
- Que ele seja chamado pelo /etc/rc.d/rc.local
- Que ele seja executável
Adicione as linhas abaixo em seu /etc/rc.d/rc.local como root
if [ -x /etc/rc.d/rc.mailMyIp ]; then . /etc/rc.d/rc.mailMyIp start fi
E vamos criar o rc.mailMyIp. Há 3 técnicas que gostaria de mencionar:
- Na função MSG() envio os dados para um arquivo. Talvez você prefira comparar o IP atual com o que está no arquivo. No dia-a-dia achei mais fácil comparar sempre com o que está legível no e-mail, vai que você deleta a mensagem...
- Eu obtenho o IP externo na linha 65: Basicamente uso o curl para acessar um site que informa meu IP, esta chamada ASP li em algum lugar das "Funções ZZ" do Aurélio, o IP já vem limpinho e como não precisamos parsear foi o campeão no teste do time{}: real < 0m0.200s, no nosso zillertal.
- A estratégia para enviar o e-mail é a seguinte:
- A placa de rede deve ter um endereço válido (em casa é 192.x.y.z, por isso nas linhas 70-72);
- Então na linha 79 damos 3 tiros de ping (-l3 -w1) para o CGI.br e contamos quantos chegam.
- Dê preferência a usar o IP, porque em caso de DNS inacessível, o tempo de espera cai bastante. Caso o DNS esteja DISPONÍVEL há um ganho de 17% (OK, 0.192s em média quando este post foi escrito).
- Se nenhum ping chegar, não tem internet. Desencane do resto.
- Se o ping chegou, busque o IP externo.
- Pegue o IP lá do e-mail e compare os dois.
- Se forem iguais não há nada a fazer.
- Se forem diferentes envie o e-mail.
- A versão start é para ser usada no boot, a versão check pelo cron, a única diferença é que o check é silencioso.
- Não esqueça de torná-lo executável!
3.1 - O script rc.mailMyIp
Uma cópia deste script está aqui: http://pastebin.com/3zqc7xeY
4. Direcionando seus e-mails para o celular
Pessoalmente acho muito confortável receber meus e-mails no celular, há um serviço já disponível no site http://mail2sms.fr.nf/help.php, basta seguir as intruções.
Eu não comentei nada sobre o cron, mas será realmente necessário?
Enfim, dúvidas, sugestões, correções envie um e-mail para movebo@linux.ime.usp.br.
[]s
;^)
Palavras-chave: automatization, bash, daemon, e-mail, external ip, gmail, ip externo, linux, msmtp, script, sms
Esta mensagem está sob a licença CreativeCommons Atribuição, Não-Comercial.

1 voto
