Configuración de Nexus, Sonar y Jenkins tras un Apache

0
11318

A la hora de montar un entorno de integración continua una opción habitual es querer tener las herramientas tras un Apache en vez de exponer los distintos puertos directamente. Sin embargo, dependiendo de las herramientas a montar su configuración no es del todo evidente. En este tutorial veremos cómo tener Jenkins, Nexus y Sonar en un servidor remoto por HTTPS con Apache.

0. Índice de contenidos

1. Introducción

A la hora de montar un entorno de integración continua una opción habitual es querer tener las herramientas tras un Apache en vez de exponer los distintos puertos directamente. Sin embargo, dependiendo de las herramientas a montar su configuración no es del todo evidente. En este tutorial veremos cómo tener Jenkins, Nexus y Sonar en un servidor remoto por HTTPS con Apache.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro Retina (2.93 Ghz Intel Core 2 Duo, 8GB DDR3).
  • Sistema Operativo: Mac OS Yosemite 10.10
  • Apache 2
  • Nexus-2.11.3-01-bundle
  • Jenkins 1.621
  • Sonar-5.1.1

3. Punto de partida

Partimos de un entorno de integración continua compuesto por las aplicaciones de Jenkins, Nexus y Sonar ya instaladas con las siguientes características:

  • Jenkins está corriendo bajo el dominio example.com:8080.
  • Nexus está corriendo bajo el dominio example.com:8081.
  • Sonar está corriendo bajo el dominio example.com:9000.
  • Apache2 está instalado y tenemos creados los certificados ssl. (En este tutorial se muestra como crear certificados)
  • Las tres aplicaciones están ejecutándose en la misma máquina.

Dada esta configuración, queremos instalar un Apache que actúe de reverse proxy de forma que yo pueda redirigir las peticiones de mi entorno de integración de forma segura y sin exponer los puertos de actuación.

Nuestro Apache tiene que:

  • Redirigir las peticiones de http://example.com/sonar a localhost:9000 pasando por https si la petición no es segura.
  • Redirigir las peticiones de http://example.com/nexus a localhost:8081 pasando por https si la petición no es segura.
  • Redirigir las peticiones de http://example.com/jenkins a localhost:8080 pasando por https si la petición no es segura.
  • Securizar el acceso de proxy por autenticación de apache, para restringir el acceso.

Para lograr esto, primero cambiaremos el context path de las aplicaciones de Sonar, Jenkins y Nexus, y después configuraremos apache para que actúe como proxy.

Una vez comprobado qué tenemos y qué queremos, ¡vamos al lio! 😉

4. Configuración de sonar

Según el punto de partida establecido, ejecutamos sonar a partir de http://example.com:9000.
Para configurar sonar detrás de Apache, necesitamos que la URL de ejecución de sonar sea como: http://example.com:9000/sonar.

Para cambiar el context path de Sonar, nos vamos a su sonar.properties, que en mi caso está en la carpeta conf dentro de la carpeta de instalación de sonar.

En el fichero sonar.properties es dónde cambiamos la propiedad sonar.web.context.

Reiniciamos el servicio de Sonar, y comprobamos la navegación en la ruta:

http://example.com:9000/sonar

Esta es toda la configuración que necesitamos tocar por la parte de Sonar 😀

5. Configuración de nexus

Nexus utiliza el context path de /nexus por defecto. Si no has alterado este parámetro, pasa directamente al punto 5.2.

5.1 Cambio del context path

De forma muy similar a Sonar:

  • Vamos a $NEXUS_HOME/conf/nexus.properties.
  • Cambiamos la propiedad nexus-webapp-context-path para que se corresponda con nexus-webapp-context-path=/nexus.

5.2 Forzar la URL base

Nexus posee una propiedad que fuerza la URL base de forma que cuando se realiza una petición actúa como si estuviera siendo llamado desde la URL base que nosotros le digamos.

Esto es justo lo que queremos, ya que será apache quien se encarge de redirigir esa petición a Nexus.

Para forzar la URL en Nexus, tenemos que ir a Administracion –> server –> Application Server Settings donde encontraremos la opción Force Base URL.

Nuestra configuración quedaría de la siguiente manera:

Que no se nos olvide reiniciar el servicio! 😀

6. Configuración de jenkins

Lo primero, igual que en el resto de aplicaciones, es hacer que el context path sea el mismo entre Apache y Jenkins. Para configurar el context path debes modificar el fichero de configuración de Jenkins, localizado en el directorio /etc/default/jenkins.

Para ello, en primer lugar declaramos la variable NAME al principio del documento, y que va a ser utilizada como $NAME.

Por último añadimos esta variable a la propiedad PREFIX, y añadimos el prefijo como parámetro en la variable JENKINS_ARGS como se ve en la siguiente imagen.

Una vez configurado, reiniciamos el servicio.

7. Configuración de apache

Ahora mismo tenemos las aplicaciones corriendo bajo las siguientes URLs:

  • Sonar: example.com/sonar
  • Nexus: example.com/nexus
  • Jenkins: example.com/jenkins

