Archivo de la categoría: General

Cómo emitir webcams en vivo con un servidor Linux y en formato FLV

Hace un tiempo tuve un cliente que quería visualizar las cámaras que había instalado en su oficina desde su casa. En aquel momento eran cámaras IP cableadas. Este tipo de cámaras tienen un servidor web integrado desde donde puedes configurar su dirección IP además de ver el vídeo que transmiten. Por lo general estas cámaras transmiten en formato mjpeg, un flujo de imágenes JPG normales, aunque también podría ser que lo hiciesen directamente en mpeg. Firefox es capaz de reproducir este formato directamente, no así Internet Explorer que necesita de un applet Java para hacerlo.

El reto consistía, por tanto, en transmitir las cámaras en un formato que se pudiese reproducir fácilmente y que se pudiese integrar en una página web, sin programas de terceros para visualizarlas. Así llegamos a la solución que hoy os presento y que no es exclusiva de cámaras IP sino que puedes utilizar cualquier webcam USB que tengas por casa. El formato que hemos escogido para el flujo de vídeo será flv,  con lo que con una sencilla aplicación Flash podremos visualizar cada una de nuestras cámaras evitando, de paso, los applets Java.

Para el proyecto de hoy necesitaremos:

  • Servidor Linux, imprescindible, en mi caso Centos5
  • Apache instalado en el servidor.
  • ffmpeg, para hacer la conversión de formatos
  • ffserver, parte del paquete ffmpeg, para transmitir elvídeo

Si no tienes el software necesario, el primer paso es instalarlo. En mi caso:

yum install ffmpeg apache

Comenzaremos configurando ffserver desde /etc/ffserver.conf:

Port 8090
BindAddress 0.0.0.0
MaxClients 1000
MaxBandwidth 10000            

<Feed feed1.ffm>
  File /tmp/feed1.ffm
  FileMaxSize 5M
</Feed>
<Feed feed2.ffm>
  File /tmp/feed2.ffm
  FileMaxSize 5M
</Feed>            

<Stream camara1.flv>
  Feed feed1.ffm
  Format flv
  VideoCodec flv
  VideoBitRate 128
  VideoBufferSize 500
  VideoFrameRate 5
  VideoSize 320x240
  NoAudio
  Preroll 5
</Stream>            

<Stream camara2.flv>
  Feed feed2.ffm
  Format flv
  VideoCodec flv
  VideoBitRate 128
  VideoBufferSize 500
  VideoFrameRate 5
  VideoSize 320x240
  NoAudio
  Preroll 5
</Stream>            

<Stream stat.html>
  Format status
</Stream>

ffserver funciona como un servidor, transmitiendo en el puerto que le indiquemos lo que recibe en los archivos que se indican en los feed’s. A continuación se indican los flujos de vídeos que vamos a utilizar (feed’s), en mi caso dos cámaras. Finalmente definimos los streams que será a lo que realmente nos conectaremos nosotros, un stream por cada feed en formato flv. Podríamos crear tantos streams de cada feed como creamos oportuno en distintos formatos, consulta la ayuda de ffserver y ffmpeg.  Finalmente creamos un stream especial, el de status, donde veremos información sobre el estado del servidor y clientes contectados.

Lanzamos el servidor ffserver tal cual.

ffserver

Con esta configuración tendremos acceso a dos flujos de vídeo en formato FLV en las direcciones:

http://localhost:8090/camara1.flv
http://localhost:8090/camara2.flv

Vale, sí, aún no hemos transmitido el vídeo, eso viene ahora. Debemos enlazar el flujo de vídeo de nuestras cámaras con ffserver para que éste haga la conversión de formato y lo emita por las urls indicadas. Para hacerlo recurrimos al inseparable compañero de ffserver, ffmpeg.

Si tus cámaras están conectadas al servidor bien sea por USB o por capturadoras de vídeo (debes tenerlas configuradas previamente):

ffmpeg -f video4linux -s 320x240 -r 5 -i /dev/video0 http://localhost:8090/feed1.ffm
ffmpeg -f video4linux -s 320x240 -r 5 -i /dev/video1 http://localhost:8090/feed2.ffm

Si tus cámaras fuesen IP habría que capturar primero el vídeo desde la cámara y pasárselo a ffmpeg, por ejemplo:

curl http://ip-de-tu-camara:8080 | ffmpeg -er 4 -y -v quiet -an -f mjpeg -r 4 -i - http://localhost:8090/feed1.ffm

Sea como sea el formato de tus cámaras, y si todo ha ido bien, tendrás a ffmpeg enviando el vídeo a ffserver para que lo convierta a FLV y lo publique en las URL’s anteriormente indicadas.

Debes tener cuidado con un detalle importante si conectas más de una cámara USB, debes enchufarlas a concentradores distintos de tu equipo para diversificar adecuadamente los flujos de vídeo y el ancho de banda que ocupan, si conectases dos cámaras al mismo concentrador no tendrían ancho de banda suficiente y se bloquearían entre ellas.

Veamos ahora como visualizar los flujos de vídeo. Necesitaremos el editor de Flash de toda la vida. Creamos un nuevo documento y arrastramos al escenario un objeto FLVPlayback. Como nombre de instancia le ponemos “video” y en sus propiedades ponemos isLive a true. En el primer frame añadimos el siguiente código:

video.contentPath=path_video;

De esta manera podremos indicar desde html la url del flujo de vídeo sin tener que tener un swf por cada cámara. Compila y publica el proyecto puesto que ya hemos terminado.

No me voy a preocupar ahora del código html generado, eso es cosa tuya. Dentro del archivo html que te genera el editor de flash tendrás algo como:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="400" id="webcam1" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="webcam.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="webcam.swf" mce_src="webcam.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="webcam1" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

Vamos a convertirlo en esto:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="400" id="webcam1" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="webcam.swf?path_video=http://192.168.90.1:8090/camara1.flv" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="webcam.swf?path_video=http://192.168.90.1:8090/camara1.flv" mce_src="webcam.swf?path_video=http://192.168.3.2:8090/camara1.flv" quality="high" bgcolor="#ffffff" width="550" height="400" name="webcam1" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

Es decir, añadimos al parámetro de la película la variable path_video con la url del flujo tal y como lo hemos generado antes. Debe ser una URL a la que se pueda acceder externamente pues el swf se conectará a ella para recoger el flujo flv generado por ffserver, si tienes un router o un firewall de por medio, deberás abrir ese puerto. Copiaremos este código tantas veces como cámaras tengamos modificando la URL del flujo de vídeo.

Voila! esto es todo, ya tienes publicadas tus cámaras en un formato sencillo de visualizar como es el FLV.  Abre la página html que has creado y comenzarás a visualizar tus cámaras.

Pero… vayamos un paso más allá. Con lo que hemos visto hasta ahora tendremos que abrir el puerto 8090 de buestra máquina para permitir el acceso a los flujos de vídeo, pero nosotros no queremos hacer esto, ya tenemos el puerto 80 con Apache a la escucha. ¿Qué hacemos? Sencillo, mod_proxy viene a nuestro rescate. Asegúrate de tenerlo habilitado en la configuración de tu Apache. Después simplemente habrá que añadir las siguientes líneas a la configuración del virtual host en el que quieres publicar los streams:

ProxyPass /camara1.flv http://127.0.0.1:8090/camara1.flv
ProxyPassReverse /camara1.flv http://127.0.0.1:8090/camara1.flv        

ProxyPass /camara2.flv http://127.0.0.1:8090/camara2.flv
ProxyPassReverse /camara2.flv http://127.0.0.1:8090/camara2.flv

Con esto estaremos enviando automáticamente cada stream desde su url original en el puerto 8090 a una url de tu virtual host del tipo http://tudominio.com/camaraX.flv. Esa ruta no existe físicamente, es virtual y Apache sabe que debe redirigirla al stream del ffserver.

