Guide to install FREE SSL certificate from Letsencrypt on Virtualmin & Webmin. 100% working.

I’ve been going at this for a little while but came up with the following steps to get it working. Its working on 06-12-2015 during the public BETA. If you run into issues please let me know.

Tested on:

  • Host OS is Ubuntu 14.04 LTS.
  • Virtualmin version: 4.18.gpl (doesn’t really matter? build 2015+)
  • Webmin version 1.770 - 1.780 (doesn’t really matter? build 2015+)

Get the following right for your “variables”, fill in your own offcourse:

MYUSERNAMEFORDOMAIN: my system username known in virtualmin


*** 1. First install Let’s Encrypt script/programm. ***

Login to SSH and get root privileges (root/sudo -i):

cd /home/user/ && git clone


cd /root/ && git clone

^^ This will download the Let’s Encrypt from github with executable script

*** 2. Create your directory where you will be saving your certificate later on. Reason for this is because Virtualmin has a protection where it only allows a certificate from the user/domains directory: ***

mkdir /home/MYUSERNAMEFORDOMAIN/ssl_certificates

*** 3. Setup your cronjobs by running: “sudo crontab -e” ***

It wil probably ask you which editor, i choose Nano, once in the editor enter the following somewhere on a new line (pick the option you choose on step 1!):

01 3 1 * * cd /home/user/letsencrypt/ && ./letsencrypt-auto certonly --email info@MYDOMAIN --agree-tos --webroot --renew-by-default -w /home/MYDOMAIN/public_html/ -d -d --authenticator webroot && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/cert.pem && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/chain.pem && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/fullchain.pem && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/privkey.pem


01 3 1 * * cd /root/letsencrypt/ && ./letsencrypt-auto certonly --email info@MYDOMAIN --agree-tos --webroot --renew-by-default -w /home/MYDOMAIN/public_html/ -d -d --authenticator webroot && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/cert.pem && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/chain.pem && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/fullchain.pem && cp -f /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/privkey.pem

^^ Above command will copy the certificates to the correct directory after requesting them (i gave a warning in step 2). It will do this every 1st of the month during the night. The reason we do this every month is because the certs are only valid 90 days and we have plenty of time to repair if something appears to be wrong with the cert later on…

Allright! The hard part is done!

*** 3.1 Please log into your Virtualmin admin panel, Select “Webmin -> System -> Scheduled Cron Jobs”. Go to your newly created Cronjob by clicking on it and select “RUN NOW”.

*** 4. in Virtualmin, select you domain and go to “Edit virtual server”, make sure that SSL is enabled under “Enabled features”.

*** 5. Under “Server configuration” go to “Manage SSL Certificate”. Select the tab “Update Certificate and Key” and under “Signed SSL certificate” select the option “File on server”, fill in the location of the certificate:

*** 6. Do the same for section “Matching private key”. Select: “/home/MYUSERNAMEFORDOMAIN/ssl_certificates/privkey.pem”

*** 7. Click on “Install Now”.

*** 8. Switch to tab “CA Certificate”, select "In file on server " and fill in: “/home/MYUSERNAMEFORDOMAIN/ssl_certificates/fullchain.pem”

*** 9. Click on “Save Certificate”. ***

DONE! ! ! It will now update every month :slight_smile:

Go to your website with HTTPS, what do you get??? :smiley: :slight_smile: :smiley:

IF you run into any issues please let me know in the comments and i’ll try to help out!

NOTE: You can’t request a lot of different certificates. You will get the message: Too many certificates already issued for: xxx. If you want a lot of certificates for subdomains please consider using a paid wildcard certificate. Letsencrypt is a service to help out (starting/small) websites.

If you like this guide and want to donate you can do so by Bitcoin: bitcoin:1gYf6whHEhLBuhEk81DFoCt65dVva94iL

thank you!

Just a small suggestion. I would pass the -d paramater for both www.domain.tld and domain.tld to make the SSL certificate work for both, like this:

-d -d

Thanks for the guide though - appreciate it :slight_smile:

Thanks for the suggestion. I’ve added it in the guide.

Oh Nice guide. I was looking at carving out some time to look into this.

Great work. I will have to give this a go at later time.

Nice work and thank you.

90 days = 3 months, probably don’t need to run it every 30 days. Otherwise nice work, and glad to see this contribution made available to us all.

Hi, thank you for guide.

I followed it and stuck at 5. as there was no certs to add.

I think You would have to wait to 1st of the month for cron to execute command :slight_smile:

so what I did is:

cd /home/user/letsencrypt/ && ./letsencrypt-auto certonly --email info@MYDOMAIN --agree-tos --webroot --renew-by-default -w /home/MYDOMAIN/public_html/ -d -d --authenticator webroot && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/cert.pem && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/chain.pem && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/fullchain.pem && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/privkey.pem


