lunes, 24 de marzo de 2014

Configurando SSL en nginx

Informe SSL de teowaki.com por sslabs.com


La configuración básica de SSL en nginx es muy sencilla. Lo primero es tener una versión de nginx compilada con el módulo ngx_http_ssl_module. Si usas la versión estandar de tu distribución linux lo más seguro es que ya tenga soporte. Puedes comprobarlo con

$ nginx -V
...
configure arguments: --prefix=/usr/share/nginx ...--with-http_ssl_module ...

En el virtual host indicaremos que vamos a usar SSL y el path de los ficheros de certificados. El proveedor donde contrates el certificado te dirá los pasos para generar estos ficheros. Como ejemplo las instrucciones de Comodo y Linode

server {
  listen        443 ssl;

  ssl_certificate      /path_to/cert.crt;
  ssl_certificate_key  /path_to/cert.key;

}

Simplemente con estas tres líneas ya tenemos nuestro servidor con soporte SSL funcionando. Pero para que tu configuración sea óptima, hay cuantos parámetros más a tener en cuenta.


SPDY

SPDY es un protocolo creado por google para reducir el tiempo de carga de las páginas web. Está soportado en Firefox y Chrome desde hace tiempo y en IE desde la version 11.

Al igual que para tener soporte de SSL, se debe compilar nginx con el módulo correspondiente, ngx_http_spdy_module.

Como me da mucha pereza compilar nginx cada vez que lanzan una nueva versión, tenemos dos alternativas, usar binarios precompilados por Passenger o usar un ppa que incluya ese módulo

He optado por la segunda opción, usando los paquetes de Chris Lea. Están compilados usando la versión de desarrollo de nginx. Aunque es la versión de desarrollo es una versión estable que tambien usan en la web de nginx tal como explican en las FAQ.

La configuración de nuevo es tan simple como añadir spdy en la directiva listen

  listen        443 ssl spdy;


TLS

La configuración por defecto de nginx soporta SSL v3 y TLS versiones 1.0, 1.1 y 1.2.

Todos los navegadores modernos soportan TLS, y SSL v3 es un protocolo antiguo y tiene algunos problemas de seguridad, así que he decidido deshabilitarlo

  # enables TLS protocols, but not SSL which is weak and should no longer be used.
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;


Strict Transport Security (HSTS)

Si vamos a usar siempre conexión segura con nuestro servidor, añadiendo la cabecera Strict Transport Security, indicamos al navegador que aunque el usuario escriba la URL con http, siempre debe conectarse de forma segura usando https.

Es una buena práctica de seguridad y muchos servicios como Twitter o Paypal añaden esta cabecera en sus respuestas.

  # Remember this setting for 365 days
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";


Ciphers

Hay mucha literatura sobre los algoritmos de cifrado que se deberían permitir, en nuestro caso he optado por seguir las recomendaciones de Comodo.

Tambien he añadido otra directiva para que sea el servidor el que decida que protocolo usar entre los disponibles en lugar de dejar la elección al cliente.

  # Disables all weak ciphers
  ssl_prefer_server_ciphers on;
  ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;



OCSP Stapling

Al conectarse el navegador a una web segura, hace una petición adicional a la autoridad certificadora para asegurarse de que el certificado es válido usando OCSP (Online Certificate Status Protocol).

Por medio de OCSP Stapling, se evita esa petición adicional incluyendo la respuesta OCSP en la misma conexión SSL, con lo que reducimos el tiempo de conexión.

Puedes leer más en Cloudfare, en la Wikipedia, y comprobar si tu servidor lo soporta siguiendo las instrucciones de Unmitigated Risk.

  # enable ocsp stapling
  ssl_stapling on;


SSL Session

Por último, siguiendo las recomendaciones de nginx para reducir la carga del procesador habilitamos la caché de sesiones SSL y aumentamos el timeout

  ssl_session_cache    shared:SSL:10m;
  ssl_session_timeout  10m;



Con esta configuración conseguimos una implementación SSL robusta y eficiente. Si conoces algún truco o mejora, por favor, dejalo en los comentarios, gracias!


miércoles, 19 de febrero de 2014

Agrupando el log de rails con rsyslog

En teowaki el servicio de API lo tenemos balanceado entre dos servidores. Los objetivos principales de balancearlo, más que la carga, han sido la protección ante fallos y la posibilidad de hacer pruebas con diferentes configuraciones en los servidores.

