How to install SSL Certificate and enable Https on Magento 2 / NGINX

The main issue I faced when trying to enable Https on Magento 2 (NGINX) with Let’s Encrypt was getting a ‘Failed authorization procedure’ during the ACME challenge.

During the certification creation, the bot asks you to specify the root directory of your web folder. For me it was obvious that this would be Magento’s directory. However, when the bot tries to access the files it generated using my shop URL (something like: http://mystore.com/.well-known/acme-challenge/Ljkdslfjfewl2323kjhlkdsfjl324ERkhdpqu20IUDLkq), it gets a 404 from Magento.

If you want to avoid this error, carefully follow the steps below.

First, let’s install certbot

$ apt-get install certbot

Quick version check (for fun)

$ certbot — version
certbot 0.27.0

Then, generate the certificate with the following command. You’ll be prompted with some questions.

$ certbot certonly --webrootSaving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices) (Enter ‘c’ to
cancel):

Enter your email and accept the ToS.

Please enter in your domain name(s) (comma and/or space separated) (Enter ‘c’
to cancel):

Enter your domain name, example : mystore.com

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mystore.com
Input the webroot for mystore.com: (Enter 'c' to cancel):

/!\ Here is the tricky part. You should not enter Magento root directory (mine was /var/www/html/magento2). Instead, you can either create a new directory in /var/www OR, like me, simply specify /var/www/html as the webroot for your store.

Keep “/var/www/html” in mind because we’ll use it in the NGINX configuration file.

As we have not yet correctly configured NGINX, certbot verification will fail. But don’t worry, let’s fix it.

$ vi /etc/nginx/snippets/letsencrypt-acme-challenge.conf

And add the following:

location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/html;
}
location = /.well-known/acme-challenge/ {
return 404;
}

Have you paid attention to the value of ‘root’?

It needs to be the same value as the webroot folder you’ll specify later during the certbot procedure.

Let’s now update our NGINX configuration.

$ vi /etc/nginx/sites-enabled/magento

Add the snippet.

upstream fastcgi_backend {
server unix:/run/php/php7.2-fpm.sock;
}

server {

listen 80;
server_name mystore.com;
set $MAGE_ROOT /var/www/html/magento2;
include /var/www/html/magento2/nginx.conf.sample;
# Include location directive for Let's Encrypt ACME Challenge
include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
}

Test your NGINX configuration and restart the server.

$ nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ service nginx restart

Make sure it’s running correctly by checking the status.

$ service nginx status● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-05-09 18:42:54 UTC; 13s ago
Docs: man:nginx(8)
Process: 31513 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
Process: 16816 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS)
Process: 31525 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 31514 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 31528 (nginx)
Tasks: 3 (limit: 2361)
CGroup: /system.slice/nginx.service
├─31528 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─31529 nginx: worker process
└─31530 nginx: worker process
May 09 18:42:54 ubuntu1804 systemd[1]: Starting A high performance web server and a reverse proxy server...
May 09 18:42:54 ubuntu1804 systemd[1]: Started A high performance web server and a reverse proxy server.

Perfect. All good. Now, we are ready to run again the certbot procedure.

$ certbot certonly --webrootSaving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel): mystore.com
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for mystore.com
Input the webroot for mystore.com: (Enter 'c' to cancel): /var/www/html
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/mystore.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/mystore.com/privkey.pem
Your cert will expire on 2021-08-09. 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

Nice! We have our certificates now. Available in the directory: ‘/etc/letsencrypt/live/mystore.com’

Now that we have them, let’s update our NGINX configuration to include them.

$ vi /etc/nginx/sites-enabled/magento

Add the following:

upstream fastcgi_backend {
server unix:/run/php/php7.2-fpm.sock;
}

server {

listen 80;
server_name mystore.com;
set $MAGE_ROOT /var/www/html/magento2;
include /var/www/html/magento2/nginx.conf.sample;
# Include location directive for Let's Encrypt ACME Challenge
include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
return 301 https://mystore.com$request_uri;
}
server {listen 443 ssl http2;
server_name mystore.com;
ssl_certificate /etc/letsencrypt/live/mystore.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mystore.com/privkey.pem;
set $MAGE_ROOT /var/www/html/magento2;
set $MAGE_MODE production;
access_log /var/log/nginx/mystore.com-access.log;
error_log /var/log/nginx/mystore.com-error.log;
include /var/www/html/magento2/nginx.conf.sample; # Include location directive for Let's Encrypt ACME Challenge
include /etc/nginx/snippets/letsencrypt-acme-challenge.conf;
}

Now, you’ll need to tell Magento 2 to start using a secure URL (Https).

$ php bin/magento setup:install --base-url=https://mystore.com/ \
--base-url-secure=https://mystore.com/

Restart NGINX and you should have your Magento 2 website securely accessible.

One last thing.

Make sure your certificates are automatically renewed. Add the below to your cronjob.

certbot renew

To test the renewal without saving the certificates, run:

$ certbot renew --dry-run

Sources:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store