Skip to content
Draft
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
7 changes: 6 additions & 1 deletion image/base/install-nginx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ git clone https://github.com/google/ngx_brotli.git
cd /tmp/ngx_brotli
git submodule update --init

# nginx ACME module (Let's Encrypt support without acme.sh)
cd /tmp
git clone --depth 1 https://github.com/nginx/nginx-acme.git

cd /tmp/nginx-$VERSION
# ignoring deprecations with -Wno-deprecated-declarations while we wait for this https://github.com/google/ngx_brotli/issues/39#issuecomment-254093378
./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wno-deprecated-declarations' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_v2_module --with-http_sub_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/tmp/ngx_brotli
./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wno-deprecated-declarations' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_v2_module --with-http_sub_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/tmp/ngx_brotli --add-module=/tmp/nginx-acme

make install

Expand All @@ -35,4 +39,5 @@ rm -f /tmp/nginx-$VERSION.tar.gz
rm -f /tmp/nginx-$VERSION.tar.gz.asc
rm -fr /tmp/libbrotli
rm -fr /tmp/ngx_brotli
rm -fr /tmp/nginx-acme
rm -fr /etc/nginx/modules-enabled/*
82 changes: 82 additions & 0 deletions templates/web.letsencrypt-nginx.ssl.template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
env:
DISCOURSE_FORCE_HTTPS: true
LETSENCRYPT_ACCOUNT_EMAIL: # optional: contact address for ACME account registration

run:
- file:
path: "/usr/local/bin/configure-letsencrypt-nginx"
chmod: "+x"
contents: |
#!/bin/bash
set -e

STATE_DIR="/shared/letsencrypt-nginx"
install -d -m 0700 -g root -o root "$STATE_DIR"

if [ -n "$LETSENCRYPT_ACCOUNT_EMAIL" ]; then
CONTACT_LINE="contact mailto:${LETSENCRYPT_ACCOUNT_EMAIL};"
else
CONTACT_LINE=""
fi

# http {} level configuration for the nginx ACME module.
# /etc/nginx/conf.d/*.conf is included from the main http block.
cat << EOF > /etc/nginx/conf.d/letsencrypt-acme.conf
resolver 1.1.1.1 8.8.8.8 ipv6=off;

acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
${CONTACT_LINE}
state_path ${STATE_DIR};
accept_terms_of_service;
}

acme_shared_zone zone=acme_shared:1M;
EOF

# server {} outlet — replace the static ssl_certificate paths written by
# web.ssl.template.yml with the ACME-managed variables and enable the
# issuer for this server.
cat << EOF > /etc/nginx/conf.d/outlets/server/20-https.conf
listen 443 ssl;
listen [::]:443 ssl;
http2 on;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

acme_certificate letsencrypt;
ssl_certificate \$acme_certificate;
ssl_certificate_key \$acme_certificate_key;
ssl_certificate_cache max=2;

ssl_session_tickets off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:1m;

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

if (\$http_host != ${DISCOURSE_HOSTNAME}) {
rewrite (.*) https://${DISCOURSE_HOSTNAME}\$1 permanent;
}
EOF

# The port 80 redirect server written by web.ssl.template.yml already
# serves /.well-known/* — the ACME module piggybacks on that location
# path for HTTP-01 challenges. No further changes needed there.

grep -q 'force_https' /var/www/discourse/config/discourse.conf \
|| echo "force_https = 'true'" >> /var/www/discourse/config/discourse.conf

hooks:
after_ssl:
- replace:
filename: /etc/runit/1.d/install-ssl
from: "# after ssl"
to: |
if [ -z "$DISABLE_LETSENCRYPT" ] || [ -n "$ENABLE_LETSENCRYPT" ]; then
/usr/local/bin/configure-ssl
/usr/local/bin/configure-letsencrypt-nginx
fi
# after ssl
Loading