├── Dockerfile ├── LICENSE ├── README.md ├── auth_part1.conf ├── auth_part2.conf ├── dhparams.pem ├── docker-compose.yml ├── hsts.conf ├── nginx.conf ├── proxy.conf ├── regen-dhparams.sh ├── security_headers.conf ├── services.d ├── certbot │ └── run └── nginx │ ├── finish │ └── run ├── temp-setup-cert.pem └── temp-setup-key.pem /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx 2 | MAINTAINER Daniel Dent (https://www.danieldent.com/) 3 | 4 | ENV S6_OVERLAY_SHA256 65f6e4dae229f667e38177d5cad0159af31754b9b8f369096b5b7a9b4580d098 5 | ENV ENVPLATE_SHA256 8366c3c480379dc325dea725aac86212c5f5d1bf55f5a9ef8e92375f42d55a41 6 | ENV CLOUDFLARE_V4_SHA256 db746a8739a51088c27d0b3c48679d21a69aab304d4c92af3ec0e89145b0cadd 7 | ENV CLOUDFLARE_V6_SHA256 559b5c5a20088758b4643621ae80be0a71567742ae1fe8e4ff32d1ca26297f8f 8 | 9 | RUN DEBIAN_FRONTEND=noninteractive apt-get update -q \ 10 | && DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y \ 11 | && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends wget curl certbot pwgen \ 12 | && echo "---> INSTALLING s6-overlay" \ 13 | && wget https://github.com/just-containers/s6-overlay/releases/download/v1.17.0.0/s6-overlay-amd64.tar.gz \ 14 | && echo $S6_OVERLAY_SHA256 s6-overlay-amd64.tar.gz | sha256sum -c \ 15 | && tar xzf s6-overlay-amd64.tar.gz -C / \ 16 | && rm s6-overlay-amd64.tar.gz \ 17 | && echo "---> INSTALLING envplate" \ 18 | && wget https://github.com/kreuzwerker/envplate/releases/download/v0.0.8/ep-linux \ 19 | && echo $ENVPLATE_SHA256 ep-linux | sha256sum -c \ 20 | && chmod +x ep-linux \ 21 | && mv ep-linux /usr/local/bin/ep \ 22 | && echo "---> CREATING CloudFlare Config Snippet (not included in config by default)" \ 23 | && echo '#Cloudflare' > /etc/nginx/cloudflare.conf \ 24 | && wget https://www.cloudflare.com/ips-v4 \ 25 | && sort ips-v4 > ips-v4.sorted \ 26 | && echo $CLOUDFLARE_V4_SHA256 ips-v4.sorted | sha256sum -c \ 27 | && cat ips-v4 | sed -e 's/^/set_real_ip_from /' -e 's/$/;/' >> /etc/nginx/cloudflare.conf \ 28 | && wget https://www.cloudflare.com/ips-v6 \ 29 | && sort ips-v6 > ips-v6.sorted \ 30 | && echo $CLOUDFLARE_V6_SHA256 ips-v6.sorted | sha256sum -c \ 31 | && cat ips-v6 | sed -e 's/^/set_real_ip_from /' -e 's/$/;/' >> /etc/nginx/cloudflare.conf \ 32 | && rm ips-v6 ips-v4 ips-v6.sorted ips-v4.sorted \ 33 | && echo "---> Creating directories" \ 34 | && mkdir -p /etc/services.d/nginx /etc/services.d/certbot \ 35 | && echo "---> Cleaning up" \ 36 | && DEBIAN_FRONTEND=noninteractive apt-get remove -y wget \ 37 | && rm -Rf /var/lib/apt /var/cache/apt \ 38 | && touch /etc/nginx/auth_part1.conf \ 39 | /etc/nginx/auth_part2.conf \ 40 | /etc/nginx/request_size.conf \ 41 | /etc/nginx/main_location.conf \ 42 | /etc/nginx/trusted_proxies.conf \ 43 | /tmp/htpasswd 44 | 45 | COPY services.d/nginx/* /etc/services.d/nginx/ 46 | COPY services.d/certbot/* /etc/services.d/certbot/ 47 | COPY nginx.conf security_headers.conf hsts.conf /etc/nginx/ 48 | COPY proxy.conf /etc/nginx/conf.d/default.conf 49 | COPY auth_part*.conf /root/ 50 | COPY dhparams.pem /etc/nginx/ 51 | COPY temp-setup-cert.pem /etc/nginx/temp-server-cert.pem 52 | COPY temp-setup-key.pem /etc/nginx/temp-server-key.pem 53 | 54 | VOLUME "/etc/letsencrypt" 55 | 56 | ENTRYPOINT ["/init"] 57 | CMD [] 58 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 Daniel Dent 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use these files except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SSL Front-End Proxy With Automatic Free Certificate Management 2 | 3 | Zero configuration required - set up SSL in 30 seconds. Out of the box A rating at SSL labs. HTTP/2 enabled for increased performance. 4 | 5 | This image contains nginx along with some glue code to automatically obtain and renew a free DV SSL certificate from [Let's Encrypt](https://letsencrypt.org/). 6 | 7 | It is configured by setting two environment variables: 8 | * `UPSTREAM` - The IP address or hostname (and optional port) of the upstream server to proxy requests towards. 9 | * `SERVERNAME` - The hostname to listen to. The system will automatically obtain an SSL certificate for this hostname. 10 | 11 | An optional `EXTRANAMES` variable can be provided with a list of additional domains to request as subject-alternative-names for the certificate. 12 | 13 | Certificates from Let's Encrypt are issued with a 90 day expiration. This image will automatically renew the certificate when it is 60 days old. 14 | 15 | Prior versions of this image used simp_le. It has been changed to use certbot due to reliability issues with simp_le. 16 | 17 | ## WARNING - HSTS Strict-Transport-Security Header 18 | 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. 20 | 21 | This header can be customized with the `HSTS_HEADER` variable. If set to `skip`, no HSTS header will be used. If set to any other value, the value of the `HSTS_HEADER` variable will be used as the header's value. e.g. to prepare for HSTS preload, you could set `HSTS_HEADER` to `max-age=31536000; includeSubDomains; preload`. 22 | 23 | ## Example Use (via docker-compose) 24 | 25 | Create a docker-compose.yml file as follows: 26 | 27 | nginx-ssl-proxy: 28 | image: danieldent/nginx-ssl-proxy 29 | restart: always 30 | environment: 31 | UPSTREAM: 127.0.0.1:8080 32 | SERVERNAME: test.example.com 33 | EXTRANAMES: www.test.example.com,test2.example.com 34 | ports: 35 | - "80:80" 36 | - "443:443" 37 | volumes: 38 | - "/etc/letsencrypt" 39 | 40 | Then simply `docker-compose up`. 41 | 42 | ## Optional: Enable Simple Authentication 43 | 44 | If the `DO_AUTH` environment variable is set to `required`, the proxy implements a simple authentication system. 45 | 46 | A user meeting any of these three criteria will be allowed access to the proxied service: 47 | 48 | * Users coming from an IP or CIDR range listed in the space-separated `WHITELIST_IPS` variable. 49 | * Users presenting a cookie named `magic_ssl_proxy_auth` set to the value of the `COOKIE_VALUE` variable. 50 | * Users providing HTTP Basic Authentication credentials, username `admin` with a password matching the `PROXY_PASSWORD` variable. 51 | 52 | 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. 53 | 54 | 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. 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 | 58 | ## Optional: Use upstream `X-Forwarded-For` headers 59 | 60 | When configuring IP based authentication, be mindful that upstream reverse proxies and your Docker configuration may result in an apparent source IP that does not match the client's true IP address. 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. 61 | 62 | Set the `REAL_IP_RECURSIVE` environment variable to `on` to cause Nginx to parse & use upstream `X-Forwarded-For` headers. 63 | 64 | The list of IPs or CIDR ranges from which Nginx will trust the `X-Forwarded-For` variable can be specified in the `SET_REAL_IP_FROM` variable. 65 | 66 | As a convenience, setting `SET_REAL_IP_FROM_CLOUDFLARE` to `yes` will cause Cloudflare's reverse proxy source IP addresses to be appended to the provided `SET_REAL_IP_FROM` list. 67 | 68 | ## Optional: Adjust request size limits & buffer size 69 | 70 | The `NGINX_CLIENT_MAX_BODY_SIZE` and `NGINX_CLIENT_BODY_BUFFER_SIZE` variables can be used to set nginx's `client_max_body_size` and `client_body_buffer_size` directives. This is most commonly required when users are uploading files to the proxied service. 71 | 72 | E.g. With `NGINX_CLIENT_MAX_BODY_SIZE` set to `100m`, nginx will allow a maximum body size of 100 megabytes. When requests are larger than `client_body_buffer_size`, nginx buffers the request using a temporary file. A larger `client_body_buffer_size` will use more memory, but will also reduce disk I/O. In many scenarios, a larger buffer size will result in increased performance. Different tradeoffs will be appropriate for different environments and use cases. 73 | 74 | ## Optional: Add Arbitrary Nginx Config 75 | 76 | The `/etc/nginx/main_location.conf` file provides a place to add arbitrary Nginx configuration directives to the main location block in the Nginx configuration file. The file is empty and can be safely overwritten in a downstream image or using a Docker volume. 77 | 78 | ## Certificate Data 79 | 80 | 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. 81 | 82 | ## Customizing 83 | 84 | Nginx configuration can be customized by editing [proxy.conf](https://github.com/DanielDent/docker-nginx-ssl-proxy/blob/master/proxy.conf) and placing a new copy of it at `/etc/nginx/conf.d/default.conf`. 85 | 86 | Example `Dockerfile`: 87 | 88 | FROM danieldent/nginx-ssl-proxy 89 | COPY proxy.conf /etc/nginx/conf.d/default.conf 90 | 91 | ## SSL Settings 92 | 93 | Reasonable defaults have been chosen for SSL cipher suites using [Mozilla's Recommendations](https://wiki.mozilla.org/Security/Server_Side_TLS). Very old browsers (such as IE6) will be unable to connect with the default settings. 94 | 95 | ## Security Headers 96 | 97 | 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. 98 | 99 | ## Dependencies 100 | 101 | * [nginx](https://hub.docker.com/_/nginx/) - proxy server 102 | * [certbot](https://certbot.eff.org/) - for handling certificate creation & validation (+ some wrappers in this image) 103 | * [envplate](https://github.com/kreuzwerker/envplate) - for allowing use of environment variables in Nginx configuration 104 | * [s6-overlay](https://github.com/just-containers/s6-overlay) - for PID 1, process supervision, zombie reaping 105 | 106 | # Issues, Contributing 107 | 108 | If you run into any problems with this image, please check for issues on [GitHub](https://github.com/DanielDent/docker-nginx-ssl-proxy/issues). 109 | Please file a pull request or create a new issue for problems or potential improvements. 110 | 111 | # License 112 | 113 | Copyright 2015-2018 [Daniel Dent](https://www.danieldent.com/). 114 | 115 | Licensed under the Apache License, Version 2.0 (the "License"); 116 | you may not use these files except in compliance with the License. 117 | You may obtain a copy of the License at 118 | 119 | http://www.apache.org/licenses/LICENSE-2.0 120 | 121 | Unless required by applicable law or agreed to in writing, software 122 | distributed under the License is distributed on an "AS IS" BASIS, 123 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124 | See the License for the specific language governing permissions and 125 | limitations under the License. 126 | 127 | Third-party contents included in builds of the image are licensed separately. 128 | -------------------------------------------------------------------------------- /auth_part1.conf: -------------------------------------------------------------------------------- 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 | } 17 | -------------------------------------------------------------------------------- /auth_part2.conf: -------------------------------------------------------------------------------- 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=/"; 4 | -------------------------------------------------------------------------------- /dhparams.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN DH PARAMETERS----- 2 | MIIBCAKCAQEA3x50AoVo52+n1fGvKzRQRg9QQq7meRlXLEr7cVGTV26qlYRccKJY 3 | V/yQX6ox+KP6jl+w3t5kPjkukzIwuBmhfza+MfGG39vvSjCjiiZFs9molaUJMIdS 4 | CQgEjlFoXWTR9S71OWb9rB3iPF5YAbz939bCu4eQ/zVUh40Oa8/nxo13aYdmWc8h 5 | GVdOPuRUOBgHflZOy1295DfeAFoZ1YJpkBFh1+HKpdlQFENqc+I8urlWbrymSHrn 6 | bG77+TF2JOiErnLAgdsg1xC1UoQS/IR09B7WmvROM/s2Oj0Q33RlLo/ZblMZJNqT 7 | JQyZKcKIvlns7I2OieU7QYou//S9M/Z+swIBAg== 8 | -----END DH PARAMETERS----- 9 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | #!docker-compose.yml 2 | 3 | nginx-ssl-proxy: 4 | image: danieldent/nginx-ssl-proxy 5 | restart: always 6 | environment: 7 | UPSTREAM: 127.0.0.1:8080 8 | SERVERNAME: test.example.com 9 | ports: 10 | - "80:80" 11 | - "443:443" 12 | volumes: 13 | - "/etc/letsencrypt" 14 | -------------------------------------------------------------------------------- /hsts.conf: -------------------------------------------------------------------------------- 1 | add_header Strict-Transport-Security "max-age=31536000" always; 2 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | 2 | user nginx; 3 | worker_processes auto; 4 | 5 | error_log /var/log/nginx/error.log warn; 6 | pid /var/run/nginx.pid; 7 | 8 | 9 | events { 10 | worker_connections 1024; 11 | } 12 | 13 | 14 | http { 15 | server_tokens off; 16 | 17 | include /etc/nginx/mime.types; 18 | default_type application/octet-stream; 19 | 20 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 21 | '$status $body_bytes_sent "$http_referer" ' 22 | '"$http_user_agent" "$http_x_forwarded_for"'; 23 | 24 | access_log /var/log/nginx/access.log main; 25 | 26 | sendfile on; 27 | #tcp_nopush on; 28 | 29 | keepalive_timeout 65; 30 | 31 | #gzip on; 32 | 33 | include /etc/nginx/conf.d/*.conf; 34 | } 35 | -------------------------------------------------------------------------------- /proxy.conf: -------------------------------------------------------------------------------- 1 | upstream origin { 2 | server ${UPSTREAM:-127.0.0.1}; 3 | } 4 | 5 | include /etc/nginx/auth_part1.conf; 6 | 7 | server { 8 | listen 443 ssl http2; 9 | server_name ${SERVERNAME:-example.com}; 10 | ssl_certificate /etc/letsencrypt/fullchain-copy.pem; 11 | ssl_certificate_key /etc/letsencrypt/privkey-copy.pem; 12 | 13 | # Performance + Privacy improvements 14 | ssl_stapling on; 15 | ssl_stapling_verify on; 16 | ssl_trusted_certificate /etc/letsencrypt/fullchain-copy.pem; 17 | resolver 8.8.8.8 208.67.222.222 valid=300s; 18 | resolver_timeout 5s; 19 | 20 | # https://mozilla.github.io/server-side-tls/ssl-config-generator/ 21 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 22 | ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; 23 | ssl_prefer_server_ciphers on; 24 | ssl_session_cache shared:SSL:10m; 25 | ssl_session_timeout 5m; 26 | ssl_dhparam /etc/nginx/dhparams.pem; 27 | 28 | 29 | location /.well-known/acme-challenge { 30 | include /etc/nginx/hsts.conf; 31 | include /etc/nginx/security_headers.conf; 32 | default_type "text/plain"; 33 | root /usr/share/nginx/html; 34 | try_files $uri =404; 35 | } 36 | 37 | location / { 38 | include /etc/nginx/auth_part2.conf; 39 | include /etc/nginx/hsts.conf; 40 | include /etc/nginx/security_headers.conf; 41 | include /etc/nginx/request_size.conf; 42 | include /etc/nginx/trusted_proxies.conf; 43 | include /etc/nginx/main_location.conf; 44 | proxy_set_header Host $host; 45 | proxy_set_header X-Forwarded-Proto $scheme; 46 | proxy_set_header X-Forwarded-Port $server_port; 47 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 48 | proxy_pass http://origin; 49 | proxy_http_version 1.1; 50 | proxy_set_header Upgrade $http_upgrade; 51 | proxy_set_header Connection "upgrade"; 52 | proxy_read_timeout 900s; 53 | } 54 | 55 | } 56 | 57 | server { 58 | listen 80; 59 | server_name ${SERVERNAME:-example.com}; 60 | 61 | location /.well-known/acme-challenge { 62 | default_type "text/plain"; 63 | root /usr/share/nginx/html; 64 | try_files $uri =404; 65 | } 66 | 67 | location = /silent_liveness_check { 68 | access_log off; 69 | return 301 https://$server_name$request_uri; 70 | } 71 | 72 | location / { 73 | return 301 https://$server_name$request_uri; 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /regen-dhparams.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | openssl dhparam -inform PEM -in dhparams.pem -check -text 4 | openssl dhparam -out dhparams.pem 2048 5 | openssl dhparam -inform PEM -in dhparams.pem -check -text 6 | -------------------------------------------------------------------------------- /security_headers.conf: -------------------------------------------------------------------------------- 1 | add_header X-Content-Type-Options "nosniff"; 2 | add_header X-Frame-Options "SAMEORIGIN"; 3 | add_header X-XSS-Protection "1; mode=block"; 4 | -------------------------------------------------------------------------------- /services.d/certbot/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | 3 | if [ -z "$SERVERNAME" ]; then 4 | echo "ERROR: Server name must be specified..." 5 | exit 1 6 | fi 7 | 8 | if ! [ -z "$EXTRANAMES" ]; then 9 | EXTRANAMES="-d $EXTRANAMES" 10 | fi 11 | 12 | echo Waiting for Nginx to come up... 13 | until curl --connect-timeout 1 http://127.0.0.1/; do 14 | sleep 1s 15 | done 16 | echo Nginx has arrived. 17 | 18 | echo Waiting for a response from http://${SERVERNAME:-example.com}/ 19 | # --dns-servers 8.8.8.8 (ideal curl flag) is not available in default build 20 | until curl --connect-timeout 1 http://${SERVERNAME:-example.com}/; do 21 | echo Request to http://${SERVERNAME:-example.com}/ failed. Until Nginx is visible at this DNS, certificate verification cannot succeed. To avoid hitting rate limits, this check will repeat every 15s until resolved. 22 | echo Let\'s Encrypt uses Google\'s DNS servers. If you have already updated your DNS host, you can flush the Google DNS cache by completing the form at https://developers.google.com/speed/public-dns/cache 23 | sleep 15s 24 | done 25 | echo Something is responding at http://${SERVERNAME:-example.com}/ 26 | 27 | while true; do 28 | 29 | if certbot certonly --non-interactive --webroot -w /usr/share/nginx/html --agree-tos \ 30 | --rsa-key-size 2048 --keep-until-expiring --expand --register-unsafely-without-email -d $SERVERNAME $EXTRANAMES; then 31 | cp /etc/letsencrypt/live/${SERVERNAME:-example.com}/privkey.pem /etc/letsencrypt/privkey-copy.pem 32 | cp /etc/letsencrypt/live/${SERVERNAME:-example.com}/fullchain.pem /etc/letsencrypt/fullchain-copy.pem 33 | nginx -s reload 34 | else 35 | if [ -e /etc/letsencrypt/live/${SERVERNAME:-example.com}/fullchain.pem ]; then 36 | BIGSLEEP="$(( 360 + $(($RANDOM % 360)) ))"m # 6-12 hours 37 | sleep $BIGSLEEP 38 | fi 39 | fi 40 | 41 | SMALLSLEEP="$(( 150 + $(($RANDOM % 300)) ))"s # 2.5-7.5 minutes 42 | sleep $SMALLSLEEP 43 | 44 | done 45 | -------------------------------------------------------------------------------- /services.d/nginx/finish: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | s6-svscanctl -t /var/run/s6/services 3 | -------------------------------------------------------------------------------- /services.d/nginx/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv bash 2 | /usr/local/bin/ep -v /etc/nginx/conf.d/* 3 | 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 | 32 | echo '' > /etc/nginx/trusted_proxies.conf 33 | 34 | if [ "$REAL_IP_RECURSIVE" == "on" ]; then 35 | echo "real_ip_header X-Forwarded-For;" >> /etc/nginx/trusted_proxies.conf \ 36 | && echo "real_ip_recursive on;" >> /etc/nginx/trusted_proxies.conf 37 | fi 38 | 39 | if [ "$SET_REAL_IP_FROM_CLOUDFLARE" == "yes" ]; then 40 | cat /etc/nginx/cloudflare.conf >> /etc/nginx/trusted_proxies.conf 41 | fi 42 | 43 | if [ "$SET_REAL_IP_FROM" != "x" ]; then 44 | SET_REAL_IP_FROM_EXPANDED="" 45 | for ip in $SET_REAL_IP_FROM; do 46 | SET_REAL_IP_FROM_EXPANDED="$SET_REAL_IP_FROM_EXPANDED set_real_ip_from ${ip};" 47 | done 48 | echo $SET_REAL_IP_FROM_EXPANDED >> /etc/nginx/trusted_proxies.conf 49 | fi 50 | 51 | if [ "$HSTS_HEADER" == "skip" ]; then 52 | echo "" > /etc/nginx/hsts.conf 53 | elif [ "x$HSTS_HEADER" != "x" ]; then 54 | echo add_header Strict-Transport-Security \"${HSTS_HEADER}\" always\; > /etc/nginx/hsts.conf 55 | fi 56 | 57 | echo '' > /etc/nginx/request_size.conf 58 | 59 | if [ "x$NGINX_CLIENT_MAX_BODY_SIZE" != "x" ]; then 60 | echo client_max_body_size ${NGINX_CLIENT_MAX_BODY_SIZE}\; >> /etc/nginx/request_size.conf 61 | fi 62 | 63 | if [ "x$NGINX_CLIENT_BODY_BUFFER_SIZE" != "x" ]; then 64 | echo client_body_buffer_size ${NGINX_CLIENT_BODY_BUFFER_SIZE}\; >> /etc/nginx/request_size.conf 65 | fi 66 | 67 | if [ ! -e /etc/letsencrypt/fullchain-copy.pem ]; then 68 | cp /etc/nginx/temp-server-cert.pem /etc/letsencrypt/fullchain-copy.pem 69 | fi 70 | 71 | if [ ! -e /etc/letsencrypt/privkey-copy.pem ]; then 72 | cp /etc/nginx/temp-server-key.pem /etc/letsencrypt/privkey-copy.pem 73 | fi 74 | 75 | exec nginx -g 'daemon off;' 76 | -------------------------------------------------------------------------------- /temp-setup-cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDqTCCApGgAwIBAgIJAOd1pk9KLOG2MA0GCSqGSIb3DQEBCwUAMGsxCzAJBgNV 3 | BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQxJDAiBgNVBAMMG0NFUlRJRklDQVRFLUZJTEUtTk9ULUxP 5 | QURFRDAeFw0xNTEyMDUxMDM3MTdaFw0zNTExMzAxMDM3MTdaMGsxCzAJBgNVBAYT 6 | AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn 7 | aXRzIFB0eSBMdGQxJDAiBgNVBAMMG0NFUlRJRklDQVRFLUZJTEUtTk9ULUxPQURF 8 | RDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALbV1YcHsv+aPjyyjnd7 9 | oD2BxM7ElgXFWFNoIpYX0pLf2utXI7e0gFNz7A8mxtT4YkWV4XhhjVEbC7HuledD 10 | J23KRXEAN8+QRfso5Oyp0IXGCl4fcQwCXcajSEmhec4chqhFxztYHn1eW3z3Z/cf 11 | 2zmnsvhExx3EugBm56LcUScSf3igOj+QMecjvWyQqPUnGdE8To+Y3z2DoITHibL7 12 | 1d7MN7HCVxhvrK2j9Z/b29vv3Bqhx/FYKlpqwSXY7cRiYJoqKZorVob6M9z4JYph 13 | JvIj5l4RfVrkhZydco9udl/FN5nHd8ijegSFKAr5LyjZNHFGJ/pYTQripRSqvNYg 14 | LUcCAwEAAaNQME4wHQYDVR0OBBYEFB8Eqd4p0zn7j9R+2wpTbfKpSPW5MB8GA1Ud 15 | IwQYMBaAFB8Eqd4p0zn7j9R+2wpTbfKpSPW5MAwGA1UdEwQFMAMBAf8wDQYJKoZI 16 | hvcNAQELBQADggEBAKoz+n7jys+1UGDw6T3RRe6F8oXv87/Q2RYffbgemEvykly5 17 | PXiErUI7cz98BvB//h1cjg3Hw2j36cesWlouqJsYEq3UgVtTp5ET/mO3doE3vc8M 18 | xICYJFoe/7d2my+6SNd6+bucykX+otf3OhcT2j1B8pg1Ih4KIZdXcGJfgv6xzICi 19 | fNjPUGwB54/JRjU/IqhnmV6nPvI9ZrSIuzbM7TvLjZ47aTOkL6kwheS/nDcK2i4C 20 | spLwQzQ9he0+qPIp3eql6SBCE4fIy7rPeNL0sS7hLZgNsufIlcsHU3hwei8fZxFl 21 | S1XDxJn3OjiCALoegfRlrFjobRf5SpPjR0K6Wcw= 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /temp-setup-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC21dWHB7L/mj48 3 | so53e6A9gcTOxJYFxVhTaCKWF9KS39rrVyO3tIBTc+wPJsbU+GJFleF4YY1RGwux 4 | 7pXnQydtykVxADfPkEX7KOTsqdCFxgpeH3EMAl3Go0hJoXnOHIaoRcc7WB59Xlt8 5 | 92f3H9s5p7L4RMcdxLoAZuei3FEnEn94oDo/kDHnI71skKj1JxnRPE6PmN89g6CE 6 | x4my+9XezDexwlcYb6yto/Wf29vb79waocfxWCpaasEl2O3EYmCaKimaK1aG+jPc 7 | +CWKYSbyI+ZeEX1a5IWcnXKPbnZfxTeZx3fIo3oEhSgK+S8o2TRxRif6WE0K4qUU 8 | qrzWIC1HAgMBAAECggEBAIjj2RdcYFyXc3mmhpxW50al3mChN2Hiu5rXIO4XsAVf 9 | rVz+xTNJ5bqV1GwTsFLMFWfcLBAhmdjb0wnJhFq+IMtG4m8UprS1ZHAD0kKPchx2 10 | hlSqXc2MCAItRnY6fCQhn4BlniGEfG+JMh6CbkjMhSrJsGnJtPtIy6p5YXzCT9Bb 11 | +CRWKre95k6D2TE7ab7pM7pkHQy8UGhAF0Nc2FMmrFQTjulcW80sIR63/3mrIP2V 12 | IQi6rR/5V+BqnarZ05WSD1+jo4NEn7mfIjiI0OhTLuB2sPeW7BPJRnsY7FmFVe1i 13 | 4tO7iyC1EYEyjTlqqBloDgMD99k8fsijfYVu7Nr3VyECgYEA6qKpNMt3tJCm4Nv2 14 | QW2l92H5GT0lzPPFcOIn8kPm0rhVu+9+v0RapppqY3ViM/J3HU4j5sz/XlitJfLK 15 | +4JfDV7fUafZ/KSxEP0ui6Gc1KfILF5wXD+W1NkUTZd3NT9Ez3k6AFcPKsMvidNF 16 | 4yx0+L32iAztEJD2hBAxZaqlbsMCgYEAx3u3IBffUZghX5h9DAxiAUv5UGfVRmUe 17 | 1TvNIRtRs7q3fuJn9jCoSMdG2mKECOhKvIOuaTxarQcsqQHOaIvmytKuZKFTEU+K 18 | dP7TIX06fGKUO3qRutBFukHb3zuH5nqMDO/U/ZaZk/Gys7Z66/eh8iRecpf6uzqI 19 | B619WzVkJy0CgYEAhIOLVqLXH2ZWqUXxRTB8/EMb4RI0yBSg3MkNUHji4v1yhiqT 20 | hcg//jnVfghshvQYK7fW9OGwFAO2/miqFPOjZTTAoShQJ6yHyBWFdRy4Ky37Envf 21 | r2nGcL2NBulVTQBHh3lqtYh1q2wC7C8jGFMiWN1IX7wVIzcL0rgmfcmrlusCgYBn 22 | 5qlIPwbjQeDIIO2o095MHJ074wk0BEFeASrjvo38lhkzLovFsCxG0/y0jLGGzi73 23 | J4M1bukvzFfXo4g17gCEzd1lrp1Mm+ha7ctcWxSWauYYYMv8yLQ4wkraZ/Bt/JBr 24 | wJNojgNqCm7wqfA2baHdNFI5T62ZzW/Cx/tOAW4r9QKBgHQB2LQZ5TxI+YU8OpHs 25 | n8AvlPvbG75R//MCBqFyipWyHcfnwKXzRkoWqlNDYElMBs3Xp2tQBo+ePY4RWYF8 26 | 6obN8dAP9TC4dFZMmsDyR5g9VMgaDHqnmVWMb14nLR0z59lcBEmFwSeGoGqcL78C 27 | 8/B79zWP6hHLINHO6CymHTyJ 28 | -----END PRIVATE KEY----- 29 | --------------------------------------------------------------------------------