Cómo configurar Nginx con SSL como proxy inverso para Jenkins

Introducción

Por defecto, Jenkins viene con su propio servidor web incorporado, que escucha en el puerto 8080. Esto es conveniente si ejecutas una instancia privada de Jenkins, o si solo necesitas poner algo en marcha rápidamente y no te importa la seguridad. Sin embargo, una vez que tengas datos de producción reales yendo a tu host, es una buena idea usar un servidor web más seguro como Nginx para manejar el tráfico.

Esta publicación detallará cómo envolver tu sitio con SSL utilizando el servidor web Nginx como un proxy inverso para tu instancia de Jenkins. Este tutorial asume cierta familiaridad con los comandos de Linux, una instalación de Jenkins funcional y una instalación de Ubuntu 20.04.

Puedes instalar Jenkins más adelante en este tutorial, si aún no lo tienes instalado.

Prerrequisitos

Esta guía asume que estás utilizando Ubuntu 20.04. Antes de comenzar, debes tener configurada una cuenta de usuario no root con privilegios de sudo en tu sistema. Puedes aprender cómo hacerlo siguiendo el tutorial de configuración inicial del servidor Ubuntu 20.04. También necesitarás tener instalado el servidor Nginx y alojar tu dominio en él. Puedes aprender cómo hacerlo con el tutorial de cómo instalar Nginx en Ubuntu 20.04.

Además, es muy importante asegurar tu instancia de Jenkins con SSL. Si es visible en internet, puedes asegurarlo con Let’s Encrypt. Puedes aprender cómo hacerlo con el tutorial de cómo asegurar Nginx con Let’s Encrypt en Ubuntu 22.04.
Como se mencionó anteriormente, este tutorial asume que Jenkins ya está instalado. Este tutorial te mostrará cómo instalar Jenkins si es necesario. Probablemente necesitarás cambiar al usuario root para ese artículo.

Paso 1 — Configurar Nginx

Nginx se ha convertido en un servidor web favorito debido a su velocidad y flexibilidad en los últimos años, lo que lo convierte en una elección ideal para nuestra aplicación.

Editar la configuración

A continuación, deberás editar el archivo de configuración predeterminado de Nginx. El siguiente ejemplo utiliza nano.

  1. sudo nano etc/nginx/sites-enabled/default

Así es como podría verse la configuración final; las secciones están desglosadas y brevemente explicadas a continuación. Puedes actualizar o reemplazar el archivo de configuración existente, aunque quizás quieras hacer primero una copia de seguridad.

server {23
    listen 80;
    return 301 https://$host$request_uri;
}

server {

    listen 443;
    server_name jenkins.domain.com;

    access_log            /var/log/nginx/jenkins.access.log;

    location / {

      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header        X-Forwarded-Proto $scheme;

      proxy_pass          http://localhost:8080;
      proxy_read_timeout  90;

      proxy_redirect      http://localhost:8080 https://jenkins.domain.com;
    }
    
    ...
}

Necesitarás actualizar las líneas de server_name y proxy_redirect con tu propio nombre de dominio. También hay algo de magia adicional de Nginx que indica que las solicitudes deben ser leídas por Nginx y reescritas en el lado de la respuesta para asegurar que el proxy inverso esté funcionando.

Guarda y cierra el archivo. Si usaste nano, puedes hacerlo presionando Ctrl + X, Y, y luego Enter.

La primera sección indica al servidor Nginx que escuche todas las solicitudes que lleguen en el puerto 80 (HTTP predeterminado) y las redirija a HTTPS.

...
server {
   listen 80;
   return 301 https://$host$request_uri;
}
...

Después de eso, ocurre el proxy. Básicamente toma cualquier solicitud entrante y la redirige a la instancia de Jenkins que está enlazada/escuchando en el puerto 8080 en la interfaz de red local.

...
location / {

    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;

    proxy_pass          http://localhost:8080;
    proxy_read_timeout  90;

    proxy_redirect      http://localhost:8080 https://jenkins.domain.com;
}
...

Nota: Si deseas obtener más información sobre el proxy en Nginx, este tutorial tiene buena información sobre la configuración de proxy de Nginx.

A few quick things to point out here. If you don’t have a domain name that resolves to your Jenkins server, then the proxy_redirect statement above won’t function correctly without modification, so keep that in mind. Also, if you misconfigure the proxy_pass (by adding a trailing slash for example), you will get something similar to the following in your Jenkins Configuration page.

Entonces, si ves este error, verifica dos veces tus configuraciones de proxy_pass y proxy_redirect en la configuración de Nginx!

Paso 2 — Configurar Jenkins

Para que Jenkins funcione con Nginx, necesitamos actualizar la configuración de Jenkins para que escuche solo en la dirección localhost en lugar de en todas (0.0.0.0), para asegurar que el tráfico se maneje correctamente. Este es un paso de seguridad importante porque si Jenkins todavía está escuchando en todas las direcciones, entonces seguirá siendo potencialmente accesible a través de su puerto original (8080). Modificaremos el archivo de configuración /etc/default/jenkins para hacer estos ajustes.

  1. sudo nano /etc/default/jenkins

Localiza la línea JENKINS\_ARGS y actualízala para que se vea así:

JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpListenAddress=127.0.0.1 --httpPort=$HTTP_PORT -ajp13Port=$AJP_PORT"

Nota que la configuración –httpListenAddress=127.0.0.1 debe ser agregada o modificada.

Luego reinicia Jenkins y Nginx.

  1. sudo service jenkins restart
  2. sudo service nginx restart

Ahora deberías poder visitar tu dominio usando HTTPS, y el sitio de Jenkins se servirá de manera segura.

Opcional — Actualizar URLs de OAuth

Si estás utilizando GitHub u otro plugin de OAuth para la autenticación, probablemente esté roto en este momento. Por ejemplo, al intentar visitar la URL, obtendrás un “Error al abrir la página” con una URL similar a http://jenkins.domain.com:8080/securityRealm/finishLogin?code=random-string.

Para solucionar esto, deberás actualizar algunas configuraciones dentro de Jenkins, incluidas las configuraciones de tu plugin OAuth. Primero, actualiza la URL de Jenkins en la interfaz gráfica de usuario de Jenkins; puedes encontrarla en el menú Jenkins -> Administrar Jenkins -> Configurar sistema -> Ubicación de Jenkins.

Actualiza la URL de Jenkins para que use HTTPS – https://jenkins.domain.com/

A continuación, actualiza tus configuraciones de OAuth con el proveedor externo. Este ejemplo es para GitHub. En GitHub, esto se puede encontrar en Configuración -> Aplicaciones -> Aplicaciones de desarrollador, en el sitio web de GitHub.

Debería haber una entrada para Jenkins. Actualiza la URL de la página principal y la URL de autorización de devolución de llamada para reflejar las configuraciones de HTTPS. Podría parecerse a lo siguiente:

Conclusión

Lo único que queda por hacer es verificar que todo funcionó correctamente. Como se mencionó anteriormente, ahora deberías poder navegar a tu URL recién configurada – jenkins.domain.com – tanto a través de HTTP como de HTTPS. Deberías ser redirigido al sitio seguro y deberías ver alguna información del sitio, incluidos tus nuevos ajustes de SSL. Como se mencionó anteriormente, si no estás utilizando nombres de host a través de DNS, es posible que la redirección no funcione como se desea. En ese caso, deberás modificar la sección proxy_pass en el archivo de configuración de Nginx.

Source:
https://www.digitalocean.com/community/tutorials/how-to-configure-nginx-with-ssl-as-a-reverse-proxy-for-jenkins