web-dev-qa-db-fra.com

L'ajout de certificats SSL au conteneur de docker NGINX ne fonctionne pas

J'essaie d'ajouter des certificats SSL (générés avec LetsEncrypt) à mon nginx. Nginx est construit à partir d'un fichier docker-compose dans lequel je crée un volume de mon hôte au conteneur afin que les conteneurs puissent accéder aux certificats et à la clé privée.

volumes:
  - /etc/nginx/certs/:/etc/nginx/certs/

Lorsque le conteneur nginx démarre et échoue avec l'erreur suivante 

[emerg] 1#1: BIO_new_file("/etc/nginx/certs/fullchain.pem") failed 
(SSL: error:02001002:system library:fopen:No such file or 
directory:fopen('/etc/nginx/certs/fullchain.pem','r') 
error:2006D080:BIO routines:BIO_new_file:no such file)

Mon fichier de configuration nginx ressemble à ceci:

server {
    listen 80;
    server_name server_blah www.server_blah;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name server_blah;
    ssl_certificate      /etc/nginx/certs/fullchain.pem;
    ssl_certificate_key  /etc/nginx/certs/privkey.pem;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
}

Qu'est-ce que je manque/fais mal?

3
cathaldcronin1

Finalement, j'ai réussi à résoudre ce problème et à répéter le processus sur mon site de développement et de production pour que les certificats SSL fonctionnent! 

Désolé pour la longueur du post!

Dans ma configuration, j’ai installé docker-docker-setup sur une machine Ubuntu 16.

Quiconque rencontre ce problème, je vais détailler les étapes que j'ai effectuées.

  1. Allez dans le répertoire où habite votre code

    cd /opt/example_dir/

  2. Créez un répertoire pour letsencrypt et son site.

    Sudo mkdir -p /opt/example_dir/letsencrypt/letsencrypt-site

  3. Créez le fichier barebones docker-compose.yml à partir du répertoire letsencrypt.

    Sudo nano /opt/example_dir/letsencrypt/docker-compose.yml

Ajoutez ce qui suit:

    version: '2'

        services:
            image: nginx:latest
            ports:
              - "80:80"
            volumes:
              - ./nginx.conf:/etc/nginx/conf.d/default.conf
              - ./letsencrypt-site:/usr/share/nginx/html
            networks:
              - docker-network

        networks:
          docker-network:
            driver: bridge

