Skip to content

Commit c9064be

Browse files
FEATURE: Move letsencrypt scripts to work on boot (#977)
* Move letsencrypt scripts to work on boot Allows ssl and letsencrypt templates to run on boot via initscripts This change adds the decision to configure https or letsencrypt to be at runtime rather than at build time via env vars. Under the hood, these are the commands, just migrated to shellscripts that run when a container boots. Runs on existence of ENABLE_SSL (base ssl template) or LETSENCRYPT_ACCOUNT_EMAIL (ssl template+letsencrypt template) Both cases checks and errors on blank hostname. * DEV: Install acme.sh using curl rather than git
1 parent 34dd695 commit c9064be

File tree

2 files changed

+105
-77
lines changed

2 files changed

+105
-77
lines changed
Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
env:
2-
LETSENCRYPT_DIR: "/shared/letsencrypt"
32
DISCOURSE_FORCE_HTTPS: true
43

5-
hooks:
6-
after_ssl:
7-
- exec:
8-
cmd:
9-
- if [ -z "$LETSENCRYPT_ACCOUNT_EMAIL" ]; then echo "LETSENCRYPT_ACCOUNT_EMAIL ENV variable is required and has not been set."; exit 1; fi
10-
- /bin/bash -c "if [[ ! \"$LETSENCRYPT_ACCOUNT_EMAIL\" =~ ([^@]+)@([^\.]+) ]]; then echo \"LETSENCRYPT_ACCOUNT_EMAIL is not a valid email address\"; exit 1; fi"
11-
12-
- exec:
13-
cmd:
14-
- cd /root && git clone --branch 3.0.6 --depth 1 https://github.com/acmesh-official/acme.sh.git && cd /root/acme.sh
15-
- touch /var/spool/cron/crontabs/root
16-
- install -d -m 0755 -g root -o root $LETSENCRYPT_DIR
17-
- cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --install --log "${LETSENCRYPT_DIR}/acme.sh.log"
18-
- cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --upgrade --auto-upgrade
19-
- cd /root/acme.sh && LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --set-default-ca --server letsencrypt
20-
21-
- file:
22-
path: "/etc/nginx/letsencrypt.conf"
23-
contents: |
4+
run:
5+
- exec:
6+
cmd:
7+
- curl https://raw.githubusercontent.com/acmesh-official/acme.sh/3.0.6/acme.sh > /opt/acme.sh
8+
- chmod +x /opt/acme.sh
9+
- file:
10+
path: "/usr/local/bin/configure-letsencrypt"
11+
chmod: "+x"
12+
contents: |
13+
#!/bin/bash
14+
touch /var/spool/cron/crontabs/root
15+
LETSENCRYPT_DIR="/shared/letsencrypt"
16+
install -d -m 0755 -g root -o root $LETSENCRYPT_DIR
17+
cd /opt
18+
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --install --log "${LETSENCRYPT_DIR}/acme.sh.log"
19+
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --upgrade --auto-upgrade
20+
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ./acme.sh --set-default-ca --server letsencrypt
21+
22+
cat << EOF > /etc/nginx/letsencrypt.conf
2423
user www-data;
2524
worker_processes auto;
2625
daemon on;
@@ -50,20 +49,34 @@ hooks:
5049
}
5150
}
5251
}
52+
EOF
5353
54-
- file:
55-
path: /etc/runit/1.d/letsencrypt
56-
chmod: "+x"
57-
contents: |
54+
sed -Ei "s/^#?ACCOUNT_EMAIL=.+/ACCOUNT_EMAIL=${LETSENCRYPT_ACCOUNT_EMAIL}/" \
55+
/shared/letsencrypt/account.conf
56+
57+
sed -Ei "s/ssl_certificate .+/ssl_certificate \/shared\/ssl\/${DISCOURSE_HOSTNAME}.cer;\
58+
ssl_certificate \/shared\/ssl\/${DISCOURSE_HOSTNAME}_ecc.cer;/" \
59+
/etc/nginx/conf.d/outlets/server/20-https.conf
60+
sed -Ei "s/ssl_certificate_key .+/ssl_certificate_key \/shared\/ssl\/${DISCOURSE_HOSTNAME}.key; \
61+
ssl_certificate_key \/shared\/ssl\/${DISCOURSE_HOSTNAME}_ecc.key;/" \
62+
/etc/nginx/conf.d/outlets/server/20-https.conf
63+
64+
exec /usr/local/bin/letsencrypt
65+
66+
- file:
67+
path: /usr/local/bin/letsencrypt
68+
chmod: "+x"
69+
contents: |
5870
#!/bin/bash
71+
LETSENCRYPT_DIR="/shared/letsencrypt"
5972
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
6073
6174
issue_cert() {
62-
LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh --issue $2 -d $$ENV_DISCOURSE_HOSTNAME --keylength $1 -w /var/www/discourse/public
75+
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh --issue $2 -d ${DISCOURSE_HOSTNAME} --keylength $1 -w /var/www/discourse/public
6376
}
6477
6578
cert_exists() {
66-
[[ "$(cd $$ENV_LETSENCRYPT_DIR/$$ENV_DISCOURSE_HOSTNAME$1 && openssl verify -CAfile <(openssl x509 -in ca.cer) fullchain.cer | grep "OK")" ]]
79+
[[ "$(cd ${LETSENCRYPT_DIR}/${DISCOURSE_HOSTNAME}$1 && openssl verify -CAfile <(openssl x509 -in ca.cer) fullchain.cer | grep "OK")" ]]
6780
}
6881
6982
########################################################
@@ -76,11 +89,11 @@ hooks:
7689
issue_cert "4096" "--force"
7790
fi
7891
79-
LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh \
92+
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh \
8093
--installcert \
81-
-d $$ENV_DISCOURSE_HOSTNAME \
82-
--fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer \
83-
--keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key \
94+
-d ${DISCOURSE_HOSTNAME} \
95+
--fullchainpath /shared/ssl/${DISCOURSE_HOSTNAME}.cer \
96+
--keypath /shared/ssl/${DISCOURSE_HOSTNAME}.key \
8497
--reloadcmd "sv reload nginx"
8598
8699
########################################################
@@ -93,11 +106,11 @@ hooks:
93106
issue_cert "ec-256" "--force"
94107
fi
95108
96-
LE_WORKING_DIR="${LETSENCRYPT_DIR}" $$ENV_LETSENCRYPT_DIR/acme.sh \
109+
LE_WORKING_DIR="${LETSENCRYPT_DIR}" ${LETSENCRYPT_DIR}/acme.sh \
97110
--installcert --ecc \
98-
-d $$ENV_DISCOURSE_HOSTNAME \
99-
--fullchainpath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer \
100-
--keypath /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.key \
111+
-d ${DISCOURSE_HOSTNAME} \
112+
--fullchainpath /shared/ssl/${DISCOURSE_HOSTNAME}_ecc.cer \
113+
--keypath /shared/ssl/${DISCOURSE_HOSTNAME}_ecc.key \
101114
--reloadcmd "sv reload nginx"
102115
103116
if cert_exists "" || cert_exists "_ecc"; then
@@ -106,22 +119,24 @@ hooks:
106119
107120
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
108121
109-
- replace:
110-
filename: /shared/letsencrypt/account.conf
111-
from: /#?ACCOUNT_EMAIL=.+/
112-
to: |
113-
ACCOUNT_EMAIL=$$ENV_LETSENCRYPT_ACCOUNT_EMAIL
114-
115-
- replace:
116-
filename: "/etc/nginx/conf.d/outlets/server/20-https.conf"
117-
from: /ssl_certificate.+/
118-
to: |
119-
ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.cer;
120-
ssl_certificate /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.cer;
121-
122-
- replace:
123-
filename: "/etc/nginx/conf.d/outlets/server/20-https.conf"
124-
from: /ssl_certificate_key.+/
125-
to: |
126-
ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME.key;
127-
ssl_certificate_key /shared/ssl/$$ENV_DISCOURSE_HOSTNAME_ecc.key;
122+
hooks:
123+
after_ssl:
124+
- file:
125+
path: /etc/runit/1.d/install-ssl
126+
chmod: "+x"
127+
contents: |
128+
#!/bin/bash
129+
if [ -z "$DISCOURSE_HOSTNAME" ]; then
130+
echo "DISCOURSE_HOSTNAME expected"
131+
exit 1
132+
fi
133+
if [ -z "$LETSENCRYPT_ACCOUNT_EMAIL" ]; then
134+
echo "LETSENCRYPT_ACCOUNT_EMAIL ENV not set. Skipping Let's Encrypt setup."
135+
exit 0
136+
fi
137+
if [[ ! "$LETSENCRYPT_ACCOUNT_EMAIL" =~ ([^@]+)@([^\.]+) ]]; then
138+
echo "LETSENCRYPT_ACCOUNT_EMAIL is not a valid email address"
139+
exit 1
140+
fi
141+
/usr/local/bin/configure-ssl
142+
exec /usr/local/bin/configure-letsencrypt

