Self signed ssl

=SSL everywhere= Una recomendación importante de seguridad es no utilizar protocolos que transmiten la información en texto plato. Al utilizar protocolos encriptados de punta a punta (como SSL) podemos prevenir un MITM atack

En ambientes internos, donde el SSL puede ser autofirmado, es necesario agregar el certificado manualmente al repositorio de claves confiables (keystore). Utilizar un SSL self signed (auto firmado), en ambientes Unix es relativamente sencillo de concretar, aquí dejamos instructivos para hacerlos.

Al usar Java, es importante incorporar el certificado al repositorio de confianza del JVM. Esto es necesario hacerlo, aunque ya hayas importado el certificado al sistema operativo.

Observación: Para ejemplificar se usa un host ficticio: ssl_mi_host_custom.joko.github.io, cambiar por el host o nro. de IP del servidor que tiene el certificado SSL que quieres agregar a tu lista de confianza.

Crear certificado
Para crear un certificado SSL Self-signed, se pueden seguir estos pasos:

sudo apt-get update sudo apt-get install openssl
 * Instalar openssl en el servidor en el cual se instalará el certificado

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
 * Generar el certificado, con validez de 365 días

Instalar certificado en Nginx
Luego de generar el certificado SSL, se debe agregar el mismo al Webserver, Nginx. Para esto, se debe agregar estas líneas al archivo de configuración de las páginas que serán servidas.

$ sudo nano /etc/nginx/sites-available/default

server { listen 443 default_server; listen [::]:443 ssl default_server;

ssl on; ssl_protocols      TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers        "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES"; ssl_certificate    /etc/ssl/crts/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

...       ...

¿Cómo darnos cuenta que necesitamos importar un certificado?
Al acceder normalmente a un servidor con SSL self signed, obtenemos algún warning o el cliente no nos permite hacerlo Ejemplo: $ curl https://mi_host_custom.joko.github.io/ curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle" of Certificate Authority (CA) public keys (CA certs). If the default bundle file isn't adequate, you can specify an alternate file using the --cacert option. If this HTTPS server uses a certificate signed by a CA represented in the bundle, the certificate verification probably failed due to a problem with the certificate (it might be expired, or the name might not match the domain name in the URL). If you'd like to turn off curl's verification of the certificate, use the -k (or --insecure) option.

En esta situación debemos conseguir el certificado del servidor (su clave pública) y manualmente confirmar que confiamos en el mismo.

¿Cuales son los pasos para importar?
El primer paso es descargar el archivo que representa a la clave pública del servidor. Luego este archivo debe de ser agregado al repositorio de claves confiables. En la siguiente sección mostramos una manera muy práctica de descargar el certificado.

Descargar certificado (CRT)
Con la siguiente linea nos conectamos al servidor devtools.hq.sodep.com.py (en el ejemplo, puerto 443) y creamos un archivo .crt con el contenido de la clave publica. HOSTNAME=devtools.hq.sodep.com.py; PORT=443; ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect $HOSTNAME:$PORT) -scq > $HOSTNAME-$PORT.crt Reemplazando el valor de la variable HOSTNAME por el nombre o nro. de IP del servidor al que nos queremos conectar. También se puede exportar desde el navegador, entrando a ver la información de seguridad, ingresando al sitio en cuestión. Con el archivo .crt obtenido, se procede a incluírlo entre los certificados del sistema operativo.

Importar al sistema operativo (Linux)
Para importar el certificado, tenemos que ejecutar:

$ sudo cp ssl_mi_host_custom.joko.github.io.crt /usr/local/share/ca-certificates $ sudo update-ca-certificates

En el caso de Arch Linux, ejecutar:

$ sudo cp ssl_mi_host_custom.joko.github.io.crt /etc/ca-certificates/trust-source/anchors/ $ sudo trust extract-compat

Para verificar que quedó integrado a los certificados de confianza del sistema operativo, puedes probar contectar al servidor con el curl

$ curl https://mi_host_custom.joko.github.io/

Importar Certificado en OSX
Para importar el certificado en OSX hay que abrir el programa keychain.


 * 1) Ir al menú "File"
 * 2) Seleccionar la opción "add Item"
 * 3) Se busca el certificado (archivo *.crt)
 * 4) Se selecciona imporlo.

En este link hay mas detalles visuales del proceso de importación.

Importar Certificado (crt) a Java
Para importar el certificado en java, se debe ejecutar. Asumiendo que se tiene configurada la variabla de entorno JAVA_HOME, apuntando al JDK de tu equipo. El default password del keystore por lo general es changeit sudo keytool -import -trustcacerts -alias mi_host_custom -file ssl_mi_host_custom.joko.github.io.crt -keystore "$JAVA_HOME/jre/lib/security/cacerts" Observación: esta serie de comandos también funcionan en Mac OS X.

Listar Certificados importados en Java
Esta lista será bastante extensa, por lo que recomendamos se lleve el output a un archivo.

keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts -v > certificados.txt

Borrar Certificado importado a Java
Para borrar un certificado que se importó a Java, se debe conocer el alias bajo el cual fue guardado. Una vez se sabe esto, se debe correr el siguiente comando: keytool -delete -alias mi_host_custom -keystore "$JAVA_HOME/jre/lib/security/cacerts"