* This will pull down the latest nginx version
* Expose port 80 
* Mount a config file (that i'll create later) 
* Maps the site directory so that we can have a simple test index.html for when 

nous commençons le conteneur nginx simple.

  1. Créez un fichier nginx.conf dans /opt/example_dir/letsencrypt

    Sudo nano /opt/example_dir/letsencrypt/nginx.conf

Mettez ce qui suit dedans

    server {
      listen 80;
      listen [::]:80;
      server_name example_server.com;

      location ~ /.well-known/acme-challenge {
          allow all;
          root /usr/share/nginx/html;
      }

      root /usr/share/nginx/html;
      index index.html;
    }

* This listens for requests on port 80 for the server with name example_server.com
* Gives the Certbot agent access to ./well-known/acme-challenge
* Sets the default root and file
  1. Créez ensuite un fichier index.html dans /opt/example_dir/letsencrypt/letsencrypt-site

Sudo nano /opt/example_dir/letsencrypt/letsencrypt-site/index.html

Ajoutez ce qui suit 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>LetsEncrypt Setup</title>
</head>
<body>

    <p>Test file for our http nginx server</p>
</body>
</html>

#### Toutes les pièces sont en place pour le conteneur nginx de base!

  1. Nous démarrons maintenant le conteneur nginx.

    cd /opt/example_dir/letsencrypt
    Sudo docker-compose up -d
    

Le conteneur nginx étant opérationnel, accédez à l'URL que vous avez définie et vous devriez obtenir la page de test index.html. À ce stade, nous sommes prêts à exécuter la commande certbot pour générer des certificats.

  1. Exécutez ce qui suit pour générer des certificats remplaçant --email par votre email 

    Sudo docker run -it --rm \
    -v /docker-volumes/etc/letsencrypt:/etc/letsencrypt \
    -v /docker-volumes/var/lib/letsencrypt:/var/lib/letsencrypt \
    -v /opt/example_dir/letsencrypt/letsencrypt-site:/data/letsencrypt \
    -v "/docker-volumes/var/log/letsencrypt:/var/log/letsencrypt" \
    certbot/certbot \
    certonly --webroot \
    --email [email protected] --agree-tos --no-eff-email \
    --webroot-path=/data/letsencrypt \
    -d example.com
    
    • Exécutez le menu fixe en mode interactif pour pouvoir voir la sortie.
    • Quand il aura fini de générer des certificats, il se supprimera.
    • Il montera 4 volumes:
      1. Le dossier letsencrypt où les certs sont stockés /
      2. Un dossier lib
      3. Cartes notre dossier de site
      4. Mappe un chemin de journalisation 
    • Il accepte de ToS
    • Spécifie le chemin Web racine
    • Spécifiez l'adresse du serveur pour lequel vous souhaitez générer des certificats.

Si cette commande a fonctionné correctement, nous avons généré des certificats pour ce serveur Web. Nous pouvons maintenant les utiliser sur notre site de production et configurer nginx pour qu’il utilise le code SSL et utilise ces certificats!

  1. Arrêtez le conteneur nginx

    cd /opt/example_dir/letsencrypt/
    Sudo docker-compose down
    

Configuration du conteneur nginx de production

La structure de répertoire devrait ressembler à ceci maintenant. Où vous avez votre projet de code/application Web, puis le dossier letsencrypt que nous avons créé ci-dessus.

/opt/example_dir
             / -> project_folder
             / -> letsencrypt
  1. Créer un dossier appelez dh-param

    Sudo mkdir -p /opt/example_dir/project_folder/dh-param
    
  2. Générer une clé DH 

    Sudo openssl dhparam -out /opt/example_dir/project_folder/dh-param/dhparam-2048.pem 2048
    
  3. Mettez à jour les fichiers docker-compose.yml et nginx.conf dans /opt/example_dir/project_folder

Le dossier projet_folder étant le lieu de vie de mon code source, je crée ici un fichier de configuration de production pour nginx et met à jour le fichier docker-compose.yml afin de monter ma clé de configuration nginx, dh-pharam ainsi que les certificats créés précédemment.

service nginx dans le menu fixe

    nginx:
        image: nginx:1.11.3
        restart: always
        ports:
          - "80:80"
          - "443:443"
          - "8000:8000"
        volumes:
          - ./nginx.conf:/etc/nginx/conf.d/default.conf
          - ./dh-param/dhparam-2048.pem:/etc/ssl/certs/dhparam-2048.pem
          - /docker-volumes/etc/letsencrypt/live/exampleserver.com/fullchain.pem:/etc/letsencrypt/live/exampleserver.com/fullchain.pem
          - /docker-volumes/etc/letsencrypt/live/exampleserver.com/privkey.pem:/etc/letsencrypt/live/exampleserver.com/privkey.pem
        networks:
          - docker-network

        volumes_from:
          - flask
        depends_on:
          - flask
          - falcon
        links:
          - datastore

nginx.conf dans project_folder

error_log /var/log/nginx/error.log warn;

server {
    listen 80;
    listen [::]:80;

    server_name exampleserver.com

    location / {
        rewrite ^ https://$Host$request_uri? permanent;
    }

    #for certbot challenges (renewal process)
    location ~ /.well-known/acme-challenge {
        allow all;
        root /data/letsencrypt;
    }
}

#https://exampleserver.com
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name exampleserver.com;

    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/exampleserver.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/exampleserver.com/privkey.pem;

    ssl_buffer_size 8k;

    ssl_dhparam /etc/ssl/certs/dhparam-2048.pem;

    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_prefer_server_ciphers on;

    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

    ssl_ecdh_curve secp384r1;
    ssl_session_tickets off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8;


    # Define the specified charset to the “Content-Type” response header field
    charset utf-8;
}

À ce stade, tout est configuré! (enfin)

  1. Spin up le conteneur de docker. 

    cd /opt/example_dir/project_folder
    Sudo docker-compose up -d
    
    # Check the docker log with:
    Sudo docker logs -f -t  
    

Je sais que c'est beaucoup d'étapes, mais c'est ce que j'ai fait, cela a fonctionné pour moi et j'espère que cela aidera quelqu'un d'autre.

2
cathaldcronin1

J'ai exactement le même problème en ce moment. Mêmes codes d'erreur.

J'ai essayé différentes choses sur mes fichiers .pem:

  • Modification des autorisations (chmod) en: .____.
    • 777
    • 755
    • 600
  • Changer le propriétaire (chown) en:
    • nginx (utilisateur défini dans nginx.conf)
    • root
  • Changer l'emplacement en:
    • / etc/ssl/certs
    • / etc/nginx/ssl
    • / etc/letsencrypt/live
  • Changer le montage du docker en: .____.
    • ro (en lecture seule)
    • rw (readwrite)

Malheureusement, aucune de ces solutions n'a fonctionné pour moi.

Il semble vraiment que nginx ne puisse pas trouver les fichiers même si je suis en mesure de les lister (ls) lorsque je me connecte au terminal conteneur.

Pour donner plus de détails, j'utilise Docker sur un NAS Synology DS918 +.

J'espère que cela aidera à trouver la solution! Je vais expérimenter et essayer diverses choses, je reviendrai si je réussis à faire en sorte que cela fonctionne!

0
Kaybi