emporio armani,fake rolex for sale,rolex sea dweller,panerai,iwc,richard mille,replica watches,bell ross,a lange sohne,cheap replica watches,jaeger lecoultre,rolex explorer,corum,rolex milgauss,breguet,piaget,franck muller,chopard
Archives for category: Networking

Yesterday I did a talk at Xing offices in Barcelona. It was about some tips on how to send emails massively from a Ruby on Rails application without being tagged as a spammer by Hotmail, Gmail or Yahoo. I’m not a dedicated expert on this, but I’ve been learning these things while developing last internet site, and I thought it may be also interesting for other developers.
Here are the slides (in english) of the presentation, formerly named “Massive emailing with Linux, Postfix and Ruby on Rails“.

Here is the PDF for downloading.

Pair programming es una técnica en la que dos programadores trabajan con una misma consola, sobre el mismo código. Normalmente uno hace la función de driver y el otro la de observer. El objetivo es evidente: crear un mejor código, a la vez que conseguir que ambos programadores lo conozcan con el mismo nivel de profundidad.

Hoy tenía un problema con el proyecto en el que estoy trabajando, y pedí a Mauro que me echase un cable a ver si entre los dos conseguíamos solucionarlo. Él estaba en su casa, y yo en la mía. Los ingredientes para cocinar un pair programming realmente fluído en remoto:

  • Port forwarding: un puerto para el acceso remoto por SSH y otro para el acceso al servidor de aplicaciones (acceso web)
  • screen: Usando una versión ligeramente modificada del screenrc de r0sk. Usamos tres consolas: [0] log del servidor, [1] vim con el código, [2] una bash para hacer accesos de mysql u otras cosas que necesitemos
  • vim: con los controles mapeados para trabajar con tabs, y el plugin de FuzzyFinderTextMate para buscar y abrir archivos… así se puede hacer todo en una sola consola
  • Skype: Para hablar todo el rato durante la sesión de programación

Los programadores maceros que usan TextMate suelen hacer el pair programming usando VNC, pero aunque no lo he probado pongo las dos manos en el fuego a que tiene que ser una cagada. La pareja screen+vim es brutal por lo lightweight y lo flexible, y consume muy poquito ancho de banda con lo que la comunicación del conjunto (ssh + skype) es perfecta.

La experiencia ha sido GENIAL, y hemos resuelto el problema en aproximadamente 1 hora. Es como trabajar en pair programming en local, tocando el mismo código y comentando todo el rato. Ha sido una pasada, y lo recomiendo a todos los programadores que trabajen separados físicamente del resto del equipo.

Valga cuanto menos a modo de recordatorio personal.

Un virtualhost habitual (atención al ==):

