Letsencrypt/Advanced

From SME Server
Revision as of 19:29, 17 August 2022 by Unnilennium (talk | contribs) (Created page with "This page was originally forked from Letsencrypt page to remove what is not related to the contrib. You can find here the original work that led to the contrib and allow a...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This page was originally forked from Letsencrypt page to remove what is not related to the contrib. You can find here the original work that led to the contrib and allow a manual installation, and few advanced configurations.


most of this topics where for SME9, and might not be still valid for SME10

Requiring SSL

Whether you used the contrib, or configured dehydrated manually, you'll probably want to configure your server to force secure web connections. For any i-bays, you can do this using the server-manager page, or using a shell command. For the Primary i-bay, you'll need to use the shell command:

db accounts setprop {accountname} SSL enabled

or

db accounts setprop Primary SSL enabled

Backup

Your certificate, private key, and other important information are stored in /etc/dehydrated, which is not included in the standard SME Server backup routines. Make sure to add this directory to your backups. See, e.g., Backup with dar if you're using the workstation backup feature. If using Affa for backup, add

Include=/etc/dehydrated

to the Affa configuration file. When using the Server-manager backup (dar) make sure the leading "/" in /etc/dehydrated is removed when you make your include file. Otherwise parse errors occur.


Advanced Topics

Obtaining certificates for other servers

The dehydrated client can be used to obtain certificates for other servers on your network, if the hostnames resolve (from outside your network) to your SME Server. Here's how to do this using the smeserver-letsencrypt contrib.

Hosts and Domains

  Note:
This section is not necessary as far as I am aware. You should just be able to set a host with "HostType local" and an InternalIP address as letsencryptSSLcert enabled and then regenerate domains.txt


You'll need to create two template fragments: one to add your hostname to /etc/dehydrated/domains.txt, and the second to handle the certificate once it's generated. To create the first, do

mkdir -p /etc/e-smith/templates-custom/etc/dehydrated/domains.txt
nano -w /etc/e-smith/templates-custom/etc/dehydrated/domains.txt/15Hostname

You can replace "Hostname" in "15Hostname" with something that's descriptive of the host you're obtaining a certificate for. If you want more than one additional certificate, create separate fragments for each one. In the file, just enter the fully-qualified domain name of the system:

hostname.domain.tld

Then Ctrl-X to exit, Y to save.

Hook Script deployment

The second template fragment will be a portion of the hook script, so the dehydrated client knows what to do with this certificate. This must be present, otherwise dehydrated will configure your SME server to use this certificate rather than the certificate for the SME Server.

mkdir -p /etc/e-smith/templates-custom/usr/bin/hook-script.sh/
nano -w 05deploy_cert_hostname

As above, replace "hostname" with something that describes the host that this script will apply to. The numeric portion can be changed, but MUST be less than 10.

At a minimum, this fragment will need to recognize that it's being called for a certificate other than the main server certificate, and exit in order to prevent later portions of the script from installing that certificate as the main server certificate. The minimal form of this fragment would be:

{
    use strict;
    use warnings;
    use esmith::ConfigDB;

    my $configDB = esmith::ConfigDB->open_ro or die("can't open Config DB");

    my $letsencryptStatus = $configDB->get_prop( 'letsencrypt', 'status' )     || 'disabled';

    if ( $letsencryptStatus ne 'disabled' ) {

    $OUT .=<<'_EOF';
if [ $1 = "deploy_cert" ] && [ $2 = "hostname.domain.tld" ]; then
 echo "$2 certificate renewed" | mail -s "Certificate renewal" admin@yourdomain.com
 exit 0
fi
_EOF

    }
}

Depending on the characteristics of the other system, though, this script may be able to install the certificate on that system. The following fragment would copy the certificate files to a remote Linux system running Apache for the web server, and reload Apache to get it to begin using the new certificate:

{
    use strict;
    use warnings;
    use esmith::ConfigDB;

    my $configDB = esmith::ConfigDB->open_ro or die("can't open Config DB");

    my $letsencryptStatus = $configDB->get_prop( 'letsencrypt', 'status' )     || 'disabled';

    if ( $letsencryptStatus ne 'disabled' ) {

    $OUT .=<<'_EOF';
if [ $1 = "deploy_cert" ] && [ $2 = "hostname.domain.tld" ]; then
  KEY=$3
  CERT=$4
  CHAIN=$6
  scp $CERT root@hostname:/etc/pki/tls/certs/pbx.familybrown.org.crt
  scp $KEY root@hostname:/etc/pki/tls/private/pbx.familybrown.org.key
  scp $CHAIN root@hostname:/etc/pki/tls/certs/server-chain.crt
  ssh root@pbx "/sbin/service httpd reload"
  echo "$2 certificate renewed" | mail -s "Certificate renewal" admin@domain.tld
  exit 0
fi
_EOF

    }
}

The following fragment would install the new certificate on a Proxmox VE host:

{
    use strict;
    use warnings;
    use esmith::ConfigDB;

    my $configDB = esmith::ConfigDB->open_ro or die("can't open Config DB");

    my $letsencryptStatus = $configDB->get_prop( 'letsencrypt', 'status' )     || 'disabled';

    if ( $letsencryptStatus ne 'disabled' ) {

    $OUT .=<<'_EOF';
if [ $1 = "deploy_cert" ] && [ $2 = "pve.domain.tld" ]; then
  KEY=$3
  CHAIN=$5
  scp $KEY root@pve:/etc/pve/nodes/pve/pveproxy-ssl.key
  scp $CHAIN root@pve:/etc/pve/nodes/pve/pveproxy-ssl.pem
  ssh root@pve "systemctl restart pveproxy"
  echo "$2 certificate renewed" | mail -s "Certificate renewal" admin@domain.tld
  exit 0
fi
_EOF

    }
}

Once you've created the template fragments, expand the templates and run dehydrated to generate the certificates:

signal-event console-save
dehydrated -c

These certificates will be automatically renewed, just like the main server certificate.

Obtaining certificates for a private SME Server

As noted above in the prerequisites section, your SME Server must ordinarily be accessible from the Internet so that the Let's Encrypt servers can validate that you control it. However, if your SME Server is not accessible from the Internet, the smeserver-letsencrypt contrib provides a method that can be used to validate domain control. In order to use this method, the following conditions must be true:

  • The hostname of your internal SME Server (example: internal.mydomain.tld) resolves, on the public Internet, to a valid IP address
  • The host to which internal.mydomain.tld resolves (example: external.mydomain.tld) has a running web server on port 80
  • The root user from internal.mydomain.tld can connect to external.mydomain.tld via SSH without entering a password (i.e., you've set up SSH public key authentication)

This method uses a simple script that's included in the smeserver-letsencrypt contrib, which requires that four database entries be set:

config setprop letsencrypt hookScript enabled
config setprop letsencrypt host external.mydomain.tld
config setprop letsencrypt user root
config setprop letsencrypt path /home/e-smith/files/ibays/Primary/html/.well-known/acme-challenge
signal-event console-save

The parts in bold above should be changed to match your situation; the path variable should be the filesystem location that external.mydomain.tld serves as /.well-known/acme-challenge/ . When dehydrated creates the challenge file, it will transfer it via scp to user@host:path/, and then allow the Let's Encrypt server to validate. Once validation is accomplished, the script will remove the challenge file from user@host:path/