Finalmente queda un detalle importante. Hasta ahora habíamos incializado ffserver por un lado y los flujos de las cámaras por otro con ffmpeg. Esto es un rollo y no nos gusta, queremos que ffserver lo inicie todo automáticamente. Pues vale, añadamos una directiva Launch a cada feed de la configuración de ffserver con los parámetros que utilizábamos para llamarlo desde la línea de comandos. En el ejemplo de nuestra primera cámara quedaría:

<Feed feed1.ffm>
  File /tmp/feed1.ffm
  FileMaxSize 5M
  Launch  ffmpeg -f video4linux -s 320x240 -r 5 -i /dev/video0
</Feed>

A partir de ahora, cada vez que lancemos ffserver tecleando simplemente ese comando, se inciarán, además del propio servidor, los streams que hayamos definido.

Hasta aquí hemos llegado por hoy. De una manera extremadamente sencilla hemos publicado nuestras webcams. Es responsabilidad tuya y sólamente tuya el asegurar el acceso a los flujos y a la página de visualización que hemos creado. Otro día quizás veamos cómo montar un sistema de videovigilancia casero con detector de presencia 😉 .

Os dejo el código de la aplicación Flash de visualización de los streams.

Error con el smtp autentificado con los clientes de Nokia a través de Qmail

Como os decía hace unos días, recientemente he cambiado el Nokia N70 que llevaba desde hace algo más de dos años por un Nokia E51. La característica más importante de este nuevo terminal es la disponibilidad de conexión WIFI, con lo cual, si tienes un poco de suerte y encuentras un punto de acceso abierto, puedes tener acceso a tu correo desde cualquier punto. No he tenido muchos problemas para encontrar puntos de acceso y habitualmente he podido leer el correo. El problema llega a la hora de enviarlo ya que siempre obtengo un error en el envío. Cansado de no saber qué ocurría y dado que voy a estar unos días fuera de casa, decidí investigar un poco.

Comencé por ver cual era la comunicación del cliente de correo con mi servidor. Para ello lancé un sniffer en mi máquina, en este caso Wireshark, nombre actual del Ethereal de toda la vida. Para no volverme loco con todo el tráfico que iba a ver añadí un filtro, de manera que sólo se mostraría el tráfico que venía desde la IP de mi conexión ADSL (11.22.33.44), así sólo vería lo que estaba generando mi propio móvil.

tshark -i2 -f "src host 111.222.333.444"

Y este fué el resultado:

3.197223 11.22.33.44 -> 55.66.77.88 TCP 49537 > smtp [SYN] Seq=0 Win=64240 Len=0 MSS=1460 TSV=1218449730 TSER=0 WS=0
3.197263 55.66.77.88 -> 11.22.33.44 TCP smtp > 49537 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=389435772 TSER=1218449730 WS=7
3.347274 11.22.33.44 -> 55.66.77.88 TCP 49537 > smtp [ACK] Seq=1 Ack=1 Win=64240 Len=0 TSV=1218663480 TSER=389435772
3.356257 55.66.77.88 -> 11.22.33.44 SMTP Response: 220 servidor ESMTP
3.509426 11.22.33.44 -> 55.66.77.88 SMTP Command: EHLO
3.509451 55.66.77.88 -> 11.22.33.44 TCP smtp > 49537 [ACK] Seq=29 Ack=22 Win=5888 Len=0 TSV=389436084 TSER=1218828105
3.509490 55.66.77.88 -> 11.22.33.44 SMTP Response: 250-servidor
3.663467 11.22.33.44 -> 55.66.77.88 SMTP Command: AUTH CRAM-MD5
3.813384 11.22.33.44 -> 55.66.77.88 SMTP Command: amlxxxxxxWFzIDkxNTM4MxxxxxxyYjVjOTdmYxxxxxxxDFhZDg2MjEw
3.853554 55.66.77.88 -> 11.22.33.44 TCP smtp > 49537 [ACK] Seq=197 Ack=95 Win=5888 Len=0 TSV=389436428 TSER=1219132230
8.817212 55.66.77.88 -> 11.22.33.44 SMTP Response: 535 authorization failed (#5.7.0)

Es decir, me estaba fallando la autentificación a través de CRAM-MD5 a pesar de que en el programa de correo del móvil tenía correctamente introducidos el usuario y la clave y el servidor, obviamente, se presentaba diciendo que soportaba este método.

[osus@servidor ~]# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 servidor ESMTP
ehlo
250-servidor
250-AUTH LOGIN CRAM-MD5 PLAIN
250-PIPELINING
250 8BITMIME

Investigando un poco averigué que para habilitar la autentificación CRAM-MD5 en Qmail, el MTA de correo que utilizo, además de instalar el parche qmail-smtp-auth es necesario sustituir el original checkpasswd  por cmd5checkpw. Con este argumento caí en la cuenta de que nunca jamás he tenido esta autentificación funcionando en mis servidores 😀 , el servidor indicaba que sí pero la realidad era que no 😛 . Ocho años utilizando Qmail y ahora me doy cuenta de que no funcionaba.

No quería complicarme mucho así que, si hasta ahora no la tenía, tampoco me importaba seguir así. Pensé entonces que, si en vez de responder a los clientes que soportaba CRAM-MD5, no se lo decía, el cliente del E51 escogería el AUTH LOGIN de toda la vida y funcionaría. ¿Cómo hacer esto? Sencillo, Qmail es de código abierto y tenemos el código fuente a nuestra disposición.

Parcheando Qmail

En los fuentes de mi Qmail (con todos sus parches) busqué la cadena en cuestión:

grep  CRAM-MD5 *

Y ahí me apareció el objetivo de nuestro parche, qmail-smtpd.c.

Dicho y hecho, abrimos el archivo con vi y buscamos la cadena en cuestión (:/CRAM-MD5) llegando a:

out("rn250-AUTH LOGIN CRAM-MD5 PLAIN");

Esto va a ser sencillo. Modificamos esa/s línea/s de manera que quede/n:

out("rn250-AUTH LOGIN PLAIN");

De este modo, cuando el cliente pregunte le diremos que soportamos LOGIN y PLAIN, pero no CRAM-MD5. He explicado esto en plural porque es más que probable que tengas dos líneas iguales y no sólo una. Puedes dejar sólo una modificada como he indicado o modificar las dos.

Compilamos ahora con un simple make. Como sólo hemos  modificado este archivo únicamente se compilará este. Hacemos una copia de seguridad de nuestro /var/qmail/bin/qmail-smtpd (por si algo no va bien) y copiamos el nuevo a esta ruta dejando los permisos, owner y group igual que tenía el que había.

Si ahora pruebas a enviar un email desde el Nokia E51 comprobarás que funciona correctamente, el cliente del teléfono escoge otro de los sistemas. Utilizando de nuevo el sniffer verás que ahora escoge AUTH LOGIN como método de autentificación.

Ya puedo enviar correo desde mis servidores con el teléfono. Gracias a un sencillo ejercicio de escucha del tráfico de red hemos averiguado cual era el problema.

Desbloquea tu teléfono móvil sin desbloquear el teléfono

Suena raro, lo se, pero veréis que todo tiene sentido.

Esto es un post algo fuera de lo que suelo escribir, pero creo que a muchos de los lectores les interesará tener acceso a Internet vía móvil y el invento es, cuanto menos, curioso.

Necesitaba un teléfono libre para utilizar la tarjeta SIM de Simyo para conectarme a Internet y lo único que tenía era mi viejo T630, sin 3G. Sin embargo la suerte quiso que acabe de cambiarme mi viejo Nokia N70 por un flamante Nokia E51 con wifi, con lo que tenía el compañero perfecto en el N70. Sólo quedaba un paso, desbloquearlo, pero me pedían 50 euros. Buscando por Internet y sin saber bien cómo, llegué a esto en una tienda en Hong Kong donde aseguraban vender una especie de adaptadores que puestos entre la SIM y el teléfono de la mayoría de compañías y terminales los desbloqueaban. Buscando alguna referencia sobre el cacharro en cuestión todo era alabanzas y buenas referencias.

Era la primera vez que oía hablar de ello, pero por el precio que proponían, 7,76 dólares (poco más de cinco euros) gastos de envío incluídos, tampoco tenía mucho que perder. Así que dicho y hecho, me compré una. Sorprendentemente cuatro días después tenía una carta en mi buzón con el adaptador en cuestión.

El aparato no es más que una lámina de plástico del tamaño de una SIM que hace de base del circuito y unas cuantas pistas para conectar ambas caras del adaptados ya que por un lado pondrás la SIM original y por el otro el teléfono. En una esquina lleva un pequeño microchip que será lo que, como veremos después, nos de algún problema para introducirla.

Esto sería mi equipo de pruebas. El Nokia N70, la SIM de Simyo y el adaptador de cinco euros. Obviamente no me creía yo mucho que esto funcionase, pero habia que probar.

img_4016.JPG

Para los incrédulos, esto es lo que dice el teléfono al poner la tarjeta directamente, está bloqueado por Vodafone.

img_4035.JPG

Cuando tienes en tu mano el adaptador y la sim ves que vas a tener problemas. Aunque yo pude colocarla más o menos bien en mi N70 reconozco que es a costa de forzar un poco el cierre. En un terminal donde la tarjeta entra en su compartimendo deslizándola no va a ser posible ponerla, así que lo mejor es operarla. Lo que tendremos que hacer, tal como véis en las siguientes fotos, es hacer un pequeño recorte en el extremo de la sim del tamaño del microchip del adaptador, de manera que al colocar una sobre otra el chip sobresale por este hueco y ámbas tarjetas quedan perfectamente unidas.

img_4021.JPG

img_4020.JPG

Procedemos ahora a colocar el adaptador y la sim en su compartimento. Primero dejamos caer el adaptador. En la foto véis como en la parte superior sobresale el microchip del que hablábamos. Si pusiésemos la sim tal cual sobre él, el compartimento no cerraría bien y habría que forzarlo un poco.

img_4023.JPG

Sin embargo, al hacerle el recorte que hemos visto, todo encaja a la perfección.

img_4024.JPG

Aquí vemos en detalle el cómo queda todo montado. Véis que encaja perfectamente.

detalle.jpg

Nos queda la prueba de fuego. ¿Funcionará?. Mejor lo véis en la foto directamente 😐 .

 img_4036.JPG

En efecto, funciona a la perfección, el teléfono no se queja de nada. Sólo tendremos que poner el adaptador debajo de cualquier SIM y funcionará en la mayoría de teléfonos. ¿Será esto cierto?. Lo probamos. Nokias, Sony Ericsson, HTC y hasta Blackberry. Todo lo que probamos funcionó. Estamos ahora pendientes de probarlas en un iPhone. Ya veremos, pero en general parece que el invento funciona.

Si tu teléfono es de esos donde la SIM entra deslizándola en su compartimento, recomiendo pegar el adaptador a la sim con pegamento, te quitarás problemas para meterla y sacarla.

Me parece simplemente genial el poder utilizar cualquiera de tus sim’s en cualquier teléfono (familia, amigos…). Ya no dependes del terminal sino simplemente de la tarjeta, la que te da el servicio y, a fin de cuentas, la que te cobra. Sencillo, barato y sin perder la garantía de tu teléfono 🙂 .

Conexiones VPN entre máquinas Linux y Windows con autentificación a través de servidor Radius y MySQL

Un día, harto de tener que abrir puertos y más puertos para cada cosa que quería hacer con el servidor Linux que tengo en casa, se me ocurrió hacer algo para poder conectarme directamente a ésa máquina y tener todos los servicios a mi disposición sin tener que crearlos uno a uno. La solución estaba clara, establecer una VPN contra ese servidor y automáticamente tendría acceso a todos los servicios disponibles. El problema principal a la hora de establecer esta red virtual era que tenía que ser sencilla, rápida de crear y, sobre todo, no necesitar software adicional ya que así podría utilizarla desde cualquier ordenador en cualquier localización. Es más, si me lo montaba bien tendría un sistema perfecto para dar soporte remoto a mis hermanas a través de VNC sin tener que abrirles esos puertos 😉 .

Por defecto todos los equipos Windows traen de serie un cliente VPN que puede contectarse a redes privadas virtuales, pero no de cualquier tipo, sólo PPTP. Podríamos haber escogido otro sistema basado en IPsec o incluso OpenVPN, pero necesitaríamos software adicional además de cerficados en ámbos extremos de la VPN, lo que no cumpliría los requisitos que nos habíamos impuesto. PPTP es un protocolo desarrollado por Microsoft (por eso viene de serie con Windows) y, gracias a eso, ha tardado mucho en haber un cliente (y más aún un servidor) que funcione bajo Linux. No es el más seguro de los protocolos de VPN 😛 pero dejémoslo en que cumple sus funciones.

La idea es, por tanto, montar un servidor PPTP bajo Linux. Una vez tengamos el servidor veremos como conectar tanto desde Linux como desde Windows. Aunque la idea de este artículo parte de un entorno doméstico es completamente aplicable a pequeñas empresas que necesiten dar acceso remoto a sus empleados sin complicarles la vida ni realizar grandes desembolsos en routers dedicados o en un servidor Windows (entendiendo esto como una máquina con algún Windows Server 😉 .

Servidor PPTP bajo Linux

Vamos a enrevesar un poco más nuestro servidor. Para da más versatilidad haremos que la autentificación de los usuarios se realice a través de un servidor Radius que posteriormente podemos utilizar para autenticar cualquier otro servicio que se nos ocurra (ftp, email, hotspot inalámbrico…).

Creo que aún es muy sencillo, vamos a complicarlo más aún. El servidor Radius autenticará, así mismo, contra una base de datos MySQL, con lo que tendremos un sistema muy facil de administrar sin tener que estar tocando archivos de texto para crear usuarios nuevos. El escenario es, por tanto PPTP+Radius+MySQL.

Como software vamos a utilizar:

  • Servidor Linux, Centos 5.2 en mi caso.
  • PopTop, servidor PPTP bajo Linux.
  • PPTP Client, cliente PPTP bajo Linux.
  • FreeRadius como servidor Radius.
  • Radiusclient como cliente Radius, para que PopTop pueda consultar el servidor Radius.

Para instalar el software, en mi caso, nada más sencillo. Primero instalamos el repositorio yum de PopTop:

rpm -Uvh http://poptop.sourceforge.net/yum/stable/fc7/pptp-release-current.noarch.rpm

Y ya podemos instalar todo el software:

yum --enablerepo=poptop-stable install freeradius freeradius-mysql radiusclient pptp pptpd

Creo que con eso sería suficiente y tendríamos todo lo necesario. Asumimos, por supuesto, que ya tienes MySQL instalado.

Antiguamente era más complicado instalar PopTop ya que había que parchear el kernel, pero hoy en día, si tu núcleo es superior a 2.6.15 (si no lo es, ¿a qué esperas para actualizarlo?), no es necesario este paso. De todos modos, si tuvieses que hacerlo, es totalmente seguro, yo mismo lo hice durante mucho tiempo. En la web de PopTop tienes las instrucciones para hacerlo.

Suponiendo que hemos instalado correctamente todo el software sin ningún problema, ya sólo nos queda configurar todos y cada uno de los pasos que conforman nuestro servidor VPN.

Configurando PopTop

Lo primero que debes hacer es decidir que direccionamiento utilizarás en tu VPN. En mi caso tengo uno independiente de todo lo demás (192.168.3.0), así puedo gestionarlo a mi antojo, permitiendo o denegando lo que se me ocurra de una manera sencilla. A continuación indico los archivos de configuración a toquetear y como tengo los míos.

/etc/pptpd.conf

[osus@servidor ~]# cat /etc/pptpd.conf
option /etc/ppp/options.pptpd
localip 192.168.3.1-5
remoteip 192.168.3.6-10

El parámetro localip tendrá las IP’s que utilizará tu servidor como locales cada vez que reciba una conexión mientras que en remoteip indicarás las que va a dar dinámicamente a los clientes. Tendrás que poner un rango lo suficientemente amplio como para cubrir las posibles conexiones simultáneas que puedas tener.

/etc/ppp/options.pptpd

[osus@servidor ~]# cat /etc/ppp/options.pptpd
name pptpd
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
require-mppe-128
proxyarp
lock
nobsdcomp
novj
novjccomp
nologfd
plugin radius.so

Sería recomendable que consultases las páginas man para saber qué hace cada parámetro.

Como véis, al final de todo indicamos al servidor PPTP que utilice el pluggin para Radius, así que configuremos todo lo relativo a Radius.

Configurando FreeRadius

/etc/raddb/clients.conf

[osus@servidor ~]# cat /etc/raddb/clients.conf
client 127.0.0.1 {
        secret          = TUCLAVESECRETA
        shortname       = localhost
}

Debemos indicar, para cada servidor Radius que tenemos, una clave de conexión y el nombre del mismo. La clave deberán utilizarla los clientes radius para consultar al servidor. Lo normal en un entorno como el nuestro es que el servidor Radius sea el mismo donde reside el servidor VPN.

El siguiente archivo es el más importante ya que se indica a FreeRadius que autentifique las peticiones contra un servidor MySQL. Como es muy largo pondré solamente las partes relevantes:

/etc/raddb/radiusd.conf

mschap {
 authtype = MS-CHAP
 use_mppe = yes
 require_strong = yes
}

authorize {
        preprocess
        mschap
        suffix
        eap
        sql
}

authenticate {
        Auth-Type MS-CHAP {
                mschap
        }
        eap
}

preacct {
        preprocess
        suffix
        files
}

accounting {
        detail
        acct_unique
        sql
}

session {
       sql
}

En /etc/raddb/sql.conf  debes configurar correctamente el acceso a tu base de datos MySQL, servidor, usuario, clave y base de datos que veremos un poco más adelante.

Configurando el cliente Radius

/etc/radiusclient/servers

[osus@servidor ~]# cat /etc/radiusclient/servers
localhost       TUCLAVESECRETA

Donde la clave es la misma que pusiste en /etc/raddb/clients.conf y localhost la dirección de tu servidor si es distinto al que tiene el pptpd.

En /etc/radiusclient debes tener el archivo dictionary.microsoft. Creo recordar que tuve algunos problemas con él, por si acaso dejo el que tengo ahora mismo que no es el que venía por defecto.

En /etc/radiusclient/radiusclient.conf asegurate que tienes los siguientes parámetros apuntando a la IP de tu servidor Radius si no es el mismo donde reside el servidor VPN:

authserver      localhost
acctserver      localhost

Si son distintos a localhost, no te olvides de configurarlos aquí.

Creando la base de datos MySQL

Llegamos al último paso.

Crea una nueva base de datos (create database radius) y un usuario con permisos sobre ella. Recuerda configurar ahora /etc/raddb/sql.conf  con estos datos.

Ahora crea la estructura de la base de datos. Con el paquete FreeRadius viene la estructura que necesitas.

mysql radius < /usr/share/doc/freeradius-1.1.3/examples/mysql.sql

El paso que viene a continuación siempre lo ignoran cuando alguien explica cómo configurar FreeRadius contra MySQL y creedme que no es nada intuitivo.

¿Cómo se rellenan las tablas de autentificación?

Buena pregunta Manel 😛 .

  • Tabla radcheck: mantiene las cuentas de usuario con los siguientes campos:
    • UserName: nombre de usuario.
    • Attribute: Password (literalmente, no la clave del usuario sino la palabra Password).
    • op: == (dos signos de igual).
    • Value: clave del usuario.
  • Table radreply: contiene parámetros de inicialización de los clientes que se conectan. Aquí yo configuro las IP’s que quiero dar a determinados clientes por cuestiones de comodidad.  Además indico que sólo voy a permitir una conexión simultánea con el mismo usuario.
    • UserName: nombre de usuario que estás configurando (según lo introducido en la tabla radcheck).
    • Attribute: la palabra Framed-IP-Address ó Simultaneous-Use, según indiques la IP a asignar a ese usuario o el número máximo de sesiones con el mismo nombre.
    • op: = (un sólo signo igual)
    • Value: 192.168.3.99 (la IP que quieras) ó el número máximo de conexiones simultáneas con el mismo usuario.
  • Table usergroup: agrupa los usuarios en grupos.
    • UserName: nombre de usuario
    • GroupName: nombre de grupo.

La tabla radact contiene el log de actividad del servidor, sesiones iniciadas, duración, etc.

Últimos pasos

Recuerda que debes abrir en tu router y/o firewall el puerto 1723 para que permita conexiones entrantes ya que es el usado por el protocolo PPTP.

Aunque como veremos más adelante podemos auditar las conexiones al servidor Radius (y por ende al servidor VPN) puede ser interesante tener un mecanismo de aviso de que un cliente se ha conectado. Una forma de hacerlo es consultando las interfaces de red disponibles en el servidor (ifconfig), habrá tantos pppX como usuarios activos. Pero hay otro método que te permite recibir, por ejemplo por email, un aviso cada vez que un usuario conecta o desconecta.

Cada vez que se levanta una interfaz ppp se ejecuta el script /etc/ppp/ip-up.local con todos los parámetros relativos a esa conexión, ip remota, local, interfaz… Igualmente cuando se desconecta se lanza /etc/ppp/ip-down.local. Solo debemos adaptar este script a nuestras necesidades. Estos scripts reciben todos los parámetros necesarios para identificar al usuario. Haríamos algo así, por ejemplo para ip-up.local.

#!/bin/sh
if [ "$5" == "192.168.3.10" ]
then
        cliente="pepito"
fi
echo  "Conexion VPN
Interfaz: $1
VPN Local: $4
VPN Remota: $5
IP Remota: $6
1: $1
2: $2
3: $3
4: $4
5: $5
6: $6
"  | mail -s "Conexion VPN - $cliente" [email protected]

De este modo recibirías un email cada vez que un usuario  levanta un tunel VPN con tu servidor y sabrías qué ip tiene el usuario y, si le has otorgado una IP fija en la configuración de Radius, sabrás qué usuario es, en este caso “pepito“.

Con ip-down.local harías un script semejante sólo que en vez de Conexión VPN en el asunto del email pondríamos Desconexión VPN. Los parámetros son exactamente los mismos.

Estos scripts podemos aprovecharlos también para crear/modificar/eliminar determinadas rutas en función de los túneles creados.

El propio paquete pptpd te habrá instalado el script de inicio necesario, en mi caso /etc/init.d/pptpd. Sólo debo añadirlo a la secuencia de arranque del runlevel de mi servidor y automáticamente estará siempre disponible el servicio.

En teoría, todas las vpn’s que se hagan contra el servidor tienen enrutamiento entre sí, es decir, podrías llegar desde un cliente a otro pasando por el servidor sin toquetear nada más. Digo en teoría porque esa es la función del parámetro proxyarp que configuramos hace un rato. Puede que este enrutamiento no sea suficiente y que necesites que los clientes VPN puedan acceder a otras subredes de tu infraestructura. Puedes hacerlo como quieras, incluso configurar un bridge, pero para estas cosas nada mejor que iptables.

Supongamos un escenario en el que tenemos una lan local de la que forma parte nuestro servidor (direccionamiento 192.168.0.0) y la nueva red que creamos para las VPN’s (direccionamiento 192.168.3.0). Para permitir el enrutamiento completo entre las dos redes haríamos algo como:

#!/bin/sh
echo 1 >/proc/sys/net/ipv4/ip_forward
LAN="192.168.0.0/16"
VPN2="192.168.3.0/24"
iptables -A FORWARD -s $LAN -d $VPN2 -j ACCEPT
iptables -A FORWARD -s $VPN2 -d $LAN -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -d $VPN2 -j MASQUERADE

Sencillo. Si sólo quisiésemos que ciertos usuarios accediesen a la red local modificaríamos la variable VPN2 por la IP que radius le da al usuario.

FreeRadius desde un  entorno web, dialup_admin

Vale, es cierto, es un auténtico coñazo gestionar FreeRadius y todos sus parámetros, así que, que mejor que un sencillo entorno web para la gestión de usuarios y visualización de actividad y log del sistema. Esta utilidad es dialup_admin. No me detendré en su instalación ya que creo que se sale fuera de este artículo y, además, es una sencilla aplicación web sin mucha dificultad.

 radiusweb.gif

Con esta herramienta será mucho más sencillo crear usuarios y sus propiedades y hacer un seguimiento de los que están conectados, periodos de conexión que han tenido, etc.

Estableciendo la VPN desde Windows

Sencillísimo. Desde Conexiones de red, se crea una conexión nueva, escoges Conectarse a la red de mi lugar de trabajo y prácticamente sólo queda introducir el host o IP de tu sevidor VPN y  conectarse. Recomiendo desmarcar la opción Usar puerta de enlace predeterminada en la red remota en las propiedades de esta nueva conexión, Funciones de red, Protocolo TCP/IP, Opciones avanzadas, de otro modo todo el trafico de Internet normal lo harás a través de la VPN.

Si todo va bien conectarás a tu servidor y tendrás acceso al mismo como si estuvieses en tu propia red local.

Estableciendo la VPN desde Linux

Desde Linux es un pelín más complicado ya que, como casi siempre, hay que hacer la configuración a mano. Existe una utilidad gráfica que permite crear las conexiones de un modo similar a Windows, pero prefiero explicar cómo hacerlo desde la consola por si tu máquina no tiene entorno gráfico.

[osus@servidor ~]# cat /etc/ppp/options.pptp
lock
noauth
refuse-eap
refuse-chap
refuse-mschap
nobsdcomp
nodeflate

Ahora indicamos el usuario y la contraseña que se utilizará para conectar. IdentificadorRed será el nombre que le demos a la conexión, puede ser lo que quieras.

[osus@servidor ~]# cat /etc/ppp/chap-secrets
usuario IdentificadorRed clave *

Ahora creamos la configuración para la conexión que vas a crear con el IdentificadorRed que comentamos antes. En TUIP debes poner el host o ip de tu servidor VPN.

[osus@servidor ~]# cat /etc/ppp/peers/IdentificadorRed
remotename IdentificadorRed
linkname IdentificadorRed
ipparam IdentificadorRed
pty "pptp TUIP --nolaunchpppd "
name usuario
require-mppe
require-mschap-v2
refuse-eap
refuse-pap
refuse-chap
refuse-mschap
#demand
holdoff 5
persist
maxfail 0
ipcp-accept-remote
ipcp-accept-local
noauth
192.168.3.1:192.168.3.254

Aquí hay dos opciones interesantes:

  • persist: vuelve a crear el tunel automáticamente si se cortase por alguna razón de manera que permanece siempre activo.
  • demand: crea automáticamente el tunel cuando se accede a la IP del servidor o a alguna otra que esté enrutada a través de este tunel,  mientras no se necesite permanece inactivo. Obviamente no debe estar en modo persist, de otro modo estará siempre activa.

Finalmente creamos un sencillo script de arranque para poder lanzarla automáticamente o simplemente para no tener que recordar los parámetros.

[osus@servidor ~]# cat /etc/init.d/IdentificadorRed
#!/bin/sh
  case "$1" in
      start)
            echo -n "Iniciando VPN IdentificadorRed "
            echo
            touch /var/lock/subsys/pptpd
            /usr/sbin/pppd call IdentificadorRed logfd 1 updetach &
            ;;
      stop)
            echo -n "Parando VPN IdentificadorRed: "
            echo
            kill -TERM `head -n 1  /var/run/ppp-IdentificadorRed.pid`
            ;;
      *)
            echo "Usage: $0 {start|stop}"
            exit 1
  esac
