SSL / TLS (Secure Socket Layer / Transport Layer Security) son protocolos criptográficos que permiten establecer un canal de comunicación segura en Internet: web, correo, fax y mensajería instantánea
CA (Certificate Authoritative): entidad reconocida a nivel mundial encargada de generar certificados de seguridad para terceros.
CSR (Certificate Signing Request): es una solicitud de firmado de certificado a una CA.
Let’s Encrypt: es una autoridad de certificación (CA) gratuita, automatizada y abierta, disponible para beneficio público. Es un servicio proporcionado por Internet Security Research Group (ISRG).
Proporciona a las personas los certificados digitales que necesitan para habilitar HTTPS (SSL/TLS) en sus sitios web, de forma gratuita, de la manera más fácil de usar posible.
Principales características:
- Gratis: cualquier persona que posea un dominio puede usar Let’s Encrypt para obtener un certificado de seguridad gratuito.
- Automático: el proceso de obtención y renovación del certificado se puede realizar de forma automática.
- Seguro: Let’s Encrypt promueve las mejores prácticas de seguridad TLS y garantizando una protección adecuada de los datos que se intercambian entre un dispositivo y otro.
- Transparente: todos los certificados emitidos o revocados se registrarán públicamente y estarán disponibles para que cualquiera pueda inspeccionarlos.
- Abierto: el protocolo de emisión y renovación automática se publica como un estándar abierto que otros pueden adoptar.
- Cooperativo: al igual que los propios protocolos de Internet subyacentes, Let’s Encrypt es un esfuerzo conjunto para beneficiar a la comunidad, más allá del control de cualquier organización.
Lego: es un cliente/librería Let’s Encrypt que permite obtener y renovar certificados Let’s Encrypt. Las principales características de lego son:
- Renovar certificados
- Revocar certificados
- Robusta implementación de todos los métodos ACME: HTTP (http-01), DNS (dns-01), TLS (tls-alpn-01)
- Soporta certificados SAM
Para ver todas las características consulte:
Le puede interesar:
- Instalar SSL Let’s Encrypt en Debian
- NGINX como proxy reverso
- ¿Cómo instalar NGINX en NetBSD?
- ¿Cómo instalar NGINX en Alpine Linux?
Nota: El siguiente procedimiento ha sido ejecutado en la distribución Alpine Linux.
1 – Descargar
Ir a Releases seleccione el binario de acuerdo a su arquitectura, en el momento de escribir este post la última versión es la 4.4.0.
$ curl -LO -# https://github.com/go-acme/lego/releases/download/v4.4.0/lego_v4.4.0_linux_amd64.tar.gz
2 – Descompactar
$ tar xzvf lego_v4.4.0_linux_amd64.tar.gz
3 – Instalar
$ sudo install lego /usr/local/bin/
4 – Ver versión
$ lego -v
lego version 4.4.0 linux/amd64
5 – Obtener ayuda
lego -h
NAME:
lego - Let's Encrypt client written in Go
USAGE:
lego [global options] command [command options] [arguments...]
VERSION:
4.4.0
COMMANDS:
run Register an account, then create and install a certificate
revoke Revoke a certificate
renew Renew a certificate
dnshelp Shows additional help for the '--dns' global option
list Display certificates and accounts information.
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--domains value, -d value Add a domain to the process. Can be specified multiple times.
--server value, -s value CA hostname (and optionally :port). The server certificate must be trusted in order to avoid further modifications to the client. (default: "https://acme-v02.api.letsencrypt.org/directory")
--accept-tos, -a By setting this flag to true you indicate that you accept the current Let's Encrypt terms of service.
--email value, -m value Email used for registration and recovery contact.
--csr value, -c value Certificate signing request filename, if an external CSR is to be used.
--eab Use External Account Binding for account registration. Requires --kid and --hmac.
--kid value Key identifier from External CA. Used for External Account Binding.
--hmac value MAC key from External CA. Should be in Base64 URL Encoding without padding format. Used for External Account Binding.
--key-type value, -k value Key type to use for private keys. Supported: rsa2048, rsa4096, rsa8192, ec256, ec384. (default: "ec256")
--filename value (deprecated) Filename of the generated certificate.
--path value Directory to use for storing the data. (default: "/root/.lego") [$LEGO_PATH]
--http Use the HTTP challenge to solve challenges. Can be mixed with other types of challenges.
--http.port value Set the port and interface to use for HTTP based challenges to listen on.Supported: interface:port or :port. (default: ":80")
--http.proxy-header value Validate against this HTTP header when solving HTTP based challenges behind a reverse proxy. (default: "Host")
--http.webroot value Set the webroot folder to use for HTTP based challenges to write directly in a file in .well-known/acme-challenge. This disables the built-in server and expects the given directory to be publicly served with access to .well-known/acme-challenge
--http.memcached-host value Set the memcached host(s) to use for HTTP based challenges. Challenges will be written to all specified hosts.
--tls Use the TLS challenge to solve challenges. Can be mixed with other types of challenges.
--tls.port value Set the port and interface to use for TLS based challenges to listen on. Supported: interface:port or :port. (default: ":443")
--dns value Solve a DNS challenge using the specified provider. Can be mixed with other types of challenges. Run 'lego dnshelp' for help on usage.
--dns.disable-cp By setting this flag to true, disables the need to wait the propagation of the TXT record to all authoritative name servers.
--dns.resolvers value Set the resolvers to use for performing recursive DNS queries. Supported: host:port. The default is to use the system resolvers, or Google's DNS resolvers if the system's cannot be determined.
--http-timeout value Set the HTTP timeout value to a specific value in seconds. (default: 0)
--dns-timeout value Set the DNS timeout value to a specific value in seconds. Used only when performing authoritative name servers queries. (default: 10)
--pem Generate a .pem file by concatenating the .key and .crt files together.
--cert.timeout value Set the certificate timeout value to a specific value in seconds. Only used when obtaining certificates. (default: 30)
--help, -h show help
--version, -v print the version
6 – Obtener certificado
6.1 – Crear DIR /var/www/letsencrypt
En el DIR /var/www/letsencrypt/.well-known/acme-challenge lego guardará el fichero que nos servirá para validar nuestro domino o sea utilizaremos el desafío/respuesta http-01 para comprobar que el dominio es nuestro, por tanto debemos creamos el DIR con el siguiente comando.
$ sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
6.2 – Creamos un virtual host para el NGINX con la siguiente configuración
server {
listen 80;
server_name midominio.com;
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/letsencrypt/;
}
}
Creamos un fichero de txt dentro de /var/www/letsencrypt/.well-known/acme-challenge/ para probar la configuración del NGINX
$ sudo echo OK > /var/www/letsencrypt/.well-known/acme-challenge/ok.txt
Recargamos la configuración del NGINX con:
$ sudo service nginx reload
Ahora trate de acceder al fichero ok.txt desde el navegador con http://midominio.com/.well-known/acme-challenge/ok.txt si accedió de manera exisota entonces podemos pasar al siguiente paso que es obtener un certificado de prueba.
6.3 – Obtener certificado usando ambiente de prueba Let’s encrypt
$ sudo lego --server=https://acme-staging-v02.api.letsencrypt.org/directory --accept-tos -m micorreo@midomnio.com -d midominio.com -d www.midominio.comm --http --http.webroot /var/www/letsencrypt --pem --path /etc/lego/ run
Como puede notar en el comando anterior la opcion –server está apuntando al ambiente de prueba Let’s Encrypt.
- –accept-tos: aceptar los términos del servicio de forma automática.
- -m: correo electrónico donde se reciben notificaciones Let’s Encrypt por ejemplo: fecha de expiración del certificado.
- -d: El dominio al cual se se le desea obtener un certificado SSL/TLS (Se puede especificar varias veces para un obtener un certificado SAN: varios dominios en un mismo certificado)
- –http: Usar el método HTTP para validar el dominio.
- –http.webroot: DIR donde se guarda los ficheros a usar en el desafío/respuesta, se necesita un servidor web que permita acceder a estos ficheros (Ver 6.2)
- –pem: Concatena el fichero .key y .crt en un solo fichero.
6.5 – Obtener certificado usando ambiente de producción Let’s encrypt
Una vez ejecutado satisfactoriamente el paso 6.3 procedemos a obtener un certificado válido y real usando el ambiente de producción, tenga en cuenta que para este ambiente existe un límite de validación fallida de 5 fallos por cuenta, por nombre de host y por hora por eso la necesidad de ejecutar el paso 6.3 ya que el ambiente de prueba tiene un límite mayor.
$ sudo lego --accept-tos -m micorreo@midomnio.com -d midominio.com -d www.midominio.comm --http --http.webroot /var/www/letsencrypt --pem --path /etc/lego/ run
Nótese que en el comando anterior quitamos la opción server. También es posible ejecutar determinadas acciones a través de hooks.
6.6 – Listar certificados
$ sudo lego --path /etc/lego/ list
6.7 – Renovar certificados de manera automática
Para renovar los certificados de manera automática cree una tarea en cron o podemos crear un script en /etc/periodic/daily/
#!/bin/sh
lego --accept-tos -m micorreo@midomnio.com -d midominio.com -d www.midominio.comm --http --http.webroot /var/www/letsencrypt --pem --path /etc/lego/ renew --renew-hook="rc-service nginx reload"
Ponga el contenido anterior en un fichero, por ejemplo /etc/periodic/daily/lego y dele permisos de ejecución, ahora todos los días se va a chequear si el certificado de seguridad debe renovarse en caso afirmativo se procede a la renovación del mismo y si la renovación fue exitosa se recarga la configuración del NGINX. Si desea forzar la renovación ejecute el comando anterior pasandole la opción --days N
donde N debe ser mayor al número de días en que expira el certificado.
7 – Configurar el NGINX
7.1 – Reemplace o modifique las siguiente directivas
Abrir el fichero principal de configuración del NGINX (/etc/nginx/nginx.conf) y ajuste las siguiente directivas a los valores correspondientes.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_timeout 1d;
Addicionar
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
Generar parámetros Diffie Hellman (DH)
openssl dhparam -out dhparam.pem 4096
Si ejecuta la operación anterior en un dispositivo con pocos recursos lo más probable es que tome un largo tiempo, por eso es recomendable que la realice en un CPU de última generación por ejemplo en mi desktop: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz con 32 GB de RAM tomó aproximadamente 1m en completarse el proceso.
Copie la llave generada para /etc/nginx/ y agregue al NGINX
ssl_dhparam dhparam.pem;
7.2 – Crear configuración para midominio.com
Cree el fichero /etc/nginx/midominio.conf y agregue:
server {
listen 443 ssl http2;
# SSL configuration
ssl_certificate /etc/lego/certificates/midominio.com.cert;
ssl_certificate_key /etc/lego/certificates/midominio.com.key;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/midominio.com.pem;
# Put here you domain
#
server_name midominio.com www.midominio.com;
root /var/www/miproyecto;
index index.php;
# Max file size useful for file uploading
#
client_max_body_size 8M;
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when
# using query string
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
7.3 – Recargar la configuración del NGINX
$ sudo service nginx reload