7.2.2.2.8. Conexión segura

El protocolo HTTP no es seguro para la transmisión de contraseñas y otros datos confidenciales, puesto que toda la información viaja en claro. La solución, como en el caso de otros protocolos no seguros, es encapsularlo dentro del protocolo criptográfico SSL/TLS[1], a fin de que el protocolo viaje cifrado. Al HTTP encapsulado dentro de TLS es a lo que se denomina HTTPs Por lo general, el puerto reservado para comunicación HTTPs es el 443/TCP.

Consecuentemente, hacer que un servidor ofrezca páginas seguras se limita a:

  • Obtener un certificado que permita el cifrado TLS.

  • Desarrollar la configuración que hace que el servidor escuche en el puerto 443 tal como se hace cuando sirve HTTP, pero indicando que en este caso debe usar el certificado anterior para cifrar.

Nota

Encapsular el tráfico HTTP dentro de TLS supone que todos los paquetes viajan cifrados y que, en consecuencia, todo el contenido HTTP, incluida la cabecera, está cifrado. Esto inutiliza cualquier cacheo de contenido o cualquier filtrado web que se base en la URL o el propio contenido.[2]

Nota

Estos certificados no son exclusivos para el servicio web. Son certificados que se usan con el protocolo TLS y, en consecuencia, sirven para cualquier protocolo que se cifre con él. Por ejemplo, también son válidos para usados con los protocolos SMTP o IMAP.

7.2.2.2.8.1. Certificados autofirmados

Advertencia

Jamás haga esto en un servidor real en producción: un certificado autofirmado no ofrece garantías al cliente sobre la identidad del servidor y, por ello, todos los navegadores alertan de la invalidez del certificado y sugieren al navegante que no accede a la página. En fase de pruebas, en cambio, sí nos puede ser muy útil utilizar certificados de estas características y por ello incluimos este epígrafe en la guía.

Crear un certificado autofirmado puede hacerse, simplemente, con openssle[3], pero es aún más sencillo usar make-ssl-cert:

# apt install ssl-cert

La postinstalación genera directamente la clave private en /etc/ssl/private/ssl-cert-snakeoil.key y la pública en /etc/ssl/certs/ssl-cert-snakeoil.pem y crea un certificado para el nombre completo de la máquina[4]. Si nuestra intención es que el certificado sirva para distintos nombres (por ejemplo, porque tenemos definidos varios dominios virtuales), entonces es necesario volver a generar los certificados:

# make-ssl-cert /usr/share/ssl-cert/ssleay.cnf keycert.pem

Así, mediante una interfaz amigable hecha en whiptail, podemos generar otro distinto. La manera más sencilla de obtener un certificado válido para cualquier nombre del domino es contestar a la primera pregunta con *.example.net. La segunda podemos dejarla en blanco. La orden genera un único fichero con las claves pública y privada. Para separarlas y dejarlas en su ubicación predeterminada:

# sed '1,/-END PRIVATE KEY-/d' keycert.pem > /etc/ssl/certs/ssl-cert-snakeoil.pem
# sed '/-END PRIVATE KEY-/q' keycert.pem > /etc/ssl/private/ssl-cert-snakeoil.key

Nota

Si no queremos usar software adicional, podemos crear un certificado autofirmado directamente con openssl con la siguiente orden:

$ openssl req -newkey rsa:2048 -nodes -x509 -days 365 -subj '/CN=info.iescastillodeluna.es' \
   -keyout /etc/ssl/private/ssl-cert-snakeoil.key \
   -out /etc/ssl/certs/ssl-cert-snakeoil.pem

Y ¡listo! Ya tenemos un certificado no fiable para crear conexiones SSL. Ahora resta configurar nginx para que lo use:

server {
   listen   443 ssl;

   server_name _;

   root /srv/www;
   try_files $uri $uri/ =404;

   include snippets/snakeoil.conf;
}

O sea, advertimos que la conexión por el puerto 443 es segura y referimos el archivo /etc/nginx/snippets/snakeoil.conf que a su vez, incluye las directivas de nginx necesarias para saber dónde se encuentran las claves. No hace falta escribir el archivo puesto que el paquete de Debian ya lo ha escrito por nosotros. Si le echamos un vistazo veremos que contiene dos directivas que refieren los archivos que generamos con make-ssl-cert:

ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;

