Let's Encrypt! This page describes how to enable SSL using letsencrypt for ''example.com''. Log in through ssh to `ssh.hcoop.net`, then follow the instructions below <> = First time setup = At the end of these steps, you'll have a certificate for www.example.com. If you want to use a different subdomain (example.com, git.example.com, etc), you'll follow modified versions of these steps in section 2. == Set up your new website with http == {{{ echo 'dom "example.com" with end;' > ~/.domtool/example.com }}} == Set up your environment == These steps are recommended but optional. If you skip them, you'll need to run {{{source ~/.acme.sh/acme.sh.env}}} each time before you generate certs. The hcoop environment doesn't use a .bashrc file by default, but `acme.sh` expects one. First create the file {{{ touch ~/.bashrc }}} Then load it in each new session. Add the following lines to ~/.bash_profile {{{ if [ -f ~/.bashrc ]; then . ~/.bashrc fi }}} == Download and install `acme.sh` == Acme.sh is a letsencrypt client written in pure bash. The third command may complain that you are not allowed to use crontab. This is fine. {{{ git clone https://github.com/acmesh-official/acme.sh.git cd acme.sh ./acme.sh --install }}} {{{#!wiki warning '''Security Precautions''' Since afs is publicly accessible, you need to take a few precautions to ensure that your certificate and private key remain private. For all key operations, keep the files in a directory that only you and the admins can read. }}} Set the correct permissions: {{{ fs sa ~/.acme.sh -clear YOUR_USERNAME all system:administrators all }}} You'll have to do this once, or you can log out and reconnect (if you set up your .bashrc): {{{ source ~/.acme.sh/acme.sh.env }}} == Generate the cert == If the ''example.com'' document root is `~/public_html/`, run {{{ acme.sh --issue -d example.com -w ~/public_html/ }}} (If the document root is some weird subdirectory, like `~/public_html/weird`, set the `-w` option to that instead.) At the end, it will print `Your cert is in` and then a path to a file ending in `.cer`. Copy this path '''without the .cer extension'''. In the next section, replace `$FILE` with this path. == Request cert installation from hcoop admins == Send a [[https://members.hcoop.net/portal/cert|SSL certificate permission request]]. Fields are filled out with: Subdomain: `www` Domain: `example.com` OpenSSL certificate: `$FILE.cer $FILE.key` See section above for context. You must also request certificate installation whenever you renew the certificate. == Update domtool config to use SSL == Now that your cert has been installed, its path will appear on the [[https://members.hcoop.net/portal/cert|certificate permission request]] page, under the heading "Your certificates." Let's say the cert path is `/etc/apache2/ssl/user/www.example.com.pem`. (That directory is really called `user`; it's not a username stand-in!) You need to add this path to your domtool configuration. Here's a simple example config, which redirects all traffic to https in a single domain. {{{ dom "example.com" where SSL = use_cert "/etc/apache2/ssl/user/www.example.com.pem" with web "www" with rewriteRule "^(.*)$" "https://www.example.com$1" [redirectWith temp] end; end; }}} Here are [[DomTool/Examples#Using_SSL_.28HTTPS.29|more single-domain examples]] and [[#Multi-domain_configuration_example|a multi-domain example]]. For reference, here's the [[DomTool|domtool manual]]. = Existing setups & tweaks = {{{#!wiki note '''Under construction''' This section is under construction. }}} == Multi-domain configuration example == `.domtool/lib.dtl` {{{ val acmeChallengeAlias = begin location "/.well-known/acme-challenge" with unset_options [indexes]; end; alias "/.well-known/acme-challenge" "/afs/hcoop.net/user/b/bk/bkhl/www/acme/.well-known/acme-challenge"; end; }}} `.domtool/elektrubadur.se`: {{{ val elektrubadurCertificate = use_cert "/etc/apache2/ssl/user/elektrubadur.se.pem"; val elektrubadurRewrite = rewriteRule "^(.*)$" "https://elektrubadur.se$1" [redirectWith permanent]; val elektrubadurSubdomainAlias = \name -> begin web name with elektrubadurRewrite; end; web name where SSL = elektrubadurCertificate; with elektrubadurRewrite; end; end; dom "elektrubadur.se" where DocumentRoot = home "www/elektrubadur.se"; CreateWWW = false; with addDefaultSPF; vhostDefault where SSL = elektrubadurCertificate; with errorDocument "404" "/404.html"; expiresByType "text/plain" access 1 days; expiresByType "text/css" access 1 days; expiresByType "image/jpeg" access 1 weeks; expiresByType "image/png" access 1 weeks; expiresByType "image/gif" access 1 weeks; expiresByType "image/svg" access 1 weeks; expiresByType "image/vnd.microsoft.icon" access 1 weeks; acmeChallengeAlias; end; vhostDefault with elektrubadurRewrite; end; elektrubadurSubdomainAlias "www"; elektrubadurSubdomainAlias "bkhl"; web "test" where DocumentRoot = home "www/test.elektrubadur.se"; SSL = elektrubadurCertificate; with acmeChallengeAlias; end; web "test" with rewriteRule "^(.*)$" "https://test.elektrubadur.se$1" [redirectWith permanent]; end; web "cloud" where DocumentRoot = home "www/cloud.elektrubadur.se"; SSL = elektrubadurCertificate; with location "/" with unset_options [indexes, multiViews]; directoryIndex ["index.php", "index.html"]; end; expiresByType "text/css" access 1 weeks; expiresByType "application/javascript" access 1 weeks; expiresByType "image/svg" access 1 weeks; expiresByType "image/gif" access 1 weeks; expiresByType "application/font-woff2" access 1 weeks; setEnvIfNoCase "^Authorization$" "(.+)" ["XAUTHORIZATION=$1"]; rewriteCond "%{HTTP_USER_AGENT}" "DavClnt" []; rewriteRule "^$" "/remote.php/webdav/" [redirectWith temp, last]; rewriteRule ".*" "-" [env "HTTP_AUTHORIZATION" "%{HTTP:Authorization}"]; rewriteRule "^\.well-known/host-meta" "/public.php?service=host-meta" [qsappend, last]; rewriteRule "^\.well-known/host-meta\.json" "/public.php?service=host-meta-json" [qsappend, last]; rewriteRule "^\.well-known/webfinger" "/public.php?service=webfinger" [qsappend, last]; rewriteRule "^\.well-known/carddav" "/remote.php/dav/" [redirectWith permanent, last]; rewriteRule "^\.well-known/caldav" "/remote.php/dav/" [redirectWith permanent, last]; rewriteRule "^remote/(.*)" "remote.php" [qsappend, last]; rewriteRule "^(?:build|tests|config|lib|3rdparty|templates)/.*" "-" [redirectWith notfound, last]; rewriteCond "%{REQUEST_URI}" "!^/\.well-known/(acme-challenge|pki-validation)/.*" []; rewriteRule "^(?:\.|autotest|occ|issue|indie|db_|console).*" "-" [redirectWith notfound, last]; acmeChallengeAlias; end; web "cloud" with rewriteRule "^(.*)$" "https://cloud.elektrubadur.se$1" [redirectWith permanent]; end; emailAlias "admin" "bkhl"; emailAlias "info" "bkhl"; end; }}} command: {{{ ~/.acme.sh/acme.sh --issue -d elektrubadur.se -d www.elektrubadur.se -d bkhl.elektrubadur.se -d cloud.elektrubadur.se -d test.elektrubadur.se -w $HOME/www/acme/ }}} And later on just `~/.acme.sh/acme.sh --renew-all`