$HTTP["host"] == "www.something.net" {

Para que www.something.net, www.something.com o www.something.lo_que_sea apunten al mismo documentroot (atención al =~):

$HTTP["host"] =~ "www.something" {

Y para que www.something.net y www.otherthing.net apunten al mismo documentroot:

$HTTP["host"] =~ "(www.something.net|www.otherthing.net)" {

El el trabajo usamos ISPConfig como gestor de paneles de alojamiento. En los servidores de nuestros clientes lo instalamos también, porque por el momento es la opción libre más completa y funcional a nivel de integración de servicios.
Todo funciona perfecto, salvo que hoy un cliente me ha reportado un fallo bastante importante: los emails enviados entre usuarios de un mismo dominio llegaban marcados como SPAM.

El problema…

Al hacer las pruebas, he comprobado que efectivamente el report de SpamAssassin señalaba lo siguiente:

Content analysis details:   (6.4 points, 5.0 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 0.5 RCVD_IN_PBL            RBL: Received via a relay in Spamhaus PBL
                            [87.221.36.208 listed in zen.spamhaus.org]
 1.6 RCVD_IN_SORBS_DUL      RBL: SORBS: sent directly from dynamic IP address
                            [87.221.36.208 listed in dnsbl.sorbs.net]
 3.2 HELO_LH_HOME           HELO_LH_HOME
 0.1 RDNS_DYNAMIC           Delivered to trusted network by host with
                            dynamic-looking rDNS
 1.0 AWL                    AWL: From: address is in the auto white-list

En el ejemplo se ve como SpamAssassin busca la IP de mi despacho (dinámica) en varias blacklists. Es lo que no alcanzo a entender… el relay se hace a través de un MTA autenticado, ¿por qué SA busca la IP de orígen? ¿No deberia basarse en la IP del MTA?

En las cabeceras del mensaje se lee lo siguiente

Received: from wrk1.sdv.home (wrk1.sdv.home [127.0.0.1])
 by wrk1.sdv.home (8.14.0/8.14.0) with ESMTP id m32BTkIg029558
 for ; Wed, 2 Apr 2008 13:29:54 +0200

Received: from mail.sysdivision.com [64.22.103.200]
 by wrk1.sdv.home with POP3 (fetchmail-6.3.8)
 for  (single-drop); Wed, 02 Apr 2008 13:29:54 +0200 (CEST)

Received: from localhost by sdv1.sysdivision.com
 with SpamAssassin (version 3.2.1);
 Wed, 02 Apr 2008 13:29:18 +0200

La primera línea responde a mi workstation y evidentemente apunta a localhost porque así lo defino en mi /etc/hosts.
La siguiente línea es la del MTA una vez que recibe el mensaje, y la última es el servidor entregando el mensaje al agente de delivery. En este caso Postfix lo filtra con procmail, quien finalmente lo mete en el buzón (Maildir).

Lo que no entiendo es: si el relay está autenticado, SpamAssassin debería fijarse en la dirección del MTA que procesa el mensaje, no en el MUA que lo escribe y lo envía.

La solución…

Bueno, en cualquier caso es evidente que cmo mi despacho tiene una IP dinámica cualquier RBL lo marcará como Spam. Así, el truco está en deshabilitar la consulta a RBL’s desde SpamAssassin (ya la tengo hecha directamente desde Postfix).
En el caso de ISPConfig se debe configurar en el siguiente fichero (parto en dos líneas por problema de espacio):

/home/admispconfig/ispconfig/tools/
/spamassassin/etc/mail/spamassassin/local.cf

Añadir al final la siguiente línea

skip_rbl_checks 1

Entonces queda otro problema, éste último más raro si cabe: SpamAssasin sigue marcando los mensajes como Spam. En este caso el report ya no incluye los checks de RBL:

Content analysis details:   (4.3 points, 3.5 required)

 pts rule name              description
---- ---------------------- --------------------------------------------------
 3.7 HELO_LH_HOME           HELO_LH_HOME
 0.0 BAYES_50               BODY: Bayesian spam probability is 40 to 60%
                            [score: 0.4950]
 0.1 RDNS_DYNAMIC           Delivered to trusted network by host with
                            dynamic-looking rDNS
 0.4 AWL                    AWL: From: address is in the auto white-list

EL test HELO_LH_HOME, para el que existe muy poquita documentación, busca en la cabecera el orígen del mensaje, para saber si proviene de una red trusted o no. En la configuración de Postfix pueden establecerse las redes trusted, pero claro no voy a confiar en direcciones externas a mi red local, eso sería tanto como hacer un relay promiscuo.

Bien pues eso se arregla en Postfix, haciendo que añada una línea a las cabeceras, diciendo que el relay está autenticado. De esa forma SpamAssassin no hará caso del untrusted relay.

Añadir la siguiente línea al fichero /etc/postfix/main.cf:

smtpd_sasl_authenticated_header = yes

Después de reiniciar Postfix, todo irá bien :-)

NOTA: Este proceso no soluciona el mismo problema cuando se usa TLS. Para ese caso, echar un ojo a este patch, que parece que arregla la papeleta pero no es demasiado recomendable porque destruye el histórico de las cabeceras Received:

Espero con esto salvar alguna vida (yo casi la pierdo tirándome a la vía del tren :-D)

3comwifi.jpgLlevo un tiempo comprobando las constantes caídas de ADSL desde que cambié mi router 3com officeconnect por un D-Link 524T sin wifi. Supongo que no es normal que caiga, porque el cambio lo hice en mi oficina, donde no hay e-mule ni aplicaciones que descarguen información consumiendo el ancho de banda de forma masiva.

Hace algún tiempo experimenté un caso similar en la oficina de un cliente, con el mismo router y el mismo problema. Tras realizar 846328946 pruebas llegamos a la conclusión de que la culpa la tenía la VPN que les había montado con OpenVPN. Si paraba el servidor OpenVPN entonces la conexión no se caía. Es muy raro, lo reconozco.
En el caso de mi oficina la situación es similar, porque tengo un servidor OpenVPN con el que conecto desde casa y desde el portátil. Así que supuse que el problema era el mismo.
Read the rest of this entry »

spam.jpgBueno pues la solución que posteé ayer era buena, pero tenía un pequeño fallo de funcionamiento en el que no había caído… comprobé durante las pruebas que los mensajes que enviaba llegaban a su destino correctamente, de lo que no me dí cuenta es de que también se enviaban al remitente :D

La explicación es fácil: se invoca a procmail con los parámetros ${sender} ${recipient} y luego ejecutar el envío desde el filtro usando “$@” como destino, se pasa entre los argumentos el primer parámetro, el sender, y por tanto también a él le llega copia del mensaje.

Obsesionado, he buscado durante horas y horas la manera de recortar la lista de argumentos desde dentro del procmailrc, pero no he sido capaz, ni dentro de los filtros ni de forma global. Si alguien lo consigue, aunque sea ya por mero desafío, que lo diga heheh

Finalmente, mi amigo fr3nd me ha hablado de Amavisd, y acostumbrado a MIMEDefang no me ha sido difícil de implementar. La verdad es que lleva en producción todo el día y de momento va bastante bien.

Las instrucciones mínimas son las siguientes:

1) Instalar amavisd

2) Editar el fichero de configuración (/etc/amavisd.conf)

3) Modificar el contenido de las siguientes líneas para personalizarlo con el dominio principal de la máquina:

$mydomain = 'somesite.net'
$myhostname = 'boxname.somesite.net'

4) Leer el resto de la configuración para acabar de ajustar los parámetros deseados (tamaño máximo de correos enviados, política por defecto ante virus y spam, sistemas de filtrado antivirus…)

5) Modificar el master.cf para añadir un transport con el filtro:

# Amavisd
smtp-amavis unix -      -       y       -       2  smtp
-o smtp_data_done_timeout=1200
-o smtp_send_xforward_command=yes
-o disable_dns_lookups=yes
-o max_use=20

127.0.0.1:10025 inet n  -       n       -       -  smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o smtpd_restriction_classes=
-o smtpd_delay_reject=no
-o smtpd_client_restrictions=permit_mynetworks,reject
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=reject_unauth_pipelining
-o smtpd_end_of_data_restrictions=
-o mynetworks=127.0.0.0/8
-o smtpd_error_sleep_time=0
-o smtpd_soft_error_limit=1001
-o smtpd_hard_error_limit=1000
-o smtpd_client_connection_count_limit=0
-o smtpd_client_connection_rate_limit=0

6) Modificar el main.cf para añadir el socket de comunicación con Amavis:

# Amavisd
content_filter = smtp-amavis:[127.0.0.1]:10024

7) Lanzar amavis (avamisd start) y reiniciar postfix

spam.jpgBueno pues esto ya me traía de caeza. Se trata de filtrar el correo con procmail (adorado Procmail) en un sistema de correo Postfix con usuarios virtuales.

Cabe decir que a mí personalmente no me gusta la idea de eliminar el spam antes de entregarlo, pero es cuestión de ahorro de ancho de banda, uno de los bienes más preciados a nivel mundial, y de los más altamente cotizados en el mercado del hosting español (y nos quejamos de la gasolina…)

