Difference between revisions of "HTTPS Certificate Configuration (Version 4.x, 5.0 and 5.1)"

From Proxmox VE
Jump to: navigation, search
m (Set up automatic renewal)
(Update to acme.sh)
Line 51: Line 51:
 
When accessing the web interface on this node, you should be presented with the new certificate. Note that the alternative certificate is only used by the web interface (including noVNC), but not by the Spice Console/Shell.
 
When accessing the web interface on this node, you should be presented with the new certificate. Note that the alternative certificate is only used by the web interface (including noVNC), but not by the Spice Console/Shell.
  
== Let's Encrypt using le.sh ==
+
== Let's Encrypt using acme.sh ==
  
 
=== Prerequisites ===
 
=== Prerequisites ===
Line 59: Line 59:
 
Your domain name needs to be publicly resolvable both ways. (Check with `<tt>$ drill -x Your.Ip.Address</tt>` or `<tt>$ dig -x Your.Ip.Address</tt>`)
 
Your domain name needs to be publicly resolvable both ways. (Check with `<tt>$ drill -x Your.Ip.Address</tt>` or `<tt>$ dig -x Your.Ip.Address</tt>`)
  
The following steps show how to achieve this using the le.sh bash script and standalone HTTP authentication.
+
The following steps show how to achieve this using the acme.sh bash script and standalone HTTP authentication.
  
 
These steps need to be repeated on each node where you want to use Let's Encrypt certificates.
 
These steps need to be repeated on each node where you want to use Let's Encrypt certificates.
Line 67: Line 67:
 
=== Install certificate chain and key ===
 
=== Install certificate chain and key ===
  
==== 1) Install le.sh ====
+
==== 0) Upgrade from le.sh to acme.sh ====
  
Install the le.sh script from https://github.com/Neilpang/le (this howto was tested with commit 9e6c420872e6e843a6a86ee31f2472574eeda3f6):
+
If you followed a previous version of this HowTo using le.sh, please uninstall le.sh and proceed with "Install acme.sh":
 +
 
 +
le.sh uninstall
 +
 
 +
acme.sh is the 2.X release of le.sh, the existing configuration should be migrated automatically when installing acme.sh.
 +
 
 +
==== 1) Install acme.sh ====
 +
 
 +
Install the acme.sh script from https://github.com/Neilpang/acme.sh (this howto was tested with commit 2d39b3df8893cd256257fe1f32ca6b0485a90dcf):
  
 
Via git:
 
Via git:
  
  git clone https://github.com/Neilpang/le.git le-master
+
  git clone https://github.com/Neilpang/acme.sh.git acme.sh-master
  
 
Or direct download:
 
Or direct download:
  
  wget 'https://github.com/Neilpang/le/archive/master.zip'
+
  wget 'https://github.com/Neilpang/acme.sh/archive/master.zip'
 
  unzip master.zip
 
  unzip master.zip
  
 
==== 2) Run the install script ====
 
==== 2) Run the install script ====
  
You must do this from within the script's directory, othrewise it won't find <tt>le.sh</tt>!
+
You must do this from within the script's directory, otherwise it won't find <tt>acme.sh</tt>! Take care to replace <tt>$EMAIL</tt> with the address that you want to register with at Let's Encrypt. Let's Encrypt will send automatic expiration reminders to this address!
  
 
  mkdir /etc/pve/.le
 
  mkdir /etc/pve/.le
  cd /root/le-master
+
  cd /root/acme-master
  ACCOUNT_CONF_PATH=/etc/pve/.le/account.conf ACCOUNT_KEY_PATH=/etc/pve/.le/account.key /root/le-master/le.sh install
+
  ./acme.sh --install --accountconf /etc/pve/.le/account.conf --accountkey /etc/pve/.le/account.key --accountemail "$EMAIL"
 +
 
 +
==== 3) Check the account config ====
  
==== 3) Edit the account config ====
+
Check the config file in <tt>/etc/pve/.le/account.conf</tt> and verify:
 +
* the <tt>ACCOUNT_EMAIL</tt> variable should be set to your email address
 +
* the <tt>ACCOUNT_KEY_PATH</tt> variable should be set to "<tt>/etc/pve/.le/account.key</tt>"
  
Edit the config file in <tt>/etc/pve/.le/account.conf</tt> and set:
+
You can edit this file with your favourite text editor if either of those is incorrect.
* the <tt>ACCOUNT_EMAIL</tt> variable
 
* the <tt>ACCOUNT_KEY_PATH</tt> to "<tt>/etc/pve/.le/account.key</tt>"
 
  
 
==== 4) Make sure port 80 is open to the public ====
 
==== 4) Make sure port 80 is open to the public ====
  
