Archivo de Octubre 2008

h1

Comprobar si un email es válido (II)

25.Octubre.2008

Ya he terminado el script que comprueba si un email es válido o no. Básicamente hace lo que comenté en el post anterior:

  1. Averigua los registros MX del dominio
  2. Los va probando hasta encontrar uno que funcione
  3. Simula el envío de un email para ver que dice el servidor sobre la dirección

He colgado un ejemplo con mensajes de debug por si alguien quiere ver como funciona o probarlo. Si estás interesado en el código, pídemelo.

Algunos problemas que tiene:

  1. Puede validar alguna dirección como correcta sin serlo ya que ciertos servidores como hotmail se lo tragan todo (seguramente para evitar comprobaciones masivas por spammers).
  2. Hay servidores como yahoo que, aparte de no implementar correctamente el protocolo, muchos de sus servidores MX rechazan las peticiones.
  3. Otros servidores, como telepolis.es dan error: 550 Reverse DNS lookup failed for host 64.235.***.***. Pero supongo que eso es problema de ellos.
  4. No es una comprobación inmediata. Algunos servidores se toman su tiempo.
h1

Comprobar si un email es válido

24.Octubre.2008

Muchos usuarios al registrarse en la web escriben direcciones de email inválidas (hotmeil.com, hotmaill.com, jotmail.com… y cosas peores, no es broma!) y esto hace que sendmail se vuelva loco. Constantemente trata de reenviarlos, resolver dominios que no existen o conectar a puertos que no responden… esto provoca que los logs de error crezcan de una forma espectacular y consume recursos de una forma que no había visto antes (sin duda por una configuración chapucera mía). Pero como la documentación de sendmail es para volverse loco y no me apetece probar otras cosas (como qmail o mail() de PEAR), haré un script en PHP que me haga la tarea de comprobar direcciones y mandar emails.

¿Cómo saber si una dirección es válida? Lo más simple sería mirar si responde a un ping.

sonic@XTC:~$ ping gmail.com
PING gmail.com (64.233.161.83) 56(84) bytes of data.
64 bytes from od-in-f83.google.com (64.233.161.83): icmp_seq=1 ttl=240 time=183 ms
64 bytes from od-in-f83.google.com (64.233.161.83): icmp_seq=2 ttl=240 time=224 ms
--- gmail.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 183.999/204.274/224.550/20.280 ms

Pero claro, eso no significa nada. Podría ser un servidor de cualquier cosa. Habría que comprobar el puerto 25, pero…

sonic@XTC:~$ telnet gmail.com 25
Trying 64.233.161.83...
Trying 66.249.91.83...
Trying 209.85.171.83...
telnet: Unable to connect to remote host: Connection timed out

Lo más normal es que no responda ya que antes deberíamos mirar los registros MX. Se suelen utilizar distintos servidores para el correo. Es muy fácil de averiguar.

sonic@XTC:~$ dig -t MX gmail.com
; <<>> DiG 9.4.2-P2 <<>> -t MX gmail.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25761
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 4, ADDITIONAL: 10
;; QUESTION SECTION:
;gmail.com.            IN    MX
;; ANSWER SECTION:
gmail.com.        244    IN    MX    10 alt2.gmail-smtp-in.l.google.com.
gmail.com.        244    IN    MX    50 gsmtp147.google.com.
gmail.com.        244    IN    MX    50 gsmtp183.google.com.
gmail.com.        244    IN    MX    5 gmail-smtp-in.l.google.com.
gmail.com.        244    IN    MX    10 alt1.gmail-smtp-in.l.google.com.
;; AUTHORITY SECTION:
gmail.com.        241375    IN    NS    ns4.google.com.
gmail.com.        241375    IN    NS    ns1.google.com.
gmail.com.        241375    IN    NS    ns2.google.com.
gmail.com.        241375    IN    NS    ns3.google.com.
;; ADDITIONAL SECTION:
gmail-smtp-in.l.google.com.   238   IN    A    209.85.129.114
gmail-smtp-in.l.google.com.   238   IN    A    209.85.129.27
alt1.gmail-smtp-in.l.google.com. 44 IN    A    209.85.147.27
alt2.gmail-smtp-in.l.google.com. 37 IN    A    209.85.133.27
alt2.gmail-smtp-in.l.google.com. 37 IN    A    209.85.133.114
gsmtp147.google.com.        4720    IN    A    209.85.147.27
gsmtp183.google.com.        5711    IN    A    64.233.183.27
ns1.google.com.           345591    IN    A    216.239.32.10
ns2.google.com.           336560    IN    A    216.239.34.10
ns4.google.com.           336560    IN    A    216.239.38.10
;; Query time: 273 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Fri Oct 24 20:58:36 2008
;; MSG SIZE  rcvd: 390