exit 0

Y eso es todo amigos. Me ha costado bastante más de lo previsto escribir este artículo ya que a medida que lo iba redactando me iba saltando nuevos recuerdos sobre detalles que se deberían nombrar.

Tened en cuenta que mi experiencia con PPTP se remonta cinco años atrás con lo que puede ser que algún detalle haya cambiado los últimos años. Después de aquel primer servidor VPN el año pasado migramos el sistema operativo a Centos5 y al configurar de nuevo el servidor VPN dejamos prácticamente todos los parámetros como estaban. No creo que tengáis ningún problema a la hora de solucionar algún pequeño detalle que pueda surgir.

Las operadoras móviles y el control de Internet

Hace algo más de un año saltaba la noticia: Vodafone UK había implantado un proxy-transcoder en su red de datos de manera que todas las conexiones de sus clientes pasaban por este sistema. Con la excusa de hacer accesibles a todos los terminales cualquier página web ya existente, modificaban completamente el aspecto de la misma, añadiendo publicidad, accesos directos a Vodafone Live! y lo que es peor, modificando las hojas de estilos de los portales, con lo que tu trabajo perdía su apariencia original.

El movimiento internacional dentro del sector fué considerable. Gente como Andrea Trasatti o Luca Passani, verdaderos gurús de la adaptación, se revelaron contra la medida. Mucha gente lo criticó.