As part of the certificate creation process, le.sh will listen for a confirmation from LetsEncrypt's servers on port 80. Check that this port is therefore not blocked by any firewall to the machine you are certifying.
+
As part of the certificate creation process, acme.sh will listen for a confirmation from LetsEncrypt's servers on port 80. Check that this port is therefore not blocked by any firewall between the machine you are certifying and the public internet.
  
You can close the port once you're done issuing all certificates for your cluster. However, be aware that as part of the certificate renewal process (managed with a cron job that le.sh installs), port 80 must also be open. You may therefore need to work out an automated way (not covered in this guide) of opening up port 80 for the renewal process.
+
You can close the port once you're done issuing all certificates for your cluster. However, be aware that as part of the certificate renewal process (managed with a cron job that acme.sh installs), port 80 must also be open. You may therefore need to work out an automated way (not covered in this guide) of opening up port 80 for the renewal process.
  
 
==== 5) Issue your first certificate ====
 
==== 5) Issue your first certificate ====
Line 104: Line 114:
 
Now you can issue your first certificate, replacing <tt>$DOMAIN</tt> with your node's fully qualified domain:
 
Now you can issue your first certificate, replacing <tt>$DOMAIN</tt> with your node's fully qualified domain:
  
  ACCOUNT_CONF_PATH=/etc/pve/.le/account.conf /root/.le/le.sh issue no $DOMAIN no 4096 /etc/pve/local/pveproxy-ssl.pem /etc/pve/local/pveproxy-ssl.key /etc/pve/local/pveproxy-ssl.pem "systemctl restart pveproxy"
+
  acme.sh --issue --standalone --keypath /etc/pve/local/pveproxy-ssl.key --fullchainpath /etc/pve/local/pveproxy-ssl.pem --reloadcmd "systemctl restart pveproxy" -d $DOMAIN
  
 
Warnings like "cp: preserving permissions for ‘/etc/pve/local/pveproxy-ssl.pem.bak’: Function not implemented" can be safely ignored.  
 
Warnings like "cp: preserving permissions for ‘/etc/pve/local/pveproxy-ssl.pem.bak’: Function not implemented" can be safely ignored.  
  
By prepending the previous command with STAGE=1 you can issue a certificate using the staging (i.e., testing) CA instead of the production CA:
+
By appending the previous command with <tt>--test</tt> you can issue a certificate using the staging (i.e., testing) CA instead of the production CA:
  STAGE=1 ACCOUNT_CONF_PATH=/etc/pve/.le/account.conf /root/.le/le.sh issue no $DOMAIN no 4096 /etc/pve/local/pveproxy-ssl.pem /etc/pve/local/pveproxy-ssl.key /etc/pve/local/pveproxy-ssl.pem "systemctl restart pveproxy"
+
  acme.sh --issue --standalone --keypath /etc/pve/local/pveproxy-ssl.key --fullchainpath /etc/pve/local/pveproxy-ssl.pem --reloadcmd "systemctl restart pveproxy" -d $DOMAIN --test
  
To "upgrade" to a production certificate, you need to rerun the issue command with a prepended FORCE=1 instead of STAGE=1, in order to replace the existing (test) certificate even though it is not yet expired. This can also be used in case the node's domain name has changed:
+
To "upgrade" to a production certificate, you need to rerun the issue command with an appended <tt>--force</tt> instead of <tt>--test</tt>, in order to replace the existing (test) certificate even though it is not yet expired. This can also be used to force a premature renewal in case the node's domain name has changed:
  FORCE=1 ACCOUNT_CONF_PATH=/etc/pve/.le/account.conf /root/.le/le.sh issue no $DOMAIN no 4096 /etc/pve/local/pveproxy-ssl.pem /etc/pve/local/pveproxy-ssl.key /etc/pve/local/pveproxy-ssl.pem "systemctl restart pveproxy"
+
  acme.sh --issue --standalone --keypath /etc/pve/local/pveproxy-ssl.key --fullchainpath /etc/pve/local/pveproxy-ssl.pem --reloadcmd "systemctl restart pveproxy" -d $DOMAIN --force
  
 
==== 6. Check it's working ====
 
==== 6. Check it's working ====
Line 126: Line 136:
 
==== 7. Set up automatic renewal ====
 
==== 7. Set up automatic renewal ====
  
le.sh installs a cron job that checks the installed certificate(s) and automatically renews them before they expire. The cron job needs to be adapted to use the account.conf file stored on the cluster file systems. Add this using the ACCOUNT_CONF_PATH variable using "crontab -e", followed by "crontab -l" to verify that the changes were saved correctly.  
+
acme.sh installs a cron job that checks the installed certificate(s) and automatically renews them before they expire.  
  