Por ejemplo, inicialmente teníamos ruby 2.0 y unicorn en ambos servidores. En Navidad se publicó la versión 2.1, la instalamos en uno de los servidores y durante unas semanas tuvimos las dos versiones conviviendo en produccion. Las conclusiones fueron que más o menos el tiempo de respuesta bajaba un  20% y el consumo de memoría subía tambien sobre un 20%, así que decidimos instalarlo en las dos máquinas.

De la misma forma queremos hacer la prueba más adelante de usar diferentes servidores de aplicaciones simultáneamante (passenger / unicorn / puma) para ver cual funciona mejor. Tambien tenemos la intención de probar JRuby 9K en cuanto esté listo para producción.

El problema del balanceo es que el log queda distribuido y es imposible seguir una petición. Afortunadamente hay una solución muy simple usando rsyslog.

El primer paso es cambiar la configuración de rails para que use syslog, que viene por defecto en ruby, por lo que no es necesario instalar ninguna gema. Tan simple como añadir una línea en config/production.rb, donde 'teowaki-api' en nuestro caso indica el nombre que usaremos para la configuración de rsyslog.

$ more config/production.rb 
...
config.logger = Syslog::Logger.new 'teowaki-api'

A partir de ahora, el log en modo production lo procesará rsyslog.

Para configurar rsyslog, primero de todo editamos /etc/rsyslog.conf en el servidor que recibirá los logs (misc en nuestro caso), permitiendo acceso por TCP en el puerto 10514 y dando permiso de escritura solo a los servidores de API.

En la configuración por defecto de rsyslog el puerto de TCP es 514, pero en ubuntu hay un problema de privilegios al usar puertos por debajo del 1024, así que he usado el 10514

$ more /etc/rsyslog.conf
....
# provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 10514
...
$AllowedSender TCP, api01, api02

Ahora creamos el fichero de configuración cada servidor de API, donde le decimos que guarde el log en /var/log en local y que tambien lo mande al servidor misc al puerto 10514


$ more /etc/rsyslog.d/40-teowaki-api.conf 
if $programname == 'teowaki-api' then /var/log/rails/teowaki-api.log 
if $programname == 'teowaki-api' then @@misc:10514 
& ~  

Y finalmente, en el servidor misc le decimos que guarde el log, que le llegará desde los servidores de API, en /var/log

$ more /etc/rsyslog.d/40-teowaki-api.conf 
if $programname == 'teowaki-api' then /var/log/rails/teowaki-api.log 
& ~  

El número 40 indica la prioridad del fichero, para que se ejecute antes que el fichero 50-default.conf, tal y como explican en este blog, que fue el que me dio la idea para esta configuración

Y esto es todo, así de simple y ya tenemos la configuración completa.

La instalación en producción la he hecho con un par de roles de ansible, uno para los servidores de API y otro para el servidor que recibe los logs y además le he añadido logrotate, pero bueno, de ansible ya hablaremos en otro post...

Más adelante quiero probar otras soluciones más potentes como Kibana y logstash, pero por ahora ya tenemos el log centralizado, que era el objetivo inicial.



jueves, 6 de febrero de 2014

Recuperando el blog