El problema no era sólo la apariencia de los portales, eso es lo que se veía directamente, el problema serio era (es) que se estaban cargando uno de los conceptos básicos de la adaptación para móviles: el UserAgent. Aunque existe en todos los navegadores web, el UserAgent cobra especial importancia en un dispositivo móvil ya que lo identifica, te aporta información sobre marca y modelo del mismo con lo que, con una buena base de datos de terminales (por ejemplo wurlf), puedes obtener compatibilidades (vídeo, mp3, mms…) y tamaños de pantalla. Al eliminarse el UserAgent se eliminaba la posibilidad de ofrecer contenido compatible con ese terminal. Pensemos en los juegos Java para móvil donde es imprescindible saber qué modelo tiene el cliente puesto que hay que darle un archivo compilado para ese mismo.

Después de algunas protestas, desde Vodafone UK decidieron enviar el UserAgent del teléfono original pero en una cabecera HTTP distinta, con lo cual tendrías que modificar TODOS tus desarrollos por culpa de esta maravillosa idea.

Finalmente se sacaron de la manga dos soluciones al transcoder:

  • Si tu dominio es .mobi no modifican el contenido ya que asumen que YA es contenido optimizado para pequeños dispositivos.
  • Una whitelist donde, si enviabas tus dominios, dejaban de filtrarlos y adaptarlos.

En realidad no sé si el segundo método llegó a funcionar alguna vez. El primero sí.

En octubre del año pasado llegaba la debacle a España. Vodafone ES ponía el famoso transcoder y todos nuestros portales móviles perdían su look&feel además de verse modificados para incluir todos los enlaces directos de Live!. También tuvimos voces de alarma.

Aquí el problema fue peor, nunca llegaron a enviar el UserAgent original. No sé si ahora lo hacen, pero en su momento no lo hicieron. Esta medida de Vodafone hizo mucho daño al sector.