The crontab entry should now look like this:
+
The crontab entry should look like this (<tt>crontab -l</tt>):
  
  0 0 * * * ACCOUNT_CONF_PATH="/etc/pve/.le/account.conf" LE_WORKING_DIR="/root/.le" /root/.le/le.sh cron > /dev/null
+
  0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
  
''(le.sh appears to have a bug that adds inverted commas incorrectly in the path to le.sh. It's a good idea to test the cron entry by running it manually from the command line to check that it's working OK.)''
+
It's a good idea to test the cron entry by running it manually from the command line to check that it's working OK:
 +
"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"
  
 
NOTE: The requirements for issuing certificates apply for renewals as well: the configured domain name '''must be resolvable and reachable on port 80 from the public internet when the renewal cron job runs'''.
 
NOTE: The requirements for issuing certificates apply for renewals as well: the configured domain name '''must be resolvable and reachable on port 80 from the public internet when the renewal cron job runs'''.
  
=== Updating le.sh ===
+
=== Updating acme.sh ===
  
le.sh can be updated with the following commands:
+
acme.sh can be updated with the following commands when installed from the git repository:
  
 
  cd /root/le-master
 
  cd /root/le-master
 
  git pull
 
  git pull
  ACCOUNT_CONF_PATH=/etc/pve/.le/account.conf ACCOUNT_KEY_PATH=/etc/pve/.le/account.key /root/le-master/le.sh install
+
  ./acme.sh --install --accountconf /etc/pve/.le/account.conf --accountkey /etc/pve/.le/account.key --accountemail "YOUR@EMAIL.ADDRESS"
  
 
=== Account key ===
 
=== Account key ===
  
It is recommended to do an off-site/offline backup of the account key file in /etc/pve/.le/account.key, in case one of your certificate private key files is lost or compromised, it can be used to revoke the associated certificate.
+
It is recommended to do an off-site/offline backup of the account key file in <tt>/etc/pve/.le/account.key</tt>, in case one of your certificate private key files is lost or compromised, it can be used to revoke the associated certificate.
  
 
== Let's Encrypt using other clients ==
 
== Let's Encrypt using other clients ==

Revision as of 14:16, 18 April 2016

Introduction

This is a howto for changing the web server certificate used by Proxmox VE, in order to enable the usage of publicly trusted certificates issued by a CA of your choice (like Let's Encrypt or a commercial CA). It has been tested on a Proxmox VE 4.1 installation, using certificates from https://www.letsencrypt.org.

Note: the previous, outdated version of this HowTo is archived at HTTPSCertificateConfigurationOld

Revert to default configuration

If you have used the previous HowTo and replaced any of the certificate or key files generated by PVE, you need to revert to the default state before proceeding.

Delete or move the following files:

  • /etc/pve/pve-root-ca.pem
  • /etc/pve/priv/pve-root-ca.key
  • /etc/pve/nodes/<node>/pve-ssl.pem
  • /etc/pve/nodes/<node>/pve-ssl.key

The latter two need to be repeated for all nodes if you have a cluster.

Afterwards, run the following command on each node of the cluster to re-generate the certificates and keys:

pvecm updatecerts -f

CAs other than Let's Encrypt

Install certificate chain and key

Since pve-manager 4.1-20, it is possible to provide alternative SSL files for each node's web interface. The following steps need to be repeated for each node where you want to use alternative certificate files.

First check your version of pve-manager and upgrade if necessary:

pveversion

You will need the following two files provided by your CA:

  • fullchain.pem (your certificate and all intermediate certificates, excluding the root certificate, in PEM format)
  • private-key.pem (your private key, in PEM format, without a password)

Now copy those files to the override locations in /etc/pve/nodes/<node> (make sure to use the correct certificate files and node!):

cp fullchain.pem /etc/pve/nodes/<node>/pveproxy-ssl.pem
cp private-key.pem /etc/pve/nodes/<node>/pveproxy-ssl.key

and restart the web interface:

systemctl restart pveproxy

The system log should inform you about the usage of the alternative SSL certificate ("Using '/etc/pve/local/pveproxy-ssl.pem' as certificate for the web interface."):

journalctl -b -u pveproxy.service

When accessing the web interface on this node, you should be presented with the new certificate. Note that the alternative certificate is only used by the web interface (including noVNC), but not by the Spice Console/Shell.

Let's Encrypt using acme.sh

Prerequisites

Let's Encrypt enables everyone with a publicly resolvable domain name to be issued SSL certificates for free.

Your domain name needs to be publicly resolvable both ways. (Check with `$ drill -x Your.Ip.Address` or `$ dig -x Your.Ip.Address`)

The following steps show how to achieve this using the acme.sh bash script and standalone HTTP authentication.

These steps need to be repeated on each node where you want to use Let's Encrypt certificates.

You need at least pve-manager >= 4.1-20 (see `$ pveversion`), so upgrade if necesasry.

Install certificate chain and key

0) Upgrade from le.sh to acme.sh