Ahora sí podemos hacer un telnet al servidor correcto:

sonic@XTC:~$ telnet gmail-smtp-in.l.google.com 25
Trying 72.14.221.114...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP
HELO hispashare.com
250 mx.google.com at your service

Ya estamos conectados al servidor de correo de google y podemos comunicarnos con él. Para comprobar si pepe@gmail.com es válido podemos hacer lo siguiente:

sonic@XTC:~$ telnet gmail-smtp-in.l.google.com 25
Trying 209.85.129.27...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP
HELO hispashare.com
250 mx.google.com at your service
MAIL FROM: <webmaster@hispashare.com>
250 2.1.0 OK
RCPT TO: <pepe@gmail.com>
550-5.1.1 The email account that you tried to reach does not exist. Please
550-5.1.1 try double-checking the recipient's email address for typos
550-5.1.1 or unnecessary spaces. Learn more at
550 5.1.1 http://mail.google.com/support/bin/answer.py?answer=6596
QUIT
221 2.0.0 closing connection
Connection closed by foreign host.

Y con estos pasos ya sabemos si un servidor existe, si es de correo y si la dirección es válida. Con una dirección correcta el resultado sería así:

RCPT TO: <hispashare@gmail.com>
250 2.1.5 OK

Eso es todo. No parece complicado de implementar en PHP así que este fin de semana haré mi propia función mail() para comprobar direcciones y mandar correo. Así podré quitar sendmail del servidor, que no me da más que dolores de cabeza (sí, lo más probable es que tenga algo mal configurado).

h1

El registro de usuarios

19.Octubre.2008

Es una ironía

Como habréis podido comprobar, he puesto un cuadro para registrarse en la web.

De momento, para el usuario normal no sirve para nada. Mi intención es que más adelante (cuando lo programe…) los usuarios registrados podrán comentar las películas, crearse un listado de sus preferidas y compartirlo (algo así como youtube). No es necesario estar registrado para bajarse las películas. Y, por supuesto, no se revelará ningún dato privado ni tu e-mail a nadie.

Sin embargo, actualmente el registro sirve para que los colaboradores de la web, los cuales tienen una cuenta con más privilegios, puedan publicar sus trabajos y modificarlos si fuese necesario. Anteriormente los colaboradores tenían acceso total a la web lo cual era un grave problema de seguridad y, por desgracia, sólo me podía permitir confiar en unos pocos. En cambio ahora, cada colaborador sólo tiene acceso a sus cosas. Esto me permitirá abrir el sistema a más gente que esté interesada en compartir sus trabajos.

h1

Don’t Panic!

17.Octubre.2008

Estos días el servidor de HispaShare ha tenido problemas.

Por un lado, como estoy terminando el sistema de usuarios, mientras hago pruebas siempre me suelo cargar algo ya que programo directamente con los archivos del servidor (práctica no recomendada).

Por otro lado hace dos días la página no cargaba, conecté al servidor por SSH y todo estaba normal, reinicié el servidor y la página seguía sin ir. Que raro. Pero al hacer un man para obtener ayuda de un comando me dice que no tiene espacio en la partición raíz. Así que empecé a mirar y lo que pasaba es que los logs habían crecido tanto (por ejemplo, el syslog ocupaba 11 gigas) que no quedaba espacio para nada más. Pensé que sería normal ya que en cuatro años nunca se me había ocurrido limpiar las telarañas. Lo borré todo y aparentemente todo volvía a la normalidad.

Pero este mediodía llego de trabajar y me dicen por el chat que la web no funciona. El mismo fallo, que los logs ocupaban toda la partición… Al final resulta que había configurado mal el servidor de correo. Pero lo peor de todo es que las tablas de la base de datos se habían corrompido ya que no se pudieron salvar correctamente al no haber espacio… Ahí ya me empiezo a preocupar porque la última copia de seguridad es de hace meses. ¿La solución mágica? El comando “repair table” de mySQL, que ya me ha salvado la vida demasiadas veces…