Hoy, casi un año después, he descubierto, por pura casualidad, que Movistar también tiene el famoso proxy-transcoder, aunque por el momento parece que no hacen un uso abusivo de él. No modifican nada visualmente ni esconden el UserAgent, pero adaptan algunas cosas. Os explico la situación que me tuvo loco durante dos días.

Preparando un portal para una importante promoción me encontré con que en un Nokia N95 las imágenes no se veían al tamaño adecuado. Nuestra plataforma adapta automáticamente el tamaño de las imágenes en función del ancho de pantalla del terminal del cliente (obtenido a partir del UserAgent).  Pues resulta que en el servidor estábamos generando las imágenes correctamente, a 240px de ancho, mientras que en el teléfono se estaban recibiendo a 95px de ancho. ¡Imposible!

Probamos con el mismo teléfono pero con tarjetas SIM de otras operadoras y voila, funcionaba a la perfección. Finalmente pruebo con otros terminales y descubro que, en efecto, están adaptando las imágenes, imagino que para reducir el tráfico de red y optimizar el ancho de banda. El problema del N95 es que, por alguna extraña razón, lo tienen mal configurado en su base de datos de terminales  y, en vez de ponerle el tamaño real de pantalla que tiene (240×320), le han puesto 95px de ancho, incluso a lo mejor es el tamaño por defecto que devuelve el transcoder si no existe ese terminal en la base de datos, razón todavía peor, el N95 es uno de los dispositivos más populares a pesar de su coste.

¿Qué hago ahora cuando  el cliente nos diga que el portal se ve mal en su N95? ¿Se creerá que la culpa es de Movistar?

¿Por qué ahora, Google?

No, no voy a hablar de Chrome. Bastante se ha hablado ya sin que casi nadie se haya preguntado porqué Google saca un navegador web justo cuando menos necesario es. Siempre he pensado que algo no triunfará hasta que gente como mis hermanas o mis amigos puedan ser potenciales usuarios. Si aún no lo son de Firefox (a pesar de tenerlo instalado), ¿lo van a ser de Chrome?. Seamos realistas, Chrome es para techies y frikies. A Firefox le ha costado años y años y más años llegar a donde está hoy.

En fin, que ese no es el tema. La pregunta es, ¿por qué ahora?. ¿Por qué todo el mundo habla de Chrome y parecen olvidarse de Android?. Hace casi un año ya que Google anunción a bombo y platillo la plataforma Android y todavía no se ha visto ningún dispositivo sobre ella. Apple anuncia su iPhone seis meses antes de lanzarlo al mercado y todo son críticas y cortinas de humo, pero lo hace Google y es como si el Todopoderoso bajase de los Cielos para hacernos ver la luz. Y no seré yo el que salga en defensa de Apple.

Google ha tenido muchos problemas en el desarrollo de Android. A pesar de contar con el apoyo de las principales empresas del sector, tecnológicamente se ha encontrado limitaciones que han tenido que ir sorteando, y una de las principales en un mundo 2.0 ha sido, sin duda, el navegador web sobre el que basar su plataforma. Los que trabajamos con dispositivos móviles conocemos bien los navegadores que traen los terminales y sus limitaciones, tanto de procesamiento como de compatibilidad. Obviamente, si Google dejase el navegador web de su flamante Android en manos de un simple navegador wap, su teoría de movilizar el mundo de Internet sería no menos que utópica. Y eso por no hablar de la utilidad de toda la nueva generación de aplicaciones online (basadas en su mayoría en Ajax).

En este escenario Google tiene claro que, para triunfar en Internet móvil, independientemente de la plataforma sobre la que esté construido el terminal, debe tener un buen navegador web, que funcione en dispositivos móviles, que sea rápido y, a ser posible, estandar. Por esta época (hace un año) los terminales de gama alta de Nokia (N7x, N95…) ya salen de fábrica con un nuevo navegador web basado en Webkit (sí, el de Apple, el del iPhone), abandonando los antiguos navegadores wap y abriendo un nuevo mundo de oportunidades y aplicaciones. Las alternativas para el gigante de las búsquedas son dos: Gecko (de la Fundación Mozilla y motor de Firefox) y Webkit. La respuesta es clara, Webkit se concibió desde un principio como un motor HTML ligero y rápido.

Basándose en estas circustancias el equipo de desarrollo de Google se pone a trabajar en el que será el futuro navegador web de Android. Y llegados a este punto digo yo,

si ya tengo el motor optimizado a mi gusto, he desarrollado una máquina javascript impresionante y todo funciona bien… ¿por qué no compilarlo y lanzar un navegador web de escritorio?

No creo que sea descabellado, pero el paso importante NO es el escritorio, donde sabe que apenas conseguirá cuota de mercado (es la realidad), su objetivo es el móvil y, visto lo visto, si consiguen el mismo rendimiento que en el escritorio, van por el buen camino.

Por cierto, a mi también se me colgó Chrome 😉 .

Síndrome postvacacional

Las vacaciones han llegado a su fin, más o menos. Aunque el verano entra en el ocaso, tengo algunos viajes programados para las próximas semanas que os iré contando puntualmente como siempre 🙂 , serán salidas de tres o cuatro días nada más. Igualmente tengo algún artículo pendiente de escapadas de fin de semana.

He recibido quejas de alguna gente que sigue mi blog o de portales donde está sindicado referente a los artículos no técnicos. Obviamente tienen razón, el carácter principal de este blog es técnico, lo que no quita que escriba lo que yo quiera, pero a ellos mis viajes como que les da bastante igual. A mi, sin embargo, como ya os habréis dado cuenta, me encanta viajar y contar los sitios a dónde voy, es una manera de que todo el mundo conozca esos lugares, y no voy a renunciar a hacerlo.

He decidido, por tanto, crear un feed exclusivo para los artículos técnicos y que cada cual escoja que el mejor le venga.

La url del nuevo feed es:

http://feeds.feedburner.com/cerebrotecnico

Feeds por categorías en WordPress

Cuando Juanjo de Planeta Codigo me propuso hacer un feed exclusivamente técnico me gustó la idea, pero no sabía cómo hacerlo. Ahora que ya estoy de vuelta al trabajo me he parado a leer un poco y, la verdad, la gente de WordPress lo ha pensado bien y es mucho más simple de lo que creía. No hay que tocar ningún fichero.  Simplemente debes crear una categoría que englobe a todos esos artículos técnicos y automáticamente tendrás el feed ya que cada cada categoría tiene el suyo propio. Sólo tendrás que añadir /feed/ al link de la categoría tal como aparece en el listado de categorías del blog. En mi caso:

http://blog.osusnet.com/category/tecnico/feed/

Eso fué lo que hice, añadir una categoría “Técnico” y asociarla a todos los artículos de esta temática ya escritos.

Sencillo ¿no?.

Regala lotería y personaliza tus participaciones y décimos

¿Regalas lotería de Navidad?
¿Cansado de no saber cómo ser original a la hora de enviar el número?

Coincidiendo con las semanas previas al Sorteo Extraordinario de Navidad del año pasado lanzamos TusDecimos.com, algo tarde pero a tiempo para que se enviasen varios miles de décimos personalizados.

Después de numerosas peticiones hoy mismo hemos cambiado el diseño del décimo por el de este año, con lo que ya puedes enviar tus participaciones a tus amigos y familiares. Ya se sabe que en vacaciones se suele comprar lotería y la gente está ansiosa por regalarla. Los décimos generados puedes descargarlos, enviarlos por email o incluso al móvil del destinatario, con lo que lo tendrá bien guardado y no lo perderá, además de resultar un modo muy original de enviar el número.

TusDecimos.com

