Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 68 additions & 53 deletions templates/web.letsencrypt.ssl.template.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
env:
LETSENCRYPT_DIR: "/shared/letsencrypt"
DISCOURSE_FORCE_HTTPS: true

hooks:
after_ssl:
- exec:
cmd:
- if [ -z "$LETSENCRYPT_ACCOUNT_EMAIL" ]; then echo "LETSENCRYPT_ACCOUNT_EMAIL ENV variable is required and has not been set."; exit 1; fi
- /bin/bash -c "if [[ ! \"$LETSENCRYPT_ACCOUNT_EMAIL\" =~ ([^@]+)@([^\.]+) ]]; then echo \"LETSENCRYPT_ACCOUNT_EMAIL is not a valid email address\"; exit 1; fi"

- exec:
cmd:
- cd /root && git clone --branch 3.0.6 --depth 1 https://github.com/acmesh-official/acme.sh.git && cd /root/acme.sh
- touch /var/spool/cron/crontabs/root
- install -d -m 0755 -g root -o root $LETSENCRYPT_DIR
- cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --install --log "${LETSENCRYPT_DIR}/acme.sh.log"
- cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --upgrade --auto-upgrade
- cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --set-default-ca --server letsencrypt

- file:
path: "/etc/nginx/letsencrypt.conf"
contents: |
run:
- exec:
cmd:
- curl https://raw.githubusercontent.com/acmesh-official/acme.sh/3.0.6/acme.sh > /opt/acme.sh
- chmod +x /opt/acme.sh
- file:
path: "/usr/local/bin/configure-letsencrypt"
chmod: "+x"
contents: |
#!/bin/bash
touch /var/spool/cron/crontabs/root
LETSENCRYPT_DIR="/shared/letsencrypt"
install -d -m 0755 -g root -o root $LETSENCRYPT_DIR
cd /opt
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --install --log "${LETSENCRYPT_DIR}/acme.sh.log"
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --upgrade --auto-upgrade
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --set-default-ca --server letsencrypt

cat << EOF > /etc/nginx/letsencrypt.conf
user www-data;
worker_processes auto;
daemon on;
Expand Down Expand Up @@ -50,20 +49,34 @@ hooks:
}
}
}
EOF

- file:
path: /etc/runit/1.d/letsencrypt
chmod: "+x"
contents: |
sed -Ei "s/^#?ACCOUNT_EMAIL=.+/ACCOUNT_EMAIL=${LETSENCRYPT_ACCOUNT_EMAIL}/" \
/shared/letsencrypt/account.conf

sed -Ei "s/ssl_certificate .+/ssl_certificate \/shared\/ssl\/${DISCOURSE_HOSTNAME}.cer;\
ssl_certificate \/shared\/ssl\/${DISCOURSE_HOSTNAME}_ecc.cer;/" \
/etc/nginx/conf.d/outlets/server/20-https.conf
sed -Ei "s/ssl_certificate_key .+/ssl_certificate_key \/shared\/ssl\/${DISCOURSE_HOSTNAME}.key; \
ssl_certificate_key \/shared\/ssl\/${DISCOURSE_HOSTNAME}_ecc.key;/" \
/etc/nginx/conf.d/outlets/server/20-https.conf

exec /usr/local/bin/letsencrypt

- file:
path: /usr/local/bin/letsencrypt
chmod: "+x"
contents: |
#!/bin/bash
LETSENCRYPT_DIR="/shared/letsencrypt"
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf

issue_cert() {
LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh --issue $2 -d $$ENV_DISCOURSE_HOSTNAME --keylength $1 -w /var/www/discourse/public
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh --issue $2 -d ${DISCOURSE_HOSTNAME} --keylength $1 -w /var/www/discourse/public
}

cert_exists() {
[[ "$(cd $$ENV_LETSENCRYPT_DIR/$$ENV_DISCOURSE_HOSTNAME$1 && openssl verify -CAfile <(openssl x509 -in ca.cer) fullchain.cer | grep "OK")" ]]
[[ "$(cd ${LETSENCRYPT_DIR}/${DISCOURSE_HOSTNAME}$1 && openssl verify -CAfile <(openssl x509 -in ca.cer) fullchain.cer | grep "OK")" ]]
}

########################################################
Expand All @@ -76,11 +89,11 @@ hooks:
issue_cert "4096" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh \
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh \
--installcert \
-d $$ENV_DISCOURSE_HOSTNAME \
--fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer \
--keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key \
-d ${DISCOURSE_HOSTNAME} \
--fullchainpath /shared/ssl/${DISCOURSE_HOSTNAME}.cer \
--keypath /shared/ssl/${DISCOURSE_HOSTNAME}.key \
--reloadcmd "sv reload nginx"