EL roblema radica en que, siendo usuarios físicos basta con poner un fichero .procmailrc en cada home, que compruebe si el mensaje está tageado como spam, y entonces lo borre. Ahora bien, siendo usuarios virtuales (mapeados en mysql) la cosa cambia y el fichero de filtrado se lee por defecto de /etc/procmailrc (en FreeBSD como es el caso, /usr/local/etc/procmailrc).

No es que eso suponga un problema, pero el caso es que no he sabido encontrar por ahí la manera de pasar el filtro primero a Spamassassin, luego dejar caer el mensaje en procmail (spamc -e, prueba superada) para que siga la ejecución del transport, y finalmente de procmail pasarlo al binario sendmail de postfix. Este último paso es el que me mataba.

Bien, pues he encontrado la solución, y la dejo aquí por si a alguien le sirve. Seguro que a muchos usuarios de VHCS les será útil :-)

En el transport he incorporado el filtro de procmail en el lugar del binario de sendmail, que invoco después desde el procmailrc. Queda así (master.cf):

spamassassin unix -     n       n       -       -       pipe
user=nobody argv=/usr/local/bin/spamc -f -e
/bin/procmail -m /usr/local/etc/procmailrc ${sender} ${recipient}

Después, el procmailrc que dejo por defecto es este:

FROM="<$1>"

:0
* ^X-Spam-Status: Yes
/dev/null

:0
! -f $FROM "$@"

Recogiendo las direcciones de orígen y destino del entorno, todo el problema se resuelve. Ahora bien… la sintaxis no es muy deducible, y en el site oficial de procmail la documentación no brilla precisamente por su abundancia.

Por otro lado, en los ejemplos de Spamassassin recomiendan filtrar por la cabecera X-Spam-Level, pero eso significa que para aumentar o disminuir el nivel a partir del que hay que borrar, es necesario editar el procmailrc y añadir o quitar asteriscos a la puntuación. Filtrando por status sólo hay que poner la puntuación en el local.cf de Spamassassin y relanzar el demonio.

Y eso es todo :-)

Hoy, cansado de entrar por ssh al server del curro para buscar en los logs la IP de mi casa entre los accesos POP3, he decidido gastar 5 minutitos en montarme un dns update para la IP dinámica que me da Jazztel. Así podré acceder a mi casa por nombre en lugar de comerme el coco cada vez.

Bueno, en realidad es algo muy muy sencillito de hacer, pero por si acaso a alguien le interesa lo explico aquí.

Primero hay que instalar el software de Bind en la máquina cliente, que tiene las herramientas necesarias para generar las claves de actualización de zonas. Una vez instalado hay que crear una clave para la zona que se quiere actualizar (una para cada zona, eso es obvio):

dnssec-keygen -a HMAC-MD5 -b 128 -n HOST ivanhq

“ivanhq” es el nombre de la clave que yo voy a crear, lo llamo así para saber qué zona actualiza, pero podría llamarse “dnskey” sin ningún problema. Esto genera dos ficheros, un .private y un .key, ni que decir tiene cuál es el público y cual el privado… el público servirá para ponerlo en la configuración del servidor, el privado no debe moverse del cliente.

Es conveniente guardar los ficheros de las claves en algún directorio que guarde relación con Bind. Yo los he puesto aquí:

mkdir /var/bind/tsig
mv Kivanhq* /var/bind/tsig/
chown -R 0066 /var/bind/tsig

Después debe modificarse el fichero de configuración de named en el servidor (named.conf). Debe incorporarse la key pública del cliente, para decirle al servidor que acepte sus updates.

key ivanhq {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret "agCr8JkmLKsgFuSw==";
};

El contenido de “secret” es la clave pública, que está contenida en el fichero .key y se puede ver con un simple “cat”. Esto se puede poner al principio del archivo, antes de la declaración de zonas.

Después debe modificarse la declaración de la zona que se va a actualizar, para permitir la actualización desde la “key ivanhq”:

zone "ivanhq.net" {
type master;
allow-update{
key ivanhq;
};
file "/etc/namedb/ivanhq.net.db";
};

Una vez hecho esto debe reiniciarse el servidor named, y ya se puede actualizar el nombre desde el cliente, por línea de comandos:

nsupdate -k /var/bind/tsig/Kivanhq.+157+25718.key

Esto lee de la entrada de consola, y ahora debemos especificar lo que debe hacer en la zona:

update delete micasa.ivanhq.net
update add micasa.ivanhq.net 60 IN A 111.222.333.444

Es necesario pulsar Enter 2 veces al final para que el servidor reciba la señal de EOF y haga efectivos los cambios en la zona. La dirección IP dinámica va en el lugar de “111.222.333.444”. Y ya está.

Yo he hecho un pequeño script que saca mi dirección IP pública, y lo ejecuto desde el cron una vez por minuto. También he encontrado problemas en la actualización si el cliente y el servidor están descompasados en tiempo… de modo que es bueno pensar en sincronizar las máquinas con ntp contra algún servidor de time (hora.rediris.es, por ejemplo).

EDICIÓN: vaya… este post es prácticamente un duplicado del que ya escribí en su día explicando cómo hacerlo en FreeBSD. No me había dado cuenta :(

logo_rev.gifDespués de muchos dolores de cabeza por fin he conseguido hacer funcionar una centralita Asterisk con algunos problemas de enrutamiento. Es sabido que SIP da problemas cuando las terminales se encuentran detrás de un router o firewall, debido a que las cabeceras de los paquetes incluyen la dirección original de la petición, con lo cual el servidor no sabe como enrutar las respuestas. Existen varias soluciones según el mapa de la instalación, que comunmente cuenta con un servidor conectado directamente a Internet y varas terminales enrutadas por el firewall/router de una oficina.

En este caso, el mapa consta de dos oficinas cuyos dispositivos están enrutados por firewalls con Netfilter. La oficina B hospeda el servidor Asterisk y varias terminales SIP. La oficina A hospeda sólamente terminales. De momento las terminales son ordenadores con SJphone o Twinkle, pero ahora vamos a sustituirlos por hardphones. Los firewalls están a su vez enrutados por los routers ADSL correspondientes, configurados en modo DMZ (NAT de todos los puertos, que no es lo mismo que un Bridge). Así, las terminales de la oficina B no tienen problemas para registrarse contra el servidor ni para establecer llamadas entre ellos. El problema lo tienen las terminales de la oficina A, que deben pasar 4 NAT’s antes de registrarse o hablar con el destino.

Aquí el mapa:

netmap011.png
Para conseguir hacerlo funcionar he necesitado un proxy SIP para la oficina A. He encontrado un par, pero Pof me habló de Siproxd y la verdad es que es sencillo de usar y la docu es muy buena.
Para la configuración de Asterisk, el fichero sip.conf necesita que se especifique el uso de NAT y las direcciones interna y externa que deben llevar las cabeceras:

[general] context=from-sip
bindport=5060
bindaddr=0.0.0.0
srvlookup=yes
disallow=all
allow=gsm
allow=ulaw
allow=ilbc
language=es
nat=yes
insecure=very
relaxdtmf=yes
dtmfmode=info
externip=111.222.333.444
localnet=192.168.2.0/255.255.255.0

El campo externip es la IP externa del router que hospeda el Asterisk (el de la oficina B). EL campo localnet es la red interna de la oficina, a la que está conectado el servidor.

En el fichero rtp.conf, especifico el rango de puertos que se usará para la transmisión de audio:

[general]
rtpstart=7000
rtpend=20000

Instalo siproxd en la oficina A, y siguiendo la docu especifico los parametros necesarios en la configuración (/etc/siproxd.conf):

if_inbound = eth1
if_outbound = eth0
hosts_allow_reg = 192.168.1.0/24
sip_listen_port = 5060
daemonize = 1
silence_log = 1
log_calls = 1
user = siproxd
registration_file = /var/lib/siproxd/siproxd_registrations
pid_file = /var/run/siproxd/siproxd.pid
rtp_proxy_enable = 1
rtp_port_low = 7000
rtp_port_high = 20000
rtp_timeout = 300
default_expires = 600
debug_level = 0
debug_port = 0

Lanzo siproxd habilitando el nivel 1 de debug:

siproxd -d -1

Añado al firewall de la oficina A (donde está el proxy) las reglas de iptables que redirigen las peticiones SIP a modo de proxy transparente. Es lo mismo que cuando se monta por ejemplo un proxy web transparente con Squid:

# Siproxd
iptables -t nat -A PREROUTING -m udp -p udp -i eth1 --destination-port 5060:5082 -j REDIRECT
iptables -A INPUT -m udp -p udp -i ppp0 --dport 5060:5082 -j ACCEPT
iptables -A INPUT -m udp -p udp -i ppp0 --dport 7000:20000 -j ACCEPT

Y ya está. Las extensiones SIP las configuro como de costumbre:

[110]
type=friend
context=from-sip
secret=xxx
language=es
username=110
host=dynamic
reinvite=no
canreinvite=no

Y en el dialplan no hay nada especial que especificar. Así funciona perfectamente, la receta la he encontrado dando vueltas por Asteriskguru, pero no me pregunteis dónde porque la verdad es que ya no recuerdo todo lo que he leído.

Por cierto, que todo esto lo he montado en Slackware, y he creado los paquetes TGZ para instalar Siproxd por si alguien los requiere. Están aquí:

libosip2-2.2.2-i686-1.tgz
siproxd-0.5.13-i686-1.tgz

Espero que a alguien pueda servirle. Desde luego a mí me ha traído de culo, y como las configuraciones cambian según el mapa de cada instalación es difícil encontrar una ayuda personalizada para solventarlo.

Ahora tengo que cambiar los softphones por hardphones, y espero no encontrarme ninguna sorpresa más. He pensado usar Grandstream BT101 para los terminales corrientes, y un GXP-2000 para la operadora, pero si a alguien se le ocurre un hardware más apropiado a un precio similar agradecería que me lo recomiende :)