La idea surgió ni más ni menos que porque todos los años teníamos el mismo problema que la mayoría al regalar lotería, ¿cómo hacerlo distinto?. Te tocaba escanear el décimo, retocarlo a mano modificando la cantidad que regalabas… Ahora todo es mucho más sencillo.

Detalles técnicos

Ya que esto es un blog de corte técnico (aunque también publique de vez en cuando temas personales :P ), explicaré como hicimos el generador de décimos automático.

Lo principal, obviamente, es comprar un décimo :P y escanearlo, mejor a 300ppp puesto que así lo tenemos a muy buena resolución. Después debes retocarlo un poco, ajustar bien los bordes y, sobre todo, eliminar las rayas cruzadas que aparecen en la zona de los números. Nosotros vamos recortando porciones del dibujo de fondo y pegándolas sobre los números hasta que todo el dibujo queda limpio. Hay que repetir el mismo paso en las zonas de la derecha de fracción, seríe y precio del décimo. Así tendremos un billete limpio para personalizar a nuestro gusto.

 Decimo de loteria de navidad personalizado

Ahora debes obtener, a través de tu programa de dibujo como Gimp, las coordenadas que vas a necesitar:

  • Posición izquierda superior del cuadro imaginario donde iría el número del décimo.
  • Posición izquierda superior del cuadro imaginario donde iría la serie.
  • Ancho máximo del cuadro imaginario donde va la serie.
  • Posición izquierda superior del cuadro imaginario donde iría la fracción.
  • Ancho máximo del cuadro imaginario donde va la fracción.
  • Posición izquierda superior del cuadro imaginario donde iría la cantidad que regalas.
  • Ancho máximo del cuadro imaginario donde va la  cantidad que regalas.

A la hora de generar los números valoramos distintos modos de hacerlo, pero el resultado nunca era del todo satisfactorio. Lo primero en lo que piensas es en utilizar las librerías GD para insertar el texto del número, pero si lo pruebas verás que el resultado es muy pobre además de muy complicado de ajustar al espacio que ocupan, principalmente porque no tienes la fuente original que utiliza el Organismo de Loterías y Apuestas del Estado.

Finalmente optamos por un modo algo más artesano. Se hicieron los 10 dígitos básicos a mano, de manera que se ajusta perfectamente el tamaño de cada dígito y puedes hacer unos números bastante parecidos a los originales.  La serie, fracción y cantidad que juegas se hacen con una fuente normal con la función imagettftext, simplemente escoge la que más te guste. Para centrar el texto en la zona donde va utiliza la función imagettfbbox, te devolverá el tamaño del texto al pintarlo en el décimo, simplemente desplaza la posición de inicio la mitad del espacio sobrante. Nuestro script es un poco más elabordado puesto que juega, además, con el tamaño de la fuente de manera que se ajuste siempre perfectamente al espacio disponible. En líneas generales seria algo como:

$size=73;//tamaño de la fuente
$fuente="tufuente.ttf"; //fuente para los numeros de serie y fraccion
$serie="3"; //serie que vas a ponerle
$anchoespacio=135; //tamaño maximo del cuadro imaginario del espacio para la serie
$xinicio=1060; //posicion izquierda del cuadro imaginario de la serie
$yinicio=235; //posicion superior del cuadro imaginario de la serie
$bbox = imagettfbbox($size, 0, $fuente, $serie."ª");
$tw = ($anchoespacio-($bbox[2] - $bbox[0]))/2;
imagettftext($src_img, $size, 0, $xinicio+$tw, $yinicio, $tc, $fuente, $serie."ª");

Esto lo repetiríamos para serie, fracción y cantidad.

Para los dígitos del décimo, mucho más simple.

$decimo="23456";
$len=strlen($decimo);
$numero=array();
for($i=0; $i<$len; $i++)
    $numero[]=$decimo[$i];

for($i=0; $i<count($numero); $i++){
    $number = imagecreatefromgif ("numeros/".$numero[$i].".gif");
    imagecopymerge($src_img, $number, 450+($i*110), 105, 0, 0, 110, 133, 100);
}

Vamos copiando cada dígito sobre la posición del décimo donde iría. Sencillo. Ya tienes tu décimo personalizado. Si quieres puedes escalarlo o hacer lo que prefieras con él.

Con esto y teniendo cuidado de que los décimos te coincidan cada año en el mismo punto al escanearlos, tienes la aplicación resuelta para siempre.

Recuerda, si vas a regalar lotería, hazlo desde TusDecimos.com.

¿Programando a los 50? No, por favor

Los que me conocen saben que uno de mis blogs habituales es Navegapolis, de Juan Palacio. Es un tío muy coherente y con mucha experiencia en el ámbito de la gestión de proyectos de software, pero lo mejor de todo es que habla desde el punto de vista de un técnico, no de un “director de”, y de los problemas que se encuentran los desarrolladores por culpa de la mala gestión de los equipos. Este artículo hace referencias a algunos de sus posts de los últimos meses:

Como referencia a uno de ellos, muy interesante también Circuitos de pérdida de talento, por José Medina.

El viernes pasado, cenando con un alto cargo de RRHH de una multinacional, surgió el tema de los equipos y las selecciones de personal en IT.  Esta persona, antes de su actual puesto, desempeñó puestos similares en consultoras y telecos, con lo que algo sabe del tema. Me sorprendieron, sin embargo, algunas de sus opiniones. Este artículo es la mía.

Desde mi punto de vista y basándome en mi experiencia, un equipo de desarrollo es más que un grupo de gente. Salvo excepciones, son personas con una elevada formación y muy especializada, acostumbradas a pensar, a crear, a diseñar, a las que les apasiona su trabajo, construir, hacer cosas que otros van a utilizar. Esto no se puede entender de otro modo, nadie en su sano juicio se metería en este sector si no le gustase, los salarios son ridículos y el trabajo estresante.

Para entender la mentalidad de un desarrollador debemos comenzar por entender la estructura de un equipo de desarrollo.

Los últimos de la cadena son ellos, los programadores, los que construyen el trabajo, los que afrontan los problemas, los buscan, los solucionan, los preveen, cumplen los plazos… y sólo son los últimos eslabones de la cadena. A continuación tendríamos al responsable del equipo, la pieza clave, el encargado de motivarlos, de valorarlos, de mimarlos. Es el Luis Aragonés de un equipo de desarrollo. Un buen responsable debería preocuparse por la situación personal de su gente,  si tienen problemas (hipotecas, parejas, divorcios, niños…) no rendirán como se espera de ellos. La solución no es pegarles el puro y que se espabilen, es la solución fácil pero la menos buena. Si una persona tiene problemas no necesita que tu le crees más. Es una persona, no un recurso, cuanto antes lo entiendas antes conseguirás formar un equipo.

Encima del equipo y su responsable están toda una maraña de jefecillos y directores de, en general preocupados exclusivamente por su culo y su nómina a final de mes. Gente que hace años pudo ser programador pero se dió cuenta que no tenian un buen futuro y ahora son jefes. Gente para la que su trabajo es cumplir ocho horas e irse a sus casas. No les gusta especialmente su trabajo ni sienten pasión por él, es necesario para llegar a final de mes y punto.

Finalmente están los departamentos comerciales, los encargados de preguntarte plazos y recortarlos a su antojo. Los encargados de decir que sí a todo lo que los clientes solicitan, independientemente de que sea o no viable, ya habrá algún programador que lo solucione, y si no, a trabajar 12 horas diarias y fines de semana para cumplir los plazos.

