docker deployment nginx under centos7 using let's encrypt free certificate

Keywords: Nginx Docker SSL PHP

Large-brand providers'SSL certificates are not cheap. They may not be much for large companies, but they are expensive for small companies and individuals. Now Let's Encrypt, a free SSL service provider, is definitely a good news for small companies or developers.

Prerequisite

  1. Have a domain name, such as mydemo.com (for domestic hosts, also need to be filed through ICP)
    Create an A record in the domain name server pointing to the IP address of the cloud host. For example, demo.mydemo.com points to the IP address of xxx. xxx. xxx. XXXX until the newly created domain name resolution can be resolved on the public network.
    It is said that domestic domain name providers support letsencrypt very poorly, but after experimentation, at least at this stage, the domain name resolved by dnspod has not encountered problems.
  2. Docker and docker-compose have some foundation, and the nginx environment has been deployed with docker

Installation through certbot script

Without special circumstances, certbot scripting is preferred.

Since the validity of letsencrypt certificate is only 90 days, if it needs to be used for a long time, it is necessary to extend the application before it expires. With the certbot scripting tool, the script for deferred application can be written to a timed task to complete automatically, which is very convenient.

1. Install the certbot tool

yum install -y epel-release
yum install -y certbot

2. Application for Certificate by certbot Order

# Usage: certbot certonly -- webroot-w [Web site directory] - d [site domain name] - m [contact email address] -- agree-tos
sudo certbot certonly --webroot -w /webser/www/blog -d mydemo.com -m li_xxxxx@163.com --agree-tos

Note: The contact email address should be true and valid. letsencrypt will send a notice email before the certificate expires. After successful application, the following Congratulations information will be displayed

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/mydemo.com/fullchain.pem. Your cert will
   expire on 2017-03-20. 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"
 - 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

The certificate is stored in:

ll /etc/letsencrypt/live/mydemo.com/

#User certificate                                   
cert.pem -> ../../archive/mydemo.com/cert1.pem
#Intermediate certificate                                    
chain.pem -> ../../archive/mydemo.com/chain1.pem
#Certificate chain.pem + cert.pem    
fullchain.pem -> ../../archive/mydemo.com/fullchain1.pem
#Certificate private key
privkey.pem -> ../../archive/mydemo.com/privkey1.pem

3. Check the validity of the order

openssl x509 -noout -dates -in /etc/letsencrypt/live/mydemo.com/cert.pem

4. Setting Timing Tasks to Update Certificates Automatically

The letsencrypt certificate is valid for 90 days, but can be updated with scripts.

#Configure crontab, update certificate at 1:5 a month, and restart docker container
00 05 01 * * sudo /usr/bin/certbot renew --quiet && sudo docker restart nginx

Note: The website must be accessible when updating certificates

5. Generating Perfect Forward Security (PFS) Key Values

PFS (perfect forward secrecy), Chinese can be called full forward secrecy. A key is required to access only the data protected by it; the elements used to generate the key are replaced one after another, and no other keys can be generated; a key is cracked without affecting the security of other keys.

#Create directory
mkdir /etc/ssl/private/ -p
#Executive order
cd /etc/ssl/private/
openssl dhparam 2048 -out dhparam.pem

6. Mount the certificate directory into the nginx container

I use docker-compose to manage containers. Here's the nginx choreography information in my docker-compse.yml file

php-fpm:
  build: docker.io/php:7.1.8-fpm
  container_name: php-fpm
  volumes:
    - /webser/www:/var/www/html
    - /etc/hosts:/etc/hosts
    - /webser/etc/php:/usr/local/etc/php/conf.d
  ports:
    - "9000:9000"      
nginx:
  image: docker.io/nginx
  container_name: nginx
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - /webser/www:/var/www/html
    - /webser/etc/nginx:/etc/nginx/conf.d
    - /webser/logs/nginx:/var/log/nginx
    - /etc/ssl:/etc/ssl
    - /etc/letsencrypt:/etc/letsencrypt
  links:
    - php-fpm

You can also mount containers with the docker command

docker run -d -v /etc/ssl:/etc/ssl -v /etc/letsencrypt:/etc/letsencrypt --name nginx docker.io/nginx

7. Configuration of nginx

server {
    listen 443 ssl http2;
    server_name fungli.top;
    access_log  /var/log/nginx/access-blog.log main;
    error_log /var/log/nginx/error-blog.log warn;
    root /var/www/html/blog/;
    index  index.html index.htm index.php;

    # File generated by letsencrypt
    ssl_certificate /etc/letsencrypt/live/mydemo.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydemo.com/privkey.pem;

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

    ssl_dhparam /etc/ssl/private/dhparam.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    # Generally recommended ssl_ciphers: https://wiki.mozilla.org/Security/Server_Side_TLS
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';
    ssl_prefer_server_ciphers on;

    location ~ \.php  {
                root /var/www/html/blog;
        include fastcgi_params;
        fastcgi_pass php-fpm:9000;
        fastcgi_split_path_info ^(.+\.php)(.*)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

    }

    location ~* ^.+\.(jpg|jpeg|gif|png|bmp|css|js|swf)$ {
        access_log off;
        #break;
    }

}

Posted by Nymphetamine on Tue, 25 Dec 2018 13:09:06 -0800