Además, debemos incluir un archivo /etc/nginx/conf.d/ssl.conf[5] con algunas directivas relativas al cifrado cuyo contenido es éste.

La configuración del sitio es muy simple y crea un servidor que sólo responde a peticiones seguras. Esto no es lo más apropiado ya que probablemente algún cliente nos haga una petición no segura por el puerto 80 y se encuentre con que el servidor, aparentemente, no existe. Así, pues, cambiemos la configuración:

server {
   listen   80;
   listen   443 ssl;

   server_name _;

   root /srv/www;
   try_files $uri $uri/ =404;

   include snippets/snakeoil.conf;

   if ($https != "on") {
      return 301 https://$host$uri$is_args$args;
   }
}

Advertencia

El if provoca que, si el tráfico es no seguro, se repita la petición por el puerto seguro. Si queremos permitir ambos tráficos podemos eliminar este bloque.

7.2.2.2.8.2. Certificados acreditados

Ver también

Si quiere profundizar en los conceptos teóricos detrás de los certificados, échele un ojo a la explicación sobre certificados digitales.

Para que un certificado de servidor cumpla con uno de sus objetivos, la identificación fehaciente del propio servidor[6], es indispensable que una autoridad de certificación ampliamente reconocida lo firme. Eso, por lo general, supone:

  • Acreditar ante la CA, que somos los dueños del dominio.

  • Pagar para la generación y renovación de los certificados.

Lo segundo provocó que en Internet durante mucho tiempo proliferaran los certificados autofirmados y que toparnos con uno, si la página no era la de un banco, no produjera demasiadas sospechas. Sin embargo con la aparición de Let’s Encrypt y el patrocinio de muchas empresas del sector tecnológico y las comunicaciones que han apostado por hacer definitivamente la web segura y la sufragan, la situación ha cambiado: ahora es muy sencillo y totalmente gratuito obtener certificados válidos y es absolutamente injustificable haber generados certificados autofirmados en un servidor público en producción.

En la actualidad, hay algunas alternativas para obtener certificados gratuitos:

Otro aspecto a tener en cuenta, además de quién nos proporcione el certificado, es cómo se acredita ante el certificador la propiedad del dominio. Los métodos son esencialmente tres:

  1. Mediante correo electrónico, que consiste en que la autoridad nos envía un mensaje de confirmación a una dirección de correo electrónico muy concreta del dominio que hayamos afirmado que es nuestro, como admin@example.net o webmaster@example.net. Los nombres de las cuentas son tales que sólo podremos poseerlos si realmente somos los propietarios.

  2. Mediante DNS, que consiste en que la autoridad nos pide que incluyamos en la zona de nuestro dominio un registro (generalmente TXT o CNAME) muy particular, cuya posterior consulta sirve a la autoridad para confirmar que somos los propietarios.

  3. Mediante el protocolo ACME, inicialmente propuesto como estándar por Let’s Encrypt que consiste en correr un cliente en la máquina del servidor web que envía un anuncio al servidor ACME (la autoridad de certificación) instándole a comprobar la propiedad del dominio. Esta comprobación se lleva a cabo por una de estas dos alternativas llamadas desafíos.

    Desafío HTTP

    Consiste en que el servidor ACME entrega al cliente un token, para que este se lo haga accesible a través del protocolo HTTP. A continuación conectará con el cliente a través de estew protocolo usando el nombre (p.e. www.example.net) con el fin de acreditar que el cliente es realmente la máquina de tal nombre. Si la comprobación tiene éxito, se entrega el certificado firmado al cliente. Si se quieren acreditar varios nombres en un mismo certificado, entonces el desafío consistirá en hacer sendas pruebas para cada uno de los nombres deseados; y sólo si todas tienen buen suceso, se entregará el certificado.

    Desafío DNS

    En este caso, el cliente utiliza el token para crear un registro TXT en la zona del dominio que se desea acreditar para que la autoridad compruebe a continuación la existencia de tal registro. En este caso, dado que se puede acreditar la propiedad sobre todo el dominio, se pueden generar certificados comodín (o sea, un certificado para *.example.net que servirá para cualquier nombre de máquina del dominio).

    Ver también

    Para más información consulte las explicaciones más prolijas de Let’s Encrypt sobre desafíos