templates/web.ssl.template.yml

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
run:
2-
- exec:
3-
cmd:
4-
- "mkdir -p /shared/ssl/"
52
- file:
6-
path: "/etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf"
3+
path: /etc/runit/1.d/install-ssl
4+
hook: ssl
5+
chmod: "+x"
6+
contents: |
7+
#!/bin/bash
8+
if [ -z "$DISCOURSE_HOSTNAME" ]; then
9+
echo "DISCOURSE_HOSTNAME expected"
10+
exit 1
11+
fi
12+
if [ -n "$ENABLE_SSL" ]; then
13+
exec /usr/local/bin/configure-ssl
14+
fi
15+
16+
- file:
17+
path: "/usr/local/bin/configure-ssl"
18+
chmod: "+x"
719
contents: |
20+
#!/bin/bash
21+
mkdir -p /shared/ssl/
22+
23+
cat << EOF > /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf
824
server {
925
listen 80;
10-
return 301 https://$$ENV_DISCOURSE_HOSTNAME$request_uri;
26+
return 301 https://${DISCOURSE_HOSTNAME}$request_uri;
1127
}
12-
- file:
13-
path: "/etc/nginx/conf.d/outlets/server/10-http.conf"
14-
contents: ""
15-
- file:
16-
hook: ssl
17-
path: "/etc/nginx/conf.d/outlets/server/20-https.conf"
18-
contents: |
28+
EOF
29+
30+
install /dev/null /etc/nginx/conf.d/outlets/server/10-http.conf
31+
32+
cat << EOF > /etc/nginx/conf.d/outlets/server/20-https.conf
1933
listen 443 ssl;
2034
http2 on;
2135
@@ -32,17 +46,16 @@ run:
3246
3347
add_header Strict-Transport-Security 'max-age=31536000';
3448
35-
if ($http_host != $$ENV_DISCOURSE_HOSTNAME) {
36-
rewrite (.*) https://$$ENV_DISCOURSE_HOSTNAME$1 permanent;
49+
if (\$http_host != ${DISCOURSE_HOSTNAME}) {
50+
rewrite (.*) https://${DISCOURSE_HOSTNAME}\$1 permanent;
3751
}
38-
- file:
39-
path: "/etc/nginx/conf.d/outlets/discourse/20-https.conf"
40-
contents: |
52+
EOF
53+
54+
cat << EOF > /etc/nginx/conf.d/outlets/discourse/20-https.conf
4155
add_header Strict-Transport-Security 'max-age=31536000';
42-
- exec:
43-
cmd:
44-
- |-
45-
if [ -f "/proc/net/if_inet6" ] ; then
46-
sed -i 's/listen 80;/listen 80;\nlisten [::]:80;/g' /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf
47-
sed -i 's/listen 443 ssl;/listen 443 ssl;\nlisten [::]:443 ssl;/g' /etc/nginx/conf.d/outlets/server/20-https.conf
48-
fi
56+
EOF
57+
58+
if [ -f "/proc/net/if_inet6" ] ; then
59+
sed -i 's/listen 80;/listen 80;\nlisten [::]:80;/g' /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf
60+
sed -i 's/listen 443 ssl;/listen 443 ssl;\nlisten [::]:443 ssl;/g' /etc/nginx/conf.d/outlets/server/20-https.conf
61+
fi

0 commit comments

Comments
 (0)