One place for hosting & domains

      Encrypt

      Cómo proteger Apache con Let’s Encrypt en Ubuntu 18.04


      Introducción

      Let’s Encrypt es una entidad de certificación (CA) que proporciona una manera sencilla de obtener e instalar certificados de TLS/SSL gratuitos, lo que permite usar HTTPS cifrado en servidores web. Simplifica el proceso al proporcionar un cliente de software, Certbot, que intenta automatizar la mayoría (cuando no todos) de los pasos requeridos. Actualmente, todo el proceso de obtención e instalación de un certificado está totalmente automatizado en Apache y Nginx.

      En este tutorial, utilizará Certbot para obtener un certificado de SSL gratuito para Apache en Ubuntu 18.04 y configurará su certificado para que se renueve de forma automática.

      En este tutorial se utilizará un archivo de host virtual de Apache por separado en lugar del archivo de configuración predeterminado. Recomendamos crear nuevos archivos de host virtual de Apache para cada dominio, ya que permite evitar errores comunes y mantiene los archivos predeterminados como una configuración de reserva.

      Requisitos previos

      Para este tutorial, necesitará lo siguiente:

      • Un servidor de Ubuntu 18.04 configurado conforme a este tutorial de configuración inicial para servidores de Ubuntu 18.04, incluido un usuario sudo no root y un firewall.

      • Un nombre de dominio registrado por completo. En este tutorial, se utilizará your_domain como ejemplo. Puede adquirir un nombre de dominio en Namecheap, obtener uno gratuito en Freenom o utilizar un registrador de dominios de su elección.

      • Los dos registros DNS que se indican a continuación se han configurado para su servidor. Puede utilizar esta introducción al DNS de DigitalOcean para obtener más información sobre cómo agregarlos.

        • Un registro A con your_domain orientado a la dirección IP pública de su servidor.
        • Un registro A con www.your_domain orientado a la dirección IP pública de su servidor.
      • Apache instalado conforme a Cómo instalar Apache en Ubuntu 18.04. Compruebe que tenga un archivo de host virtual para su dominio. En este tutorial, se utilizará /etc/apche2/sites-available/your_domain.conf como ejemplo.

      Paso 1: Instalar Certbot

      El primer paso para utilizar Let’s Encrypt para obtener un certificado SSL es instalar el software Certbot en su servidor.

      Existe mucha actividad relacionada con el desarrollo de Certbot. Esto hace que sus paquetes proporcionados por Ubuntu suelan perder vigencia. Sin embargo, los desarrolladores de Certbot mantienen un repositorio de software de Ubuntu con versiones actualizadas, de modo que en su lugar usaremos ese repositorio.

      Primero, agregue el repositorio:

      • sudo add-apt-repository ppa:certbot/certbot

      Debe presionar ENTER para aceptar.

      Instale el paquete Apache de Certbot con apt:

      • sudo apt install python-certbot-apache

      Con esto, Certbot estará listo para utilizarse. Sin embargo, para que configure SSL para Apache debemos verificar parte de la configuración de Apache.

      Paso 2: Configurar el certificado SSL

      Certbot debe poder encontrar el host virtual adecuado en su configuración de Apache para poder configurar SSL de forma automática. De forma específica, lo hace buscando una directiva ServerName que coincida con el dominio para el que usted solicite un certificado.

      Si siguió el paso de configuración del host virtual en el tutorial de instalación de Apache, debe disponer de un bloque VirtualHost para su dominio en /etc/apache2/sites-available/your_domain.com.conf con la directiva ServerName ya establecida de forma adecuada.

      Para comprobarlo, abra el archivo de host virtual para su dominio utilizando nano o el editor de texto que prefiera:

      • sudo nano /etc/apache2/sites-available/your_domain.conf

      Busque la línea de ServerName existente. Debería tener el siguiente aspecto:

      /etc/apache2/sites-available/your_domain.conf

      ...
      ServerName your_domain;
      ...
      

      Si esto sucede, salga de su editor y continúe con el paso siguiente.

      De lo contrario, actualícelo para que coincida. A continuación, guarde el archivo, cierre el editor y verifique la sintaxis de las modificaciones de la configuración:

      • sudo apache2ctl configtest

      Si encuentra un mensaje de error, vuelva a abrir el archivo de host virtual y verifique que no haya errores ortográficos y que no falten caracteres. Una vez que la sintaxis de su archivo de configuración sea correcta, vuelva a abrir Apache para cargar la configuración nueva:

      • sudo systemctl reload apache2

      Ahora, Certbot podrá encontrar el bloque VirtualHost correcto y actualizarlo.

      A continuación, actualizaremos el firewall para permitir el tráfico de HTTPS.

      Paso 3: Habilitar HTTPS a través del firewall

      Si tiene habilitado el firewall de ufw, como se recomienda en las guías de los requisitos previos, deberá ajustar la configuración para permitir el tráfico de HTTPS. Afortunadamente, Apache registra algunos perfiles con ufw después de la instalación.

      Puede ver la configuración actual escribiendo lo siguiente:

      Probablemente tendrá este aspecto, lo cual significa que solo se permite el tráfico de HTTP al servidor web:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache (v6) ALLOW Anywhere (v6)

      Para permitir de forma adicional el tráfico de HTTPS, habilite el perfil de Apache Full y borre el permiso del perfil redundante de Apache:

      • sudo ufw allow 'Apache Full'
      • sudo ufw delete allow 'Apache'

      Ahora, su estado debería tener el siguiente aspecto:

      Output

      Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Apache Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Apache Full (v6) ALLOW Anywhere (v6)

      A continuación, ejecutaremos Certbot y buscaremos nuestros certificados.

      Paso 4: Obtener un certificado SSL

      Certbot ofrece varias alternativas para obtener certificados SSL a través de complementos. El complemento de Apache se encargará de reconfigurar Apache y volver a cargar la configuración cuando sea necesario. Para utilizar este complemento, escriba lo siguiente:

      • sudo certbot --apache -d your_domain -d www.your_domain

      Con esto, se ejecuta certbot con el complemento --apache, usando -d a fin de especificar los nombres para los cuales desea que el certificado tenga validez.

      Si es la primera vez que ejecuta certbot, se le solicitará introducir una dirección de correo electrónico y aceptar las condiciones de servicio. A continuación, certbot se comunicará con el servidor de Let’s Encrypt y, luego, realizará una comprobación para verificar que usted controle el dominio para el que solicita un certificado.

      Si la comprobación se realiza correctamente, certbot le preguntará cómo desea configurar sus ajustes de HTTPS:

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Seleccione su elección y presione ENTER. La configuración se actualizará y Apache se volverá a cargar para aplicar los ajustes nuevos. certbot concluirá con un mensaje que le indicará que el proceso se realizó con éxito y le brindará información sobre la ubicación de sus certificados:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2018-07-23. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Así, sus certificados se quedarán descargados, instalados y cargados. Intente volver a cargar su sitio web utilizando https:// y observe el indicador de seguridad de su navegador. Debería indicar que el sitio cuenta con la protección correcta, en general, con un ícono de un candado verde. Si prueba su servidor utilizando SSL Labs Server Test, obtendrá una calificación A.

      Terminaremos con una prueba del proceso de renovación.

      Paso 5: Verificar la renovación automática de Certbot

      Los certificados de Let’s Encrypt son válidos únicamente por noventa días. El propósito de esto es incentivar a los usuarios a automatizar sus procesos de renovación de certificados. El paquete de certbot que instalamos se encargará de esto agregando una secuencia de comandos de renovación a /etc/cron.d. Esta secuencia de comandos se ejecuta dos veces al día y renovará de forma automática cualquier certificado que caduque en treinta o menos días.

      Para probar el proceso de renovación, puede hacer un simulacro con certbot:

      • sudo certbot renew --dry-run

      Si no ve errores, no habrá inconvenientes. Cuando sea necesario, Certbot renovará sus certificados y volverá a cargar Apache para registrar los cambios. Si el proceso de renovación automática falla, Let’s Encrypt enviará un mensaje a la dirección de correo electrónico que especificó en el que se le advertirá cuándo se aproxime la fecha de vencimiento de sus certificados.

      Conclusión

      En este tutorial, instaló el certbot del cliente Let’s Encrypt, descargó certificados SSL para su dominio, configuró Apache para utilizarlos y definió la renovación automática de certificados. Si tiene preguntas adicionales sobre la utilización de Certbot, la documentación es un buen punto de partida.



      Source link

      How To Acquire a Let’s Encrypt Certificate Using Ansible on Ubuntu 18.04


      The author selected the Electronic Frontier Foundation to receive a donation as part of the Write for DOnations program.

      Introduction

      Modern infrastructure management is best done using automated processes and tools. Acquiring a Let’s Encrypt certificate using the standard Certbot client is quick and easy, but is generally a task that has to be done manually when commissioning servers. This is manageable for an individual server setup, but can become tedious when deploying a larger fleet.

      Using a configuration management tool such as Ansible to acquire a certificate makes this task completely automatic and reproducible. If you ever have to rebuild or update your server, you can just run your Ansible playbook, rather than having to manually carry out the steps again.

      In this tutorial, you’ll write an Ansible playbook to acquire a Let’s Encrypt certificate automatically for an Ansible host machine.

      Prerequisites

      To complete this tutorial, you will need:

      The first server will be used as your Ansible server, which we will call Ansible server throughout this tutorial. This is where Ansible will run to send the commands to the host machine. Alternatively, you can use your local machine or any other machine that has your Ansible inventory configured as your Ansible server.

      On your Ansible server, you’ll need:

      The second server will be used as your Ansible host, which we will call the host machine throughout this tutorial. This is the machine that you wish to configure and issue certificates on. This machine will also run a web server to serve the certificate issuance validation files.

      On your host machine, you’ll need:

      • A domain name that you are eligible to acquire a TLS certificate for, with the required DNS records configured to point to your Ansible host machine. In this particular example, the playbook will acquire a certificate valid for your-domain and www.your-domain, however it can be adjusted for other domains or subdomains if required.

      • A web server that is accessible from the internet over port 80 (HTTP), for example by following steps 1, 2, and 3 of How To Install the Apache Web Server on Ubuntu 18.04. This could also be an Nginx server, or any other suitable web server software.

      Once you have these ready, log in to your Ansible server as your non-root user to begin.

      Step 1 — Configuring the Settings for the Let’s Encrypt Ansible Module

      Ansible has a built-in module named letsencrypt, which allows you to acquire valid TLS certificates using the ACME (Automated Certificate Management Environment) protocol.

      In this first step, you will add a host variables configuration file to define the configuration variables that are required to use the module.

      Note: The letsencrypt module has been renamed to acme_certificate as of Ansible 2.6. The letsencrypt name is now an alias of acme_certificate, so will still work, but you way wish to use acme_certificate instead, to ensure future-proofness of your playbooks. You can check your Ansible version using ansible --version. As of the writing of this tutorial, the Ubuntu 18.04 Apt repositories don’t support acme_certificate yet.

      Firstly, create the host_vars Ansible directory on your Ansible server:

      • sudo mkdir /etc/ansible/host_vars

      Next, create a new file in the /etc/ansible/host_vars directory with the name of your Ansible host machine. In this example, you’ll use host1 as the name of the host:

      • sudo nano /etc/ansible/host_vars/host1

      The following sample configuration includes everything you need to get started, including: the validation method and server address, an email address to receive certificate expiry reminders to, and the directories where your Let’s Encrypt keys and certificates will be saved.

      Copy the sample configuration into the file:

      /etc/ansible/host_vars/host1

      ---
      acme_challenge_type: http-01
      acme_directory: https://acme-v02.api.letsencrypt.org/directory
      acme_version: 2
      acme_email: certificate-reminders@your-domain
      letsencrypt_dir: /etc/letsencrypt
      letsencrypt_keys_dir: /etc/letsencrypt/keys
      letsencrypt_csrs_dir: /etc/letsencrypt/csrs
      letsencrypt_certs_dir: /etc/letsencrypt/certs
      letsencrypt_account_key: /etc/letsencrypt/account/account.key
      domain_name: your-domain
      

      Save and close the file when you’ve finished.

      Adjust the domain name and email address as required. You can use any email address—it doesn’t have to be the one on your-domain.

      Some of the directory/file paths defined may not actually exist on your server yet. This is OK; the first part of the playbook will be to create these directories and assign the relevant permissions.

      You’ve added the required configuration variables to your Ansible inventory file. Next, you will begin writing the playbook to acquire a certificate.

      Step 2 — Creating the Let’s Encrypt Directories and Account Key

      In this step, you’ll write the Ansible tasks that you’ll use to create the required Let’s Encrypt directories, assign the correct permissions, and generate a Let’s Encrypt account key.

      Firstly, create a new playbook named letsencrypt-issue.yml on your Ansible server in a new directory of your choice, for example /home/user/ansible-playbooks:

      • cd ~
      • mkdir ansible-playbooks
      • cd ansible-playbooks
      • nano letsencrypt-issue.yml

      Before you can start writing Ansible tasks, you’ll need to specify the hosts and associated settings. Adjust the following according to how you referred to your hosts in the prerequisite tutorial. Then add the following to the top of the file:

      letsencrypt-issue.yml

      ---
      - hosts: "host1"
        tasks:
      

      Now you can begin writing the required tasks, the first of which is to create the file system directories required to store the Let’s Encrypt files. Add the following Ansible task to the file after the previous content:

      letsencrypt-issue.yml

      ...
        - name: "Create required directories in /etc/letsencrypt"
          file:
            path: "/etc/letsencrypt/{{ item }}"
            state: directory
            owner: root
            group: root
            mode: u=rwx,g=x,o=x
          with_items:
          - account
          - certs
          - csrs
          - keys
      

      This Ansible task will create the account, certs, csrs, and keys directories in /etc/letsencrypt, which is where the files required for acquiring certificates will be stored.

      You set the owner of the directories to root and apply the permissions u=rwx,g=x,o=x so that only root has read and write access to them. This is recommended as the directories will contain private keys, certificate signing requests (CSRs), and signed certificates, which should be kept confidential.

      Next, the Let’s Encrypt account key needs to be created. You’ll use this to identify yourself to the Let’s Encrypt service.

      Add the following task to your playbook:

      letsencrypt-issue.yml

      ...
        - name: "Generate a Let's Encrypt account key"
          shell: "if [ ! -f {{ letsencrypt_account_key }} ]; then openssl genrsa 4096 | sudo tee {{ letsencrypt_account_key }}; fi"
      

      The account key doesn’t need to be re-created every time you renew the certificates, so you also add a check for an existing key if [ ! -f {{ letsencrypt_account_key }} ];, to make sure that it isn’t overwritten.

      You’ll continue to work in letsencrypt-issue.yml in the next step, so don’t close this file yet.

      You’ve created your playbook and set up the initial configuration and tasks in order to prepare for acquiring your Let’s Encrypt certificate. Next, you will add further tasks for the private key and CSR generation.

      Step 3 — Generating Your Private Key and Certificate Signing Request

      In this step, you’ll write the playbook tasks to generate the required private key and certificate signing request.

      The first task in this section will generate the required private key for your certificate. Add the following to the end of your playbook that you started writing in Step 2:

      letsencrypt-issue.yml

      ...
        - name: "Generate Let's Encrypt private key"
          shell: "openssl genrsa 4096 | sudo tee /etc/letsencrypt/keys/{{ domain_name }}.key"
      

      Subdomains on the same domain will all be added to the same certificate through the use of Subject Alternate Names (SANs), so you only need to generate one private key for now.

      You’ll use the next task to generate a Certificate Signing Request (CSR) for the certificate that you want to acquire. This is submitted to Let’s Encrypt in order for them to validate and issue each certificate.

      Add the following to the end of the playbook:

      letsencrypt-issue.yml

      ...
        - name: "Generate Let's Encrypt CSR"
          shell: "openssl req -new -sha256 -key /etc/letsencrypt/keys/{{ domain_name }}.key -subj "/CN={{ domain_name }}" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "n[SAN]nsubjectAltName=DNS:{{ domain_name }},DNS:www.{{ domain_name }}")) | sudo tee /etc/letsencrypt/csrs/{{ domain_name }}.csr"
          args:
            executable: /bin/bash
      

      This task generates a CSR for your domain, with the www subdomain added to the certificate as a SAN.

      You’ll continue to work in letsencrypt-issue.yml in the next step, so don’t close this file yet.

      You’ve written the Ansible tasks to generate the private key and CSR for your certificate. Next, you’ll work on the tasks that will begin the validation and issuance process.

      Step 4 — Starting the ACME Validation Process

      In this step, you’ll write a task to submit the Certificate Signing Request to Let’s Encrypt using the outputted files from the task documented in Step 3. This will return some challenge files, which you’ll need to serve on your web server in order to prove ownership of the domain name and subdomain for which you’re requesting a certificate.

      The following task will submit the CSR for your-domain. Add it to the end of your playbook:

      letsencrypt-issue.yml

      ...
        - name: "Begin Let's Encrypt challenges"
          letsencrypt:
            acme_directory: "{{ acme_directory }}"
            acme_version: "{{ acme_version }}"
            account_key_src: "{{ letsencrypt_account_key }}"
            account_email: "{{ acme_email }}"
            terms_agreed: 1
            challenge: "{{ acme_challenge_type }}"
            csr: "{{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr"
            dest: "{{ letsencrypt_certs_dir }}/{{ domain_name }}.crt"
            fullchain_dest: "{{ letsencrypt_certs_dir }}/fullchain_{{ domain_name }}.crt"
            remaining_days: 91
          register: acme_challenge_your_domain
      

      This task makes wide usage of the variables that you configured in Step 1. It registers a variable containing the ACME challenge files that you’ll use in the next step. You’ll need to manually adjust the name of the variable to contain your-domain, but with all . characters replaced with a _, as dots cannot be used in a variable name. For example, the variable for example.com would become acme_challenge_example_com.

      You’ll continue to work in letsencrypt-issue.yml in the next step, so don’t close this file yet.

      You’ve written a task to submit your CSR to Let’s Encrypt. Next, you will add a task to implement the ACME challenge files for finalization of the certificate validation process.

      Step 5 — Implementing the ACME Challenge Files

      In this step, you will write an Ansible task to read and implement the ACME challenge files. These files prove that you’re eligible to acquire a certificate for the requested domains and subdomains.

      The ACME challenge files must be served on a web server listening on port 80, at the /.well-known/acme-challenge/ path for the domain or subdomain that you’re requesting a certificate for. For example, in order to validate the certificate request for www.your-domain, the ACME challenge file will need to be accessible over the internet at the following path: http://www.your-domain/.well-known/acme-challenge.

      The method for serving these files at the required destinations will vary significantly depending on your current web server setup. However, in this guide, we will assume that you have a web server (as per the prerequisite tutorial) configured to serve files out of the /var/www/html directory. Therefore you may need to adjust the task accordingly in order to be compatible with your own web server setup.

      Firstly, add the following task that creates the .well-known/acme-challenge/ directory structure required to serve the files to the end of your playbook:

      letsencrypt-issue.yml

      ...
        - name: "Create .well-known/acme-challenge directory"
          file:
            path: /var/www/html/.well-known/acme-challenge
            state: directory
            owner: root
            group: root
            mode: u=rwx,g=rx,o=rx
      

      Make sure to adjust the path accordingly if you are using a directory other than /var/www/html to serve files with your web server.

      Next, you’ll implement the ACME challenge files that were saved into the acme_challenge_your-domain variable in Step 4 with the following task:

      letsencrypt-issue.yml

      ...
        - name: "Implement http-01 challenge files"
          copy:
            content: "{{ acme_challenge_your_domain['challenge_data'][item]['http-01']['resource_value'] }}"
            dest: "/var/www/html/{{ acme_challenge_your_domain['challenge_data'][item]['http-01']['resource'] }}"
            owner: root
            group: root
            mode: u=rw,g=r,o=r
          with_items:
          - "{{ domain_name }}"
          - "www.{{ domain_name }}"
      

      Note that you need to manually adjust the acme_challenge_your_domain variable name in the task to be set to the name of your ACME challenge variable, which is acme_challenge_ followed by your domain name, but with all . characters replaced with _. This Ansible task copies the ACME validation files from the variable into the .well-known/acme-challenge path on your web server. This will allow Let’s Encrypt to retrieve them in order to verify the ownership of the domain and your eligibility to acquire a certificate.

      You’ll continue to work in letsencrypt-issue.yml in the next step, so don’t close this file yet.

      You’ve written the Ansible tasks required to create the ACME validation directory and files. Next, you will complete the ACME verification process and acquire the signed certificate.

      Step 6 — Acquiring Your Certificate

      In this step, you’ll write a task to trigger Let’s Encrypt to verify the ACME challenge files that you submitted, which will allow you to acquire your signed certificate(s).

      The following task validates the ACME challenge files that you implemented in Step 5 and saves your signed certificates to the specified paths. Add it to the end of your playbook:

      letsencrypt-issue.yml

      ...
        - name: "Complete Let's Encrypt challenges"
          letsencrypt:
            acme_directory: "{{ acme_directory }}"
            acme_version: "{{ acme_version }}"
            account_key_src: "{{ letsencrypt_account_key }}"
            account_email: "{{ acme_email }}"
            challenge: "{{ acme_challenge_type }}"
            csr: "{{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr"
            dest: "{{ letsencrypt_certs_dir }}/{{ domain_name }}.crt"
            chain_dest: "{{ letsencrypt_certs_dir }}/chain_{{ domain_name }}.crt"
            fullchain_dest: "{{ letsencrypt_certs_dir }}/fullchain_{{ domain_name }}"
            data: "{{ acme_challenge_your_domain }}"
      

      Similarly to Step 4, this task makes use of the variables that you configured in Step 1. Once the task has completed, it will save the signed certificate to the specified paths, allowing you to begin using it for your application or service.

      Note that you’ll need to manually adjust the data value in the task to be set to the name of your ACME challenge variable, similarly to Step 5.

      Following is the full playbook showing each of the tasks you’ve added:

      letsencrypt-issue.yml

      - hosts: "host1"
        tasks:
      
        - name: "Create required directories in /etc/letsencrypt"
          file:
            path: "/etc/letsencrypt/{{ item }}"
            state: directory
            owner: root
            group: root
            mode: u=rwx,g=x,o=x
          with_items:
          - account
          - certs
          - csrs
          - keys
      
        - name: "Generate a Let's Encrypt account key"
          shell: "if [ ! -f {{ letsencrypt_account_key }} ]; then openssl genrsa 4096 | sudo tee {{ letsencrypt_account_key }}; fi"
      
        - name: "Generate Let's Encrypt private key"
          shell: "openssl genrsa 4096 | sudo tee /etc/letsencrypt/keys/{{ domain_name }}.key"
      
        - name: "Generate Let's Encrypt CSR"
          shell: "openssl req -new -sha256 -key /etc/letsencrypt/keys/{{ domain_name }}.key -subj "/CN={{ domain_name }}" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "n[SAN]nsubjectAltName=DNS:{{ domain_name }},DNS:www.{{ domain_name }}")) | sudo tee /etc/letsencrypt/csrs/{{ domain_name }}.csr"
          args:
            executable: /bin/bash
      
        - name: "Begin Let's Encrypt challenges"
          letsencrypt:
            acme_directory: "{{ acme_directory }}"
            acme_version: "{{ acme_version }}"
            account_key_src: "{{ letsencrypt_account_key }}"
            account_email: "{{ acme_email }}"
            terms_agreed: 1
            challenge: "{{ acme_challenge_type }}"
            csr: "{{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr"
            dest: "{{ letsencrypt_certs_dir }}/{{ domain_name }}.crt"
            fullchain_dest: "{{ letsencrypt_certs_dir }}/fullchain_{{ domain_name }}.crt"
            remaining_days: 91
          register: acme_challenge_your_domain
      
        - name: "Create .well-known/acme-challenge directory"
          file:
            path: /var/www/html/.well-known/acme-challenge
            state: directory
            owner: root
            group: root
            mode: u=rwx,g=rx,o=rx
      
        - name: "Implement http-01 challenge files"
          copy:
            content: "{{ acme_challenge_your_domain['challenge_data'][item]['http-01']['resource_value'] }}"
            dest: "/var/www/html/{{ acme_challenge_your_domain['challenge_data'][item]['http-01']['resource'] }}"
            owner: root
            group: root
            mode: u=rw,g=r,o=r
          with_items:
          - "{{ domain_name }}"
          - "www.{{ domain_name }}"
      
        - name: "Complete Let's Encrypt challenges"
          letsencrypt:
            acme_directory: "{{ acme_directory }}"
            acme_version: "{{ acme_version }}"
            account_key_src: "{{ letsencrypt_account_key }}"
            account_email: "{{ acme_email }}"
            challenge: "{{ acme_challenge_type }}"
            csr: "{{ letsencrypt_csrs_dir }}/{{ domain_name }}.csr"
            dest: "{{ letsencrypt_certs_dir }}/{{ domain_name }}.crt"
            chain_dest: "{{ letsencrypt_certs_dir }}/chain_{{ domain_name }}.crt"
            fullchain_dest: "{{ letsencrypt_certs_dir }}/fullchain_{{ domain_name }}"
            data: "{{ acme_challenge_your_domain }}"
      

      Save and close your file when you’re finished.

      You’ve added the task to complete the ACME challenges and acquire your signed certificate. Next, you’ll run the playbook against your Ansible host machine in order to run all of the actions.

      Step 7 — Running Your Playbook

      Now that you’ve written the playbook and all of the required tasks, you can run it against your Ansible host machine to issue the certificate.

      From your Ansible server, you can run the playbook using the ansible-playbook command:

      • ansible-playbook letsencrypt-issue.yml

      This will run the playbook, one task at a time. You’ll see output similar to the following:

      Output

      PLAY [host1] ********************************************************************************** TASK [Gathering Facts] ************************************************************************ ok: [host1] TASK [Create required directories in /etc/letsencrypt] **************************************** changed: [host1] => (item=account) changed: [host1] => (item=certs) changed: [host1] => (item=csrs) changed: [host1] => (item=keys) TASK [Generate a Let's Encrypt account key] *************************************************** changed: [host1] TASK [Generate Let's Encrypt private key] ***************************************************** changed: [host1] TASK [Generate Let's Encrypt CSR] ************************************************************* changed: [host1] TASK [Begin Let's Encrypt challenges] ********************************************************* changed: [host1] TASK [Create .well-known/acme-challenge directory] ******************************************** changed: [host1] TASK [Implement http-01 challenge files] ****************************************************** changed: [host1] => (item=your-domain) changed: [host1] => (item=www.your-domain) TASK [Complete Let's Encrypt challenges] ****************************************************** changed: [host1] PLAY RECAP ************************************************************************************ host1 : ok=9 changed=8 unreachable=0 failed=0

      If any errors are encountered while the playbook is running, these will be outputted for your review.

      Once the playbook has finished, your valid Let’s Encrypt certificate will be saved to the /etc/letsencrypt/certs directory on your host machine. You can then use this, along with the private key in /etc/letsencrypt/keys, to secure connections to your web server, mail server, etc.

      Let’s Encrypt certificates are valid for 90 days by default. You will receive renewal reminders via email to the address that you specified in Step 1. To renew your certificate, you can run the playbook again. Make sure to double check that any services using your certificate have picked up the new one, as sometimes you may need to manually install it, move it to a particular directory, or restart the service for it to properly adopt the new certificate.

      In this step, you ran your playbook which issued your valid Let’s Encrypt certificate.

      Conclusion

      In this article you wrote an Ansible playbook to request and acquire a valid Let’s Encrypt certificate.

      As a next step, you can look into using your new playbook to issue certificates for a large fleet of servers. You could even create a central ACME validation server that can issue certificates centrally and distribute them out to web servers.

      Finally, if you’d like to learn more about the ACME specification and Let’s Encrypt project, you may wish to review the following links:

      You may also like to view some other relevant Ansible tutorials:



      Source link

      How To Secure Apache with Let’s Encrypt on FreeBSD 12.0


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free TLS/SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps.

      In this tutorial, you will use Certbot to set up a TLS/SSL certificate from Let’s Encrypt on a FreeBSD 12.0 server running Apache as a web server. Additionally, you will automate the certificate renewal process using a cron job.

      Prerequisites

      Before you begin this guide you’ll need the following:

      • A FreeBSD 12.0 server that you can set up as you wish using this guide on How To Get Started with FreeBSD.

      • Apache installed by completing Step 1 of this FAMP stack tutorial.

      • An enabled firewall by using the firewall configuration step in this tutorial instructions.

      • Two DNS A Records that point your domain to the public IP address of your server. Our setup will use your-domain and www.your-domain as the domain names, both of which will require a valid DNS record. You can follow this introduction to DigitalOcean DNS for details on how to add the DNS records with the DigitalOcean platform. DNS A records are required because of how Let’s Encrypt validates that you own the domain for which it is issuing a certificate. For example, if you want to obtain a certificate for your-domain, that domain must resolve to your server for the validation process to work.

      Once these prerequisites are fulfilled you can start installing Certbot, the tool that will allow you to install Let’s Encrypt certificates.

      A Let’s Encrypt certificate ensures that users’ browsers can verify that the web server is secured by a trusted Certificate Authority. Communications with the web server are protected by encryption using HTTPS.

      In this step you’ll install the Certbot tool for your web server to make a request to the Let’s Encrypt servers in order to issue a valid certificate and keys for your domain.

      Run the following command to install the Certbot package and its Apache HTTP plugin:

      • sudo pkg install -y py36-certbot py36-certbot-apache

      Now that you’ve installed the package, you can move on to enable TLS connections in the web server.

      Step 2 — Enabling SSL/TLS connections in Apache HTTP

      By default any install of Apache HTTP will be serving content on port 80 (HTTP). The Listen 80 entry in the main httpd.conf configuration file confirms this. In order to allow HTTPS connections, you’ll need the default port to be 443. To add port 443 and to establish SSL/TLS connections you’ll enable the mod_ssl module in Apache HTTP.

      To find this module in the httpd.conf file, you’ll use grep with the -n flag to number the lines from the file in the specified path. Here you’ll find mod_ssl.so by running the following command:

      • grep -n 'mod_ssl.so' /usr/local/etc/apache24/httpd.conf

      As output you’ll receive the number for the line you need:

      /usr/local/etc/apache24/httpd.conf

      148 #LoadModule ssl_module libexec/apache24/mod_ssl.so
      

      To enable the module, you’ll remove the hashtag symbol at the beginning of the line.

      Using the line number from the previous command open the file with the following:

      • sudo vi +148 /usr/local/etc/apache24/httpd.conf

      This will take you directly to the correct line for editing.

      Edit the line to look like the following by pressing x:

      /usr/local/etc/apache24/httpd.conf

      #LoadModule session_dbd_module libexec/apache24/mod_session_dbd.so
      #LoadModule slotmem_shm_module libexec/apache24/mod_slotmem_shm.so
      #LoadModule slotmem_plain_module libexec/apache24/mod_slotmem_plain.so
      LoadModule ssl_module libexec/apache24/mod_ssl.so
      #LoadModule dialup_module libexec/apache24/mod_dialup.so
      #LoadModule http2_module libexec/apache24/mod_http2.so
      #LoadModule proxy_http2_module libexec/apache24/mod_proxy_http2.so
      

      Once you’ve removed the #, press :wq and then ENTER to close the file.

      You’ve enabled the SSL/TLS capabilities in Apache HTTP. In the next step you’ll configure the virtual hosts in Apache HTTP.

      Step 3 — Enabling and Configuring Virtual Hosts

      A virtual host is a method by which several websites can concurrently and independently live in the same server using the same Apache HTTP installation. Certbot requires this setup to place specific rules within the configuration file (virtual host) for the Let’s Encrypt certificates to work.

      To begin, you’ll enable virtual hosts in Apache HTTP. Run the following command to locate the directive in the file:

      • grep -n 'vhosts' /usr/local/etc/apache24/httpd.conf

      You’ll see the line number in your output:

      Output

      508 #Include etc/apache24/extra/httpd-vhosts.conf

      Now use the following command to edit the file and remove # from the beginning of that line:

      • sudo vi +508 /usr/local/etc/apache24/httpd.conf

      As before, hit x to delete # from the beginning of the line to look like the following:

      /usr/local/etc/apache24/httpd.conf

      ...
      # User home directories
      #Include etc/apache24/extra/httpd-userdir.conf
      
      # Real-time info on requests and configuration
      #Include etc/apache24/extra/httpd-info.conf
      
      # Virtual hosts
      Include etc/apache24/extra/httpd-vhosts.conf
      
      # Local access to the Apache HTTP Server Manual
      #Include etc/apache24/extra/httpd-manual.conf
      
      # Distributed authoring and versioning (WebDAV)
      #Include etc/apache24/extra/httpd-dav.conf
      ...
      

      Then press :wq and ENTER to save and quit the file.

      Now that you’ve enabled virtual hosts in Apache HTTP you’ll modify the default virtual host configuration file to replace the example domains with your domain name.

      You’ll now add a virtual host block to the httpd-vhosts.conf file. You’ll edit the file and remove the two existing VirtualHost blocks, after the comments block at line 23, with the following command:

      • sudo vi +23 /usr/local/etc/apache24/extra/httpd-vhosts.conf

      After opening the file remove the two existing VirtualHost configuration blocks, then add the following block with this specific configuration:

      /usr/local/etc/apache24/extra/httpd-vhosts.conf

      <VirtualHost *:80>
          ServerAdmin your_email@your_domain.com
          DocumentRoot "/usr/local/www/apache24/data/your_domain.com"
          ServerName your_domain.com
          ServerAlias www.your_domain.com
          ErrorLog "/var/log/your_domain.com-error_log"
          CustomLog "/var/log/your_domain.com-access_log" common
      </VirtualHost>
      

      In this block you’re configuring the following:

      • ServerAdmin: This is where the email from the person in charge of that particular site is placed.
      • DocumentRoot: This directive defines where the files for the specific site will be placed and be read from.
      • ServerName: This is for the domain name of the site.
      • ServerAlias: Similar to ServerName but placing www. before the domain name.
      • ErrorLog: This is where the error log path is declared. All error messages will be written in the file specified in this directive.
      • CustomLog: Similar to ErrorLog but this time the file is the one collecting all the access logs.

      Finally you’ll create the directory where the site will be placed. This path has to match the one you’ve declared in the DocumentRoot directive in the httpd-vhosts.conf file.

      • sudo mkdir /usr/local/www/apache24/data/your_domain.com

      Now change the permissions of the directory so the Apache HTTP process (running as the www user) can work with it:

      • sudo chown -R www:www /usr/local/www/apache24/data/your_domain.com

      You’ve used chown to change the ownership with the -R flag to make the action recursive. The user and group are set by the www:www.

      You’ve enabled virtual hosts in Apache HTTP. You’ll now enable the rewrite module.

      Step 4 — Enabling the Rewrite Module

      Enabling the rewrite module within Apache HTTP is necessary to make URLs change, for example when redirecting from HTTP to HTTPS.

      Use the following command to find the rewrite module:

      • grep -n 'rewrite' /usr/local/etc/apache24/httpd.conf

      You’ll see output similar to:

      Output

      180 #LoadModule rewrite_module libexec/apache24/mod_rewrite.so

      To enable the module you will now remove # from the beginning of the line:

      • sudo vi +180 /usr/local/etc/apache24/httpd.conf

      Edit your file to look like the following by hitting x to delete # from the start of the line:

      /usr/local/etc/apache24/httpd.conf

      #LoadModule actions_module libexec/apache24/mod_actions.so
      #LoadModule speling_module libexec/apache24/mod_speling.so
      #LoadModule userdir_module libexec/apache24/mod_userdir.so
      LoadModule alias_module libexec/apache24/mod_alias.so
      LoadModule rewrite_module libexec/apache24/mod_rewrite.so
      LoadModule php7_module        libexec/apache24/libphp7.so
      
      # Third party modules
      IncludeOptional etc/apache24/modules.d/[0-9][0-9][0-9]_*.conf
      
      <IfModule unixd_module>
      

      Save and exit this file.

      You’ve now finished setting up the necessary configurations in Apache.

      Step 5 — Obtaining a Let’s Encrypt Certificate

      Certbot provides a variety of ways to obtain SSL certificates through various plugins. The apache plugin will take care of reconfiguring Apache HTTP. To execute the interactive installation and obtain a certificate that covers only a single domain, run the following certbot command:

      • sudo certbot --apache -d your-domain -d www.your-domain

      If you want to install a single certificate that is valid for multiple domains or subdomains, you can pass them as additional parameters to the command, tagging each new domain or subdomain with the -d flag. The first domain name in the list of parameters will be the base domain used by Let’s Encrypt to create the certificate. For this reason, pass the base domain name first, followed by any additional subdomains or aliases.

      If this is your first time running certbot on this server, the client will prompt you to enter an email address and agree to the Let’s Encrypt terms of service. After doing so, certbot will communicate with the Let’s Encrypt server, then run a challenge to verify that you control the domain you’re requesting a certificate for.

      If the challenge is successful, Certbot will ask how you’d like to configure your HTTPS settings:

      Output

      . . . Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

      You will also be able to choose between enabling both HTTP and HTTPS access or forcing all requests to redirect to HTTPS. For better security, it is recommended to choose the option 2: Redirect if you do not have any special need to allow unencrypted connections. Select your choice then hit ENTER.

      This will update the configuration and reload Apache HTTP to pick up the new settings. certbot will wrap up with a message telling you the process was successful and where your certificates are stored:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /usr/local/etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /usr/local/etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on yyyy-mm-dd. To obtain a new or tweaked version of this certificate in the future, simply run certbot again. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /usr/local/etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Your certificates are now downloaded, installed, and configured. Try reloading your website using https:// and notice your browser’s security indicator. It’ll represent that the site is properly secured, usually with a green lock icon. If you test your server using the SSL Labs Server Test, it will get an A grade.

      Certbot has made some important configuration changes. When it installs the certificates in your web server it has to place them in specific paths. If you now read the content in the httpd-vhosts.conf file you’ll observe a few changes made by the Certbot program.

      For example in the <VirtualHost *:80> section the redirect rules (if chosen) are placed at the bottom of it.

      /usr/local/etc/apache24/extra/httpd-vhosts.conf

      RewriteEngine on
      RewriteCond %{SERVER_NAME} =www.your_domain.com [OR]
      RewriteCond %{SERVER_NAME} =your_domain.com
      RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
      

      Certbot has also created a file called httpd-vhosts-le-ssl.conf where the configuration for the certificates on Apache has been placed:

      /usr/local/etc/apache24/extra/httpd-vhosts-le-ssl.conf

      <IfModule mod_ssl.c>
      <VirtualHost *:443>
          ServerAdmin your_email@your_domain.com
          DocumentRoot "/usr/local/www/apache24/data/your_domain.com"
          ServerName your_domain.com
          ServerAlias www.your_domain.com
          ErrorLog "/var/log/your_domain.com-error_log"
          CustomLog "/var/log/your_domain.com-access_log" common
      
      Include /usr/local/etc/letsencrypt/options-ssl-apache.conf
      SSLCertificateFile /usr/local/etc/letsencrypt/live/your_domain.com/fullchain.pem
      SSLCertificateKeyFile /usr/local/etc/letsencrypt/live/your_domain.com/privkey.pem
      </VirtualHost>
      </IfModule>
      

      Note: If you would like to make changes to the use of cipher suites on sites with Let’s Encrypt certificates, you can do so in the /usr/local/etc/letsencrypt/options-ssl-apache.conf file.

      Having obtained your Let’s Encrypt certificate, you can now move on to set up automatic renewals.

      Step 6 — Configuring Automatic Certificate Renewal

      Let’s Encrypt certificates are valid for 90 days, but it’s recommended that you renew the certificates every 60 days to allow a margin of error. Because of this, it is best practice to automate this process to periodically check and renew the certificate.

      First, let’s examine the command that you will use to renew the certificate. The certbot Let’s Encrypt client has a renew command that automatically checks the currently installed certificates and tries to renew them if they are less than 30 days away from the expiration date. By using the --dry-run option, you can run a simulation of this task to test how renew works:

      • sudo certbot renew --dry-run

      A practical way to ensure your certificates will not get outdated is to create a cron job that will periodically execute the automatic renewal command for you. Since the renewal first checks for the expiration date and only executes the renewal if the certificate is less than 30 days away from expiration, it is safe to create a cron job that runs every week or even every day.

      The official Certbot documentation recommends running cron twice per day. This will ensure that, in case Let’s Encrypt initiates a certificate revocation, there will be no more than half a day before Certbot renews your certificate.

      Edit the crontab to create a new job that will run the renewal twice per day. To edit the crontab for the root user, run:

      Place the following configuration in the file so that, twice a day, the system will look for renewable certificates and will renew them if they need to:

      SHELL=/bin/sh
      PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin
      # Order of crontab fields
      # minute    hour    mday    month   wday    command
        0         0,12    *       *       *       /usr/local/bin/certbot renew
      

      In the first two lines you are declaring the environment variables, hence where the executable paths are found and what shell they’re executing on. You then indicate the time frames you’re interested in and the command to execute.

      With this short set of instructions you’ve configured the automatic renewal of certificates.

      Conclusion

      In this tutorial, you’ve installed the Let’s Encrypt client certbot, downloaded SSL certificates for a domain, configured Apache to use these certificates, and set up automatic certificate renewal. For further information see Certbot’s documentation.



      Source link