Bajo esta estructura es fácil adivinar que muy pocos programadores (o ninguno) sienten, con 30 años, que quieren seguir siendo programadores a los 50, picacódigos que decimos. Todos aspiramos a ser responsables o, a poder ser, directores de algo y que otros hagan el trabajo. Triste pero cierto. Hay comerciales, gente de marketing, rrhh… con salarios de 50 a 70.000 euros al año pero nunca habrá un programador, ni siquiera un analista, que llegue a esas cifras. ¿Por qué?. Ellos hacen un trabajo imprescindible, fabrican, piensan, se echan a la espalda un duro trabajo. Un trabajo para el que, en muchos casos, se han pasado años y años en la facultad estudiando, soportando asignaturas y profesores duros (¿ingenierías vs. ADE, derecho, psicología…?). ¿Todo para qué? ¿Para empezar con 800 euros al mes y con suerte, en un par de años, llegar a los 1.000?

Esta persona con la que hablaba me comentaba que, para ella, un equipo eran un par de buenos programadores y el resto picacódigos. Imagino que la estructura que pasaba por su cabeza hablaba más de analistas que de programadores. Aún así es un grave error pensar así. Es como pensar que un equipo de fútbol son dos galácticos y 9 jugadores de relleno que se encargan de dar balones a las estrellas. Qué queréis que os diga, yo prefiero un equipo bien formado de 11 jugadores donde la integración del conjunto cree una estructura sólida y eficaz, un equipo del que ninguno de sus componenes quiere salir pero tampoco necesite destacar, que se sientan valorados y que sientan que participan en algo importante. Alguien diría, claro, ese es el trabajo del responsable del equipo, motivarlo. Y yo le contestaría, entre basura no se puede motivar a nadie. No le puedes hablar de motivación a alguien que cobra 15.000 euros anuales. Su motivación es buscar quien le de 16.500 y cambiar de trabajo. La motivación comienza por el salario y las políticas de mejoras. Si un empleado no puede pagarse un piso, irse de vacaciones unos días o salir a tomar unas copas… ¿cómo vas a motivarle? ¿le vas a contar milongas de que lo que hace es importantísimo? ¿que aquí va a aprender mucho? Yo, sinceramente, me reiría de ti en tu cara.

No vas a ganar la Eurocopa si no tienes equipo. No necesitas a los mejores, pero sí a unos cuantos válidos, compenetrados y motivados. Empieza por un sueldo decente. Trátalos como si fuesen personas, no como animales (de hecho a los animales se les trata muchas veces mejor que a los empleados). Preocúpate por sus vidas y que se sientan valorados. Esa es la motivación que te toca, que sientan que hacen algo útil y que su opinión cuenta, no son simples machacas, es gente que piensa y le gusta encontrar mejores soluciones. Si consigues una maquinaria bien engrasada y trabajando en equipo, sin competencias internas, sin que nadie busque medallitas, con lealtad, con capacidad para reconocer el error de uno y solucionarlo entre todos, amigo, tu trabajo así será mucho más sencillo y productivo.

Cuando un responsable de equipo consigue formar un buen grupo de gente intentará por todos los medios llevárselo con él allá donde vaya, es su garantía de trabajo y confía plenamente en ese equipo, los valora por encima de todo, sabe que su trabajo, si no tiene debajo un buen equipo, será casi imposible.

Siempre se dice que nadie es indispensable, y es cierto, nadie lo es, pero el hecho de que una persona abandone el equipo y entre una nueva puede llevar a tu equipo al fracaso. Puede desestabilizarlo, crear competencias que no existían por el simple hecho de buscar las conocidas medallitas… ¿En serio vale la pena dejar marchar a un buen trabajador sólo por no negociar con él? ¡Qué fácil es pensar que dónde había ese hay más! De un modo o de otro, tu equipo se resentirá y tu serás el primero en sufrir las consecuencias, tu planificación se irá por la borda y los plazos comenzarán a agobiarte.

Hablemos también de los de más arriba, de los directores de. Sí, esos con tan poca autoestima que en cuanto aparece alguien que intenta hacer bien las cosas hacen todo lo posible para cargárselos creyendo que así salvan su puesto de trabajo cuando en realidad están destruyéndolo lentamente. Como argumenta José Medina:

los números uno se rodean de números uno, y los doses, de treses y cuatros

Sobran más comentarios. Más aún en esta conocida cultura que hace jefes a los que ayer eran machacas, la cultura del peloteo, sí. El machaca convertido en jefe será siempre un número tres o cuatro que intentará que un número uno no se le suba a las barbas.

Un programador es una persona que se tiene que reciclar contínuamente, cada año su trabajo cambia, cambian las tecnologías, los lenguajes, las máquinas… y él está ahí al pié del cañón. ¿Os imagináis la experiencia que debe tener un tío de 50 años que lleve 25 programando? Impresionante. Pero nadie lo va a valorar. No. Más bien al contrario. Pensarán, vaya, menudo paquete tiene que ser este para ser un simple programador a su edad… En efecto, esta es la realidad.

Que nadie olvide que, por mucho director de que haya, no estarías ahora utilizando un ordenador si no existiesen los programadores. Es un trabajo donde te acuestas pensando y te levantas buscando soluciones. Piénsalo la próxima vez que arranques tu ordenador.

Por todo esto, no, a los 50 prefiero ser el responsable de un buen equipo e intentar hacer lo que hoy no nos dejan y que los que vengan detrás crean que ser programador es un buen trabajo, digno, gratificante y que te permitirá jubilarte.

Alguien que conozco me llamará ahora idealista 😉 , que todo esto está muy bien pero la realidad es bien distinta. En efecto, así es, pero a mi también me queda algo de idealismo aún. Esperemos que dure.

Sé que se me han quedado algunas cosas que quería decir en el tintero, pero ya está bien de aburriros, me ha quedado más largo de lo que esperaba. Hasta la próxima 🙂 .

¿Como fue tu primera conexión a Internet?

Me copio de Jose Alberto Hernandis una interesante entrada que, tal y como él comenta, y después de mi artículo Historias y homenajes en 8bits, podría titular también “Historias del abuelete 2”, jejejeje.

Mi primer contacto con Internet se produjo a finales de 1994, recién llegado a la universidad, en la ETSE Telecomunicación de Vigo. Un inocente chaval de 18 añitos entraba en contacto con el mundo exterior. Comenzamos a tener correo electrónico con unos Macintosh prehistóricos, no sé qué modelo eran pero os aseguro que de los primeros. Al poco tiempo se renovó el parque de PC’s de la Escuela por unos flamantes Pentium90 y nos permitieron recauchutar los viejos 286 para montar una red Linux de uso exclusivo para alumnos en un pasillo muerto (había muchos en aquél extraño edificio). Por aquél entonces ya disponíamos de cuentas personales de correo, de acceso a la red y acceso shell. Por cierto, la mía me la bloquearon al poco tiempo 😉 .

Corría el año 1996 cuando tuve mi primera conexión en casa, un modem 28.800 de ultimísima generación con una superoferta de RedesTB (después CTV y hoy Wanadoo). Comenzar a utilizarlo fue un caos ya que tenía MSDOS6.22+Windows3.11 (ya existía Windows95 pero me negaba a instalarlo 😛 ), así que me tenía que pelear con Trumpet Winsock para lograr conectar a Internet y no había manera así que, después de ver un artículo en PC-Actual sobre cómo conectar con Linux editando no sé cuantos archivos a mano (de aquella tendría un Red Hat 4.1 o similar) decidí a probar suerte con él y así fue como, señoras y señores, mi primera conexión a Internet desde mi casa fue ¡con Linux! (por friki que parezca) y durante muchos meses, hasta que me decidí a migrar mi 486 a Windows95.

Por razones obvias tuve que llegar a un acuerdo con mis padres para hacerme cargo del gasto telefónico porque sí, queridos niños y niñas, hubo un tiempo en este país donde no existían las tarifas planas ni banda ancha y pagábamos una millonada para conectarnos media horita a hipervelocidad, jejejeje. El problema fue que el gasto fue creciendo exponencialmente, sobre todo al descubir los chats y las chavalas que en ellos moraban, pero eso, amigos, es otra historia 😉 .