Como los certificados tienen un tiempo de vigencia (p.e. los certificados gratuitos de las dos primeras autoridades reseñadas, 90 días; y el de la última, 180), lo adecuado es utilizar un mecanismo que habilite las renovaciones automáticas lo cual es posible si hacemos uso de clientes ACME. Las tres autoridades soportan este protocolo, así que lo que necesitamos es un cliente ACME solvente. Hay varios (certbot, dehydrated, etc), pero nos centraremos en el script acme.sh porque presenta algunas ventajas:

  • Está enteramente escrito en POSIX shell, lo que evita la necesidad de dependencias más allá de las estrictamente necesarias (openssl y wget o curl) que de todas maneras ya tendremos instaladas.

  • Soporta las tres autoridades referidas que permiten obtener certificados gratuitos.

En cambio, no tiene paquete oficial en Debian, pero podemos suplir esto de un modo bastante sencillo.

Generación del paquete

Advertencia

El método de instalación que se propone consiste en generar un archivo deb, en vez de hacer una instalación directa. Para generar tal archivo son necesarias herramientas accesorias que no se necesitarán para nada más, por lo que se recomienda generar el deb en una máquina distinta a la que albergue el servidor. Para instalar las herramientas accesorias es necesario hacer:

# apt install unzip debhelper

que, como verá, instala bastantes paquetes.

Aunque el propio script proporciona un método de instalación, es más conveniente que procuremos crear un paquete de Debian, Para ello, existe otro repositorio que nos permite generar el paquete que deseamos. Basta con descargar el repositorio (por ejemplo el zip) y:

# unzip acme.sh-debian-master.zip
# cd acme.sh-debian-master

El script genera el paquete a partir de una copia del repositorio oficial que puede estar desfasada, así que antes de generarlo es conveniente editar debian/rules:

GITHUBUSER = acmesh-official
BRANCH = master

y, hecha la modificación, ya se puede generar el paquete:

# make debian

que generará en el directorio padre el paquete listo para ser instalado.

Instalación de acme.sh

Como hemos generado el paquete la instalación es sumamente sencilla:

# cd ..
# apt install ./acme.sh_0.1-2_amd64.deb

Advertencia

El paquete, no obstante, tiene un par de defectos que es imprescindible corregir:

  • Para las renovaciones automáticas de certificados, el script original añade una línea al cron de root para que comprueba diariamente si es preciso renovar alguno:

    11 0 * * * "/usr/lib/acme.sh"/acme.sh --cron --home /usr/lib/acme.sh > /dev/null
    

    donde 11 es un minuto aleatorio. Esto tal vez funcione, si se usa directamente el script sin demasiada personalización. Sin embargo, el paquete guarda la configuración en /etc/acme.sh y es dentro de ese directorio donde se encuentran los certificados, por lo que la renovación automática fallará. La solución es alterar esa línea para que se carguen las variables de ambiente:

    11 0 * * * . /etc/acme.sh/acme.sh.env ; "/usr/lib/acme.sh"/acme.sh --cron > /dev/null
    
  • No incluye ningún script de desinstalación prerm, por lo que ni se elimina el trabajo de cron ni la línea que se creó en /root/.bashrc por lo que habrá que hacer ambas acciones a mano.

Si su intención es generar inmediatamente el certificado sin salir de la sesión de administrador, entonces deberá cargar a mano el archivo que define las variables de ambiente:

# . /etc/acme.sh/acme.sh.env

Generación del certificado

Proponemos lo más sencillo[7] (y que en muchos casos nos será suficiente):

  • Con Let’s Encrypt, puesto que no requiere ningún tipo de registro. A partir de la versión 3.0, la CA predefinida pasó a ser ZeroSSL. Hasta ese momento lo había sido Let’s Encrypt. Hay una opción (--server[8]) que permite indicar con qué CA se pretende trabajar. Sin embargo, es más cómodo cambiar la predefinición:

    # acme.sh --set-default-ca  --server letsencrypt
    
  • El desafío HTTP.

    Advertencia

    No obstante, si pretende albergar múltiples sitios en el mismo servidor web, sopese la posibilidad de generar un certificado comodín con el desafío DNS.

  • Ya tenemos creado el servidor web, aunque no seguro porque carecemos aún de certificado[9]. Por ejemplo:

    server {
       listen   80;
    
       server_name example.net
                   www.example.net;
    
       root /srv/www/default;
       try_files $uri $uri/ =404;
    }
    