If you followed a previous version of this HowTo using le.sh, please uninstall le.sh and proceed with "Install acme.sh":

le.sh uninstall

acme.sh is the 2.X release of le.sh, the existing configuration should be migrated automatically when installing acme.sh.

1) Install acme.sh

Install the acme.sh script from https://github.com/Neilpang/acme.sh (this howto was tested with commit 2d39b3df8893cd256257fe1f32ca6b0485a90dcf):

Via git:

git clone https://github.com/Neilpang/acme.sh.git acme.sh-master

Or direct download:

wget 'https://github.com/Neilpang/acme.sh/archive/master.zip'
unzip master.zip

2) Run the install script

You must do this from within the script's directory, otherwise it won't find acme.sh! Take care to replace $EMAIL with the address that you want to register with at Let's Encrypt. Let's Encrypt will send automatic expiration reminders to this address!

mkdir /etc/pve/.le
cd /root/acme-master
./acme.sh --install --accountconf /etc/pve/.le/account.conf --accountkey /etc/pve/.le/account.key --accountemail "$EMAIL"

3) Check the account config

Check the config file in /etc/pve/.le/account.conf and verify:

  • the ACCOUNT_EMAIL variable should be set to your email address
  • the ACCOUNT_KEY_PATH variable should be set to "/etc/pve/.le/account.key"

You can edit this file with your favourite text editor if either of those is incorrect.

4) Make sure port 80 is open to the public

As part of the certificate creation process, acme.sh will listen for a confirmation from LetsEncrypt's servers on port 80. Check that this port is therefore not blocked by any firewall between the machine you are certifying and the public internet.

You can close the port once you're done issuing all certificates for your cluster. However, be aware that as part of the certificate renewal process (managed with a cron job that acme.sh installs), port 80 must also be open. You may therefore need to work out an automated way (not covered in this guide) of opening up port 80 for the renewal process.

5) Issue your first certificate

Now you can issue your first certificate, replacing $DOMAIN with your node's fully qualified domain:

acme.sh --issue --standalone --keypath /etc/pve/local/pveproxy-ssl.key --fullchainpath /etc/pve/local/pveproxy-ssl.pem --reloadcmd "systemctl restart pveproxy" -d $DOMAIN

Warnings like "cp: preserving permissions for ‘/etc/pve/local/pveproxy-ssl.pem.bak’: Function not implemented" can be safely ignored.

By appending the previous command with --test you can issue a certificate using the staging (i.e., testing) CA instead of the production CA:

acme.sh --issue --standalone --keypath /etc/pve/local/pveproxy-ssl.key --fullchainpath /etc/pve/local/pveproxy-ssl.pem --reloadcmd "systemctl restart pveproxy" -d $DOMAIN --test

To "upgrade" to a production certificate, you need to rerun the issue command with an appended --force instead of --test, in order to replace the existing (test) certificate even though it is not yet expired. This can also be used to force a premature renewal in case the node's domain name has changed:

acme.sh --issue --standalone --keypath /etc/pve/local/pveproxy-ssl.key --fullchainpath /etc/pve/local/pveproxy-ssl.pem --reloadcmd "systemctl restart pveproxy" -d $DOMAIN --force

6. Check it's working

If necessary, close the firewall port again.

The system log should inform you about the usage of the alternative SSL certificate ("Using '/etc/pve/local/pveproxy-ssl.pem' as certificate for the web interface."):

journalctl -b -u pveproxy.service

When accessing the web interface on this node, you should be presented with the new certificate. Note that the alternative certificate is only used by the web interface (including noVNC), but not by the Spice Console/Shell.

7. Set up automatic renewal

acme.sh installs a cron job that checks the installed certificate(s) and automatically renews them before they expire.

The crontab entry should look like this (crontab -l):

0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

It's a good idea to test the cron entry by running it manually from the command line to check that it's working OK:

"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh"

NOTE: The requirements for issuing certificates apply for renewals as well: the configured domain name must be resolvable and reachable on port 80 from the public internet when the renewal cron job runs.

Updating acme.sh

acme.sh can be updated with the following commands when installed from the git repository:

cd /root/le-master
git pull
./acme.sh --install --accountconf /etc/pve/.le/account.conf --accountkey /etc/pve/.le/account.key --accountemail "YOUR@EMAIL.ADDRESS"

Account key

It is recommended to do an off-site/offline backup of the account key file in /etc/pve/.le/account.key, in case one of your certificate private key files is lost or compromised, it can be used to revoke the associated certificate.

Let's Encrypt using other clients

It should also be possible to use other Let's Encrypt clients, as long as care is taken that the issued as well as renewed certificates and the associated keys are copied to the correct locations, and the pveproxy service is restarted afterwards.