Hace ya casi 6 años escribí la primera entrada en este blog. Mi idea inicial era escribir una entrada cada mes, mantuve bien el ritmo en el 2008 y el 2009, el 2010 empecé a flaquear y en el 2013 no he escrito ni una triste entrada :(

El 2013 ha sido un año de muchos cambios, dejé la empresa donde había estado trabajando desde el 2007 para intentar junto a Javi la loca aventura de montar un producto SaaS que haga más felices a los desarrolladores. Desde diciembre tenemos teowaki en producción, y estamos bastante orgullosos del resultado.

Uno de las consecuencias ha sido que mi stack tecnológico ha cambiado mucho. Estos años la mayoría de mis proyectos estaban basados en ruby on rails en el servidor, MySQL como almacen de datos y una parte cliente que cada vez iba siendo más compleja, pero casi siempre basada en las vistas de rails y jQuery.

Aprovechando que teniamos 'poder absoluto' para decidir la tecnología a usar, optamos por una arquitectura que por ahora está dando muy buen resultado.

Para empezar, queríamos que la API fuera un ciudadano de primera clase del proyecto, así que hemos desarrollado por un backend en modo API y el front es simplemente un cliente más de esa API.

Tambien hemos empezado a usar redis para mucho más que para la gestión de colas y nuestra base de datos es PostgreSQL.

Aunque ya hacía algo de sistemas anteriormente, tambien me he introducido un poco más en el mundo devops, instalando los servidores con Ansible. Otro cambio ha sido que en lugar de usar apache / passenger como servidor web y de aplicaciones, estamos probando la combinación nginx / unicorn.

Del mismo modo, he tenido que resetear lo que sabía de JavaScript, aprendiendo a usar AngularJS en el cliente de la API.

Así que creo que tengo bastantes cosas que contar sobre mi trabajo y voy a intentar recuperar el ritmo de una entrada por mes, a ver si lo consigo al menos durante otros dos años como cuando empecé este blog.


domingo, 30 de septiembre de 2012

Instalando Ubuntu en Vostro 3500 (parte 2)

Hace año y medio escribí una entrada en el blog explicando los problemas que había tenido con la instalación de Ubuntu Maverick en mi Dell Vostro 3500. Por los comentarios que tuve, parece que había bastante gente con los mismos problemas que yo (y que tambien me ayudaron a arreglar mis problemas), así que ahora que hace unos meses que actualicé a Ubuntu Precise (12.04), llegó el momento de actualizar la entrada.

Tarjeta gráfica


Como comenté en entrada anterior, este portátil tiene una tarjeta híbrida que no está soportada en ubuntu por defecto. Hace algo más de un año probé Bumblebee, pero estaba bastante verde, me dio muchos problemas y acabé por desinstalarlo. En cambio ahora es un proyecto bastante estable y llevo utilizándolo varios meses sin ningún problema.


Usando Bumblebee, por una parte, se consigue una mejor gestión del consumo de energía desactivando la tarjeta cuando no se usa (lo que se nota bastante trabajando con batería) y por otra permite activarla manualmente ejecutando las aplicaciones desde consola anteponiendo el comando optirun


He leído en pcworld y en phoronix que nvidia ha empezado a trabajar en un driver para este tipo de tarjetas, pero todavía no hay fechas, así que por ahora la mejor opción sin duda es Bumblebee.



HDMI

He probado a conectar el portátil a la tele con un cable HDMI y detecta la tele, pero no se ve el vídeo (con un cable VGA funciona sin problema). 

No he investigado el problema, así que no se si es un problema de configuración o si realmente no se puede.

Lector de huellas

El lector de huellas integrado (VFS300) todavía no está soportado. Hay un error abierto en launchpad desde hace bastante tiempo y en el comentario #51 hay un paquete que añade soporte para este lector.


Ejecutando las instrucciones del comentario en la configuración del usuario se puede activar su uso.  Pero me he encontrado varios problemas. El primero es que no va muy fino (la mayoría de las veces me da error al reconocer la huella) y el segundo es que al hacer login vuelve a pedir la contraseña para desbloquear el keyring (el keyring es donde ubuntu guarda las contraseñas, p.e. las de las wifis).


En la descripción del PPA oficial de fprint está muy bien explicado que es el keyring y como desactivar que pida contraseña (sección 'Note on keyrings and passwordless login') aunque esta última parte no la he probado.


Volviendo a launchpad, en el último comentario de final de agosto, pone que el bug ya está corregido, pero todavía no está aplicado en la versión de ubuntu. En resumen, seguiré con el lector desactivado por ahora hasta que esté mejor integrado.

La última versión de fprint ya incluye el soporte para el lector, así que instalándolo según las instrucciones, ya se puede usar sin problemas, aunque con las limitaciones que he comentado antes.




Unity


Otro de los grandes cambios al actualizar ubuntu fue cambiar gnome por unity, al principio es todo un poco raro, pero a la que llevas un tiempo usándolo se nota la mejora, queda bastante más espacio libre en la pantalla al tener los menús integrados en la barra superior y no tener la barra inferior de aplicaciones y a la que te acostumbras a buscar las aplicaciones por nombre (pulsando la tecla windows) es mucho más cómodo que la búsqueda por menú de gnome.


Con Unity desaparecen todos los indicadores del menú superior (por ejemplo el icono de skype), pero se pueden activar fácilmente tal y como explican en webupd8 ejecutando desde consola
gsettings set com.canonical.Unity.Panel systray-whitelist "['all']"

Otro problema para mi era no tener los applets de gnome, que usaba varios. Los que me he instalado son:

System Load Indicator para tener monitorizado el uso de memoría, cpu y carga del sistema
sudo add-apt-repository ppa:indicator-multiload/stable-daily
sudo apt-get update
sudo apt-get install indicator-multiload
Jupiter para la gestión automática del consumo cuando se trabaja con batería. Tiene más opciones, pero no las uso normalmente
sudo add-apt-repository ppa:webupd8team/jupitersudo apt-get update
sudo apt-get install jupiter
Hardware Sensors Indicators para tener monitorizar los sensores, principalmente el de temperatura
sudo add-apt-repository ppa:alexmurray/indicator-sensors
sudo apt-get update
sudo apt-get install indicator-sensors
Previamente a instalar esta última aplicación ejecuté xsensors que detecta los sensores disponibles y instala los módulos necesarios para los sensores detectados.
sudo apt-get install xsensors
sudo sensors-detect

En AskUbuntu hay una lista bastante completa de applets.

Ventilador

El ventilador ya no se puede gestionar como en gnome usando las alarmas de sensors applets, así que he optado por la solución que me propuso samsagax en mi post anterior, gracias de nuevo!

La solución consiste en installar i8kutils y arrancar el módulo (para que arranque automáticamente al reiniciar se debe añadir i8k en /etc/modules)
sudo apt-get i8kutils
sudo modprobe i8k
Una vez instalado, editamos el fichero .i8kmon en el home del usuario, con los umbrales de temperatura adecuados para nuestra instalación (en man i8kmon los explica perfectamente)
more ~/.i8kmon 
set config(0) {{- 0}  -1  55  -1  60}
set config(1) {{- 1}  50  65  55  70}
set config(2) {{- 1}  50  65  55  70}
set config(3) {{- 2}  60 128  65 128}

Si no se configura tiene unos valores por defecto de temperatura, que en mi caso creo que son demasiado altos. Tambien se puede configurar en /etc/default/i8kmon. aunque prefiero la opción de ponerlo en mi home, ya que tengo particiones separadas para home y / y si formateo / no pierdo la configuración.

Y ya solo queda arrancarlo (-a para que controle la velocidad del ventilador a parte de monitorizar y -d para que arranque en modo demonio)
i8kmon -a -d


Bueno, pues por ahora esto es todo respecto a mi configuración. Como en la entrada anterior, iré actualizando a medida que vaya descubriendo nuevas configuraciones....




viernes, 15 de junio de 2012

Euruko 2012 - Impresiones

Para no perder la tradición, de nuevo he estado en Euruko, este año en Amsterdam.

Aprovechando que hemos puesto en común las impresiones en ASPgems (agradecido porque de nuevo me financió este año el viaje) y que acaban de publicar los vídeos en vimeo, es el momento de reflexionar un poco sobre la conferencia.

La verdad es que este año me ha decepcionado un poco. Es una conferencia a la que he ido ya varias veces y la tenía un poco idealizada, como una conferencia pequeña, en la que siempre me sorprendían las conferencias, con multitud de aplicaciones curiosas de ruby fuera del mundo web que es el que conozco y uso habitualmente.

Pero este año me encontré con una conferencia multitudinaria, demasiado rígida, en la que preferían cortar las preguntas antes de retrasar cinco minutos la siguiente charla, demasiado 'enterprise' (el señor jruby contando la maravillas de su producto, idem el señor rubinius, ...) y sin nada que me sorprendiera especialmente.


Espero que el año que viene en Atenas le vuelvan a dar el toque de frescura que ha perdido.

A pesar de que parece muy negativo todo lo que he puesto, porque tenía unas espectativas demasiado altas, la conferencia ha sido interesante y ha habido unas cuantas charlas recomendables. Si me tuviera que quedar con cinco elegiría:

Bruno Aguirre - The Future is Dead: Long live the Past, filosofando un poco sobre programación
Mitchell Hashimoto - Building a Ruby Library, the Parts No One Talks About dando buenos consejos sobre como hacer una librería en ruby
Roy Tomeij - The Joy of Front-End, A Journey with Bob Ross con más interesantes consejos, en este caso de front-end
Sean Cribbs - A Case of Accidental Concurrency planteando un problema real de concurrencia y el proceso de resolución
Martin Rehfeld - Ruby & Erlang, At Scale with Style aunque no fue de las mejores charlas, siempre es interesante ver como resuelven en wooga sus problemas de escalabilidad


Nos vemos en Atenas :)