[PYTHON] SSL-enable multiple sites on one server with nginx and Let's Encrypt

Here, I will introduce how to SSL-enable a site using Let's Encrypt and nginx, and what I did when I operated multiple sites on one server using the nginx function as it is and all of them were SSL-enabled. To do. We have released the nginx configuration file, so please refer to here for details. https://github.com/TakuKobayashi/ActivatingNginxConf

What is SSL

SSL is a mechanism for communicating by encrypting data. If you enable SSL, you will be able to use URLs such as https: // (for HTTP) and wss: // (for Websocket) as shown below. https.png

For details, see here, etc.

SSL certificate

A SSL certificate </ b> </ font> is required to make the server SSL-enabled and able to communicate. SSL certificates are commonly referred to as Certificate Authorities and are trusted. You need to pay money from the three parties to get a certificate issued. The cost is tens of thousands to hundreds of thousands of yen per year </ font>. It is high...

What is Let's Encrypt?

Let's Encrypt is a certificate authority (organization / project) that issues SSL certificates for free </ font>.

Get an SSL certificate using Let's Encrypt

To get an SSL certificate using Let's Encrypt, Python 2.7 or higher must be installed, so install Python 2.7 or higher. I installed Python after putting in Pyenv so that I could switch between Python versions.

Install python

Install the libraries required to use Pyenv (for CentOS)

yum install gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel bzip2 sqlite
zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel

Install Pyenv

git clone git://github.com/yyuu/pyenv.git

Pass the path to Pyenv

cd pyenv/
vi ~/.bashrc

Find the location of pyenv in .bashrc (here in / app / library / pyenv) and write the following and pass it through.

export PYENV_ROOT="/app/library/pyenv"
if [ -d "${PYENV_ROOT}" ]; then
    export PATH=${PYENV_ROOT}/bin:$PATH
    eval "$(pyenv init -)"
fi

Enable the set path.

source ~/.bashrc

And

pyenv

If there are no errors, the path has passed.

Find out which version of Python you can install

pyenv install --list

Install Python using Pyenv

Here we will install Python 2.7.13

pyenv install 2.7.13

Make the installed Python available

pyenv global 2.7.13

with this

python

Is executed, and if no error occurs, the installation is complete.

Get an SSL certificate from Let's Encrypt

Create a dedicated path to verify the certificate

The next time you use certbot to get a certificate, it will check to see if the server exists. You need to create a dedicated path to accommodate this check. This time, we will deal with it by creating a directory under the document root. Use Nginx For Nginx, the document root can be found in [nginx root directory] /conf.d/default.conf. In this case, it is the content described below.

 location / {
   root   /usr/share/nginx/html;
   index  index.html index.htm;
 }

Therefore, create an empty directory to set the path from the document root as shown below.

mkdir [nginx root directory]/html/.well-known

Next, edit [nginx root directory] /nginx.conf so that the created path can be used on the nginx side.

http{
  ...
  server {
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
  }
}

Then restart nginx for the changes to apply.

service nginx restart

Install certbot (using Git)

certbot is a tool provided by Let ’s Encrypt and is an agent (client) that communicates with Let ’s Encrypt. There is a method that does not use Git, but this time I will install it by the method that uses Git.

git clone https://github.com/certbot/certbot

Get a certificate using certbot

cd certbot/
./certbot-auto certonly

Then, there are the following announcements, so we will make various settings.

How would you like to authenticate with the ACME CA?

1: Spin up a temporary webserver (standalone)

2: Place files in webroot directory (webroot)

Select the appropriate number [1-2] then enter: 2
Enter email address (used for urgent renewal and security notices) (Enter 'c' to

cancel):[mail address]

Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf. You must agree
in order to register with the ACME server at

https://acme-v01.api.letsencrypt.org/directory

(A)gree/(C)ancel: A



Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and

our work to encrypt the web, protect its users and defend digital rights.

(Y)es/(N)o: Y
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):[Domain name](Ifyouwanttosetmultipledomains,listthemseparatedbycommas.Hereue4yochi.Settonet)
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ue4yochi.net

Select the webroot for ue4yochi.net:

1: Enter a new webroot

Press 1 [enter] to confirm the selection (press 'c' to cancel): 1
Input the webroot for ue4yochi.net: (Enter 'c' to cancel):[The path of the directory created above]

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/ue4yochi.net/fullchain.pem. Your cert will
   expire on 2017-10-03. To obtain a new or tweaked version of this
   certificate in the future, simply run certbot-auto again. To
   non-interactively renew all of your certificates, run
   "certbot-auto 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

