Soapui mocks sobre https con apache y centOS 7 desde cero

Soapui mocks sobre https con apache y centOS 7 desde cero

[:es]Continuando con la serie de servicios mocks con soap-ui, nuestro próximo paso es agregar conexiones seguras https con un certificado gratis emitido por letsencrypt.

Partimos nuestro procedimiento desde un CentOS 6.8, pero a pesar que seguimos un procedimiento similar al que se va a describir, el certificado siempre quedaba inválido, indicando que “Common name” no correspondía al nombre del host (Lo cual era cierto, hablando del archivo /etc/hosts, pero finalmente el certificado que se deseaba emitir correspondía a un subdominio con un registro DNS tipo A, apuntando a la IP de la máquina), considerando ésto, y sumado a las vulnerabildiades con esa distribución al POODLE attack, migramos a CentOS 7.1.1503 (Core).

Bueno, manos a la obra. Como lo indica el post, es desde cero, así que vamos a suponer que tenemos nuestro SO recién instalado con cuenta root. Lo primero será entonces crear una cuenta de usuario con permisos de sudo.

Sistema Operativo

# Instalar sudo para agregar el usuario a los sudoers de la máquina
$ yum install sudo
# Crear el usuario y asignarle un password, así mismo, agregarlo al grupo wheel, 
# que en CentOS por defecto tiene privilegios de sudo
$ adduser username
$ passwd username
$ usermod -aG wheel username
# Instalar crontab para ejecutar la renovación programada del certificado
$sudo yum -y install cronie
# Subir el demonio de crontab:
$ sudo service crond start

De ahora en adelante, conectarse (ssh) con ese usuario, y ejecutar los comandos que requieren privilegios con sudo

Apache

Para la instalación y configuración de apache, se siguió el siguiente procedimiento:

# Instalación de apache
$ sudo yum install httpd
# Instalación de mod_proxy_html para el proxy reverso que va a ir desde apache a soapui
$ sudo yum install mod_proxy_html
# Instalación de mod_ssl que servirá para levantar apache en modo seguro (puerto 443)
$ sudo yum -y install mod_ssl
# Habilitar apache como servicio cada vez que suba
$ sudo systemctl enable httpd.service

Es importante activar mod_ssl, en caso contrario, un error común obtenido con el certbot de letsencrypt será:

Failed authorization procedure. subdomain.domain (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to XXX.YYY.ZZZ.OOO:443 for TLS-SNI-01 challenge

Activar el módulo proxy

# Hacer una copia de la configuración por defecto
$ cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.bk
$ sudo vi /etc/httpd/conf/httpd.conf

Buscar por la posición adecuada para agregar las directivas LoadModule y adicionar:

LoadModule proxy_html_module modules/mod_proxy_html.so

Agregar un nuevo archivo de virtual host

$ vi /etc/httpd/conf.d/vhost.conf 

Si hay un firewall activo, permitir el tráfico a apache por el 443 así:

firewall-cmd --add-service=https --permanent
firewall-cmd --reload

En este punto, se asume que la instalación de soap-ui está completa y se ha logrado subir el mockservicerunner de manera exitosa, como recomendación repasar este post y dependiendo en que puerto y contexto esté corriendo la instancia de soapui, agregar:

<VirtualHost *:80>
     ServerName subdomain.domain.com
     ProxyPass /context-path http://0.0.0.0:9090/context-path
     ProxyPassReverse /context-path http://0.0.0.0:9090/context-path
     ErrorLog /var/www/html/my-folder/logs/error.log
     CustomLog /var/www/html/my-folder/logs/access.log combined
</VirtualHost>
# Crear la carpeta de logs referida anteriormente
$ sudo mkdir -p /var/www/html/my-folder/logs    
# Reiniciar apache
$ sudo service httpd restart
# O también, así:
$ sudo systemctl restart httpd.service

Probar que la configuración tenga efecto, para ello se recomienda hacer un llamado a uno de los servicios que se tenga en los mock services, ya no usando el puerto del mock, sino el 80, donde apache haría la magia del proxy reverso enviando la petición. Un ejemplo de llamada exitosa con postman sería:

Certificado

Nuestro último paso es la instalación del certificado usando el servicio gratis de letsencrypt (Usando la configuración Apache + CentOS 7). Recordar que la emisión de este tipo de certificados se hace hasta por 3 meses y luego expirará, por lo que es necesario ir renovándolo.

Lo primero es habilitar el repositorio EPEL (Extra Packages for Enterprise Linux) que para usuarios de centOS se hace con:

$ sudo yum install epel-release

Luego instalar el Certbot de apache de letsencrypt

$ sudo yum install python-certbot-apache

Ahora, permitiendo que bot haga los cambios de forma autónoma (el otro modo es usando el modificador certonly)

$ certbot --apache

Se ejecutará un asistente que guía el proceso de creación:

  1. Los logs serán almacenados en una ruta como /var/log/letsencrypt/letsencrypt.log,
  2. Se confirma los nombres para emitir el certificado (datos extraídos de vhost.conf)
  3. Se obtiene el certificado y se hace la validación del mismo (tls-sni-01).
  4. Se genera la clave de tamaño 2048 bits, y se almacena en una ruta similar a /etc/letsencrypt/keys/0000_key-certbot.pem
  5. Se genera el CSR (Certificate Signing request) y se almacena en /etc/letsencrypt/csr/0000_csr-certbot.pem
  6. Se habilita apache para operar en el puerto 443 agregando un nuevo virtual host SSL en la carpeta
    /etc/httpd/conf.d/vhost-ssl.conf (Se agrega el sufijo -ssl al archivo original)
  7. Se consulta si HTTPS será opcional, Easy permitirá accesso HTTP como HTTPS, mientras que Secure no permitirá HTTP
  8. Felicidades! El certificado fue almacenado en /etc/letsencrypt/live/subdomain.domain.com/fullchain.pem

Revisemos el archivo generado en la configuración de apache, donde se puede validar en donde quedan finalmente los certificados, la cadena y la llave privada.

<IfModule mod_ssl.c>
<VirtualHost *:443>
     ServerName subdomain.domain.com
     ProxyPass /context-path http://0.0.0.0:9090/context-path
     ProxyPassReverse /context-path http://0.0.0.0:9090/context-path
     ErrorLog /var/www/html/sodexo/logs/error.log
     CustomLog /var/www/html/my-folder/logs/access.log combined
SSLCertificateFile /etc/letsencrypt/live/subdomain.domain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/subdomain.domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateChainFile /etc/letsencrypt/live/subdomain.domain.com/chain.pem
</VirtualHost>
</IfModule>

Siempre se recomienda validar la validez del certificado usando un servicio que provee Qualys SSL Labs, usando la siguiente URL. Si todo está ok, y el rating del certificado es trusted, y ojalá con rating A, estamos listos para que el certificado sea aceptado por browsers y otros clientes.

Reiniciar apache de nuevo y validar que los servicios respondan ahora correctamente (con postman):

$ sudo service httpd restart


Respuesta esperada: 200 OK

Por último, programar la entrada de renovación del certificado para evitar que se invalide luego de los 3 meses, para ello:

# Validar que el demonio este arriba 
$ pgrep cron 
# La salida anterior no debería ser blanca, sino el PID del demonio cron<<</span
$ sudo crontab -e

Agregar la siguiente línea, que se ejecutará todos los lunes a las 2:30 am y si el certificado está por expirar, lo renovará automáticamente.

30 2 * * 1 certbot renew >> /var/log/le-renew.log

Cuando el certificado aún tiene la suficiente vigencia, en el log sale algo como:

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/vhost.conf
-------------------------------------------------------------------------------
The following certs are not due for renewal yet:
  /etc/letsencrypt/live/subdomain.domain.com/fullchain.pem (skipped)
No renewals were attempted.

Referencias

twitterFacebooklinkedin[:]