<?xml-stylesheet type="text/xsl" href="http://stoa.usp.br/leok/rss/rssstyles.xsl"?>
<rss version='2.0'   xmlns:dc='http://purl.org/dc/elements/1.1/'>
    <channel xml:base='http://stoa.usp.br/leok/'>
        <title><![CDATA[Leonardo K. T. Toshimitsu : Atividade]]></title>
        <description><![CDATA[Atividade de Leonardo K. T. Toshimitsu, no Stoa.]]></description>
        <generator>Elgg</generator>
        <link>http://stoa.usp.br/leok/</link>        
        <item>
            <title><![CDATA[Receba mensagens de seu servidor Linux via e-mail/SMS]]></title>
            <link>http://stoa.usp.br/leok/weblog/91102.html</link>
            <guid isPermaLink="true">http://stoa.usp.br/leok/weblog/91102.html</guid>
            <pubDate>Tue, 12 Apr 2011 15:18:11 GMT</pubDate>
		<dc:subject><![CDATA[bash]]></dc:subject>
		<dc:subject><![CDATA[sms]]></dc:subject>
		<dc:subject><![CDATA[script]]></dc:subject>
		<dc:subject><![CDATA[msmtp]]></dc:subject>
		<dc:subject><![CDATA[linux]]></dc:subject>
		<dc:subject><![CDATA[ip externo]]></dc:subject>
		<dc:subject><![CDATA[gmail]]></dc:subject>
		<dc:subject><![CDATA[external ip]]></dc:subject>
		<dc:subject><![CDATA[e-mail]]></dc:subject>
		<dc:subject><![CDATA[daemon]]></dc:subject>
		<dc:subject><![CDATA[automatization]]></dc:subject>
            <description><![CDATA[<table style="background-color: #cccccc; color: black; margin: 5px; padding: 5px;"  border="0">
<tbody>
<tr>
<td><strong>Tipo:</strong></td>
<td>Script</td>
</tr>
<tr>
<td><strong>Função:</strong></td>
<td>Automatizar o envio de mensagens do sistema</td>
</tr>
<tr>
<td><strong>Linguagens:</strong></td>
<td>BASH Script, C, AWK, SED</td>
</tr>
<tr>
<td><strong>Ferramentas:</strong></td>
<td>msmtp, gmail, daemon, cron, mail2sms</td>
</tr>
</tbody>
</table>
<p> </p>
<h3>Resumo</h3>
<p>Hoje vou lhes mostrar uma técnica para enviar mensagens de seu Linux e recebê-las via e-mail e/ou SMS, vulgo torpedo.</p>
<p>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.</p>
<p>É, 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.<br />Então, mãos à obra pessoal.<br />Nossa tarefa será dividida em 3 partes:</p>
<ol>
<li>Instalar o software de envio de e-mails;</li>
<li>Criar os scripts para ler automaticamente os e-mails;</li>
<li>Criar um script para ser executado pelo boot e pelo cron.</li>
</ol>
<hr />
<h3>
Índice</h3>
<table border="0">
<tbody>
<tr>
<td>1.</td>
<td><a href="#msmtp">Instalando o msmtp</a>;</td>
</tr>
<tr>
<td>1.1</td>
<td><a href="#pem">Gerando os certificados PEM</a>;</td>
</tr>
<tr>
<td>1.2</td>
<td><a href="#msmtprc">Configurando o .msmtprc</a>;</td>
</tr>
<tr>
<td>2.</td>
<td><a href="#wget">Lendo os e-mails com o wget</a>;</td>
</tr>
<tr>
<td>2.1</td>
<td><a href="#ssh">Acessando o servidor remoto</a>;</td>
</tr>
<tr>
<td>3.</td>
<td><a href="#sshome">Criando um script de checagem e envio</a>;</td>
</tr>
<tr>
<td>3.1</td>
<td><a href="#mailMyIp">O script rc.mailMyIp</a>;</td>
</tr>
<tr>
<td>4.</td>
<td><a href="#mail2sms">Direcionando seus e-mails para o celular</a>.</td>
</tr>
</tbody>
</table>
<p> </p>
<hr />
<h2>
     <a name="msmtp"> 1 - Enviando os e-mails: msmtp + gmail</a> </h2>
<p>
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:
  &lt; <a href="http://msmtp.sourceforge.net/doc/msmtp.html"  target="_blank">http://msmtp.sourceforge.net/doc/msmtp.html</a> &gt;
O código-fonte pode ser baixado aqui:
     &lt; <a href="http://sourceforge.net/projects/msmtp/"  target="_blank">http://sourceforge.net/projects/msmtp/</a>&gt;</p>
<p><strong>Instalação </strong></p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
<p>$ wget sourceforge.net/projects/msmtp/files/msmtp/1.4.23/msmtp-1.4.23.tar.bz2<br />$ tar xjvf msmtp-1.4.23.tar.bz2<br />$ cd msmtp-1.4.23<br />$ ./configure<br />$ make<br /># make install</p>
</div>
<p>
Se você estiver no Debian ou algum variante rode:  
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ sudo apt-get install `apt-cache search msmtp | awk '{print $1}'`</div>
<p>
Para configurar o msmtp eu me baseei <a href="http://www.andrews-corner.org/mutt.html"  target="_blank">neste</a> ó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á. 
</p>
<hr />
<h3>
       <a name="pem"> 1.1 - Gerando os certificados PEM</a></h3>
<p>
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:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ mkdir -pv $HOME/.certs &amp;&amp; cat &gt; $HOME/.certs/Equifax_Secure_CA.pem &lt;&lt; FIM
<pre>-----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</pre>
</div>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
<pre>$ cat &gt; $HOME/.certs/Thawte_Premium_Server_CA.pem &lt;&lt; FIM
<pre>-----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</pre>
</pre>
</div>
<p>
Hora de dizer ao openssl que temos os certificados:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ c_rehash $HOME/.certs/</div>
<p>
OK, tudo pronto para configurar o .msmtprc.
</p>
<hr />
<h3>
      <a name="msmtprc"> 1.2 - Configurando o .msmtprc</a></h3>
<p>
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é:
</p>
<table style="background-color: #cccccc; color: black; margin: 10px; padding: 5px;"  border="0">
<tbody>
<tr>
<td>Endereço no gmail:</td>
<td>zeh@gmail.com</td>
</tr>
<tr>
<td>Senha do gmail:</td>
<td>53nH*</td>
</tr>
<tr>
<td>USER: </td>
<td>zeh</td>
</tr>
<tr>
<td>HOSTNAME:</td>
<td>NAVI</td>
</tr>
</tbody>
</table>
<p>
E seu arquivo de configuração: 
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
<pre>$ cat &gt; $HOME/.msmtprc &lt;&lt; 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 </pre>
</div>
<p>
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: 
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ echo -e "Subject: Teste 1nnCan you read me?" | msmtp zeh@gmail.com </div>
<p>
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.
</p>
<hr />
<h2>
     <a name="wget"> 2 - Lendo e-mails com o wget</a></h2>
<p>
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:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
<a href="https://zeh:53nH*@mail.google.com/mail/feed/atom">https://zeh:53nH*@mail.google.com/mail/feed/atom</a> </div>
<p>
O mesmo efeito pode ser obtido sem um navegador através do auxílio do wget:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ /usr/bin/wget --secure-protocol=TLSv1 --timeout=3 -t1 -q -O - <a href="https://zeh:53nH*@mail.google.com/mail/feed/atom">https://zeh:53nH*@mail.google.com/mail/feed/atom</a> --no-check-certificate </div>
<p>
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:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
Subject: NAVI has booted, check your IP<br />
NAVI has booted at 2010-09-12 23:51:15<br />
NAVI IP=207.135.111.25</div>
<p>
Um grep 'IP=' no comando acima bastaria para retornar
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
&lt;summary&gt;NAVI has booted at 2010-09-12 23:51:15 NAVI IP=207.135.111.25&lt;/summary&gt; </div>
<p>
Mas este sed consumirá muito menos processos:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
sed '/NAVI IP/!d;s/.*=//g;s/&lt;.*//g;q' </div>
<p>
Ele se divide em quatro partes:
</p>
<table style="background-color: #cccccc; color: black; margin: 10px; padding: 5px;"  border="0">
<tbody>
<tr>
<td>/NAVI IP/!d</td>
<td>Não apague a linha que contiver o padrão NAVI(espaço)IP</td>
</tr>
<tr>
<td>s/.*=//g</td>
<td>Apague tudo do 'igual' para trás</td>
</tr>
<tr>
<td>s/&lt;.*//g</td>
<td>Apague tudo do início da tag '&lt;' para frente</td>
</tr>
<tr>
<td>q</td>
<td>Pegue apenas a primeira linha (o e-mail recente) e saia (quit)</td>
</tr>
</tbody>
</table>
<p>
Por fim, para não ficar com a senha em um script, simplemente compilei a chamada em C em um arquivo <a href="http://pastebin.com/vifNG9Ub"  target="_blank">naviip.c</a>:
</p>
<p>
<iframe src="http://pastebin.com/embed_iframe.php?i=V3ZDbKms"  style="border:medium none; width: 100%;"></iframe></p>
<p>
Compile assim:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ gcc naviip.c -Wall -ansi -o naviip</div>
<p>
Teste o programa:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ ./naviip </div>
<p>
De preferência jogue-o em algum lugar do seu PATH.<br />
Um dos diretórios abaixo:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ echo $PATH </div>
<p>
No Slackware o diretório $HOME está incluído.
Pessoalmente gosto de:
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
$ mkdir -pv $HOME/bin<br />
$ echo -e 'PATH=$PATH:$HOME/binnexport PATH' &gt;&gt; $HOME/.bashrc<br />
$ source $HOME/.bashrc</div>
<p>
e vou supô-lo de agora em diante.
</p>
<hr />
<h3>
        <a name="ssh"> 2.1 - Acessando o servidor remoto</a></h3>
<p>
É 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: 
</p>
<p>
<iframe src="http://pastebin.com/embed_iframe.php?i=iwghBW5F"  style="border:medium none; width: 100%;"></iframe></p>
<p>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 ;^)!<br />
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.<br />
<strong>ATENÇÃO</strong>: se você tiver um roteador na frente do servidor precisará abrir a porta correspondente e/ou fazer um port fowarding.
</p>
<hr />
<h3>
<a name="sshome"> 3 - Criando o script de checagem e envio</a></h3>
<p>
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:
</p>
<ol>
<li> Que ele seja chamado pelo /etc/rc.d/rc.local</li>
<li> Que ele seja executável</li>
</ol>
<p>
Adicione as linhas abaixo em seu /etc/rc.d/rc.local como root
</p>
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
<pre>if [ -x /etc/rc.d/rc.mailMyIp ]; then
   . /etc/rc.d/rc.mailMyIp start
fi</pre>
</div>
<p>
E vamos criar o rc.mailMyIp.
Há 3 técnicas que gostaria de mencionar:
</p>
<ol>
<li>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...</li>
<li>Eu obtenho o IP externo na linha 65:
<div class="code"  style="background-color:#000000; color:#00ff00; font-family:'Courier New', Courier, monospace">
IP=`curl -s <a href="http://www.whatismyip.com/automation/n09230945.asp`">http://www.whatismyip.com/automation/n09230945.asp`</a></div>
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 &lt; 0m0.200s, no nosso <em>zillertal</em>.</li>
<li>A estratégia para enviar o e-mail é a seguinte:<ol>
<li>A placa de rede deve ter um endereço válido (em casa é 192.x.y.z, por isso nas linhas 70-72);</li>
<li>Então na linha 79 damos 3 tiros de ping (-l3 -w1) para o CGI.br e contamos quantos chegam.<ol>
<li>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).</li>
<li>Se nenhum ping chegar, não tem internet. Desencane do resto.</li>
</ol></li>
<li>Se o ping chegou, busque o IP externo.</li>
<li>Pegue o IP lá do e-mail e compare os dois.</li>
<li>Se forem iguais não há nada a fazer.</li>
<li>Se forem diferentes envie o e-mail.</li>
<li>A versão start é para ser usada no boot, a versão check pelo cron, a única diferença é que o check é silencioso.</li>
</ol></li>
<li>Não esqueça de torná-lo executável!</li>
</ol>

<hr />
<h2>
        <a name="mailMyIp"></a> 3.1 - O script rc.mailMyIp</h2>
<p>
Uma cópia deste script está aqui: <a href="http://pastebin.com/3zqc7xeY"  target="_blank">http://pastebin.com/3zqc7xeY</a>
<iframe src="http://pastebin.com/embed_iframe.php?i=3zqc7xeY"  style="border:medium none; width: 100%;"></iframe>
</p>
<hr />
<h2>
        <a name="mail2sms"></a> 4. Direcionando seus e-mails para o celular</h2>
<p>Pessoalmente acho muito confortável receber meus e-mails no celular, há um serviço já disponível no site <a href="http://mail2sms.fr.nf/help.php"  target="_blank">http://mail2sms.fr.nf/help.php</a>, basta seguir as intruções.</p>
<p>Eu não comentei nada sobre o cron, mas será realmente necessário?</p>
<p>Enfim, dúvidas, sugestões, correções envie um e-mail para <a href="mailto:movebo@linux.ime.usp.br">movebo@linux.ime.usp.br</a>.</p>
<p>[]s<br />
;^)</p>]]></description>
        </item>
        
    </channel>
</rss>