diff --git a/files/nginx/redirector.conf b/files/nginx/redirector.conf index 08e33bd5..48b2e8ba 100644 --- a/files/nginx/redirector.conf +++ b/files/nginx/redirector.conf @@ -4,6 +4,10 @@ server { listen 80 default_server reuseport; listen [::]:80 default_server reuseport; + if ($http_host != ${CNAME}) { + return 421; + } + # Anything requesting this particular URL should be served content from # Certbot's folder so the HTTP-01 ACME challenges can be completed for the # HTTPS certificates. diff --git a/files/nginx/setup-odk.sh b/files/nginx/setup-odk.sh index 85520dd5..bb080c9c 100644 --- a/files/nginx/setup-odk.sh +++ b/files/nginx/setup-odk.sh @@ -25,12 +25,13 @@ if [ "$SSL_TYPE" = "selfsign" ] && [ ! -s "$SELFSIGN_PATH/privkey.pem" ]; then -days 3650 -nodes -sha256 fi +CNAME="$( [ "$SSL_TYPE" = "customssl" ] && echo "local" || echo "$DOMAIN")" +export CNAME + # start from fresh templates in case ssl type has changed echo "writing fresh nginx templates..." # redirector.conf gets deleted if using upstream SSL so copy it back -cp /usr/share/odk/nginx/redirector.conf /etc/nginx/conf.d/redirector.conf - -CNAME=$( [ "$SSL_TYPE" = "customssl" ] && echo "local" || echo "$DOMAIN") \ +envsubst '$CNAME' < /usr/share/odk/nginx/redirector.conf > /etc/nginx/conf.d/redirector.conf envsubst '$SSL_TYPE $CNAME $SENTRY_ORG_SUBDOMAIN $SENTRY_KEY $SENTRY_PROJECT' \ < /usr/share/odk/nginx/odk.conf.template \ > /etc/nginx/conf.d/odk.conf @@ -49,7 +50,7 @@ else echo "starting nginx for upstream ssl..." else # remove letsencrypt challenge reply, but keep 80 to 443 redirection - perl -i -ne 'print if $. < 7 || $. > 14' /etc/nginx/conf.d/redirector.conf + perl -i -ne 'print if $. < 11 || $. > 18' /etc/nginx/conf.d/redirector.conf echo "starting nginx for custom ssl and self-signed certs..." fi exec nginx -g "daemon off;" diff --git a/test/run-tests.sh b/test/run-tests.sh index 3833414f..5ee0cb3d 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -39,7 +39,7 @@ wait_for_http_response 5 localhost:8383/health 200 log "Waiting for mock enketo..." wait_for_http_response 5 localhost:8005/health 200 log "Waiting for nginx..." -wait_for_http_response 90 localhost:9000 301 +wait_for_http_response 90 localhost:9000 421 npm run test:nginx diff --git a/test/test-nginx.js b/test/test-nginx.js index a6181f5f..68eca608 100644 --- a/test/test-nginx.js +++ b/test/test-nginx.js @@ -126,6 +126,16 @@ describe('nginx config', () => { assert.equal(body['x-forwarded-proto'], 'https'); }); + it('should reject HTTP requests with incorrect host header supplied', async () => { + // when + const res = await fetchHttp('/', { headers:{ host:'bad.example.com' } }); + + console.log('res.location:', res.headers.get('location')); + + // then + assert.equal(res.status, 421); + }); + it('should reject HTTPS requests with incorrect host header supplied', async () => { // when const res = await fetchHttps('/', { headers:{ host:'bad.example.com' } });