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:
https://zeh:53nH*@mail.google.com/mail/feed/atom
O mesmo efeito pode ser obtido sem um navegador através do auxílio do wget:
/usr/bin/wget --secure-protocol=TLSv1 --timeout=3 -t1 -q -O - https://zeh:53nH*@mail.google.com/mail/feed/atom --no-check-certificate
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:
Subject: NAVI has booted, check your IP
NAVI was booted at 2010-09-12 23:51:15
NAVI IP=207.135.111.25
Um grep 'IP=' no comando acima bastaria para retornar:
<summary>NAVI was booted at 2010-09-12 23:51:15 NAVI IP=207.135.111.25</summary>
Mas este sed consumirá muito menos processos:
sed '/NAVI IP/!d;s/.*=//g;s/<.*//g;q'
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 último e-mail) e saia (quit)
Por fim, para não ficar com a senha em um script, simplesmente compilei a chamada em C em um arquivo naviip.c:
#include <stdio.h>
#include <stdlib.h>
int main() {
system( "/usr/bin/wget --secure-protocol=TLSv1 --timeout=3 -t1 -q -O - https://zeh:53nH*@mail.google.com/mail/feed/atom --no-check-certificate | sed '/NAVI IP/!d;s/.*=//g;s/<.*//g;q'" );
return 0;
}
Compile assim:
gcc naviip.c -Wall -ansi -o naviip
Teste o programa:
./naviip
De preferência jogue-o em algum lugar do seu PATH.
echo $PATH
No Slackware o diretório $HOME está incluído. Pessoalmente gosto de:
mkdir -pv $HOME/bin
$ echo -e 'PATH=$PATH:$HOME/bin
export 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:
cd $HOME/bin && touch sshhome && chmod 700 sshome && cat > sshhome << FIM
#!/bin/bash
NAVIIP=`which naviip`
NMAP=`which nmap`
echo -n "Retrieving your homebox IP through gmail: "
IP=`$NAVIIP`
if [ -n "$IP" ] && [ "$IP" != '
' ]
then
echo -en "$IP
Scanning the service behind secret port: "
SCAN=` $NMAP -sV -p2247 $IP | sed '/2247/!d' `
STATE=` echo $SCAN | awk '{print $2}' `
SERVICE=` echo $SCAN | awk '{print $4" "$5}'`
echo $SERVICE $STATE
if [ "$STATE" = "open" ]; then
echo "Proceeding with ssh connection: "
ssh -l zeh -p 2247 $IP
fi
else
echo -e "FAILED.
Sorry, I could not retrieve your IP"
echo "Exiting..."
fi
FIM
Repare que por muita ou pouca paranoia 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! (TODO ;^)
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 os mais diversos, está agora com nosso antigo IP.