Si la resolución DNS de esos dos nombres conduce a nuestro servidor web, generar un certificado para esos nombres se lleva a cabo con:

# acme.sh --issue -d example.net -d www.example.net -w /srv/www/default

donde -d introduce los nombres de máquina y -w el directorio raíz para ese servidor virtual.

Nota

Podemos en un mismo certificado asociar varios nombres a distintos directorios raíz, para lo cual debemos expresar cada directorio raíz inmediatamente después de cada nombre:

# acme.sh --issue -d example.net -w /srv/www/default \
                  -d www.example.net -w /srv/www/default \
                  -d moodle.example.net -w /srv/www/moodle

Cuando usamos el desafío HTTP y los sitios son muchos, manejar tantos nombres y directorios diferentes puede ser un poco engorroso. Una solución cómoda consiste en crear un snippets/acme.conf con el siguiente contenido:

#
# Autogeneración de certificados con ACME.
#

if ($uri ~ "/.well-known/acme-challenge/") {
    break;
}

location ^~ "/.well-known/acme-challenge/" {
    root /srv/www/acme;
}

que provoca que la consulta ACME siempre se lleve a cabo dentro del directorio /srv/www/acme, por lo que la orden de generación de certificados quedaría simplemente:

# acme.sh --issue -d example.net -d www.example.net -d moodle.example.net -w /srv/www/acme

Una vez generado el certificado, deberá aparecernos como disponible:

# acme.sh --list

Sin embargo, debemos instalarlo para que pueda usarlo nuestro servidor nginx[10]:

# acme.sh --install-cert -d example.net --key-file /etc/ssl/private/letsencrypt-example.net.key \
   --fullchain-file /etc/ssl/certs/letsencrypt-fullchain-example.net.cer --reloadcmd "systemctl force-reload nginx"

Esta orden toma las claves, la copia en la localización que indicamos y reinicia el servidor por lo que ya es funcional el certificado y, además, se renovará automáticamente sin necesidad de que demos la orden expresa o tengamos que reiniciar el servidor manualmente.

Nota

Una línea como la anterior es útil cuando el servidor que usa el certificado mantiene por separado la(s) clave(s) pública(s) de la privada. No hay, sin embargo, ninguna opción que copie juntas en un mismo archivo todas las claves, por lo que si el servidor que usa el certificado requiere esto (p.e. el proxy inverso haproxy) entonces tenemos que recurrir a generar el archivo dentro de la orden que expresa --reloadcmd:

# acme.sh --install-cert -d example.net \
          --reloadcmd 'cat $CERT_KEY_PATH $CERT_FULLCHAIN_PATH > /etc/haproxy/keycert.pem && systemctl restart haproxy'

Si deseamos revocar y borrar alguno de los certificados:

# acme.sh --revoke -d example.net
# acme.sh --remove -d example.net

El certificado, aunque ya no esté activo (no aparecerá al usar --list), no se borrará del directorio /etc/acme.sh/cert/example.net. Esta operación deberemos hacerla a mano.

Advertencia

Si ha configurado el servidor de manera que la conexión no segura redirige a la segura (lo cual es muy habitual), la revocación no funcionará, así que, antes de revocar comprueba, asegúrese de inhabilitarlo temporalmente.

Configuración

La configuración es prácticamente idéntica a la propuesta para los certificados autofirmados:

server {
   listen   443 ssl;

   server_name _;

   root /srv/www;
   try_files $uri $uri/ =404;

   include snippets/cert.conf;

   # Cabecera HSTS
   add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
}

La última línea de la configuración (opcional) añade una cabecera HSTS a las respuestas que obliga al cliente a usar siempre HTTPs y a no aceptar tras la primera visita a la página bajo ningún concepto un certificado no fiable. (p.e. uno autofirmado)[11]. Para más información, consulte el epígrafe dedicado al ataque SSLstrip.

Por su parte, cert.conf (que cumple el papel de snakeoil.conf y en esta ocasión sí tendremos que crear) tiene el siguiente contenido:

ssl_certificate /etc/ssl/certs/letsencrypt-fullchain-example.net.cer;
ssl_certificate_key /etc/ssl/private/letsencrypt-example.net.key;
ssl_trusted_certificate /etc/ssl/certs/letsencrypt-fullchain-example.net.cer;

Nota

