Setup Let’s encrypt TLS certificate for Proxmox [Update]

February 21, 2016

The graphical interface of Proxmox runs on port 8006 and uses HTTPS. By default this is a self signed certificate, which is a problem if you login in from a client the first time. In this case you’re not sure if there is no MitM attack going on. But there is a solution for this by using Let’s encrypt.

First you need to install git

apt-get install git

download the client software

cd /root
git clone

and now you need to “patch” it as with running containers the check for a free port 80 most likely fails as a container with a running a web server is quite common. Open this file /root/letsencrypt/letsencrypt/plugins/ with an editor and place

return False

as first command in the already_listening method. Make sure that it is aligned with the line above and below as Python requires that. It should look this:


ps: If you started to read this article after calling ./letsencrypt-auto the first time you also need to patch following file the same way.


[Update] In the newer version the client is called certbot and so the path got changed to



Now make sure that Port 80 is not firewalled and therefore reachable from the Internet and call following command:

cd /root/letsencrypt/
./letsencrypt-auto certonly --standalone --standalone-supported-challenges http-01 -d <dnsname>

Replace with the <dnsname> with the dns name you use to connect to the management Web GUI. If all worked, you should see following:

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live//fullchain.pem. Your cert
will expire on 2016-05-21. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- If you like Let's Encrypt, please consider supporting our work by:

Now only saving the old certificate with these commands …

mv /etc/pve/pve-root-ca.pem /etc/pve/pve-root-ca.pem.orig
mv /etc/pve/local/pve-ssl.key /etc/pve/local/pve-ssl.key.orig
mv /etc/pve/local/pve-ssl.pem /etc/pve/local/pve-ssl.pem.orig

and copying the new ones to the correct place …

cp /etc/letsencrypt/live/<hostname>/chain.pem /etc/pve/pve-root-ca.pem
cp /etc/letsencrypt/live/<hostname>/privkey.pem /etc/pve/local/pve-ssl.key
cp /etc/letsencrypt/live/<hostname>/cert.pem /etc/pve/local/pve-ssl.pem

followed by a restart of the processes:

service pveproxy restart
service pvedaemon restart

is open.

The last 5 commands are needed, because the special file system Proxmox uses for /etc/pve does not support symlinks. You need to execute that 5 commands after each renewal. The option for this is “renew”. You can/should automate the renew process.


RSS feed for comments on this post. TrackBack URI

  1. Thanks for this, it worked perfectly.

    You have an issue though – in the cp /etc/let… lines you have your own domain name rather than a note to change the details to the end user’s domain name.

    Best regards

    Comment by Greg Fenton — March 15, 2016 #

  2. As a follow on, I use this as my cron job to renew the certificate automatically every 3 months:
    0 0 1 JAN,APR,JUL,OCT * cd /root/letsencrypt; ./letsencrypt-auto renew --agree-tos [email protected]

    Comment by Greg Fenton — March 15, 2016 #

  3. thx, changed that.

    Comment by robert — March 16, 2016 #

  4. GReat !


    Comment by Henri — May 21, 2016 #

  5. Hey! I have a problem…
    View this:

    WARNING: unable to check for updates.
    Creating virtual environment…
    Installing Python packages…
    Traceback (most recent call last):
    File “/tmp/tmp.1FK3d4Wlgo/”, line 146, in
    File “/tmp/tmp.1FK3d4Wlgo/”, line 130, in main
    for url, digest in PACKAGES]
    File “/tmp/tmp.1FK3d4Wlgo/”, line 112, in hashed_download
    response = opener().open(url)
    File “/usr/lib/python2.7/”, line 431, in open
    response = self._open(req, data)
    File “/usr/lib/python2.7/”, line 449, in _open
    ‘_open’, req)
    File “/usr/lib/python2.7/”, line 409, in _call_chain
    result = func(*args)
    File “/usr/lib/python2.7/”, line 1240, in https_open
    File “/usr/lib/python2.7/”, line 1197, in do_open
    raise URLError(err)

    I do not understand the error, except it comes from python. Any idea how to set this problem?

    Comment by Paul — September 11, 2016 #

  6. urllib2 is a library for downloading stuff, so I seems to be fair to guess that something at downloading did not work. Are you using a http proxy, blocking access to internet on that server or something that changes the traffic? An other possibility is that there is a temporary problem with the let’s encrypt server.

    Comment by robert — September 11, 2016 #

  7. I do not use a proxy, but I’m on my ADSL (personal connection).
    What ports to open? TCP? UDP?


    Comment by Paul — September 11, 2016 #

  8. don’t know .. just look with tcpdump if a connection is attempted and not working.

    Comment by robert — September 11, 2016 #

  9. I’m looking at, and it is possible that it comes to IPv6

    Comment by Paul — September 11, 2016 #

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Powered by WordPress
Entries and comments feeds. Valid XHTML and CSS. 39 queries. 0.048 seconds.