cd /root/letsencrypt/ && ./letsencrypt-auto certonly --email info@MYDOMAIN --agree-tos --webroot --renew-by-default -w /home/MYDOMAIN/public_html/ -d -d --authenticator webroot && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/cert.pem && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/chain.pem && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/fullchain.pem && cp /etc/letsencrypt/live/ /home/MYUSERNAMEFORDOMAIN/ssl_certificates/privkey.pem


This worked great except for some python errors I ran into with virtual environments.

I am running CentOS 6 on my box so I installed pip to get the virutal issue resolved. Still had problems and found it easier to install python 2.7 following

I would suggest you disable the repos when you’ve got your python installed cause the EPEL repo will update proftpd which breaks the FTP in my version of Virtualmin.

The problem I have now is I can’t seem to get apache to expose the /.well-known folder so letsencrypt can’t verify the domain. Anyone have a quick idea how to do this in virtualmin? I’ve tried setting up alias and redirects. I’m guessing somewhere in virtualmin it is blocking hidden files/folders. But I can’t seem to find it.

The script will put a file in the public_html/.well-known/acme-challenge/ folder. Then it will see if it can access that path on the webbrowser.
What happens if you login to FTP and see if any files get written during verification? Also what is your error? Maybe you can use --verbose.

I tried the --verbose which kicks back a dialog error.

However points to using --text -vvvvvv instead which gets the script to run.

Everything goes fine. files get download and copied into the .well-known/acme-challenge but then it returns
The following ‘urn:acme:error:unauthorized’ errors were reported by
the server:

I am pretty sure it’s an apache indexignore issue. Cause in my httpd.conf I see where it has .?? as ignore. If i’m not mistaken this should keep “hidden” files and folders from showing up. I try to browse to ./well-known/test.html and I get a 404 error like the page doesn’t exist.

I’ve commented out the indexignore. Restarted the apache. No joy. I’ve tried adding IndexIgnore Reset On and restarted with no joy as well. Until I can see into that folder I am pretty sure I am going to have issues.

So the --verbose throws a python dialog error. But using --text -vvvvvv from generated the information.

Turned out to be a permission issue as I suspected in Apache as I was unable to browse files in ./well-known. Apparently when I was working on this yesterday I screwed up my httpd.conf because the site I was trying to get the SSL cert was loading a different virtual host.

Rolled back my httpd.conf. restarted Apache then ran the script again. This time everything appeared to work except it wouldn’t let me install the CA.

Went back into virtualmin and disabled SSL on the site. Saved. Restart Apache. Re-Enable SSL. Restart Apache. It accepted the CA at that point.

Strange thing is in VirtualMin it shows:

Web server hostname XXX.XXX Issuer name Let’s Encrypt Authority X1
Issuer organization Let’s Encrypt Expiry date Mar 12 14:11:00 2016 GMT
Certificate type Signed by CA

And I copied the cert to webmin/usermin/etc without issue and https to those address now show a valid SSL cert! Happy happy joy joy.

But still shows a self-signed cert. I’ve restarted Apache again with no joy. Maybe I’ll just reboot the whole server and see what happens.

Ok so I think my sever is possessed :p.

Just for the record:

OS CentOS 6.7
Webmin version 1.770
Virtualmin version 4.18

So my system hostname is <=- obviously not the real domain

and the virtualhost I am trying to set this up on is This is where I think the issue is happening.

When I go into virtualmin/Edit virtual Server/enable features/ssl website enabled things break. Once I click that on everything in gets can’t seem to find the virtualhost information and defaults to /var/www/html instead of the /home directory.

If I go back into vitualmin and uncheck SSL. restore my httpd.conf file and restart the server. Everything is back to normal.

So somewhere, somehow I think i need to change my systemhost name. I’ve tried in ssl.conf to change it to localhost with no joy.

small note… cp doesn’t like it when files already exists… so other rm the file or cp -f it instead

else looking forward to the plugin for virtualmin is completed

just hope there will be an on/off for each domain, so that not all need to run it.

Thanks for the addition! Added it into the guide.

thanks :slight_smile:

I’ve added an extra step 3.1 (moved from the addition). If you do that before 5 it should go better since the certs will be created.

I havent had an issue with the system host name. My system host name is for a different domain.
Are the ssl certs copied to ssl_certificates?
Also if you check the signing company in your webbrowser, what does it say?

So this was obviously a misconfig on my part.

Inside the virtual host settings/Server Configuration/Change IP. My Shared address was my ext. IP. Once I changed the shared address to the internal IP and specified my External IP address to the correct information. Everything works great now!

This is a nice tutorial, thank you for sharing it. Would it be worth adding some common troubleshooting to the guide?

One that tripped me up:
LetsEncrypt checks the URL “^.well-known/acme-challenge” on your domain. Domains running Drupal will, by default, block this URL causing LetsEncrypt to fail to generate the certificates properly. See for a clear solution.