# rm-rf.es | Administración de sistemas

Blog de un SysAdmin Unix, Gnu/Linux, Windows y lo que haga falta.

POODLE: deshabilitar SSLv3 en Postfix, Sendmail, Dovecot, Courier-imap

En la entrada anterior veíamos como deshabilitar SSLv3 en los servidores web Apache, Nginx, Lighttpd para protegernos de la vulnerabilidad crítica en SSL 3.0 POODLE. Ahora nos centramos en los servidores de correo (POP3, IMAP, SMTP) y vamos a ver como deshabilitarlo en Postfix, Sendmail, Dovecot y Courier-imap.

Deshabilitar SSLv3 en Postfix

Para quitar SSLv3 en Postfix debemos editar el archivo de configuración /etc/postfix/main.cf y modificar la directiva de configuración smtpd_tls_mandatory_protocols, bloqueando las versiones 2 y 3 de SSL:

/etc/postfix/main.cf
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3

Reiniciamos postfix para activar los cambios:

# service postfix restart

Deshabilitar SSLv3 en Sendmail

En sendmail, debemos editar la plantilla del archivo de configuración sendmail.mc y modificar la sección LOCAL_CONFIG y editar lo siguiente:

CipherList=HIGH
ServerSSLOptions=+SSL_OP_NO_SSLv2 +SSL_OP_NO_SSLv3 +SSL_OP_CIPHER_SERVER_PREFERENCE
ClientSSLOptions=+SSL_OP_NO_SSLv2 +SSL_OP_NO_SSLv3

Usamos el comando m4 para generar el archivo de configuración:

m4 sendmail.mc > /etc/sendmail.cf

Y reiniciamos sendmail:

/etc/init.d/sendmail restart

Deshabilitar SSLv3 en Dovecot

Para Dovecot debemos tener en cuenta que según la versión hay que realizar modificaciones distintas.

En versiones superiores a la 2.1 editamos el archivo de configuración /etc/dovecot/local.conf añadiendo la siguiente línea:

/etc/dovecot/local.conf
ssl_protocols = !SSLv2 !SSLv3

Para versiones inferiores editamos el archivo /etc/dovecot/conf.d/10-ssl.conf y añadimos la línea:

/etc/dovecot/conf.d/10-ssl.conf
ssl_cipher_list = ALL:!LOW:!SSLv2:!SSLv3:!EXP:!aNULL

En ambos casos, después de aplicar los cambios hay que reiniciar el servicio:

# service dovecot restart

Deshabilitar SSLv3 en Courier-imap

En Courier-Imap, editamos el archivo de configuración /etc/courier/imapd-ssl con la siguiente configuración:

/etc/courier/imapd-ssl
IMAPDSSLSTART=NO
IMAPDSTARTTLS=YES
IMAP_TLS_REQUIRED=1
TLS_PROTOCOL=TLS1
TLS_STARTTLS_PROTOCOL=TLS1

Y reiniciamos el servicio:

# service courier-imap restart

POODLE: deshabilitar SSLv3 en Apache, Nginx, Lighttpd

Vamos a ver como deshabilitar SSLv3 en los servidores web más conocidos: Apache, Nginx y Lighttpd. Podéis ver los detalles de la vulnerabilidad en el post POODLE: vulnerabilidad crítica en SSL 3.0

Deshabilitar SSLv3 en Apache

Para deshabilitar SSLv3 en el servidor web Apache debemos modificar la directiva SSLProtocol ofrecida por el módulo mod_ssl.

Por defecto, en sistemas Red Hat, CentOS y derivados esta directiva se especifica en el archivo de configuración donde se engloba toda la configuración SSL:

/etc/httpd/conf.d/ssl.conf

Debemos modificar la directiva por lo siguiente, que permite todos los protocolos excepto SSLv3 y SSLv2.

SSLProtocol all -SSLv3 -SSLv2

