HTTPS con un Certificado Autofirmado en Nginx en Linux

CompTIABeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá a asegurar un servidor web Nginx en Linux implementando HTTPS con un certificado autofirmado. Comenzará instalando el servidor web Nginx y asegurándose de que esté funcionando correctamente, estableciendo la base para la configuración segura. Después de la configuración inicial, utilizará el kit de herramientas OpenSSL para generar un certificado SSL autofirmado, un componente crítico para habilitar las comunicaciones cifradas.

Una vez creado el certificado, procederá a modificar la configuración de Nginx para servir contenido web a través del protocolo seguro HTTPS. Los pasos finales del laboratorio se centran en la verificación y las pruebas. Activará la nueva configuración y utilizará herramientas de línea de comandos como curl y openssl para probar la conexión HTTPS e inspeccionar los detalles de su certificado autofirmado recién creado, confirmando que su servidor está debidamente asegurado.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 92%. Ha recibido una tasa de reseñas positivas del 100% por parte de los estudiantes.

Instalar y Iniciar el Servidor Web Nginx

En este paso, instalará el servidor web Nginx. Nginx es un servidor web de alto rendimiento que se utiliza ampliamente para servir contenido web. Primero lo instalaremos y luego verificaremos que se está ejecutando correctamente. Esta instancia de Nginx en ejecución servirá como base para nuestra posterior configuración de HTTPS.

Primero, es una buena práctica actualizar la lista de paquetes de su sistema para asegurarse de que está obteniendo las últimas versiones de software.

Ejecute el siguiente comando en su terminal:

sudo apt update

Verá cómo el sistema obtiene información de paquetes de sus fuentes configuradas. La salida será similar a esta:

Hit:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Get:2 http://archive.ubuntu.com/ubuntu jammy-updates InRelease [119 kB]
...
Fetched 1,585 kB in 2s (924 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

Ahora, puede proceder a instalar Nginx. Utilizaremos el comando apt install. Se agrega la bandera -y para confirmar automáticamente la instalación, evitando cualquier solicitud interactiva.

sudo apt install nginx -y

El proceso de instalación descargará y configurará Nginx y sus dependencias. Al finalizar, debería ver una salida que indique que el paquete nginx ha sido configurado.

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  nginx-common nginx-core
...
Setting up nginx-common (1.18.0-6ubuntu14.4) ...
Setting up nginx-core (1.18.0-6ubuntu14.4) ...
Setting up nginx (1.18.0-6ubuntu14.4) ...
Processing triggers for ufw (0.36.1-4ubuntu0.1) ...
Processing triggers for man-db (2.10.2-1) ...

Aunque el proceso de instalación a menudo inicia el servicio, es una buena práctica gestionarlo explícitamente. Utilizaremos systemctl, la utilidad estándar para controlar servicios en sistemas Linux modernos.

Inicie el servicio Nginx con este comando:

sudo systemctl start nginx

Este comando no producirá ninguna salida si se ejecuta correctamente. Para confirmar que el servicio se está ejecutando, verifique su estado.

sudo systemctl status nginx

La salida proporcionará información detallada sobre el servicio. Busque la línea Active: active (running), que confirma que Nginx está activo y funcionando.

● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2023-10-30 08:30:00 UTC; 5s ago
       Docs: man:nginx(8)
   Main PID: 1234 (nginx)
      Tasks: 2 (limit: 4617)
     Memory: 4.8M
        CPU: 43ms
     CGroup: /system.slice/nginx.service
             ├─1234 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             └─1235 "nginx: worker process"

Ahora ha instalado e iniciado correctamente el servidor web Nginx. En el siguiente paso, generará un certificado digital, que es un requisito previo para habilitar HTTPS.

Generar un Certificado SSL Autofirmado con OpenSSL

En este paso, creará un certificado digital autofirmado y su clave privada correspondiente. Para habilitar HTTPS, un servidor web necesita un certificado digital para probar su identidad a los clientes y una clave privada para establecer una conexión segura y cifrada. Utilizaremos la herramienta de línea de comandos openssl, una utilidad robusta para trabajar con SSL/TLS.

Un certificado digital vincula una clave pública a una identidad (como el nombre de dominio de un sitio web). Normalmente, los certificados son emitidos y firmados por una Autoridad de Certificación (CA) de confianza. Sin embargo, para fines de prueba y desarrollo, podemos crear un certificado autofirmado, que es firmado por su propio creador. Aunque los navegadores mostrarán una advertencia de seguridad para tales certificados, son perfectamente funcionales para un entorno de laboratorio como este.

Primero, creemos un directorio dedicado dentro de la carpeta de configuración de Nginx para almacenar nuestro certificado SSL y clave. Esto mantiene nuestros archivos organizados y seguros.

sudo mkdir -p /etc/nginx/ssl

Ahora, usaremos un único comando openssl para generar tanto la clave privada RSA de 2048 bits como el certificado autofirmado, válido por 365 días. Los colocaremos directamente en el directorio /etc/nginx/ssl/.

Aquí hay un desglose de las opciones del comando:

  • req -x509: Crea un certificado autofirmado.
  • -nodes: Evita que la clave privada se cifre con una frase de contraseña. Esto es importante para que Nginx pueda iniciarse sin intervención manual.
  • -days 365: Establece el período de validez del certificado en un año.
  • -newkey rsa:2048: Genera una nueva clave privada RSA de 2048 bits.
  • -keyout: Especifica el archivo de salida para la clave privada (/etc/nginx/ssl/nginx.key).
  • -out: Especifica el archivo de salida para el certificado (/etc/nginx/ssl/nginx.crt).
  • -subj: Proporciona la información del sujeto del certificado de forma no interactiva. CN=localhost es el Nombre Común (Common Name), que debe coincidir con la dirección que utiliza para acceder al sitio.

Ejecute el siguiente comando:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/nginx.key \
  -out /etc/nginx/ssl/nginx.crt \
  -subj "/C=US/ST=State/L=City/O=LabOrg/OU=IT/CN=localhost"

Después de ejecutar el comando, verá una salida que confirma la generación de la clave.

Generating a RSA private key
writing new private key to '/etc/nginx/ssl/nginx.key'
-----

La clave privada (/etc/nginx/ssl/nginx.key) es extremadamente sensible. Si se ve comprometida, un atacante podría suplantar su servidor. Por lo tanto, es fundamental restringir sus permisos de archivo para que solo el usuario root pueda leerla.

sudo chmod 600 /etc/nginx/ssl/nginx.key

Este comando establece los permisos de lectura y escritura solo para el propietario (root), y ningún permiso para nadie más. Esta es una medida de seguridad crucial.

¡Excelente! Ahora ha creado un certificado autofirmado (nginx.crt) y una clave privada segura (nginx.key). En el siguiente paso, configurará Nginx para usar estos dos archivos para habilitar HTTPS.

Configurar Nginx para Servir Contenido a través de HTTPS

En este paso, modificará la configuración de Nginx para habilitar HTTPS. Con el certificado y la clave privada listos del paso anterior, ahora necesita instruir a Nginx para que los utilice. Esto implica editar el archivo de configuración del sitio de Nginx para que escuche en el puerto 443 (el puerto estándar para HTTPS) y especificar las rutas a sus archivos de certificado y clave.

Antes de editar cualquier archivo de configuración, es una práctica recomendable crear una copia de seguridad. Esto le permite revertir fácilmente al estado original si algo sale mal. Hagamos una copia de seguridad del archivo de configuración del sitio predeterminado de Nginx.

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

Ahora, editará el archivo de configuración principal utilizando el editor de texto nano. Este archivo contiene bloques de servidor que definen cómo Nginx maneja las solicitudes entrantes.

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

Dentro del editor nano, verá un bloque de servidor predeterminado configurado para HTTP en el puerto 80. Desplácese hacia abajo hasta encontrar la sección de configuración de SSL, que generalmente está comentada. Necesita descomentar esta sección y asegurarse de que coincida con la configuración a continuación. Este bloque le indica a Nginx que escuche conexiones seguras en el puerto 443 y especifica qué certificado y clave usar para el handshake TLS.

Elimine el bloque de servidor SSL comentado existente y reemplácelo con el siguiente contenido, o simplemente descoméntelo y edítelo para que coincida.

## --- CONTENT TO ADD/UNCOMMENT IN /etc/nginx/sites-available/default ---
server {
    listen 443 ssl;
    listen [::]:443 ssl;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name localhost;

    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;

    location / {
        try_files $uri $uri/ =404;
    }
}
## --- END CONTENT ---

Aquí se explica qué significan estas directivas:

  • listen 443 ssl: Indica a Nginx que escuche las conexiones entrantes en el puerto 443 y que las maneje utilizando el protocolo SSL/TLS.
  • server_name localhost: Define qué bloque de servidor usar para las solicitudes a localhost.
  • ssl_certificate: Especifica la ruta a su archivo de certificado público (nginx.crt).
  • ssl_certificate_key: Especifica la ruta a su archivo de clave privada (nginx.key).

Después de agregar el contenido, guarde el archivo y salga de nano presionando Ctrl+X, seguido de Y, y luego Enter.

Antes de aplicar los cambios, es crucial probar la configuración de Nginx para detectar cualquier error de sintaxis. Esto evita que una configuración rota desactive su servidor web.

sudo nginx -t

Si la configuración es correcta, verá un mensaje de éxito.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Si ve algún error, vuelva a abrir el archivo de configuración y revise cuidadosamente si hay errores tipográficos o puntos y comas faltantes.

Ahora ha configurado correctamente Nginx para servir contenido a través de HTTPS. El siguiente paso es aplicar estos cambios reiniciando el servicio y probando la conexión.

Activar y Probar la Configuración HTTPS con curl

En este paso, aplicará la nueva configuración de Nginx y confirmará que su servidor web está sirviendo contenido correctamente a través de HTTPS. Aunque ha modificado el archivo de configuración en disco, el proceso de Nginx en ejecución todavía está utilizando la configuración antigua. Debe reiniciar el servicio para que los cambios surtan efecto.

Para aplicar la nueva configuración, reinicie el servicio Nginx usando systemctl.

sudo systemctl restart nginx

Este comando no produce ninguna salida si tiene éxito. Nginx ahora estará escuchando en el puerto 443 y estará listo para manejar solicitudes HTTPS utilizando el certificado y la clave que proporcionó.

Ahora, probemos el endpoint HTTPS. Utilizaremos curl, una herramienta de línea de comandos para transferir datos con URLs. Intentaremos obtener la página principal de nuestro servidor utilizando el protocolo https://.

Cuando se conecta a un servidor usando HTTPS, su cliente (en este caso, curl) verifica si el certificado del servidor está firmado por una Autoridad de Certificación (CA) de confianza. Dado que creamos un certificado autofirmado, no es de confianza por defecto, y curl se negará a conectarse, mostrando un error de validación del certificado.

Para solucionar esto en nuestra prueba, usamos la bandera -k o --insecure. Esta bandera le dice a curl que omita la validación del certificado. Esto no es seguro y no debe usarse en producción, pero es necesario para probar un certificado autofirmado en un entorno de laboratorio.

Ejecute el siguiente comando para probar su servidor HTTPS:

curl -k https://localhost

Si su configuración es correcta, curl se conectará exitosamente al servidor e imprimirá el contenido HTML de la página de bienvenida predeterminada de Nginx.

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Recibir esta salida HTML confirma que su servidor Nginx está configurado correctamente y sirviendo contenido a través de una conexión HTTPS cifrada. En el paso final, aprenderá cómo inspeccionar el certificado que el servidor está presentando.

Inspeccionar el Certificado SSL del Servidor con OpenSSL

En este paso final, examinará los detalles del certificado digital que su servidor Nginx está presentando a los clientes. Esta es una habilidad crucial para solucionar problemas de TLS/HTTPS y verificar la identidad de un servidor. Utilizará la herramienta openssl nuevamente, pero esta vez como un cliente para conectarse a su propio servidor e inspeccionar el certificado que proporciona.

Utilizaremos una combinación de dos comandos openssl conectados por una tubería (|).

  • openssl s_client -connect localhost:443: Este comando actúa como un cliente SSL/TLS genérico y se conecta al servidor y puerto especificados. Mostrará el certificado del servidor junto con los detalles de la sesión.
  • openssl x509 -text -noout: Este comando se utiliza para analizar y mostrar el contenido de un certificado X.509 en un formato legible por humanos.

Enviaremos la salida de s_client directamente a x509 para analizar el certificado sobre la marcha. El echo | al principio evita que s_client espere la entrada del usuario, y 2>/dev/null oculta los mensajes de estado de la conexión. Guardaremos la salida en un archivo para mayor claridad.

Ejecute el siguiente comando para conectarse a su servidor, extraer el certificado, analizarlo y guardar los detalles en un archivo llamado /tmp/server_certificate_details.txt.

echo | openssl s_client -connect localhost:443 2> /dev/null | openssl x509 -text -noout > /tmp/server_certificate_details.txt

Ahora, muestre el contenido del archivo que acaba de crear para ver los detalles del certificado.

cat /tmp/server_certificate_details.txt

Verá un desglose detallado de las propiedades del certificado.

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = State, L = City, O = LabOrg, OU = IT, CN = localhost
        Validity
            Not Before: Oct 30 09:00:00 2023 GMT
            Not After : Oct 29 09:00:00 2024 GMT
        Subject: C = US, ST = State, L = City, O = LabOrg, OU = IT, CN = localhost
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
                    ...
                Exponent: 65537 (0x10001)
...

Tómese un momento para examinar la salida. Observe estos campos clave:

  • Issuer: La entidad que firmó el certificado.
  • Subject: La entidad a la que se emitió el certificado.
  • CN (Common Name): El dominio específico para el que es el certificado (localhost).

Dado que este es un certificado autofirmado, los campos Issuer y Subject son idénticos. Esta es la característica definitoria de un certificado autofirmado. También puede ver el período de validez y los detalles de la clave pública.

¡Felicitaciones! Ha configurado exitosamente un servidor web Nginx con un certificado SSL autofirmado, lo ha configurado para HTTPS, ha probado la conexión y ha inspeccionado los detalles del certificado. Ahora tiene una comprensión fundamental de los componentes involucrados en la seguridad del tráfico web con TLS/HTTPS.

Resumen

En este laboratorio, aprendió el proceso completo de implementación de HTTPS en un servidor web Nginx en un entorno Linux utilizando un certificado autofirmado. Comenzó configurando la base, que implicó actualizar la lista de paquetes del sistema e instalar el servidor web Nginx utilizando el gestor de paquetes apt. El núcleo del laboratorio se centró en la seguridad, donde utilizó el kit de herramientas OpenSSL para generar una clave privada y un certificado SSL autofirmado correspondiente, que son los componentes esenciales para habilitar conexiones cifradas.

Con el certificado creado, procedió a configurar el servidor Nginx. Esto implicó modificar sus archivos de configuración para crear un bloque de servidor que escuche en el puerto 443 para el tráfico HTTPS y apuntarlo a las rutas de su nuevo certificado y clave privada. Para finalizar el proceso, activó la nueva configuración y realizó pasos de verificación cruciales. Utilizó el comando curl para probar la conexión HTTPS desde la línea de comandos y confirmó que el servidor respondía de forma segura. Finalmente, utilizó OpenSSL como herramienta cliente para inspeccionar el certificado del servidor, validando que se estaba sirviendo el certificado correcto.