Es posible que deseemos que el tráfico sea exclusivamente seguro y evitar que el usuario se comunique a través del puerto 80. Eso podemos lograrlo con la cabecera HSTS o incluyendo la redirección con el if comentada anteriormente.

Además, debemos definir un archivo para configurar algunas directivas relacionadas con el SSL en /etc/nginx/conf.d/ssl.conf con este contenido:

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+AES;
ssl_ecdh_curve secp384r1;

ssl_stapling on;
ssl_stapling_verify on;

add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

7.2.2.2.8.3. Aspectos adicionales

7.2.2.2.8.3.1. Múltiples dominios virtuales

Cuando el servidor define varios dominios virtuales y dos o más de ellos usan tráfico seguro debe tenerse en cuenta que, en principio, el servidor web conoce cuál es el nombre de máquina usado en la petición a través del comando GET o las cabeceras HTTP. Al ser el tráfico cifrado, el acceso a esta información no es accesible hasta que no se use el certificado correspondiente para descifrarla. Esa es la razón por la que, en principio, el certificado debería ser común a todos los dominios virtuales. Para subsanar esta limitación el protocolo SSL ideó la extensión SNI, que soportan la mayor parte de los navegadores modernos y, muy probablemente la versión de nginx que se esté utilizando:

# nginx -V

En caso de que nginx soporte SNI, puede definirse un certificado diferente en cada sitio a través de ssl_certificate y ssl_certificate_key. Para los sitios seguros en que no se defina un certificado, se usará el declarado en el servidor predeterminado[12]. Una configuración posible puede ser esta:

server {
   listen   80       default_server;
   listen   443 ssl  default_server;

   server name _;

   include snippets/letsencrypt.conf;

   # Resto de configuración.
}

server {
   listen 80;
   listen 443;  # Nótese que no hace falta ni usar ssl.

   server_name  moodle.example.net;

   # Configuración para moodle
}

server  {
   listen 80;
   listen 443 ssl;

   server_name  alt.example.net;

   include snippets/zerossl.conf;

   # Configuración para este sitio.
}