Una vez realizado, reiniciamos Apache:

# service httpd restart

En Debian y Ubuntu el archivo de configuración ssl.conf se encuentra en una ruta distinta:

/etc/apache2/mods-available/ssl.conf
# service apache2 restart

Deshabilitar SSLv3 en Nginx

En Nginx SSLv3 también está habilitado por defecto.

Debemos modificar la directiva ssl_protocols del archivo de configuración nginx.conf, esta directiva especificará los distintos protocolos permitidos en el bloque http { }:

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

Si quitamos la versión 3 quedaría la siguiente configuración:

ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;

Una vez modificado recargamos la configuración de nginx:

# nginx -s reload

Deshabilitar SSLv3 en Lighttpd

En Lighttpd editamos el archivo de configuración:

/etc/lighttpd/lighttpd.conf

Y deshabilitamos SSLv3 y SSLv2:

ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"

Y reiniciamos el servicio:

# service lighttpd restart

POODLE: vulnerabilidad crítica en SSL 3.0

Y seguimos con las vulnerabilidades críticas, tras los problemas de bash en las últimas semanas con las vulnerabilidades CVE-2014-6271 y CVE-2014-7169 ahora le toca el turno al protocolo SSL (OpenSSL no se salva, por supuesto) con una vulnerabilidad (CVE-2014-3566) detectada ayer 14 de octubre y que todavía está siendo investigada por Bodo Möller, Thai Duong y Krzysztof Kotowicz que son los que han descubierto la vulnerabilidad.

El protocolo SSL 3.0 es un protocolo que ya tenía sus detractores desde hace tiempo y que debía ser renovado tras sus 15 años de antiguedad, es utilizado tanto en OpenSSL (a partir de la versión) 1.0.1i como en otros productos (la mayoría de navegadores todavía lo soportan, aunque ya han confirmado que será deshabilitado en próximas versiones), el ataque básicamente permite forzar que el cliente pase a utilizar este protocolo de SSL 3.0 en lugar de uno superior y a partir de ahí comenzar el ataque pudiendo acceder a los datos sin cifrar con un man-in-the-middle aunque se encuentre en una sesión cifrada con SSL, esto lo realizan a través de un ataque tipo MitM.

La solución actual pasa por deshabilitar el soporte a SSL 3.0 o utilizar cifrados CBC-mode en SSL 3.0, el problema es que actualmente esto generará muchos problemas de compatibilidad con programas que sí que utilicen SSL 3.0. La solución recomendada es habilitar TLS_FALLBACK_SCSV, un mecanismo que soluciona los problemas causados por reintentar conexiones fallidas y prevenir que los atacantes puedan forzar a los navegadores a utilizar SSL 3.0 y TLS 1.2, 1.1 y 1.0

Como ya digo, por ahora no hay demasiada información recopilada y se está investigando la incidencia así que os voy a dejar unos enlaces de referencia y si es necesario iré actualizando el artículo conforme la información vaya llegando.

Información sobre POODLE en el sitio web de OpenSSL:

https://www.openssl.org/~bodo/ssl-poodle.pdf

Google Online Security

http://googleonlinesecurity.blogspot.com/2014/10/this-poodle-bites-exploiting-ssl-Google30.html

Vulnerabilidad CVE-2014-3566

http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-3566

Actualización 16:00

Red Hat publica la solución a la vulnerabilidad:

Opción 1: Deshabilitar SSLv2 y SSLv3 (Habilitar todo exceptoSSLv2 y SSLv3)

SSLProtocol All -SSLv2 -SSLv3

Opción 2: Deshabilitar todo excepto TLSv1.x

En RHEL 7 y RHEL 6.6 y posteriores:

SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2

En otras plataformas:

SSLProtocol -All +TLSv1

Reiniciar HTTPD tras aplicar los cambios:

# service httpd restart

OpenSSL: SSL23_GET_SERVER_HELLO:unknown protocol

Con OpenSSL podemos comprobar el estado de una conexión SSL o si la configuración de un servidor web (Apache, IIS, Lighttpd, NginX…) es correcta, tanto a nivel de certificado como de listeners.

El comando para lanzar una petición al servidor web es el siguiente:

# openssl s_client -connect miservidorweb.com

Podemos especificar un puerto distinto:

# openssl s_client -connect miservidorweb.com:444

El hilo venía a raíz de este posible error que puede aparecer al intentar establecer la conexión:

# openssl s_client -connect miservidorweb.com
CONNECTED(00000003)
140360151582536:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:699:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 113 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE

Podemos ver que OpenSSL no encuentra el protocolo a través del cual comunicarse por SSL. El problema se encuentra en el servidor web, o bien no hemos configurado HTTPS por el puerto de conexión indicado (444) en este caso, o directamente el listener no está bien configurado en el servidor.

Deberíamos revisar la configuración del servidor web. ¿Está configurado para escuchar HTTPS por el puerto indicado? Es posible que se haya modificado la configuración y el puerto haya sido modificado sólo parcialmente.

Una vez confirmado que todo esta bien a nivel de servidor web, volvemos a probar y debería funcionar correctamente, volcando por salida estándar la información del certificado:

# openssl s_client -connect miservidorweb.com:444
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = "GeoTrust, Inc.", CN = GeoTrust SSL CA
verify return:1
verify return:1
---
Certificate chain
 0 s:/serialNumber=qGb8I
   i:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
 1 s:/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
---
Server certificate
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
subject=/serialNumber=qGb8IgRr-
issuer=/C=US/O=GeoTrust, Inc./CN=GeoTrust SSL CA
---
No client certificate CA names sent
---
SSL handshake has read 3136 bytes and written 311 bytes
---
[...]

Tomcat 7 HTTPS: APR y JSSE

Tomcat ofrece dos formas de trabajar con SSL: JSSE y APR. La implementación de SSL basada en JSSE forma parte del Java Runtime (desde la versión 1.4) mientras que con el conector nativo APR se utiliza el motor de OpenSSL.

Por defecto, Tomcat 7 utiliza APR, cuya principal diferencia en la configuración respecto a JSSE es que APR utiliza archivos de certificado normales (.crt,.key) en lugar de almacenarlos en un keystore. De este modo, si usamos APR deberemos especificar la ruta al fichero de certificado, al fichero de la llave privada y al de los certificados raíz/intermedios. Si en cambio usamos JSSE simplemente configuraremos la ruta al Keystore.

Ejemplo de configuración con APR:

<Connector
protocol="HTTP/1.1"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
SSLCertificateFile="/usr/local/ssl/server.crt"
SSLCertificateKeyFile="/usr/local/ssl/server.pem"
SSLVerifyClient="optional" SSLProtocol="TLSv1"/>

Ejemplo de configuración con JSSE:

<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="/usr/local/ssl/.keystore" keystorePass="mipassword"
clientAuth="false" sslProtocol="TLS"/>

Como véis, en uno especificamos los ficheros de certificado y en otro el Keystore, además, cambia el protocolo del conector según sea APR o JSSE. Si por ejemplo no cambiamos el protocolo de conector y usamos HTTP/1.1 en una configuración JSSE con keystore, al arrancar, Tomcat soltará el siguiente error en el archivo de log catalina.out:

SEVERE: Failed to initialize end point associated with ProtocolHandler ["http-ap
r-8443"]
java.lang.Exception: Connector attribute SSLCertificateFile must be defined when
using SSL with APR
at org.apache.tomcat.util.net.AprEndpoint.bind(AprEndpoint.java:484)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:554.
[...]

keytool error: java.lang.Exception: Failed to establish chain from reply

Este error puede ocurrir al importar un certificado SSL a un keystore:

keytool error: java.lang.Exception: Failed to establish chain from reply

En este caso ha sucedido al importar con el comando keytool un certificado SSL del cual previamente habíamos generado un Certificate Request (CSR) en un servidor de aplicaciones tomcat:

# keytool -import -alias mikeystore -keystore tomcat -file www.foo.com.cer
keytool error: java.lang.Exception: Failed to establish chain from reply

El error se produce porque no hemos instalado en el orden correcto (o nos hemos dejado alguno) los certificados de la cadena de confianza:

ROOT Certificate -> Intermediante Certificate -> SSL Certificate

Así que antes de instalar el certificado definitivo debemos importar el resto de certificados que nos facilita la entidad certificadora, y en el orden correcto:

Importamos el certificado ROOT:

# keytool -import -alias root -keystore mikeystore -trustcacerts -file root.cer

Importamos el certificado Intermedio:

# keytool -import -alias root_ca -keystore mikeystore -trustcacerts -file ca.cer

Y finalmente importamos nuestro certificado final:

# keytool -import -alias tomcat -keystore mikeystore -file www.foo.com.cer

Cómo generar un SSL Certificate Request (CSR) en Tomcat

Estos son los pasos para generar un CSR (SSL Certificate Request) en Tomcat. Este tutorial se basa en la creación de un nuevo keystore.

Lo primero es crear el keystore que almacenará el certificado y la private key. El comando a utilizar para todas las operaciones es keytool. Forzamos el tamaño de la private key a 2048 bits con el parámetro keysize, le indicamos que el algoritmo es RSA y que el alias para el certificado dentro del keystore es “tomcat”:

# keytool -genkey -alias tomcat -keyalg RSA -keysize 2048 \
-keystore /usr/share/tomcat/conf/ssl/tomcat_keystore
Enter keystore password:  
Re-enter new password: 
What is your first and last name?
  [Unknown]:  www.rm-rf.es
What is the name of your organizational unit?
  [Unknown]:  IT
What is the name of your organization?
  [Unknown]:  Mi compañía
What is the name of your City or Locality?
  [Unknown]:  Madrid
What is the name of your State or Province?
  [Unknown]:  Madrid
What is the two-letter country code for this unit?
  [Unknown]:  ES
Is CN=www.rm-rf.es, OU=IT, O=Mi compañía, L=Madrid, ST=Madrid, C=ES correct?
  [no]:  yes

Enter key password for 
	(RETURN if same as keystore password):  

Como podéis ver, solicita el password del keystore (lo utilizaremos para acceder a los contenidos del mismo), el Common Name para el certificado (first and last name, un poco ambiguo…), y el resto de datos de organización, empresa, ciudad, etc. Finalmente la clave para la key, que podemos seleccionar la misma que para el keystore.

Con esto ya tenemos el keystore creado y la private key con todos los datos. Podemos asegurarnos listando el contenido del keystore:

# keytool -list -keystore /usr/share/tomcat/conf/ssl/tomcat_keystore
Enter keystore password:  

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

tomcat, 21-ago-2014, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 9C:B1:.......

Para generar el CSR a partir de esa información ejecutamos el siguiente comando:

# keytool -certreq -keyalg RSA -alias tomcat -file /usr/share/tomcat/conf/ssl/certreq.csr \
-keystore /usr/share/tomcat/conf/ssl/tomcat_keystore

Una vez ejecutado ya tendremos el fichero .csr que se envía a las empresas certificadoras para que emitan el certificado SSL.

# cat  /usr/share/tomcat/conf/ssl/certreq.csr
-----BEGIN NEW CERTIFICATE REQUEST-----
[...]
-----END NEW CERTIFICATE REQUEST-----

Encriptar y firmar documentos PDF directamente desde Alfresco

El AMP (Alfresco Module Package) Alfresco PDF Toolkit nos permite añadir una serie de funcionalidades extra al gestor documental Alfresco que nos permiten manipular y trabajar con documentos PDF. En nuestro caso las funciones que más nos han interesado han sido la de encriptar y firmar digitalmente documentos a golpe de click o regla/workflow.

Alfresco PDF Toolkit es un proyecto que se aloja en Google Code y permite ya su integración con la interfaz “Share” además de “Alfresco” a partir de la versión 1.0 del plugin y Alfresco 4.x.

Esta nueva versión incorpora las siguientes funcionalidades sobre documentos PDF:

  • Unir documentos
  • Dividir documentos
  • Dividir documentos indicando páginas específicas
  • Añadir un PDF dentro de otro en una página específica
  • Marcas de agua
  • Encriptación
  • Firma digital
  • Transformar documentos TIFF a PDF
  • Metadatos extendidos para capturar información de encriptación o firmas
  • Buscar documentos encriptados o firmados a partir de metadatos de firma

La forma de instalación es la misma que con cualquier AMP, revisad el siguiente artículo para más detalle: Instalar AMPs en Alfresco. Una vez instalado aparecerán todas las nuevas acciones en las acciones de los documentos PDF:

alfresco-pdf-toolkit

Para probar la firma digital podemos crear un certificado self-signed y almacenarlo en un keystore. Ese keystore se puede probar subiéndolo a la home del usuario que lo va a utilizar. En el caso de entornos productivos se pueden generar procedimientos automáticos para evitar que el keystore esté almacenado en la misma máquina que Alfresco. En entornos de pruebas podéis generar un certificado del siguiente modo:

# keytool -genkey -keyalg RSA -alias "Alejandro G" -keypass PASSWORD -keystore keystore.ks -dname "cn=Alejandro G, c=ES"

Ese keystore.ks lo podéis usar para la firma digital. Veréis que os la pide a la hora de firmar junto con otros valores como la pass del keystore, la pass del certificado, el Alias, etc.

No dudés en ver este vídeo presentación de todas las posibilidades que ofrece Alfresco PDF Toolkit y su funcionamiento en el Front-End Share:

Redirigir tráfico http a https en Sun Java System Web Server

Vamos a ver como forzar la redirección de tráfico HTTP a HTTPS para una instancia web de Sun Java System Web Server o si fuera necesario únicamente para una sección concreta del website. Por seguridad es muy probable que queramos evitar que a un sitio web o partes del mismo se pueda acceder sin protocolo seguro (ssl-https).

En el fichero de configuración obj.conf ó foo-obj.conf de la instancia podemos establecer estas configuraciones de redirección. Para ello utilizaremos la etiqueta Client dentro del objeto Default.

En el siguiente ejemplo forzamos el uso de https para la url (urlhost) test.rm-rf.es y para todo el website (from=”/” y from=”/*”. Lo que nos indica que el origen del tráfico tiene que ser siempre http es el atributo security=”false”, es decir, todo el tráfico que no sea https y que cumpla lo que indican los NameTrans ejecutará la redirección:

<Object name="default">
<Client match="all" security="false" urlhost="test.rm-rf.es">
NameTrans fn="redirect" from="/" url-prefix="https://test.rm-rf.es/"
NameTrans fn="redirect" from="/*" url-prefix="https://test.rm-rf.es/"
</Client>
....
....
....
</Object>

Si quisiéramos redirigir únicamente una ruta concreta en lugar de especificar ” podemos indicar la ruta:

<Object name="default">
<Client match="all" security="false" urlhost="test.rm-rf.es">
NameTrans fn="redirect" from="/prueba/" url-prefix="https://test.rm-rf.es/"
</Client>
....
....
....
</Object>

Una vez realizados los cambios reiniciamos la instancia para hacerlos efectivos:

# ./stopserv; ./startserv

En la documentación oficial encontraréis más información sobre cada una de las directivas y atributos (NameTrans, fn, urlhost, security…)

Generar un certificado SSL con genkey (Red Hat Keypair Generation)

Hoy vamos a ver una alternativa a la generación de certificados SSL con OpenSSL. Genkey (Red Hat Keypair Generation) es un comando disponible como parte del paquete crypto-utils:

# yum whatprovides */genkey
Loaded plugins: fastestmirror, presto
Loading mirror speeds from cached hostfile
....
....

crypto-utils-2.4.1-24.2.el6.i686 : SSL certificate and key management utilities
Repo        : base
Matched from:
Filename    : /usr/bin/genkey

Aprovechamos entonces para instalarlo:

# yum install crypto-utils

Echando un vistazo a la ayuda podemos ver las opciones del comando:

# genkey 
Usage: genkey [options] servername
    --test   Test mode, faster seeding, overwrite existing key
    --genreq Generate a Certificate Signing Request (CSR)
    --makeca Generate a self-signed certificate for a CA
    --days   Days until expiry of self-signed certificate (default 30)
    --renew  CSR is for cert renewal, reusing existing key pair, openssl certs only
    --cacert Renewal is for a CA certificate, needed for openssl certs only
    --nss    Use the nss database for keys and certificates
    --gdb    For package maintainers, to trace into the nss utilities

¡Qué motivo podríamos tener para utilizar genkey en lugar de openssl? Corregidme si hay algún otro más, pero en principio lo que yo veo es que no tenemos que acordarnos de los comandos de openssl ya que genkey es un asistente en modo text/gráfico desde línea de comandos que nos guía con todos los pasos.

Si quisieramos generar un certificado self-signed para ssl.rm-rf.es seguiríamos estos pasos:

# genkey ssl.rm-rf.es

Comienza el asistente, que ya nos indica donde van a guardarse los ficheros resultantes (llaves privadas, certificados, certificate requests, CA requests, etc.)

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 1

Indicamos el tamaño de la llave, a mayor tamaño en bits, mayor seguridad, también costará más tiempo generarla:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 2

Esperamos a la generación de los bits aleatorios:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 3

Y la generación de datos aleatorios. Se recomienda mover el ratón o escribir en la consola del servidor/máquina para acelerar el proceso:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 4

Si quisiéramos enviar una petición de CSR a una entidad certificadora autoritativa (CA) este sería el momento:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 5

Para mayor seguridad podemos encriptar la llave privada del certificado. La frase de paso (passphrase) que indiquemos tendrá que ser introducida cada vez que arranquemos el servicio web seguro.

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 6

Por último introducimos los datos de nuestro certificado:

Generar un certificado SSL con genkey (Red Hat Keypair Generation) 7

Una vez aceptado podremos ver en la línea de comandos la ejecución del proceso por genkey:

/usr/bin/keyutil -c makecert -g 1024 -s "CN=ssl.rm-rf.es, OU=IT, O=Rm-RF, L=Zaragoza, ST=Zaragoza, C=ES" -v 1 -a -z /etc/pki/tls/.rand.2492 -o /etc/pki/tls/certs/ssl.rm-rf.es.crt -k /etc/pki/tls/private/ssl.rm-rf.es.key
cmdstr: makecert

cmd_CreateNewCert
command:  makecert
keysize = 1024 bits
subject = CN=ssl.rm-rf.es, OU=IT, O=Rm-RF, L=Zaragoza, ST=Zaragoza, C=ES
valid for 1 months
random seed from /etc/pki/tls/.rand.2492
output will be written to /etc/pki/tls/certs/ssl.rm-rf.es.crt
output key written to /etc/pki/tls/private/ssl.rm-rf.es.key

Generating key. This may take a few moments...

Made a key
Opened tmprequest for writing
(null) Copying the cert pointer
Created a certificate
Wrote 882 bytes of encoded data to /etc/pki/tls/private/ssl.rm-rf.es.key 
Wrote the key to:
/etc/pki/tls/private/ssl.rm-rf.es.key

Y nuestra private key y certificado ya están disponibles para su uso.