Bueno, ésto es lo último que me faltaba comentar. Cómo he hecho funcionar la wifi. La verdad es que no tiene ningún secreto, y buscando un poco de info en la página del proyecto y en los foros de Gentoo se configura en un tris. Pero bueno, por si a alguien le sirve aquí dejo los pasos que yo he seguido:

echo "net-wireless/ipw3945d ~x86" >> /etc/portage/package.keywords
echo "net-wireless/ipw3945 ~x86" >> /etc/portage/package.keywords
echo "net-wireless/ieee80211 ~x86" >> /etc/portage/package.keywords
echo "net-wireless/ipw3945-ucode ~x86" >> /etc/portage/package.keywords
emerge  net-wireless/ipw3945d net-wireless/ipw3945  net-wireless/ieee80211 net-wireless/ipw3945-ucode

Hecho esto ya tenemos los módulos para la tarjeta. Sobre la configuración del núcleo, aquí dejé en su día la que uso yo en mi ordenador, y funciona bien. Podeis probarla.

Entonces, maté muchas horas buscando un gestor gráfico de conexiones, y como no encontré ninguno que me funcionase al 100%, me puse y programé unos scripts pequeñitos para configurar la red según el lugar donde voy a conectarme.

Lo que hay que hacer es sencillo, cargar el módulo y lanzar el demonio que controla la interfaz:

modprobe ipw3945
ipw3945d

Y ahora ya solo queda configurar la interfaz que levanta (en mi caso es eth1):

iwconfig eth1 essid "loser"
iwconfig eth1 key "AAAA-BBBB-CCCC-DDDD-EEEE-FFFF-00"
ifconfig eth1 down
ifconfig eth1 192.168.1.1
route add default gw 192.168.1.254
echo "search loserhome.net" > /etc/resolv.conf
echo "nameserver 192.168.1.10" >> /etc/resolv.conf

Cambiad el nombre del dominio, las direcciones IP, el ESSID, la clave WEP y el servidor DNS… y ya teneis funcionando la wifi. Si quereis soporte para claves WPA y WPA2, solo hay que instalar WPA supplicant. Aunque yo todavía no lo he probado no tardaré mucho en hacerlo… ya diré algo por aquí según como funcione :-)