Con esta configuración, el sitio moodle.example.net usará el mismo certificado que el sitio predeterminado (el incluido en snippets/letsencrypt.conf, mientras que el sitio alt.example.net utiliza un certificado distinto definido en snippets/zerossl.conf. Podemos cerciorarnos de que esto realmente funciona haciendo una consulte con el navegador y consultando los certificados, o desde la consola con openssl al servidor:

$ openssl s_client -servername alt.example.net -connect alt.example.net:https < /dev/null | grep 'CN ='

Advertencia

openssl no usa SNI a menos que se use la opción -servername, de modo que haga las pruebas incluyéndola.

7.2.2.2.8.3.2. Certificados con ZeroSSL

ZeroSSL es una buena alternativa a Let’s Encrypt y, además. en las últimas versiones del script es la CA predefinida [13], aunque requiere un registro previo que puede hacerse desde la propia línea de órdenes:

# acme.sh  --server zerossl --register-account -m micorreo@example.net

Nota

Si ya estábamos registrados, sígase la documentación oficial de acme.sh sobre certificados de ZeroSSL

Advertencia

No se incluye la opción --server en las órdenes posteriores, porque suponemos que nunca llegó a cambiar la CA predefinida, como se sugirió anteriormente. Si lo llegó a hacer, no obstante, siempre puedo volver a usar esa orden para que vuelva a ser ZeroSSL.

Hecho el registro, la generación de certificados con --issue es exactamente igual, excepto por la salvedad de que deberermos añadir --server zerossl:

# acme.sh -issue -d zero.iescdl.es -w /srv/www/zero1 \
   -d zero2.iescdl.es -w /srv/www/zero2

Obviamente, además, habrá que instalar el certificado.

7.2.2.2.8.3.3. Desafío DNS

Cuando en un servidor web disponemos distintos sitios (blogs con wordpress, moodle, aplicaciones diversas), el certificado tendrá que contenemos muchos nombres y se tendrán que llevar a cabo pruebas en muchos directorios raíz. Si, además, ampliamos los servicios y creamos un nuevo sitio con un nuevo nombre, tendremos que regenerar el certificado para incluirlo. Para evitarlo, lo mejor es generar un certificado comodín y esto sólo se puede hacer utilizando el desafío DNS. Su única dificultad es que durante la generación y renovación del certificado, requiere la creación dinámica del registro TXT en nuestra zona DNS y que se pueda realmente hacer y cómo depende de cuál sea nuestro proveedor de DNS[14].

La documentación de acme.sh tiene un documento donde repasa cómo usar con acme.sh las API de distintos proveedores de DNS. Si se siguen las instrucciones para nuestro proveedor, la obtención del certificado usando el desafío DNS se limita a:

# acme.sh --issue -d example.net -d '*.example.net' --dns dns_ovh

Nota

El argumento de --dns depende del proveedor.

7.2.2.2.8.3.4. El cliente certbot

Advertencia

Este epígrafe se incluye, exclusivamente, por haber sido escrito su contenido con anterioridad a gran parte de la exposición sobre certificados digitales. Es más aconsejable utilizar acme.sh, como se ha propuesto en el resto del texto, puesto que certbot está escrito en Python y requiere dependencias que muy probable sólo necesite para su ejecución

Tiene paquete en debian, así que su instalación es sumamente sencilla:

# apt install certbot

Como los certificados obtenidos se pueden usar luego con distinto software, certbot tiene distintos plugins para, además de crear o renovar el certificado, proceder a su instalación en ellos. Nosotros, no obstante, sólo repararemos en dos:

  • standalone, que debe usarse si prevemos que no tendremos ocupado nunca el puerto 80. Con este plugin, el propio certboot levanta temporalmente un servidor web en el proceso de creación o renovación. No debe usarse si montamos un servidor web, porque en ese caso, la renovación fallará levantando el servidor web temporal al encontrar ocupado el puerto.

  • webroot, que implica tener un servidor web instalado e indicarle a certboot cuál es el directorio raíz del mismo.

Nosotros usaremos este último, suponiendo que ya tenemos listo el servidor web y que nuestro directorio raíz es /srv/www, Tras ello, podemos lanzar la generación del certificado así:

# certbot certonly --webroot -w /srv/www -d www.example.net \
   --non-interactive --agree-tos --email licencias@iesmiravent.es \
   --post-hook "/etc/letsencrypt/posthook.sh"

Como resultado de la orden tendremos dentro de /etc/letsencrypt/live/www.example.net las claves generadas y, además, justamente tras la generación, se habrá ejecutado el script que pasemos con la opción --post-hook[15]. Lo que realmente haya que hacer para que la nueva clave sea efectiva dependerá de cómo se tenga configurado el servidor. La gracia de incluir el script es que certboot viene con un timer de systemd para intentar diariamente la renovación del script y que este proceso de renovación también lanza el script. Por tanto, podremos olvidarnos por completo de estar al tanto de la actualización.

En una configuración simple en que el propio nginx se encarga del cifrado y utilizamos la configuración propuesta en el próximo epígrafe, basta con que el script se limite a reiniciar nginx. Por tanto:

#!/bin/sh

systemctl reload-or-restart nginx.service

Para casos más complejos, como cuando del cifrado se encarga haproxy, es necesario juntar las claves pública y privada (fullchain.pem y privkey.pem) en un único fichero. Este script se encarga de ello.

Nota

Es posible también generar un certificado asociados a varios nombres repitiendo las opciones -w y -d, de modo que las opciones -d harán referencia al -w que las precede. Por ejemplo:

# certbot certonly --webroot -w /srv/www/main -d example.net -d www.example.net \
   -w /srv/www/blog -d blog.example.net --non-interactive --agree-tos \
   --email licencias@iesmiravent.es --post-hook "/etc/letsencrypt/posthook.sh"

Es común que en algún momento añadamos un nuevo sitio al servidor y necesitemos que este sitio también use cifrado. Podemos ampliar el uso del mismo certificado al nuevo sitio usando la opción --expand:

# certbot certonly --webroot --expand -w /srv/www -d www.example.net \
   -w /srv/www/moodle -d moodle.example.net \
   --non-interactive --agree-tos --email licencias@iesmiravent.es \
   --post-hook "/etc/letsencrypt/posthook.sh"

Hay, eso sí, que enumerar todos los dominios a los que ya estaba asociado el servidor y añadir los nuevos.

La configuración es idéntica a la ya propuesta, aunque cambian las rutas a los archivos de claves, por lo que tendremos que cambiar el contenido de snippets/cert.conf:

ssl_certificate /etc/letsencrypt/live/www.example.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.net/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/www.example.net/fullchain.pem;

Notas al pie