########################################################
Expand All @@ -93,11 +106,11 @@ hooks:
issue_cert "ec-256" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh \
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh \
--installcert --ecc \
-d $$ENV_DISCOURSE_HOSTNAME \
--fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer \
--keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.key \
-d ${DISCOURSE_HOSTNAME} \
--fullchainpath /shared/ssl/${DISCOURSE_HOSTNAME}_ecc.cer \
--keypath /shared/ssl/${DISCOURSE_HOSTNAME}_ecc.key \
--reloadcmd "sv reload nginx"

if cert_exists "" || cert_exists "_ecc"; then
Expand All @@ -106,22 +119,24 @@ hooks:

/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop

- replace:
filename: /shared/letsencrypt/account.conf
from: /#?ACCOUNT_EMAIL=.+/
to: |
ACCOUNT_EMAIL=$$ENV_LETSENCRYPT_ACCOUNT_EMAIL

- replace:
filename: "/etc/nginx/conf.d/outlets/server/20-https.conf"
from: /ssl_certificate.+/
to: |
ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer;
ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer;

- replace:
filename: "/etc/nginx/conf.d/outlets/server/20-https.conf"
from: /ssl_certificate_key.+/
to: |
ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key;
ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.key;
hooks:
after_ssl:
- file:
path: /etc/runit/1.d/install-ssl
chmod: "+x"
contents: |
#!/bin/bash
if [ -z "$DISCOURSE_HOSTNAME" ]; then
echo "DISCOURSE_HOSTNAME expected"
exit 1
fi
if [ -z "$LETSENCRYPT_ACCOUNT_EMAIL" ]; then
echo "LETSENCRYPT_ACCOUNT_EMAIL ENV not set. Skipping Let's Encrypt setup."
exit 0
fi
if [[ ! "$LETSENCRYPT_ACCOUNT_EMAIL" =~ ([^@]+)@([^\.]+) ]]; then
echo "LETSENCRYPT_ACCOUNT_EMAIL is not a valid email address"
exit 1
fi
/usr/local/bin/configure-ssl
exec /usr/local/bin/configure-letsencrypt
61 changes: 37 additions & 24 deletions templates/web.ssl.template.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
run:
- exec:
cmd:
- "mkdir -p /shared/ssl/"
- file:
path: "/etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf"
path: /etc/runit/1.d/install-ssl
hook: ssl
chmod: "+x"
contents: |
#!/bin/bash
if [ -z "$DISCOURSE_HOSTNAME" ]; then
echo "DISCOURSE_HOSTNAME expected"
exit 1
fi
if [ -n "$ENABLE_SSL" ]; then
exec /usr/local/bin/configure-ssl
fi

- file:
path: "/usr/local/bin/configure-ssl"
chmod: "+x"
contents: |
#!/bin/bash
mkdir -p /shared/ssl/

cat << EOF > /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf
server {
listen 80;
return 301 https://$$ENV_DISCOURSE_HOSTNAME$request_uri;
return 301 https://${DISCOURSE_HOSTNAME}$request_uri;
}
- file:
path: "/etc/nginx/conf.d/outlets/server/10-http.conf"
contents: ""
- file:
hook: ssl
path: "/etc/nginx/conf.d/outlets/server/20-https.conf"
contents: |
EOF

install /dev/null /etc/nginx/conf.d/outlets/server/10-http.conf

cat << EOF > /etc/nginx/conf.d/outlets/server/20-https.conf
listen 443 ssl;
http2 on;

Expand All @@ -32,17 +46,16 @@ run:

add_header Strict-Transport-Security 'max-age=31536000';

if ($http_host != $$ENV_DISCOURSE_HOSTNAME) {
rewrite (.*) https://$$ENV_DISCOURSE_HOSTNAME$1 permanent;
if (\$http_host != ${DISCOURSE_HOSTNAME}) {
rewrite (.*) https://${DISCOURSE_HOSTNAME}\$1 permanent;
}
- file:
path: "/etc/nginx/conf.d/outlets/discourse/20-https.conf"
contents: |
EOF

cat << EOF > /etc/nginx/conf.d/outlets/discourse/20-https.conf
add_header Strict-Transport-Security 'max-age=31536000';
- exec:
cmd:
- |-
if [ -f "/proc/net/if_inet6" ] ; then
sed -i 's/listen 80;/listen 80;\nlisten [::]:80;/g' /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf
sed -i 's/listen 443 ssl;/listen 443 ssl;\nlisten [::]:443 ssl;/g' /etc/nginx/conf.d/outlets/server/20-https.conf
fi
EOF

if [ -f "/proc/net/if_inet6" ] ; then
sed -i 's/listen 80;/listen 80;\nlisten [::]:80;/g' /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf
sed -i 's/listen 443 ssl;/listen 443 ssl;\nlisten [::]:443 ssl;/g' /etc/nginx/conf.d/outlets/server/20-https.conf
fi