Developer Advocate
This tutorial will show you how to set up a TLS/SSL certificate from Let’s Encrypt on an Ubuntu 16.04 server running Apache as a web server.
SSL certificates are used within web servers to encrypt the traffic between the server and client, providing extra security for users accessing your application. Let’s Encrypt provides an easy way to obtain and install trusted certificates for free.
In order to complete this guide, you will need:
ServerName
.When you are ready to move on, log into your server using your sudo-enabled account.
Let’s Encrypt certificates are fetched via client software running on your server. The official client is called Certbot, and its developers maintain their own Ubuntu software repository with up-to-date versions. Because Certbot is in such active development it’s worth using this repository to install a newer version than Ubuntu provides by default.
First, add the repository:
You’ll need to press ENTER
to accept. Afterwards, update the package list to pick up the new repository’s package information:
And finally, install Certbot from the new repository with apt-get
:
The certbot
Let’s Encrypt client is now ready to use.
Generating the SSL certificate for Apache using Certbot is quite straightforward. The client will automatically obtain and install a new SSL certificate that is valid for the domains provided as parameters.
To execute the interactive installation and obtain a certificate that covers only a single domain, run the certbot
command like so, where example.com is 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. The first domain name in the list of parameters will be the base domain used by Let’s Encrypt to create the certificate, and for that reason we recommend that you pass the bare top-level domain name as first in the list, followed by any additional subdomains or aliases:
For this example, the base domain will be example.com
.
If you have multiple virtual hosts, you should run certbot
once for each to generate a new certificate for each. You can distribute multiple domains and subdomains across your virtual hosts in any way.
After the dependencies are installed, you will be presented with a step-by-step guide to customize your certificate options. You will be asked to provide an email address for lost key recovery and notices, and you will be able to choose between enabling both http
and https
access or forcing all requests to redirect to https
. It is usually safest to require https
, unless you have a specific need for unencrypted http
traffic.
When the installation is finished, you should be able to find the generated certificate files at /etc/letsencrypt/live
. You can verify the status of your SSL certificate with the following link (don’t forget to replace example.com with your base domain):
https://www.ssllabs.com/ssltest/analyze.html?d=example.com&latest
You should now be able to access your website using a https
prefix.
Let’s Encrypt certificates only last for 90 days. However, the certbot package we installed takes care of this for us by running certbot renew
twice a day via a systemd timer. On non-systemd distributions this functionality is provided by a cron script placed in /etc/cron.d
. The task runs twice daily and will renew any certificate that’s within thirty days of expiration.
To test the renewal process, you can do a dry run with certbot
:
If you see no errors, you’re all set. When necessary, Certbot will renew your certificates and reload Apache to pick up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.
In this guide, we saw how to install a free SSL certificate from Let’s Encrypt in order to secure a website hosted with Apache. We recommend that you check the official Let’s Encrypt blog for important updates from time to time, and read the Certbot documentation for more details about the Certbot client.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Unfortunately, it doesn’t seem to work like this.
I did it on mine as follows:
And when I test my server by going to ssllabs.com/ssltest/analyze.html?d=example.com, it says
Subject baz.example.com
Common names baz.example.com
Alternative names bar.example.com example.com foo.example.com www.example.com
It seems like it took the last parameter given, and is displaying the alternative names in alphabetical order, although with my sample size of one I can’t say that for certain.
But other than that (and it really doesn’t matter all that much, anyway – all the domains are encrypted just fine), I was really impressed with the whole process. Both with how easy Let’s Encrypt is to use, and with the succinctness of this tutorial. It gets an A on SSL Labs, and I was only able to get to a B using other SSL providers, and that after a hell of a lot of work.
Thanks a heap for providing this.
Please try this link and it should help you: https://www.wordpresstutorialsadvanced.in/setup-ssl-certificates-amazon-lightsail/
I get the following error on a fresh installed ubuntu 16.04 server:
Any suggestions on that? Thanks.
The same here…
Hi there… try this in your server export LC_ALL=“en_US.UTF-8” export LC_CTYPE=“en_US.UTF-8”
at least it work for me this that problem :)
Hi,
After I enter this step:
I get this error:
Note - I was literally testing this out, and used the example.com domain.
Any idea what the issue might be?
Thank you for a great post!
Any chance you are using ServerPilot? I am, and I got the same error you did. I ended up following this tutorial instead, and it worked perfectly:
https://bjoernfranzen.com/how-to-set-up-a-letsencrypt-ssl-certificate-for-your-wordpress-website-on-a-digital-ocean-server-managed-with-a-serverpilot-free-account/
In the Let’s Encrypt tutorial for nginx, there was a section on adding the Diffie-Hellman Group cert as well, resulting in a A+ grading from ssllabs. How would one go about doing the same with the apache server? (This, as well as the tutorials for older versions of Ubuntu skip this section)
I believe you need to enable HSTS response headers to get an A+ rating from SSL Labs.
Please, for the sake of the letsencrypt servers, don’t just copy the crontab config from this article, but rather put in some other arbitrary numbers (another weekday & time)! Otherwise thousands of clients will renew exactly at the same time every Monday at 2:30 am, which will potentially DDoS the servers.
This should be put in the article itself as a heads up!
Came to to make sure someone mentioned this. Please pick a random time and day, it doesn’t matter when, but I suspect the Let’s Encrypt server admins dread 2:30AM on Mondays by this point.
HI, thanks for the tutorial. i’m not sure why the https://www domain got 403 forbidden error You don’t have permission to access / on this server. , the rest is perfect. so i can access https://domain.com , but again the problem 403 shows in https://www.domain.com
thanks
Guys, solved the problem by adding the conf file @ etc/apache2/sites-available/000-default-le-ssl.conf
i added this both ServerName domain.com ServerAlias www.domain.com
cheers
does this work also for ubuntu 32bit 14.04 ?
just a heads up that this generates an additional config file for your virtual host, with -le-ssl.conf appended on the end. I didn’t realise and spent ages editing my virtualhosts config file to allow htaccess override and it wasn’t working. I was editing:
/etc/apache2/sites-enabled/website.com.conf
when i should’ve edited:
/etc/apache2/sites-enabled/website.com-le-ssl.conf
Hopefully that’ll save someone else a headache!
I was wondering how you’d go about adding another domain to the base domain so that a single certificate is valid for multiple domains. I set up a base domain already, but wasn’t sure exactly how I’d go about adding additional domains in the future. If the base domain I already created and added is myfirstdomain.com (I also added www.myfirstdomain.com when setting this up), is the following command correct? Not sure if I need to just basically add all domains all over again.
Thanks!
I am getting an error message. Kindly help Creating virtual environment… Traceback (most recent call last): File “/usr/lib/python3/dist-packages/virtualenv.py”, line 2363, in <module> main() File “/usr/lib/python3/dist-packages/virtualenv.py”, line 719, in main symlink=options.symlink) File “/usr/lib/python3/dist-packages/virtualenv.py”, line 988, in create_environment download=download, File “/usr/lib/python3/dist-packages/virtualenv.py”, line 918, in install_wheel call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT) File “/usr/lib/python3/dist-packages/virtualenv.py”, line 812, in call_subprocess % (cmd_desc, proc.returncode)) OSError: Command /root/.local/share/letsencrypt/bin/python2.7 - setuptools pkg_resources pip wheel failed with error code 1 root@misg:/opt/letsencrypt# cd root@misg:~# cd /etc/letsencrypt/live -bash: cd: /etc/letsencrypt/live: No such file or directory
i am getting this error ```Creating virtual environment… Traceback (most recent call last): File “/usr/lib/python3/dist-packages/virtualenv.py”, line 2363, in <module> main() File “/usr/lib/python3/dist-packages/virtualenv.py”, line 719, in main symlink=options.symlink) File “/usr/lib/python3/dist-packages/virtualenv.py”, line 988, in create_environment download=download, File “/usr/lib/python3/dist-packages/virtualenv.py”, line 918, in install_wheel call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT) File “/usr/lib/python3/dist-packages/virtualenv.py”, line 812, in call_subprocess % (cmd_desc, proc.returncode)) OSError: Command /root/.local/share/letsencrypt/bin/python2.7 - setuptools pkg_resources pip wheel failed with error code 1
Thanks for the great article! I have a Ubuntu 12.04 server, and these instructions mostly worked for it. I found that I first had to stop the Apache server, then edit /etc/letsencrypt/options-ssl-apache.conf to comment out the “SSLCompression” line therein. Hope this helps someone.
I get the error :
Failed authorization procedure. MYDOMAIN.com (tls-sni-01): urn:acme:error:connection :: The server could not connect to the client to verify the domain :: Failed to connect to MY_IP:443 for TLS-SNI-01 challenge
IMPORTANT NOTES:
The following errors were reported by the server:
Domain: MYDOMAIN.com Type: connection Detail: Failed to connect to MY_IP:443 for TLS-SNI-01 challenge
To fix these errors, please make sure that your domain name was entered correctly and the DNS A record(s) for that domain contain(s) the right IP address. Additionally, please check that your computer has a publicly routable IP address and that no firewalls are preventing the server from communicating with the client. If you’re using the webroot plugin, you should also verify that you are serving files from the webroot path you provided.
WARNING do not do this TUTO after the other one about SSL, to create a Self-Signed SSL certificate: https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-apache-in-ubuntu-16-04
I didi it and it completely broke my Apache config, I had crazy infinite redirect loops, and impossible to understand what was going on.
So I had to reinstall completely my droplet with a snapshot (happy to have done one before SSL tuto).
Whenever I try to run the command “./letsencrypt-auto --apache -d mydomain.com” I get this error.
I had a working web app but after following this tutorial I get “Index of /” (which has my project files) when I use https. and when I use plain HTTP I get a blank “Index of /”
Hello,
It’s a great tutorial. Thanks a lot. I have a problem that, after I use the following command:
./letsencrypt-auto --apache -d example.com -d www.example.com
and choose “forcing all requests to redirect to https”,
when i input the “example.com” in the browser, it redirect to HTTPS form like “https://example.com” and works fine. but when I input the “www.example.com” in the browser, it still using the HTTP form “http://www.example.com”, instead of HTTPS form, and I can access “http://www.example.com” successfully.
Could you please help? Thanks in advance.
Tutorial works perfectly on Debian Jessie 8.5.
Thank you!
I followed this guide a few months back and everything is working correctly. However, I’m unable to update the Let’s Encrypt client using the command sudo git pull. Here is the output from my SSH session when running the command.
Any idea on what I should do to get my client to update without it losing my configuration (if that even happens)?
When I head to my domain name it won’t let me prepend www to my https:// URI. Netflix is https://www.netflix.com, where mine is still https://example.com rather than https://www.example.com.
In my VirtualHost I have the ServerName as www.example.com & ServerAlias as example.com. I’ve added certificates to both www.example.com & example.com. with the delimiter being -d. What could the issue be?(I’m using my actual domain name not example.com …). Thanks for any help in advance!