Restaurar el acceso verificado al sitio de ayuda

CiberseguridadBeginner
Practicar Ahora

Introducción

Un equipo de soporte acaba de desplegar un sitio de ayuda, pero los clientes rechazan la conexión HTTPS. HTTPS usa TLS para cifrar el tráfico y demostrar qué servidor responde. El cifrado por sí solo no demuestra identidad: el cliente también debe reconocer el nombre solicitado y confiar en el emisor del certificado.

Repararás certificados sintéticos de formación en un servidor Nginx real. Basta con conocer el uso básico del terminal; aquí se presentan la inspección de certificados y la configuración del servicio. Client y Server son sesiones y directorios distintos de una misma VM, no equipos separados. Nginx se ejecuta en un contenedor preparado. HTTPS Monitor, opcional, muestra sondeos TLS internos en tiempo real; el candado del navegador corresponde a otra conexión externa.

Obtener una referencia de confianza

En este paso, descargarás un documento de un servicio funcional antes de compararlo con el sitio de ayuda averiado. Un nombre de host identifica el servicio solicitado. Todos los nombres de formación terminan en .lab.test y son locales a este ejercicio.

Usa la pestaña Client. curl obtiene una URL. --cacert root.crt confía en la autoridad de certificación (CA) suministrada, que firma certificados. Esta CA es un ancla de confianza de formación, no una autoridad pública. --resolve asocia un nombre y puerto con una dirección IP, conservando el nombre para TLS y HTTP. 127.0.0.1 representa esta VM; el puerto 8443 llega al servicio Nginx preparado. --noproxy '*' envía la solicitud directamente; las comillas impiden que el shell expanda *. --fail rechaza errores HTTP y --output guarda el documento real del servicio para usarlo después.

curl --noproxy '*' --fail --cacert root.crt --resolve status.lab.test:8443:127.0.0.1 --output reference.txt https://status.lab.test:8443/

cat muestra el contenido de un archivo:

cat reference.txt
status service: training content available

La descarga es un documento de referencia real, no un informe. Solicita ahora el nombre previsto del sitio de ayuda. Se espera que el comando falle y vuelva al indicador; continúa después.

curl --noproxy '*' --cacert root.crt --resolve help.lab.test:8443:127.0.0.1 https://help.lab.test:8443/
curl: (60) SSL: no alternative certificate subject name matches target host name 'help.lab.test'
...

La referencia funcionó con la misma CA y dirección. Este error señala un nombre incorrecto, no un servidor detenido. Conserva el nombre previsto: cambiar la URL probaría otra identidad.

Inspeccionar y montar la cadena de certificados

En este paso, compararás la identidad servida con un certificado preparado y construirás un paquete utilizable. Un certificado contiene una clave pública e información de identidad. Su clave privada correspondiente permanece en el servidor. Nunca pegues una clave privada en un informe ni la envíes a clientes.

En Client, inspecciona el certificado realmente servido. openssl s_client abre una conexión TLS; -connect indica la dirección y -servername envía el nombre solicitado mediante Server Name Indication (SNI), permitiendo alojar varios sitios en un único listener de Nginx. < /dev/null finaliza la entrada interactiva. 2>/dev/null oculta los diagnósticos solo para esta inspección. La tubería | pasa el certificado a openssl x509; -noout oculta el certificado codificado y las demás opciones muestran campos concretos. Esta inspección no demuestra por sí misma la confianza.

openssl s_client -connect 127.0.0.1:8443 -servername help.lab.test </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
subject=CN = legacy.lab.test
issuer=CN = LabEx Training Issuing CA
notBefore=...
notAfter=...
X509v3 Subject Alternative Name:
    DNS:legacy.lab.test

El nombre alternativo del sujeto (SAN) enumera los nombres aceptados. issuer identifica al firmante; las fechas delimitan la validez. La preparación genera certificados nuevos para esta VM: los certificados finales duran 365 días. Una fecha válida no compensa un nombre incorrecto.

Cambia a Server. openssl x509 -in lee un certificado local en lugar de una respuesta de red:

openssl x509 -in certs/help.crt -noout -subject -issuer -dates -ext subjectAltName

Su SAN es DNS:help.lab.test, coincidente con la solicitud. Esta es la relación prevista:

Elemento Función
help.crt y help.key Certificado y clave privada del sitio de ayuda
docs.crt y docs.key Certificado y clave privada del sitio de documentación
issuing.crt CA intermedia que firmó ambos sitios
../client/root.crt CA raíz de confianza del cliente

La cadena es certificado del sitio → CA intermedia → CA raíz de confianza. Nginx debe enviar primero el certificado final y después el intermedio. El cliente ya confía en la raíz y no es necesario enviarla. Construye ese paquete público con cat; > escribe la salida en un archivo y sustituye su contenido anterior. La clave privada no forma parte del paquete.

cat certs/help.crt certs/issuing.crt > certs/help-fullchain.pem

openssl verify comprueba el paquete con la raíz de confianza indicada. -untrusted aporta intermediarios como posibles enlaces, no como raíces adicionales de confianza; -verify_hostname comprueba el nombre previsto.

