Skip to content

Commit f5f378e

Browse files
committed
Add Authentication Feature + updates/improvements
1 parent 982f68e commit f5f378e

File tree

7 files changed

+83
-15
lines changed

7 files changed

+83
-15
lines changed

Dockerfile

+7-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ENV CLOUDFLARE_V6_SHA256 e7d84e6f9f8668279312a4ed836ce69cab1750d6745062c7e73d953
88

99
RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \
1010
&& DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y \
11-
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends wget curl certbot \
11+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends wget curl certbot pwgen \
1212
&& echo "---> INSTALLING s6-overlay" \
1313
&& wget https://github.com/just-containers/s6-overlay/releases/download/v1.17.0.0/s6-overlay-amd64.tar.gz \
1414
&& echo $S6_OVERLAY_SHA256 s6-overlay-amd64.tar.gz | sha256sum -c \
@@ -27,18 +27,21 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \
2727
&& wget https://www.cloudflare.com/ips-v6 \
2828
&& echo $CLOUDFLARE_V6_SHA256 ips-v6 | sha256sum -c \
2929
&& cat ips-v6 | sed -e 's/^/set_real_ip_from /' >> /etc/nginx/cloudflare.conf \
30-
&& echo "real_ip_header CF-Connecting-IP;" >> /etc/nginx/cloudflare.conf \
30+
&& echo "real_ip_header X-Forwarded-For;" >> /etc/nginx/cloudflare.conf \
31+
&& echo "real_ip_recursive on;" >> /etc/nginx/cloudflare.conf \
3132
&& rm ips-v6 ips-v4 \
3233
&& echo "---> Creating directories" \
3334
&& mkdir -p /etc/services.d/nginx /etc/services.d/certbot \
3435
&& echo "---> Cleaning up" \
3536
&& DEBIAN_FRONTEND=noninteractive apt-get remove -y wget \
36-
&& rm -Rf /var/lib/apt /var/cache/apt
37+
&& rm -Rf /var/lib/apt /var/cache/apt \
38+
&& touch /etc/nginx/auth_part1.conf /etc/nginx/auth_part2.conf /tmp/htpasswd
3739

3840
COPY services.d/nginx/* /etc/services.d/nginx/
3941
COPY services.d/certbot/* /etc/services.d/certbot/
40-
COPY nginx.conf /etc/nginx/
42+
COPY nginx.conf security_headers.conf /etc/nginx/
4143
COPY proxy.conf /etc/nginx/conf.d/default.conf
44+
COPY auth_part*.conf /root/
4245
COPY dhparams.pem /etc/nginx/
4346
COPY temp-setup-cert.pem /etc/nginx/temp-server-cert.pem
4447
COPY temp-setup-key.pem /etc/nginx/temp-server-key.pem

README.md

+21-7
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ Prior versions of this image used simp_le. It has been changed to use certbot du
1616

1717
## WARNING
1818

19-
This image's default configuration includes a String-Transport-Security header with expiry set to 18 weeks (~ 4 months). Visitors' browsers will cache this header for 6 months and will refuse to connect except over SSL.
20-
21-
Eventually, you may wish to:
22-
* Increase the header's expiration time.
23-
* Have your domain included in browser [HSTS Preload](https://hstspreload.appspot.com/) lists.
19+
This image's default configuration includes a `Strict-Transport-Security` header with expiry set to 1 year. Visitors' browsers will cache this header and will refuse to connect except over SSL. Eventually, you may wish to have your domain included in browser [HSTS Preload](https://hstspreload.appspot.com/) lists.
2420

2521
## Example Use (via docker-compose)
2622

@@ -41,6 +37,24 @@ Create a docker-compose.yml file as follows:
4137

4238
Then simply `docker-compose up`.
4339

40+
## Optional: Enable Simple Authentication
41+
42+
If the `DO_AUTH` environment variable is set to `required`, the proxy implements a simple authentication system.
43+
44+
A user meeting any of these three criteria will be allowed access to the proxied service:
45+
46+
* Users coming from an IP or CIDR range listed in the space-separated `WHITELIST_IPS` variable.
47+
* Users presenting a cookie named `magic_ssl_proxy_auth` set to the value of the `COOKIE_VALUE` variable.
48+
* Users providing HTTP Basic Authentication credentials, username `admin` with a password matching the `PROXY_PASSWORD` variable.
49+
50+
A user that correctly authenticates with HTTP Basic Authentication will have their `magic_ssl_proxy_auth` cookie set so that they are not required to re-authenticate.
51+
52+
By default, no IPs are whitelisted. When authentication is enabled, the `COOKIE_VALUE` and `PROXY_PASSWORD` values will be chosen randomly if they are not provided. If randomly chosen, the randomly chosen values will be output to the console during container startup. The `PROXY_PASSWORD` value will also be available in the `/tmp/proxy_password` file within the container, while the chosen `COOKIE_VALUE` will be available in the `/etc/nginx/auth_part1.conf` file.
53+
54+
When configuring IP based authentication, be mindful that reverse proxies and your Docker configuration may result in an apparent source IP that does not match the client's true IP address. Additional instances of the `set_real_ip_from` directive can be provided with the IP addresses of your trusted HTTP proxies. By default, Cloudflare IP addresses will be trusted to provide an `X-Forwarded-For` header. Directly exposing this image to the internet (e.g. via the `ports` directive as in the above example) will remove one source of potential problems with IP based authentication.
55+
56+
Nginx limits the length of your `COOKIE_VALUE` for performance reasons. If your `COOKIE_VALUE` is too long, nginx will refuse to start and will display errors relating to `server_names_hash_bucket_size` and `server_names_hash_max_size`. If you have difficulties, try decreasing the legnth of your cookie or add directives to your Nginx configuration to increase the maximum size.
57+
4458
## Certificate Data
4559

4660
A `/etc/letsencrypt` volume is used to maintain certificate data. An `account_key.json` file holds the key to your Let's Encrypt account - which provides a convenient way to revoke a certificate.
@@ -60,7 +74,7 @@ Reasonable defaults have been chosen for SSL cipher suites using [Mozilla's Reco
6074

6175
## Security Headers
6276

63-
Reasonable defaults have been chosen with an eye towards a configuration which is more secure by default. See https://www.owasp.org/index.php/List_of_useful_HTTP_headers for more information on the headers used.
77+
Reasonable defaults have been chosen with an eye towards a configuration which is more secure by default. See https://www.owasp.org/index.php/List_of_useful_HTTP_headers for more information on the headers used. These headers can be disabled by setting the `SECURITY_HEADERS` variable to `skip`. If your upstream server is itself sending these headers, setting the `SECURITY_HEADERS` variable will avoid the presence of multiple instances of these headers in responses.
6478

6579
## Dependencies
6680

@@ -76,7 +90,7 @@ Please file a pull request or create a new issue for problems or potential impro
7690

7791
# License
7892

79-
Copyright 2015 [Daniel Dent](https://www.danieldent.com/).
93+
Copyright 2015-2018 [Daniel Dent](https://www.danieldent.com/).
8094

8195
Licensed under the Apache License, Version 2.0 (the "License");
8296
you may not use these files except in compliance with the License.

auth_part1.conf

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
map $cookie_magic_ssl_proxy_auth $checkifcookieok {
2+
"${COOKIE_VALUE}" "yes";
3+
default "no";
4+
}
5+
6+
geo $checkifipok {
7+
${IPR_EXPANDED}
8+
default "no";
9+
}
10+
11+
map $checkifcookieok$checkifipok $do_proxy_auth {
12+
"yesyes" "off";
13+
"yesno" "off";
14+
"noyes" "off";
15+
default "Authentication Required";
16+
}

auth_part2.conf

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
auth_basic $do_proxy_auth;
2+
auth_basic_user_file /tmp/htpasswd;
3+
add_header Set-Cookie "magic_ssl_proxy_auth=${COOKIE_VALUE};max-age=3153600000;Secure;HttpOnly;path=/";

proxy.conf

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ upstream origin {
22
server ${UPSTREAM:-127.0.0.1};
33
}
44

5+
include /etc/nginx/auth_part1.conf;
6+
57
server {
68
listen 443 ssl http2;
79
server_name ${SERVERNAME:-example.com};
@@ -24,10 +26,8 @@ server {
2426
ssl_dhparam /etc/nginx/dhparams.pem;
2527

2628
# https://www.owasp.org/index.php/List_of_useful_HTTP_headers
27-
add_header Strict-Transport-Security "max-age=10886400";
28-
add_header X-Content-Type-Options "nosniff";
29-
add_header X-Frame-Options "SAMEORIGIN";
30-
add_header X-XSS-Protection "1; mode=block";
29+
add_header Strict-Transport-Security "max-age=31536000";
30+
include "/etc/nginx/security_headers.conf";
3131

3232
location /.well-known/acme-challenge {
3333
default_type "text/plain";
@@ -36,6 +36,7 @@ server {
3636
}
3737

3838
location / {
39+
include /etc/nginx/auth_part2.conf;
3940
proxy_set_header Host $host;
4041
proxy_set_header X-Forwarded-Proto $scheme;
4142
proxy_set_header X-Forwarded-Port $server_port;

security_headers.conf

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_header X-Content-Type-Options "nosniff";
2+
add_header X-Frame-Options "SAMEORIGIN";
3+
add_header X-XSS-Protection "1; mode=block";

services.d/nginx/run

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,34 @@
11
#!/usr/bin/with-contenv bash
22
/usr/local/bin/ep -v /etc/nginx/conf.d/*
33

4+
if [ "$DO_AUTH" == "required" ]; then
5+
cp /root/auth* /etc/nginx
6+
7+
# Set random cookie/password values if not provided
8+
if [ "x$COOKIE_VALUE" == "x" ]; then
9+
COOKIE_VALUE=$(pwgen -s -B 25)
10+
echo Cookie Value: $COOKIE_VALUE
11+
fi
12+
if [ "x$PROXY_PASSWORD" == "x" ]; then
13+
PROXY_PASSWORD=$(pwgen -s -B 25)
14+
echo Proxy Password: $PROXY_PASSWORD
15+
echo Proxy Password: $PROXY_PASSWORD > /tmp/proxy_password
16+
fi
17+
echo -n "admin:" > /tmp/htpasswd
18+
echo $PROXY_PASSWORD | openssl passwd -apr1 -stdin >> /tmp/htpasswd
19+
20+
IPR_EXPANDED=""
21+
for ip in $WHITELIST_IPS; do
22+
IPR_EXPANDED="$IPR_EXPANDED $ip \"yes\"; "
23+
done
24+
25+
COOKIE_VALUE="$COOKIE_VALUE" IPR_EXPANDED="$IPR_EXPANDED" /usr/local/bin/ep -v /etc/nginx/auth_part*.conf
26+
fi
27+
28+
if [ "$SECURITY_HEADERS" == "skip" ]; then
29+
echo "" > /etc/nginx/security_headers.conf
30+
fi
31+
432
if [ ! -e /etc/letsencrypt/fullchain-copy.pem ]; then
533
cp /etc/nginx/temp-server-cert.pem /etc/letsencrypt/fullchain-copy.pem
634
fi

0 commit comments

Comments
 (0)