Above, In / etc / letsencrypt / live / [domain name] / </ font> If you have the fullchain.pem </ font> and privkey.pem </ font> files, you have obtained the certificate.

Apply the obtained certificate and enable SSL.

Edit the nginx.conf file as follows:

http{
  ...
  server {
    listen 443 ssl;
        server_name domain A;
    ...
    ssl_certificate     /etc/letsencrypt/live/[Domain name]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[Domain name]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }
}

Then restart nginx for the changes to apply.

service nginx restart

If the server is running now https://ドメインAにブラウザでアクセスすることができれば、SSL化完了です。

Operate multiple sites on one server using nginx, and make all SSL

The above SSL support in nginx can be applied even when trying to operate multiple sites on one server. I don't want to spend too much money, so it would be nice if I could run multiple sites on one server ♪ Moreover, I'd be happy if all of them could support SSL ♪ However, one or more domains are required to operate multiple sites on one server </ b> </ font>.

Setting to operate multiple sites (different domains) on one server with nginx

At this point, the settings for one site have already been completed. First, create a checkable path like the first one so that you can get a certificate for the second site with certbot. You can use the same one as the first one, but you need to set each one. Describe the nginx configuration file as follows.

http{
  ...
  server {
    listen 443 ssl;
        server_name domain A;
    ...
    ssl_certificate     /etc/letsencrypt/live/[Domain name]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[Domain name]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }

  server {
    listen 443 ssl;
        server_name domain B;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
}

Then restart nginx for the changes to apply.

service nginx restart

Issuance of SSL certificate that can be used on multiple sites

Enter the following in the same way as the above certificate acquisition procedure.

./certbot-auto certonly

In this case, if you have already obtained a certificate and you want to acquire a new domain and add a certificate, you can apply it by executing the same procedure. Continue reading the announcements that came out,

...
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel):Domain A,Domain B,...
...

When the above questions are asked, it is possible to issue certificates corresponding to multiple domains by arranging multiple types of domains separated by ,. At the time of setting, you will be asked where to check each, but it is OK because you specify the same one.

Apply the certificate obtained by nginx to each.

Since the certificate corresponding to multiple domains is set in the same file in the same location as the first case above, modify nginx.conf as follows so that it will be the same when applying to multiple domains. I will.

http{
  ...
  server {
    listen 443 ssl;
        server_name domain A;
    ...
    ssl_certificate     /etc/letsencrypt/live/[Domain name]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[Domain name]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }

  server {
    listen 443 ssl;
        server_name domain B;
    ssl_certificate     /etc/letsencrypt/live/[Domain name]/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/[Domain name]/privkey.pem;
    ...
    location ^~ /.well-known/acme-challenge/ {
      root /usr/share/nginx/html/.well-known;
    }
    ...
    location / {
      ...
    }
  }
}

Then restart nginx for the changes to apply.

service nginx restart

If the server is running now https://ドメインA and https://ドメインB If you can access with a browser, both are SSL-enabled.

Supplement

If you set the above one server to be able to see multiple different domains, the upper setting described in nginx.conf will take precedence. For example, if you enter the following URL https://[IPアドレス] Or https://[DNS名] If you enter, the domain A site is displayed.

Automatic renewal of SSL certificate

The expiration date of the certificate obtained by Let's Encrypt is 3 months </ font>. Therefore, it is necessary to renew the certificate before it expires. If you want to renew the certificate automatically, you can renew it automatically by setting cron.

crontab -e

Open the cron settings with and set as follows.

0 4 1 * * [certbot-pass with auto]/certbot-auto renew && service nginx reload

Now you can automatically renew the SSL certificate and reflect the settings in nginx. (The above process checks once a month for certificate renewal)

reference

Automatically renew Let's Encrypt (Certbot) SSL certificate in Nginx + reverse proxy environment without stopping the web server --Qiita The story of trying to Let's Encrypt while using Nginx as a reverse proxy-Qiita Install Let's Encrypt on a server running on Nginx and issue an SSL certificate --UTALI How to set SSL certificate issuance and automatic renewal with Let's Encrypt + Nginx --Qiita The speed of light WEB server (nginx) is SSL and HTTP / 2 by let's encrypt. In addition, set the security evaluation to A +. --Qiita Publishing a secure website with Let ’s Encrypt SSL certificate-Sakura Knowledge