Skip to content

Commit

Permalink
feat: basic auth support for nginx (#677)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhhyi authored Jun 16, 2021
1 parent f5992f7 commit 7c3e193
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 3 deletions.
5 changes: 5 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ services:
# COMPRESSION: 0
# DEVICE_DETECTION: 0
# MULTI_CHANNEL_SOURCE: env:///ASDF?type=application/yaml
# BASIC_AUTH: 'developer:!InterShop00!'
# BASIC_AUTH_IP_WHITELIST: |
# # - 172.22.0.1
# - 1.2.3.4
MULTI_CHANNEL: |
.+:
- baseHref: /en
Expand All @@ -39,6 +43,7 @@ services:
- baseHref: /de
channel: default
lang: de_DE
protected: false
- baseHref: /fr
channel: default
lang: fr_FR
Expand Down
18 changes: 18 additions & 0 deletions docs/guides/multi-site-configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ All other properties are optional:
- **features**: Comma-separated list of activated features
- **lang**: The default language as defined in the Angular CLI environment
- **theme**: The theme used for the channel (format: `<theme-name>(|<icon-color>)?`)
- **protected**: Selectively unprotect a given domain and/or baseHref. Only applies in combination with globally activated nginx basic authentication.

Dynamically directing the PWA to different ICM installations can be done by using:

Expand Down Expand Up @@ -187,6 +188,23 @@ To see what is possible through multi-site handling, have a look at this extende
theme: 'blue|688dc3'
```

### Extended Example with two domains, one with basic auth (except /fr), the other without

```yaml
de.+\.com:
lang: de_DE
channel: inspired-inTRONICS-DE
protected: false
ca.+\.com:
- baseHref: /fr
channel: inspired-inTRONICS-CA
lang: fr_FR
protected: false
- baseHref: /en
channel: inspired-inTRONICS-CA
lang: en_US
```

# Further References

- [Guide - Building and Running nginx Docker Image](../guides/nginx-startup.md)
Expand Down
21 changes: 21 additions & 0 deletions docs/guides/nginx-startup.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,27 @@ For HTTP, the server will run on default port 80.
If HTTPS is chosen as an upstream, it will run on default port 443.
In the latter case the files `server.key` and `server.crt` have to be supplied in the container folder `/etx/nginx` (either by volume mapping with `docker run` or in the image itself by `docker build`).

### Basic Auth

For deploying to test environments that should not be indexed by search bots or should not be accessible by the public, the nginx container can be set up with basic authentication.
Just supply a single user-password combination as environment variable, i.e. `BASIC_AUTH=<user>:<password>`.
You can also whitelist IPs by supplying a YAML list to the environment variable `BASIC_AUTH_IP_WHITELIST`:

```yaml
nginx:
environment:
BASIC_AUTH: 'developer:!InterShop00!'
BASIC_AUTH_IP_WHITELIST: |
- 172.22.0.1
- 1.2.3.4
```
Entries of the IP whitelist are added to the nginx config as [`allow`](http://nginx.org/en/docs/http/ngx_http_access_module.html) statements, which also supports IP ranges.
Please refer to the linked nginx documentation on how to configure this.

After activating basic authentication for your setup globally you can also selectively deactivate it per site.
See [Multi-Site Configurations](../guides/multi-site-configurations.md#Examples) for examples on how to do that.

### Multi-Site

If the nginx container is run without further configuration, the default Angular CLI environment properties are not overridden.
Expand Down
2 changes: 1 addition & 1 deletion nginx/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ADD https://github.com/hairyhenderson/gomplate/releases/download/v3.8.0/gomplate

FROM ubuntu:latest
RUN apt-get update && \
apt-get install -y gettext-base libssl1.1 && \
apt-get install -y gettext-base libssl1.1 apache2-utils && \
apt-get -y autoremove && \
apt-get clean && \
rm -r /var/cache/apt /var/lib/apt/lists
Expand Down
26 changes: 26 additions & 0 deletions nginx/channel.conf.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@
{{- $icmScheme := "" }}{{ if (has . "icmScheme") }}{{ $icmScheme = join ( slice "icmScheme" .icmScheme ) "=" }}{{ end }}
{{- $icmPort := "" }}{{ if (has . "icmPort") }}{{ $icmPort = join ( slice "icmPort" .icmPort ) "=" }}{{ end }}
{{- $icmHost := "default" }}{{ if (has . "icmHost") }}{{ $icmHost = .icmHost }}{{ end }}

{{- $protected := true }}{{ if (has . "protected") }}{{ $protected = .protected }}{{ end }}
{{- if $protected }}
{{ else }}
allow all;
auth_basic off;
{{ end }}
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Expand Down Expand Up @@ -60,9 +67,23 @@ server {
error_log /dev/stdout notice;
rewrite_log on;
{{- end }}
{{ if getenv "BASIC_AUTH" }}
{{ if getenv "BASIC_AUTH_IP_WHITELIST" }}
satisfy any;
{{- range $ip := (ds "ipwhitelist") }}
allow {{ $ip }};
{{- end }}
deny all;
{{- end }}
auth_basic "Protected Area";
auth_basic_user_file /etc/nginx/.htpasswd;
{{- end }}

# let ICM handle everything ICM related
location ~* ^/INTERSHOP.*$ {
allow all;
auth_basic off;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Expand All @@ -80,6 +101,9 @@ server {

# respect cache entries of static assets
location ~* ^/(ngx_pagespeed_beacon|metrics|assets|.*\.(js|css|ico|json|txt|webmanifest|woff|woff2))(.*)$ {
allow all;
auth_basic off;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Expand All @@ -103,6 +127,8 @@ server {
{{- if (has ($mapping | jsonpath "$..baseHref") "/") }}
{{- else }}
location / {
allow all;
auth_basic off;
{{ $first := index $mapping 0 -}}
rewrite ^/$ "$scheme://$http_host{{ $first.baseHref }}/home" permanent;
rewrite ^(.*)$ "$scheme://$http_host{{ $first.baseHref }}$request_uri" permanent;
Expand Down
9 changes: 7 additions & 2 deletions nginx/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ set -e

[ -f "/etc/nginx/conf.d/default.conf" ] && rm /etc/nginx/conf.d/default.conf

find /etc/nginx/features/*.conf | xargs -I{} echo {} | sed -e "s%.*\/\(\w*\).conf%\1%" | grep -E '^\w+$' | while read feature; do echo "# $feature" ; env | grep -iqE "^$feature=(on|1|true|yes)$" && echo "include /etc/nginx/features/${feature}.conf;" || echo "include /etc/nginx/features/${feature}-off[.]conf;" ; done >/etc/nginx/conf.d/features.conf
if [ -n "$BASIC_AUTH" ]
then
htpasswd -bc /etc/nginx/.htpasswd $(echo "$BASIC_AUTH" | sed 's/:/ /')
fi

find /etc/nginx/features/*.conf -print0 | xargs -0 -I{} echo {} | sed -e "s%.*\/\(\w*\).conf%\1%" | grep -E '^\w+$' | while read feature; do echo "# $feature" ; env | grep -iqE "^$feature=(on|1|true|yes)$" && echo "include /etc/nginx/features/${feature}.conf;" || echo "include /etc/nginx/features/${feature}-off[.]conf;" ; done >/etc/nginx/conf.d/features.conf

if [ -z "$MULTI_CHANNEL_SOURCE" ]
then
Expand All @@ -19,7 +24,7 @@ then
fi
fi

/gomplate -d "domains=$MULTI_CHANNEL_SOURCE" </etc/nginx/conf.d/channel.conf.tmpl >/etc/nginx/conf.d/multi-channel.conf
/gomplate -d "domains=$MULTI_CHANNEL_SOURCE" -d 'ipwhitelist=env:///BASIC_AUTH_IP_WHITELIST?type=application/yaml' </etc/nginx/conf.d/channel.conf.tmpl >/etc/nginx/conf.d/multi-channel.conf

# Generate Pagespeed config based on environment variables
env | grep NPSC_ | sed -e 's/^NPSC_//g' -e "s/\([A-Z_]*\)=/\L\1=/g" -e "s/_\([a-zA-Z]\)/\u\1/g" -e "s/^\([a-zA-Z]\)/\u\1/g" -e 's/=.*$//' -e 's/\=/ /' -e 's/^/\pagespeed /' > /tmp/pagespeed-prefix.txt
Expand Down

0 comments on commit 7c3e193

Please sign in to comment.