Ahora vamos a configurar nuestro Apache para reciba y maneje estas peticiones, redireccionando del puerto 80 al puerto 443 las peticiones que comiencen con el context path de /sonar, /nexus y /jenkins, de forma que el que hace la petición no sepa donde están los servicios que realiza por debajo.

7.1. Habilitar módulos proxy

Para ello necesitamos habilitar los siguientes módulos de apache:

  • mod_proxy: Este módulo permite que Apache actúe como proxy.
  • mod_proxy_http: Requiere el módulo anterior para funcionar, y nos permite hacer actuar como proxy para peticiones HTTP y HTTPS.
  • mod_rewrite: Nos da una serie de reglas basadas un motor de expresiones regulares para mapear URLs.
  • mod_ssl: Nos da soporte para SSL para Apache.
  • mod_headers: Nos permite modificar, reemplazar o eliminar cabeceras de las peticiones y respuestas HTTP.

Para habilitar los módulos de apache utilizamos los siguientes comandos:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers

NOTA: Reiniciamos el servicio para que se activen los nuevos módulos

7.2. Creación del Site

Ahora crearemos el site donde se harán las redirecciones del puerto 80 al puerto 443, y las redirecciones de apache para los servicios que tenemos preparados.

Para ello creamos el fichero example.conf dentro de la carpeta /etc/apache2/sites-available.

example.conf
<VirtualHost *:80>
    ServerName example.com

    #Redirect all http traffic to https if it is pointed at /jenkins /nexus /sonar
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} ^/(jenkins|nexus|sonar)/?.*$
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

    CustomLog /var/log/apache2/example.log combined
    ErrorLog /var/log/apache2/example-error.log
</VirtualHost>

<VirtualHost *:443>
	SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/example.crt
    SSLCertificateKeyFile /etc/apache2/ssl/example.key

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyRequests Off
    
    ProxyPass /sonar http://localhost:9000/sonar
    ProxyPassReverse /sonar http://localhost:9000/sonar

    ProxyPass /nexus http://localhost:8081/nexus
    ProxyPassReverse /nexus http://localhost:8081/nexus

    ProxyPass /jenkins http://localhost:8080/jenkins nocanon
    ProxyPassReverse /jenkins http://localhost:8080/jenkins
    AllowEncodedSlashes NoDecode

    CustomLog /var/log/apache2/example-https.log combined
    ErrorLog /var/log/apache2/example-https-error.log
</VirtualHost>

Vamos a analizar que hace este fichero:

  • Creamos dos host virtuales de Apache, en los cuales uno escucha por el puerto 80 (estandar de HTTP) y otro por el puerto 443 (estandar de HTTPS). El «*» significa que cualquiera puede acceder a esta ip.
  • Dentro de la configuración del puerto, vemos que al principio le indicamos el nombre del servidor, con el dominio que hayamos elegido, en este caso example.com
  • Después habilitamos el motor de redirecciones, y establecemos dos condiciones, que son acumulativas y cada una es más restrictiva que la anterior:

    • La primera redirecciona todas las peticiones HTTP a HTTPS.
    • La segunda especifica que la URI debe tener en el primer fragmento del context path que hayamos elegido como /nexus, /sonar ó /jenkins de forma que solo estas URL serán redireccionadas al puerto 443.
  • Añadimos un par de logs, para tener registro de los accesos y los errores.
  • Declaramos el segundo virtual host, que recibirá las peticiones redireccionadas por el puerto 443.
  • Activamos la configuración de SSL, indicando el certificado y la clave que tenemos creados para el sitio y los colocamos en el directorio /etc/apache2/ssl
  • La etiqueta <Proxy> indica sirve para poder limitar el acceso. En nuestro caso, está habilitado para cualquiera que quiera acceder.
  • El parámetro ProxyRequests Off sirve para que Apache no actúe como un forward proxy, ya que nosotros solo queremos que este redireccione las peticiones que vengan de clientes externos.
  • El caso de Sonar y Nexus es muy parecido: la directiva ProxyPass mapea los servidores remotos en una URL local haciendo que la URL https://example.com/sonar/example se transforme en https://localhost:9000/sonar/example. La directiva ProxyPassReverse es esencial para que cuando te muevas dentro del mismo sitio, Apache redireccione las cabeceras de forma que no salgas pidiendo la URL interna.
  • En el caso de la redireccion de Jenkins, y tal como dice la documentación es necesario añadir las propiedades nocanon y AllowEncodedSlashed NoDecode ya que son requeridas para diversas características de Jenkins
  • NOTA: En este caso redirigimos a localhost debido a que las tres aplicaciones están instaladas en la misma máquina que apache. En caso de que estén en máquinas distintas simplemente hay que sustituir la url por el dominio donde se encuentren estas aplicaciones

Una vez creado el fichero, necesitamos decirle a Apache que utilice la configuración de este sitio, en lugar de la configuración por defecto. Para ello, ejecutamos los comandos:

a2ensite example
a2dissite 000-default

