From 93d90884e290dad2076079ded8fefd98c2da6237 Mon Sep 17 00:00:00 2001 From: Steve Kamerman Date: Wed, 18 Oct 2017 12:57:59 -0400 Subject: [PATCH] Implemented NETWORK_ACCESS (squash commit) --- Dockerfile | 2 ++ README.md | 19 +++++++++++++++++++ network_internal.conf | 6 ++++++ nginx.tmpl | 36 ++++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 network_internal.conf diff --git a/Dockerfile b/Dockerfile index 851bcaa..cdf47c5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,8 @@ RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VER && tar -C /usr/local/bin -xvzf docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz \ && rm /docker-gen-linux-amd64-$DOCKER_GEN_VERSION.tar.gz +COPY network_internal.conf /etc/nginx/ + COPY . /app/ WORKDIR /app/ diff --git a/README.md b/README.md index 639289c..8fa4bc5 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,25 @@ $ docker network connect my-other-network my-nginx-proxy In this example, the `my-nginx-proxy` container will be connected to `my-network` and `my-other-network` and will be able to proxy to other containers attached to those networks. +### Internet vs. Local Network Access + +If you allow traffic from the public internet to access your `nginx-proxy` container, you may want to restrict some containers to the internal network only, so they cannot be accessed from the public internet. On containers that should be restricted to the internal network, you should set the environment variable `NETWORK_ACCESS=internal`. By default, the *internal* network is defined as `127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16`. To change the list of networks considered internal, mount a file on the `nginx-proxy` at `/etc/nginx/network_internal.conf` with these contents, edited to suit your needs: + +``` +# These networks are considered "internal" +allow 127.0.0.0/8; +allow 10.0.0.0/8; +allow 192.168.0.0/16; +allow 172.16.0.0/12; + +# Traffic from all other networks will be rejected +deny all; +``` + +When internal-only access is enabled, external clients with be denied with an `HTTP 403 Forbidden` + +> If there is a load-balancer / reverse proxy in front of `nginx-proxy` that hides the client IP (example: AWS Application/Elastic Load Balancer), you will need to use the nginx `realip` module (already installed) to extract the client's IP from the HTTP request headers. Please see the [nginx realip module configuration](http://nginx.org/en/docs/http/ngx_http_realip_module.html) for more details. This configuration can be added to a new config file and mounted in `/etc/nginx/conf.d/`. + ### SSL Backends If you would like the reverse proxy to connect to your backend using HTTPS instead of HTTP, set `VIRTUAL_PROTO=https` on the backend container. diff --git a/network_internal.conf b/network_internal.conf new file mode 100644 index 0000000..cdf3c9c --- /dev/null +++ b/network_internal.conf @@ -0,0 +1,6 @@ +# Only allow traffic from internal clients +allow 127.0.0.0/8; +allow 10.0.0.0/8; +allow 192.168.0.0/16; +allow 172.16.0.0/12; +deny all; diff --git a/nginx.tmpl b/nginx.tmpl index 3c26a9c..cf4f6f1 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -147,6 +147,12 @@ upstream {{ $upstream_name }} { {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}} {{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }} +{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} +{{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} + +{{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}} +{{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }} + {{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}} {{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }} @@ -187,6 +193,11 @@ server { {{ end }} access_log /var/log/nginx/access.log vhost; + {{ if eq $network_tag "internal" }} + # Only allow traffic from internal clients + include /etc/nginx/network_internal.conf; + {{ end }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS'; @@ -230,11 +241,11 @@ server { auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/nginx/vhost.d/default_location") }} - include /etc/nginx/vhost.d/default_location; - {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; + {{ else if (exists "/etc/nginx/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} } } @@ -250,6 +261,11 @@ server { {{ end }} access_log /var/log/nginx/access.log vhost; + {{ if eq $network_tag "internal" }} + # Only allow traffic from internal clients + include /etc/nginx/network_internal.conf; + {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }}; {{ else if (exists "/etc/nginx/vhost.d/default") }} @@ -267,11 +283,11 @@ server { auth_basic "Restricted {{ $host }}"; auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }}; {{ end }} - {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} - include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; - {{ else if (exists "/etc/nginx/vhost.d/default_location") }} - include /etc/nginx/vhost.d/default_location; - {{ end }} + {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }} + include {{ printf "/etc/nginx/vhost.d/%s_location" $host}}; + {{ else if (exists "/etc/nginx/vhost.d/default_location") }} + include /etc/nginx/vhost.d/default_location; + {{ end }} } }