openssl verify -CAfile ../client/root.crt -untrusted certs/help-fullchain.pem -verify_hostname help.lab.test certs/help-fullchain.pem
certs/help-fullchain.pem: OK

Si falla, revisa el orden y la escritura de los archivos y repite cat. Esto valida el paquete preparado; falta que el servidor activo lo utilice.

Aplicar la identidad del sitio de ayuda

En este paso, harás que Nginx sirva la identidad correcta sin interrumpir el sitio de estado. En Server, muestra la configuración con cat:

cat conf/help.conf

server_name selecciona el sitio. ssl_certificate indica la cadena pública; ssl_certificate_key, su clave privada. Las rutas que comienzan por /tls/ están dentro del contenedor Nginx preparado y corresponden a certs/ en este directorio. La línea return 200 proporciona el contenido real de formación. Conserva el listener, el nombre y la respuesta.

Abre el archivo con el editor de texto nano:

nano conf/help.conf

Usa las flechas para localizar las dos directivas TLS. Sustituye solo esas dos líneas por:

    ssl_certificate /tls/help-fullchain.pem;
    ssl_certificate_key /tls/help.key;

Los puntos y coma terminan las directivas Nginx. Guarda con Ctrl+O, pulsa Enter y sal con Ctrl+X. Si escribes mal una ruta, vuelve a abrir el mismo archivo y corrígela.

sudo ejecuta un comando con privilegios administrativos. docker exec https-edge ejecuta el comando siguiente en el contenedor preparado. nginx -t prueba la configuración sin aplicarla:

sudo docker exec https-edge nginx -t

Busca syntax is ok y test is successful. Si falla, corrige el archivo y la línea indicados antes de continuar. nginx -s reload solicita al servicio activo que cargue la configuración probada:

sudo docker exec https-edge nginx -s reload

Cambia a Client y repite la solicitud prevista. La recarga puede tardar un momento; repite la misma solicitud si todavía recibe el certificado anterior.

curl --noproxy '*' --fail --cacert root.crt --resolve help.lab.test:8443:127.0.0.1 https://help.lab.test:8443/
help service: training content available

Conserva también el funcionamiento normal del sitio de referencia:

curl --noproxy '*' --fail --cacert root.crt --resolve status.lab.test:8443:127.0.0.1 https://status.lab.test:8443/

El éxito comprueba el nombre, la cadena y las fechas reales antes de aceptar la respuesta. Editar únicamente un certificado no utilizado no produciría este resultado.

Reparar un intermediario ausente

En este paso, distinguirás una cadena incompleta del nombre incorrecto que ya reparaste. En Client, solicita el sitio de documentación preparado. Este fallo es intencional:

curl --noproxy '*' --cacert root.crt --resolve docs.lab.test:8443:127.0.0.1 https://docs.lab.test:8443/
curl: (60) SSL certificate problem: unable to get local issuer certificate
...

Ambos fallos usan el código de salida 60; lee la explicación. Inspecciona el certificado servido con la misma estructura de comando:

openssl s_client -connect 127.0.0.1:8443 -servername docs.lab.test </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName

Esta vez el SAN es DNS:docs.lab.test. El nombre es correcto, pero Nginx solo envía el certificado final y el cliente no puede vincular su emisor con la raíz.

Para una comparación controlada, -k omite la verificación. Demuestra que se puede obtener contenido aunque la confianza siga rota:

curl --noproxy '*' -k --resolve docs.lab.test:8443:127.0.0.1 https://docs.lab.test:8443/

Ver docs service: training content available aquí no es una reparación. Vuelve a Server, inspecciona el archivo activo y ábrelo:

cat conf/docs.conf
nano conf/docs.conf

El archivo preparado docs-fullchain.pem ya contiene el certificado final y el intermedio en orden. Sustituye únicamente la línea ssl_certificate:

    ssl_certificate /tls/docs-fullchain.pem;

Conserva /tls/docs.key como clave privada. Guarda y sal como antes; después prueba y recarga:

sudo docker exec https-edge nginx -t
sudo docker exec https-edge nginx -s reload

En Client, solicita los tres nombres previstos sin -k. El bucle asigna a host cada valor; $host inserta ese valor y las comillas dobles mantienen unido cada argumento resultante.

for host in help docs status; do
  curl --noproxy '*' --fail --cacert root.crt --resolve "$host.lab.test:8443:127.0.0.1" "https://$host.lab.test:8443/"
done

Espera las tres respuestas correspondientes. Puedes actualizar HTTPS Monitor para comparar sus sondeos independientes en tiempo real. Para corregir un error, vuelve a la configuración apropiada, prueba y recarga; no cambies la raíz de confianza ni los nombres previstos. En despliegues reales, obtén certificados aprobados mediante el proceso de emisión de tu organización; aquí se ofrecen candidatos sintéticos para centrarte en el diagnóstico.

Resumen

Descargaste una referencia de confianza, inspeccionaste nombres y emisores reales, montaste un paquete final/intermedio y lo aplicaste mediante una recarga probada de Nginx. Reparaste un nombre incorrecto y una cadena incompleta conservando el servicio normal. El siguiente desafío combina esas decisiones para otro portal.