De esta manera habilitamos la configuración que acabamos de crear, y deshabilitamos la configuración por defecto de Apache.

¡¡Ya tenemos nuestro Apache actuando como proxy!! 😀

NOTA: Para que esta configuración funcione es necesario que tengas los certificados del sitio, o dará error al hacer la redirección. Si prefieres hacerlo todo por el puerto 80, entonces elimina las líneas de la redirección y copia las directivas del proxy en el virtual host del puerto 80. El documento quedaría de la siguiente forma:

example.conf
<VirtualHost *:80>
    ServerName example.com

	<Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyRequests Off
    
    ProxyPass /sonar http://localhost:9000/sonar
    ProxyPassReverse /sonar http://localhost:9000/sonar

    ProxyPass /nexus http://localhost:8081/nexus
    ProxyPassReverse /nexus http://localhost:8081/nexus

    ProxyPass /jenkins http://localhost:8080/jenkins nocanon
    ProxyPassReverse /jenkins http://localhost:8080/jenkins
    AllowEncodedSlashes NoDecode

    CustomLog /var/log/apache2/example.log combined
    ErrorLog /var/log/apache2/example-error.log
</VirtualHost>

8. Securización de las aplicaciones

Aunque ya tenemos nuestro proxy funcionando, nunca viene mal una capa de seguridad extra a la hora de proteger nuestros entornos de integración. Lo que vamos a hacer es añadir la seguridad que nos aporta apache.

Para ello, habilitamos el módulo auth_digest, que nos permite realizar una autenticación en la que se encriptan los datos antes de ser enviada.

También nos descargamos la herramienta htdigest, para lo que necesitamos instalar apache2-utils.

sudo a2enmod
apt-get install apache2-utils

Reiniciamos el servicio y creamos el archivo auth_digest dentro de la carpeta /etc/apache2/digest. Para ello ejecutamos el comando:

htdigest -c /etc/apache2/auth_digest restringido example 

Acto seguido nos pedirá una contraseña para el usuario «example». Vamos a analizar que hace cada parte del comando que acabamos de ejecutar:

  • La propiedad -c crea el archivo si no existe.
  • La ruta /etc/apache2/auth_digest indica donde se creará el archivo.
  • A continuación se selecciona el nombre del realm (restringido), que es el grupo al que pertenece al usuario y suele ser también el valor que se le da la propiedad AuthName en las directivas que usan digest.
  • Por último va el nombre del usuario, que en nuestro caos se llama example.

Una vez creado nuestro usuario, modificamos el site example.conf añadiendo la siguiente directiva dentro de las etiquetas <virtualhost *:443></virtualhost>.

#Digest auth for all requests
<Location "/*">
    AuthType Digest
    AuthName "restringido"
    AuthUserFile "/etc/apache2/auth_digest"
    Require valid-user
</Location>

Analizando el archivo vemos que:

  • La etiqueta <Location> indica restricciones a nivel de URL, de modo que aquí le decimos que sin importar la URL que sea, nos pida autenticación via digest.
  • El tipo de autenticación se indica con AuthType, en AuthName se indica generalmente el realm elegido.
  • Se indica donde se encuentra el fichero de autenticación con la propiedad AuthUserFile.
  • Por último, se dice que solo se permitan los usuarios que estén autenticados.

Nuestro fichero de configuración queda de la siguiente manera:

example.conf
<VirtualHost *:80>
    ServerName example.com

    #Redirect all http traffic to https if it is pointed at /jenkins /nexus /sonar
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{REQUEST_URI} ^/(jenkins|nexus|sonar)/?.*$
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

    CustomLog /var/log/apache2/example.log combined
    ErrorLog /var/log/apache2/example-error.log
</VirtualHost>

<VirtualHost *:443>
	SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/example.crt
    SSLCertificateKeyFile /etc/apache2/ssl/example.key

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyRequests Off
    
    ProxyPass /sonar http://localhost:9000/sonar
    ProxyPassReverse /sonar http://localhost:9000/sonar

    ProxyPass /nexus http://localhost:8081/nexus
    ProxyPassReverse /nexus http://localhost:8081/nexus

    ProxyPass /jenkins http://localhost:8080/jenkins nocanon
    ProxyPassReverse /jenkins http://localhost:8080/jenkins
    AllowEncodedSlashes NoDecode

    #Digest auth for all https requests
	<Location "/*">
	    AuthType Digest
	    AuthName "restringido"
	    AuthUserFile "/etc/apache2/auth_digest"
	    Require valid-user
	</Location>

    CustomLog /var/log/apache2/example-https.log combined
    ErrorLog /var/log/apache2/example-https-error.log
</VirtualHost>

Reiniciamos el servicio y comprobamos como al acceder a la URL http://example.com/sonar se realiza una redirección a https://example.com/sonar, pidiendo antes la autenticación de Apache.

9. Conclusiones

Poner las aplicaciones detrás de un reverse proxy, es habitual en los desarrollos debido a la capa de protección que ofrece frente ataques directos, así como ocultar los puertos en los que son ejecutados las aplicaciones.

10. Referencias

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad