├── .gitignore
├── config
├── crontab
├── 10_stream_acme.conf
├── 10_default_https.conf
├── error-pages
│ ├── 404
│ │ └── 00_index.html
│ ├── 40x
│ │ └── 00_index.html
│ ├── 50x
│ │ └── 00_index.html
│ ├── all
│ │ └── 00_index.html
│ ├── 01_unified.conf
│ └── 01_default.conf
├── 10_default.conf
├── 00_log.conf
├── 00_log_with_geoip.conf
├── 02_proxy.conf
├── nginx.conf
├── 01_ssl.conf
├── 03_geoip2.conf
└── 00_vars.conf
├── config.sh
├── examples
├── stream.d
│ └── mysql.conf
├── vhost.d
│ ├── example.com.conf
│ ├── git.example.com.conf
│ ├── 00_default.conf
│ ├── wiki.example.com.conf
│ ├── static.example.com.conf
│ ├── nexus3.example.com.conf
│ ├── oidc.lua
│ └── repo.example.com.conf
└── epage.d
│ └── all
│ ├── 13_Clock.html
│ ├── 11_Matrix_Rain.html
│ ├── 10_Newton_Cradle.html
│ └── 12_Solar_System.html
├── bin
├── update-certs
├── watch-config
├── entrypoint.sh
├── nginx-utils.awk
├── nginx-utils.sh
└── build-certs
├── run.sh
├── README.md
├── LICENSE
└── Dockerfile
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
3 |
--------------------------------------------------------------------------------
/config/crontab:
--------------------------------------------------------------------------------
1 | # m h dom mon dow command
2 | 41 6,15 * * * /usr/bin/update-certs
3 |
--------------------------------------------------------------------------------
/config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | IMAGE_VERSION=1.15.12-r1
4 | IMAGE_NAME=flytreeleft/nginx-gateway
5 |
6 | IMAGE_GEOIP_NAME=flytreeleft/nginx-gateway-with-geoip
7 |
--------------------------------------------------------------------------------
/examples/stream.d/mysql.conf:
--------------------------------------------------------------------------------
1 | upstream mysql_upstreams {
2 | server mysql0:3306;
3 | server mysql1:3306;
4 | }
5 |
6 | server {
7 | listen 3306;
8 |
9 | proxy_pass mysql_upstreams;
10 |
11 | error_log /var/log/nginx/sites/mysql.example.com/error.log;
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/config/10_stream_acme.conf:
--------------------------------------------------------------------------------
1 | map $ssl_preread_alpn_protocols $backend {
2 | # ~\bacme-tls/1\b unix:/tmp/nginx-tls-alpn.sock;
3 | # default unix:/tmp/nginx-ssl.sock;
4 | ~\bacme-tls/1\b 0.0.0.0:21443;
5 | default 0.0.0.0:20443;
6 | }
7 |
8 | server {
9 | listen 443;
10 | listen [::]:443;
11 |
12 | ssl_preread on;
13 | proxy_pass $backend;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/vhost.d/example.com.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 443 ssl;
3 | listen [::]:443 ssl;
4 |
5 | server_name example.com;
6 |
7 | include /etc/nginx/vhost.d/example.com/*.conf;
8 |
9 | location / {
10 | # Disable proxy cache
11 | proxy_cache off;
12 |
13 | # Avoid to get address resolve error when starting
14 | set $target http://:80;
15 | proxy_pass $target;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/vhost.d/git.example.com.conf:
--------------------------------------------------------------------------------
1 | ##
2 | # Gitlab service proxy settings
3 | ##
4 |
5 | server {
6 | listen 443 ssl;
7 | listen [::]:443 ssl;
8 |
9 | server_name git.example.com;
10 |
11 | include /etc/nginx/vhost.d/git.example.com/*.conf;
12 |
13 | # Support to push big files
14 | client_max_body_size 100M;
15 |
16 | location / {
17 | # Avoid to get address resolve error when starting
18 | set $target http://:;
19 | proxy_pass $target;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/bin/update-certs:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | CERT_DIR=/etc/letsencrypt
4 | VHOSTD=/etc/nginx/vhost.d
5 | LOCK="${CERT_DIR}/.lck"
6 |
7 | if [ -e ${LOCK} ]; then
8 | exit 0
9 | else
10 | touch ${LOCK}
11 | fi
12 |
13 |
14 | # https://github.com/acmesh-official/acme.sh
15 | /usr/bin/acme.sh \
16 | --cron \
17 | --home /opt/acme.sh \
18 | --config-home "${CERT_DIR}/config" \
19 | "$@" \
20 | >> "${CERT_DIR}/update.log" \
21 | 2>&1
22 |
23 | chown -R nginx:nginx ${VHOSTD} ${CERT_DIR}/certs \
24 | && chmod go-rw -R ${VHOSTD} ${CERT_DIR}/certs \
25 | && /usr/sbin/nginx -s reload
26 |
27 | rm -f ${LOCK}
28 |
--------------------------------------------------------------------------------
/config/10_default_https.conf:
--------------------------------------------------------------------------------
1 | # The port 443 is the default ssl port,
2 | # if you want to create ssl keys for all https server from scratch,
3 | # you need to enable this configuration for making a default https server
4 | # to make sure the nginx can be started successfully
5 | # https://itecnotes.com/server/nginx-disable-ssl-on-an-nginx-server-block-listening-on-port-443/#related-embeded
6 | server {
7 | listen 443 ssl default_server;
8 | listen [::]:443 ssl default_server;
9 | server_name _;
10 |
11 | ssl_certificate /etc/nginx/ssl/default_https_ssl.crt;
12 | ssl_certificate_key /etc/nginx/ssl/default_https_ssl.key;
13 |
14 | return 404;
15 | }
16 |
--------------------------------------------------------------------------------
/examples/vhost.d/00_default.conf:
--------------------------------------------------------------------------------
1 | # http://nginx.org/en/docs/http/server_names.html
2 | # https://community.letsencrypt.org/t/ocsp-stapling-nginx-server/30865/8#post_9
3 | resolver 8.8.8.8 valid=300s;
4 | resolver_timeout 5s;
5 |
6 | # Websocket support
7 | proxy_http_version 1.1;
8 | proxy_set_header Upgrade $http_upgrade;
9 | proxy_set_header Connection "upgrade";
10 |
11 | # Force to change the redirect url's scheme to https
12 | proxy_redirect http:// $scheme://;
13 | proxy_redirect / /;
14 |
15 | # Intercept proxy errors (e.g. 404, 500, etc.) and redirected them to nginx
16 | ## http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors
17 | #proxy_intercept_errors on;
18 |
--------------------------------------------------------------------------------
/config/error-pages/404/00_index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 404 - Page Not Found
6 |
7 |
8 | 404 Page Not Found
9 |
10 | nginx.com
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/config/error-pages/40x/00_index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{status}} - {{status_msg}}
6 |
7 |
8 | {{status}} {{status_msg}}
9 |
10 | nginx.com
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/config/error-pages/50x/00_index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{status}} - {{status_msg}}
6 |
7 |
8 | {{status}} {{status_msg}}
9 |
10 | nginx.com
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/config/error-pages/all/00_index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{status}} - {{status_msg}}
6 |
7 |
8 | {{status}} {{status_msg}}
9 |
10 | nginx.com
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/config/10_default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80 default_server;
3 | listen [::]:80 default_server;
4 | server_name _;
5 |
6 | # https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion/blob/master/app/nginx_location.conf
7 | location ^~ /.well-known/acme-challenge/ {
8 | allow all;
9 |
10 | # NOTE: The '/' must be put at the end.
11 | ## https://www.leavesongs.com/PENETRATION/nginx-insecure-configuration.html#_1
12 | alias /etc/letsencrypt/.well-known/acme-challenge/;
13 | try_files $uri =404;
14 |
15 | break;
16 | }
17 |
18 | # Health checking for k8s pod
19 | ## https://github.com/robszumski/k8s-service-proxy/blob/master/nginx.conf
20 | location /health {
21 | access_log off;
22 | add_header Content-Type text/plain;
23 |
24 | return 200;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/config/00_log.conf:
--------------------------------------------------------------------------------
1 | # Rotate access log with the variable '$logdate' like 'access_log /var/log/nginx/access$logdate.log main;'.
2 | # But it's not possible to embed variables in error_log directives:
3 | ## https://github.com/fcambus/nginx-resources/issues/12
4 | ## https://www.cambus.net/log-rotation-directly-within-nginx-configuration-file/
5 | map $time_iso8601 $logdate {
6 | default '';
7 | '~^(?\d{4})-(?\d{2})-(?\d{2})' _$year-$month-$day;
8 | }
9 |
10 | # http://nginx.org/en/docs/http/ngx_http_log_module.html
11 | log_format main '$remote_addr - $remote_user [$time_local]'
12 | ' "$request"'
13 | ' $upstream_cache_status $status'
14 | ' $body_bytes_sent $request_time'
15 | ' "$http_referer" "$http_user_agent"'
16 | ' "$http_x_forwarded_for"';
17 |
18 | error_log /var/log/nginx/error.log debug;
19 | access_log /var/log/nginx/access$logdate.log main;
20 |
--------------------------------------------------------------------------------
/config/00_log_with_geoip.conf:
--------------------------------------------------------------------------------
1 | # Rotate access log with the variable '$logdate' like 'access_log /var/log/nginx/access$logdate.log main;'.
2 | # But it's not possible to embed variables in error_log directives:
3 | ## https://github.com/fcambus/nginx-resources/issues/12
4 | ## https://www.cambus.net/log-rotation-directly-within-nginx-configuration-file/
5 | map $time_iso8601 $logdate {
6 | default '';
7 | '~^(?\d{4})-(?\d{2})-(?\d{2})' _$year-$month-$day;
8 | }
9 |
10 | # http://nginx.org/en/docs/http/ngx_http_log_module.html
11 | log_format main '$remote_addr - $remote_user [$time_local]'
12 | ' "$request"'
13 | ' $upstream_cache_status $status'
14 | ' $body_bytes_sent $request_time'
15 | ' "$http_referer" "$http_user_agent"'
16 | ' "$http_x_forwarded_for"'
17 | ' "$http_x_geoip_data"';
18 |
19 | error_log /var/log/nginx/error.log debug;
20 | access_log /var/log/nginx/access$logdate.log main;
21 |
--------------------------------------------------------------------------------
/config/error-pages/01_unified.conf:
--------------------------------------------------------------------------------
1 | ##
2 | # Randomly choose the *.html (e.g. 00_xx.html) to be used as error page,
3 | # but all files will be used to display all errors.
4 | #
5 | # All error pages (*.html) will be picked from /etc/nginx/epage.d/,
6 | # the files in it's child directory are ignored.
7 | ##
8 |
9 | # Obmit the `[=[response]]` syntax to keep the error response code for clients.
10 | ## http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
11 | error_page 404 400 401 403 500 502 503 504 /_/;
12 |
13 | location /_/ {
14 | internal;
15 | random_index on;
16 |
17 | # http://nginx.org/en/docs/http/ngx_http_core_module.html#alias
18 | # https://stackoverflow.com/questions/10631933/nginx-static-file-serving-confusion-with-root-alias#answer-10647080
19 | alias /etc/nginx/epage.d/all/;
20 |
21 | # Replace the placeholders in response content
22 | # for showing the corresponding status and message.
23 | sub_filter '{{status}}' '$status';
24 | sub_filter '{{status_msg}}' '$status_msg';
25 | sub_filter_once off;
26 | }
27 |
--------------------------------------------------------------------------------
/config/02_proxy.conf:
--------------------------------------------------------------------------------
1 | proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:50m inactive=1d max_size=200m;
2 | proxy_cache cache_zone;
3 | proxy_cache_key $host$uri$is_args$args;
4 | proxy_cache_valid 200 304 1h;
5 |
6 | # https://github.com/jwilder/nginx-proxy/issues/130#issuecomment-88962969
7 | ## issue with ip and the nginx proxy
8 | real_ip_header X-Forwarded-For;
9 | set_real_ip_from 172.17.0.0/16;
10 |
11 | # http://nginx.org/en/docs/http/ngx_http_proxy_module.html
12 | proxy_set_header Host $host;
13 | proxy_set_header X-Real-IP $remote_addr;
14 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
15 | proxy_set_header X-Forwarded-Proto $scheme;
16 | proxy_set_header X-Forwarded-Ssl on;
17 |
18 | # Mitigate httpoxy attack
19 | proxy_set_header Proxy "";
20 | proxy_connect_timeout 120;
21 | proxy_send_timeout 120;
22 | proxy_read_timeout 120;
23 | proxy_buffer_size 4k;
24 | proxy_buffers 4 256k;
25 | proxy_busy_buffers_size 512k;
26 | proxy_temp_file_write_size 512k;
27 |
28 | # Nginx cache check
29 | ## http://www.361way.com/nginx-cache/2665.html
30 | add_header Nginx-Cache $upstream_cache_status;
31 |
--------------------------------------------------------------------------------
/bin/watch-config:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . /usr/bin/nginx-utils.sh
4 |
5 | while [[ -n "$1" ]]; do
6 | case "$1" in
7 | --)
8 | shift
9 | CMD="$@"
10 | break
11 | ;;
12 | esac
13 | shift
14 | done
15 |
16 | if [ "x$CMD" = "x" ]; then
17 | echo "Usage: $0 -- "
18 | exit 0
19 | fi
20 |
21 |
22 | CHECK_REF_FILE="/tmp/watch-config-check.ref"
23 | touch "${CHECK_REF_FILE}"
24 |
25 | update_ref() {
26 | local timestamp="$(date +%Y%m%d%H%M.%S)"
27 |
28 | touch "${CHECK_REF_FILE}" -t ${timestamp}
29 | }
30 |
31 | has_modified_anyof() {
32 | local result="false"
33 |
34 | while [[ -n "$1" ]]; do
35 | if [[ ! -e "${CHECK_REF_FILE}" || "x$(find "$1" -newer "${CHECK_REF_FILE}" 2>/dev/null)" != "x" ]]; then
36 | result="true"
37 | break
38 | fi
39 | shift
40 | done
41 |
42 | [[ "$result" = "true" ]]
43 | }
44 |
45 | run_cmd() {
46 | local cmd="$1"
47 |
48 | eval "${cmd}"
49 | update_ref
50 | }
51 |
52 |
53 | target_dirs=(
54 | $(get_include_files_from /etc/nginx/nginx.conf | sed -E 's|/[^/]+$||g; /^\/etc\/nginx$/d;' | uniq)
55 | )
56 | while true; do
57 | sleep 10s
58 |
59 | if has_modified_anyof "${target_dirs[@]}"; then
60 | run_cmd "${CMD}"
61 | fi
62 | done
63 |
--------------------------------------------------------------------------------
/examples/vhost.d/wiki.example.com.conf:
--------------------------------------------------------------------------------
1 | ##
2 | # Mediawiki service proxy settings, and enable user authentication
3 | ##
4 |
5 | server {
6 | listen 443 ssl;
7 | listen [::]:443 ssl;
8 |
9 | server_name wiki.example.com;
10 |
11 | include /etc/nginx/vhost.d/wiki.example.com/*.conf;
12 |
13 | client_max_body_size 100M;
14 |
15 | location / {
16 | # http://docs.openhab.org/installation/security.html#nginx-auth-users
17 | satisfy any;
18 | deny all;
19 | auth_basic "Username and Password Required";
20 | # Debian: apt-get install apache2-utils
21 | # CentOS: yum install httpd-tools
22 | # Create first account: htpasswd -c .htpasswd
23 | # Add new account: htpasswd .htpasswd
24 | # Remove existing account: htpasswd -D .htpasswd
25 | auth_basic_user_file /etc/nginx/vhost.d/wiki.example.com/.htpasswd;
26 |
27 | # Authentication with OpenID
28 | #set $oidc_realm "";
29 | #set $oidc_client_id "";
30 | #set $oidc_ip_whitelist "10.10.0.1, 10.10.0.2";
31 | #access_by_lua_file /etc/nginx/vhost.d/oidc.lua;
32 |
33 | # Avoid to get address resolve error when starting
34 | set $target http://:;
35 | proxy_pass $target;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/config/error-pages/01_default.conf:
--------------------------------------------------------------------------------
1 | ##
2 | # Randomly choose the *.html (e.g. 00_xx.html) to be used as error page.
3 | # If the target directory only contains a single HTML file,
4 | # this file will be always the unique error page (A fixed error page).
5 | #
6 | # The error page (*.html) will be picked from the child directories of /etc/nginx/epage.d/
7 | # e.g. /404/, /40x/, /50x/.
8 | ##
9 |
10 | # Obmit the `[=[response]]` syntax to keep the error response code for clients.
11 | ## http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page
12 | error_page 404 /404/;
13 | error_page 400 401 403 /40x/;
14 | error_page 500 502 503 504 /50x/;
15 |
16 | location /404/ {
17 | internal;
18 | random_index on;
19 |
20 | root /etc/nginx/epage.d;
21 | }
22 |
23 | location /40x/ {
24 | internal;
25 | random_index on;
26 |
27 | root /etc/nginx/epage.d;
28 |
29 | # Replace the placeholders in response content
30 | # for showing the corresponding status and message.
31 | sub_filter '{{status}}' '$status';
32 | sub_filter '{{status_msg}}' '$status_msg';
33 | sub_filter_once off;
34 | }
35 |
36 | location /50x/ {
37 | internal;
38 | random_index on;
39 |
40 | root /etc/nginx/epage.d;
41 |
42 | # Replace the placeholders in response content
43 | # for showing the corresponding status and message.
44 | sub_filter '{{status}}' '$status';
45 | sub_filter '{{status_msg}}' '$status_msg';
46 | sub_filter_once off;
47 | }
48 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
4 | . "${DIR}/config.sh"
5 |
6 |
7 | DCR_NAME=nginx-gateway
8 | DCR_IMAGE="${IMAGE_NAME}:${IMAGE_VERSION}"
9 |
10 | DCR_VOLUME=/var/lib/nginx-gateway
11 |
12 | DEBUG=false
13 | ULIMIT=655360
14 | ENABLE_CUSTOM_ERROR_PAGE=true
15 | CERT_EMAIL=nobody@example.com
16 |
17 | #ulimit -n ${ULIMIT}
18 | docker rm -f ${DCR_NAME}
19 | rm -f "${DCR_VOLUME}/letsencrypt/.lck"
20 |
21 | # http://serverfault.com/questions/786389/nginx-docker-container-cannot-see-client-ip-when-using-iptables-false-option#answer-788088
22 | docker run -d --name ${DCR_NAME} \
23 | --restart always \
24 | --network host \
25 | --ulimit nofile=${ULIMIT} \
26 | -p 443:443 -p 80:80 \
27 | -e DEBUG=${DEBUG} \
28 | -e CERT_EMAIL=${CERT_EMAIL} \
29 | -e ENABLE_CUSTOM_ERROR_PAGE=${ENABLE_CUSTOM_ERROR_PAGE} \
30 | -e DISABLE_CERTBOT=false \
31 | -e DISABLE_GIXY=false \
32 | -v /usr/share/zoneinfo:/usr/share/zoneinfo:ro \
33 | -v /etc/localtime:/etc/localtime:ro \
34 | -v ${DCR_VOLUME}/logs:/var/log/nginx/sites \
35 | -v ${DCR_VOLUME}/letsencrypt:/etc/letsencrypt \
36 | -v ${DCR_VOLUME}/vhost.d:/etc/nginx/vhost.d \
37 | -v ${DCR_VOLUME}/stream.d:/etc/nginx/stream.d \
38 | -v ${DCR_VOLUME}/epage.d:/etc/nginx/epage.d \
39 | ${DCR_IMAGE}
40 |
--------------------------------------------------------------------------------
/config/nginx.conf:
--------------------------------------------------------------------------------
1 | user nginx;
2 | # https://www.oschina.net/translate/nginx-tutorial-performance
3 | worker_processes auto;
4 | worker_rlimit_nofile 655360;
5 |
6 | pid /var/run/nginx.pid;
7 | error_log /var/log/nginx/error.log debug;
8 |
9 | events {
10 | use epoll;
11 | worker_connections 65536;
12 | multi_accept on;
13 | }
14 |
15 | http {
16 | sendfile on;
17 | tcp_nopush on;
18 | # sets TCP_NODELAY flag, used on keep-alive connections
19 | tcp_nodelay on;
20 | keepalive_timeout 60;
21 | keepalive_requests 100000;
22 | reset_timedout_connection on;
23 | types_hash_max_size 2048;
24 | client_body_timeout 12;
25 | client_header_timeout 12;
26 | send_timeout 10;
27 | server_tokens off;
28 |
29 | # For chunked cookie: https://github.com/pingidentity/lua-resty-openidc/issues/33
30 | client_body_buffer_size 16k;
31 | client_header_buffer_size 1k;
32 | large_client_header_buffers 4 16k;
33 | client_max_body_size 10M;
34 | #server_names_hash_bucket_size 64;
35 | #server_name_in_redirect off;
36 |
37 | include /etc/nginx/mime.types;
38 | default_type application/octet-stream;
39 |
40 | gzip on;
41 | gzip_disable "MSIE [1-6].";
42 | gzip_vary on;
43 | gzip_proxied any;
44 | gzip_comp_level 6;
45 | gzip_buffers 16 8k;
46 | gzip_min_length 100;
47 | gzip_http_version 1.1;
48 | gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
49 |
50 | # Lua modules
51 | lua_package_path '/usr/local/share/lua/5.1/?.lua;;';
52 |
53 | include /etc/nginx/conf.d/*.conf;
54 | include /etc/nginx/vhost.d/*.conf;
55 | }
56 |
57 | stream {
58 | include /etc/nginx/vstream.d/*.conf;
59 | include /etc/nginx/stream.d/*.conf;
60 | }
61 |
--------------------------------------------------------------------------------
/config/01_ssl.conf:
--------------------------------------------------------------------------------
1 | # https://mozilla.github.io/server-side-tls/ssl-config-generator/
2 |
3 | # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
4 | #ssl_certificate /etc/letsencrypt/live/example.com/signed_cert_plus_intermediates;
5 | #ssl_certificate_key /etc/letsencrypt/live/example.com/private_key;
6 | # Improve HTTPS performance with session resumption
7 | ssl_session_cache shared:SSL:10m;
8 | ssl_session_timeout 5m;
9 | ssl_session_tickets off;
10 |
11 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
12 | ## openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
13 | ssl_dhparam /etc/nginx/ssl/dhparam.pem;
14 |
15 | # intermediate configuration. tweak to your needs.
16 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
17 | 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:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
18 | ssl_prefer_server_ciphers on;
19 |
20 | # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
21 | add_header Strict-Transport-Security max-age=15768000;
22 |
23 | # OCSP Stapling ---
24 | # fetch OCSP records from URL in ssl_certificate and cache them
25 | #ssl_stapling on;
26 | #ssl_stapling_verify on;
27 |
28 | ## verify chain of trust of OCSP response using Root CA and Intermediate certs
29 | ### NOTE: ssl_certificate module aready includes intermediates
30 | #### http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling
31 | #ssl_trusted_certificate /etc/letsencrypt/live/example.com/root_CA_cert_plus_intermediates;
32 |
--------------------------------------------------------------------------------
/config/03_geoip2.conf:
--------------------------------------------------------------------------------
1 | # http://www.treselle.com/blog/nginx-with-geoip2-maxmind-database-to-fetch-user-geo-location-data/#Configuring_Nginx_with_MaxMind_Databases
2 | # https://dev.maxmind.com/geoip/geoip2/geolite2/
3 | # https://dev.maxmind.com/geoip/geoip2/whats-new-in-geoip2/#Web_Service_Example
4 | geoip2 /etc/nginx/geoip2/GeoLite2-Country.mmdb {
5 | $geoip_country_code source=$remote_addr country iso_code;
6 | $geoip_country_name country names en;
7 | }
8 |
9 | geoip2 /etc/nginx/geoip2/GeoLite2-City.mmdb {
10 | $geoip_state_name subdivisions 0 names en;
11 | $geoip_state_code subdivisions 0 iso_code;
12 | $geoip_city_name city names en;
13 | $geoip_postal_code postal code;
14 | $geoip_latitude location latitude;
15 | $geoip_longitude location longitude;
16 | }
17 |
18 | access_by_lua_block {
19 | -- https://github.com/dauer/geohash/blob/master/lua/lib/geohash.lua
20 | -- Access http://geohash.org/{geohash} to watch the location
21 | local geohash = "-"
22 | local geodata = "-"
23 |
24 | if ngx.var.geoip_latitude and ngx.var.geoip_longitude then
25 | local GeoHash = require("geohash")
26 | GeoHash.precision(6)
27 |
28 | -- "Ave, New York, NY, United States, US (40.746482,-74.01508; dr5rg9xv7wu0)"
29 | geohash = GeoHash.encode(tonumber(ngx.var.geoip_latitude), tonumber(ngx.var.geoip_longitude))
30 | geodata = string.format("%s, %s, %s, %s, %s (%s,%s; %s)",
31 | ngx.var.geoip_city_name ? ngx.var.geoip_city_name : "-",
32 | ngx.var.geoip_state_name ? ngx.var.geoip_state_name : "-",
33 | ngx.var.geoip_state_code ? ngx.var.geoip_state_code : "-",
34 | ngx.var.geoip_country_name ? ngx.var.geoip_country_name : "-",
35 | ngx.var.geoip_country_code ? ngx.var.geoip_country_code : "-",
36 | ngx.var.geoip_latitude,
37 | ngx.var.geoip_longitude,
38 | geohash)
39 | end
40 |
41 | ngx.req.set_header("X-GeoIP-GeoHash", geohash)
42 | ngx.req.set_header("X-GeoIP-Data", geodata)
43 |
44 | -- ngx.log(ngx.DEBUG, ngx.var.http_x_geoip_geohash.." - "..ngx.var.http_x_geoip_data)
45 | }
46 |
--------------------------------------------------------------------------------
/examples/vhost.d/static.example.com.conf:
--------------------------------------------------------------------------------
1 | ##
2 | # Remote static file proxy settings, and support to forward the target to the squid proxy
3 | #
4 | # Proxies:
5 | # - https://static.example.com/*/http://others.com/asset.js -> http://others.com/asset.js
6 | ##
7 |
8 | server {
9 | listen 443 ssl;
10 | listen [::]:443 ssl;
11 |
12 | server_name static.example.com;
13 |
14 | include /etc/nginx/vhost.d/static.example.com/*.conf;
15 |
16 | # https://static.example.com/*/http://others.com/asset.js -> http://others.com/asset.js
17 | ## https://www.mediasuite.co.nz/blog/proxying-s3-downloads-nginx/
18 | location ~* ^/\*/(http[s]?):?/(.*?)/(.*)$ {
19 | # Note: Remove the directive 'internal;' to accept the external requests,
20 | # otherwise it will return 404 for the external requests.
21 | # See http://nginx.org/en/docs/http/ngx_http_core_module.html#internal
22 | set $backend_protocol $1;
23 | set $backend_host $2;
24 | set $backend_path $3;
25 | set $backend_uri $backend_host/$backend_path$is_args$args;
26 | set $backend_url $backend_protocol://$backend_uri;
27 |
28 | # Headers for the remote server, unset Authorization and Cookie for security reasons.
29 | proxy_set_header Host $backend_host;
30 | proxy_set_header Authorization '';
31 | proxy_set_header Cookie '';
32 |
33 | # Stops the local disk from being written to (just forwards data through)
34 | proxy_max_temp_file_size 0;
35 |
36 | # Forward the target to the squid proxy
37 | ## https://serverfault.com/questions/583743/how-to-make-an-existing-caching-nginx-proxy-use-another-proxy-to-bypass-a-firewa#683955
38 | ## Hide the reponse header to protect the backend proxy
39 | ### http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header
40 | proxy_hide_header Via;
41 | proxy_hide_header X-Cache;
42 | proxy_hide_header X-Cache-Hits;
43 | proxy_hide_header X-Cache-Lookup;
44 | proxy_hide_header X-Fastly-Request-ID;
45 | proxy_hide_header X-Served-By;
46 | proxy_hide_header X-Timer;
47 | rewrite ^(.*)$ "://$backend_uri" break;
48 | rewrite ^(.*)$ "$backend_protocol$1" break;
49 | proxy_pass http://:3128;
50 |
51 | # Proxy to the target directly
52 | #proxy_pass $backend_url;
53 |
54 | proxy_intercept_errors on;
55 | error_page 301 302 307 = @handle_backend_redirect;
56 | }
57 |
58 | # Nginx Embedded Variables: http://nginx.org/en/docs/varindex.html
59 | location @handle_backend_redirect {
60 | return 302 $scheme://$host/*/$upstream_http_location;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/bin/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | . /usr/bin/nginx-utils.sh
4 |
5 | ERROR_PAGES=${EPAGED}
6 | if [[ "$(ls -A "${ERROR_PAGES}" 2>/dev/null)" = "" || "${ENABLE_CUSTOM_ERROR_PAGE}" = "force" ]]; then
7 | cp -r ${DEFAULT_ERROR_PAGES}/* ${ERROR_PAGES}
8 | rm -rf ${ERROR_PAGES}/*.conf
9 | fi
10 | case ${ENABLE_CUSTOM_ERROR_PAGE} in
11 | false)
12 | rm -rf ${ERROR_PAGES}/01_default.conf
13 | ;;
14 | unified)
15 | cat ${DEFAULT_ERROR_PAGES}/01_unified.conf > ${ERROR_PAGES}/01_default.conf
16 | ;;
17 | *)
18 | cat ${DEFAULT_ERROR_PAGES}/01_default.conf > ${ERROR_PAGES}/01_default.conf
19 | ;;
20 | esac
21 |
22 |
23 | rm -f "${CERT_DIR}/.lck"
24 |
25 | if [[ ! -d "/opt/acme.sh" && "${DISABLE_CERTBOT}" != "true" ]]; then
26 | pushd /opt/acme.sh-src
27 | # https://github.com/acmesh-official/acme.sh
28 | bash ./acme.sh \
29 | --install \
30 | --home /opt/acme.sh \
31 | --config-home "${CERT_DIR}/config" \
32 | --cert-home "${CERT_DIR}/certs" \
33 | --nocron \
34 | --log \
35 | --debug 2>/dev/null \
36 | && ln -sf /opt/acme.sh/acme.sh /usr/bin/acme.sh \
37 | && chmod +x /opt/acme.sh/acme.sh /usr/bin/acme.sh
38 | popd
39 | fi
40 |
41 | if [[ "${DISABLE_CERTBOT}" = "true" || "${CERT_CHALLENGE_TYPE}" != "alpn" ]]; then
42 | rm -f /etc/nginx/vstream.d/10_stream_acme.conf
43 | fi
44 | if [[ "${DISABLE_DEFAULT_HTTPS_SERVER}" = "true" ]]; then
45 | rm -f /etc/nginx/conf.d/10_default_https.conf
46 | fi
47 | if [[ "${DISABLE_CERTBOT}" = "true" || "${CERT_CHALLENGE_TYPE}" = "dns" ]]; then
48 | # Cancel automically updating
49 | rm -f /var/spool/cron/crontabs/root
50 | else
51 | crond -c /var/spool/cron/crontabs -b -L /var/log/cron/cron.log
52 | fi
53 |
54 |
55 | # https://github.com/yandex/gixy#usage
56 | if [[ "${DISABLE_GIXY}" != "true" && -e /usr/bin/gixy ]]; then
57 | # Note: Gixy will search all `include` directives
58 | /usr/bin/gixy /etc/nginx/nginx.conf
59 | fi
60 |
61 | # just check if the certification file exist
62 | /usr/bin/build-certs true true
63 | # create missing log
64 | check_log_files_for /etc/nginx/nginx.conf
65 | # and remove invaild ssl listen
66 | if [[ "${DISABLE_CERTBOT}" = "true" ]]; then
67 | update_server_ssl_for /etc/nginx/nginx.conf
68 | fi
69 |
70 |
71 | export -f update_host_config_for
72 | CERT_BUILD_CMD="update_host_config_for /etc/nginx/nginx.conf; /usr/sbin/nginx -s reload"
73 |
74 | if [[ "${CERT_CHALLENGE_TYPE}" = "dns" ]]; then
75 | echo "The cert challenge type is set to DNS, you should run the script /usr/bin/build-certs interactively"
76 | else
77 | CERT_BUILD_CMD="/usr/bin/build-certs ${DISABLE_CERTBOT} >> '${CERT_DIR}/build.log' 2>&1; ${CERT_BUILD_CMD}"
78 | fi
79 | /usr/bin/watch-config -- "${CERT_BUILD_CMD}" &
80 |
81 |
82 | NGINX=nginx
83 | if [[ "${DEBUG}" = "true" ]]; then
84 | NGINX=nginx-debug
85 | fi
86 |
87 | chown -R nginx /var/log/nginx
88 |
89 | eval "${NGINX} -g \"daemon off;\""
90 |
--------------------------------------------------------------------------------
/config/00_vars.conf:
--------------------------------------------------------------------------------
1 | # https://gist.github.com/tmthrgd/3504859568e1dba9ee80e260f974a708
2 | map $status $status_msg {
3 | default "An error occured";
4 | 100 Continue;
5 | 101 "Switching Protocols";
6 | 102 Processing; # WebDAV; RFC 2518
7 | 200 OK;
8 | 201 Created;
9 | 202 Accepted;
10 | 203 "Non-Authoritative Information";
11 | 204 "No Content";
12 | 205 "Reset Content";
13 | 206 "Partial Content";
14 | 207 Multi-Status; # WebDAV; RFC 4918
15 | 208 "Already Reported"; # WebDAV; RFC 5842
16 | 226 "IM Used"; # RFC 3229
17 | 300 "Multiple Choices";
18 | 301 "Moved Permanently";
19 | 302 Found;
20 | 303 "See Other";
21 | 304 "Not Modified";
22 | 305 "Use Proxy";
23 | 306 "Switch Proxy";
24 | 307 "Temporary Redirect";
25 | 308 "Permanent Redirect"; # RFC 7538
26 | 400 "Bad Request";
27 | 401 Unauthorized;
28 | 402 "Payment Required";
29 | 403 Forbidden;
30 | 404 "Not Found";
31 | 405 "Method Not Allowed";
32 | 406 "Not Acceptable";
33 | 407 "Proxy Authentication Required";
34 | 408 "Request Timeout";
35 | 409 Conflict;
36 | 410 Gone;
37 | 411 "Length Required";
38 | 412 "Precondition Failed";
39 | 413 "Request Entity Too Large";
40 | 414 "Request-URI Too Long";
41 | 415 "Unsupported Media Type";
42 | 416 "Requested Range Not Satisfiable";
43 | 417 "Expectation Failed";
44 | 418 "I'm a teapot"; # RFC 2324
45 | 419 "Authentication Timeout"; # not in RFC 2616
46 | # 420 "Method Failure"; # Spring Framework
47 | 420 "Enhance Your Calm"; # Twitter
48 | 422 "Unprocessable Entity"; # WebDAV; RFC 4918
49 | 423 Locked; # WebDAV; RFC 4918
50 | 424 "Failed Dependency"; # WebDAV; RFC 4918
51 | 426 "Upgrade Required";
52 | 428 "Precondition Required"; # RFC 6585
53 | 429 "Too Many Requests"; # RFC 6585
54 | 431 "Request Header Fields Too Large"; # RFC 6585
55 | 440 "Login Timeout"; # Microsoft
56 | 444 "No Response"; # Nginx
57 | 449 "Retry With"; # Microsoft
58 | 450 "Blocked by Windows Parental Controls"; # Microsoft
59 | 451 "Unavailable For Legal Reasons"; # Internet draft
60 | # 451 Redirect; # Microsoft
61 | 494 "Request Header Too Large"; # Nginx
62 | 495 "Cert Error"; # Nginx
63 | 496 "No Cert"; # Nginx
64 | 497 "HTTP to HTTPS"; # Nginx
65 | 498 "Token expired/invalid"; # Esri
66 | 499 "Client Closed Request"; # Nginx
67 | # 499 "Token required"; # Esri
68 | 500 "Internal Server Error";
69 | 501 "Not Implemented";
70 | 502 "Bad Gateway";
71 | 503 "Service Unavailable";
72 | 504 "Gateway Timeout";
73 | 505 "HTTP Version Not Supported";
74 | 506 "Variant Also Negotiates"; # RFC 2295
75 | 507 "Insufficient Storage"; # WebDAV; RFC 4918
76 | 508 "Loop Detected"; # WebDAV; RFC 5842
77 | 509 "Bandwidth Limit Exceeded"; # Apache bw/limited extension
78 | 510 "Not Extended"; # RFC 2774
79 | 511 "Network Authentication Required"; # RFC 6585
80 | 598 "Network read timeout error"; # Unknown
81 | 599 "Network connect timeout error"; # Unknown
82 | }
83 |
--------------------------------------------------------------------------------
/bin/nginx-utils.awk:
--------------------------------------------------------------------------------
1 | BEGIN {
2 | cmd = "cat '" source_file "'"
3 |
4 | content_lines_index = 0
5 | current_block_index = 0
6 | while ( ( cmd | getline ) > 0 ) {
7 | line = $0
8 |
9 | content_lines_index += 1
10 | content_lines[content_lines_index] = line
11 |
12 | if ( match(line, /^[^#]+\{/) ) {
13 | current_block_index += 1
14 | }
15 | else if ( match(line, /^[[:space:]]*\}/) ) {
16 | current_block_index += 1
17 | }
18 | # listen 443 ssl;
19 | # listen [::]:443 ssl;
20 | else if ( match(line, /^[[:space:]]*listen[[:space:]]+.+;/) ) {
21 | listen_directive_block_indexes[content_lines_index] = current_block_index
22 | }
23 | else if ( match(line, /^[[:space:]]*include[[:space:]]+.+;/) ) {
24 | include_file = line
25 | # include /etc/nginx/vhost.d//*.conf;
26 | gsub(/^[[:space:]]*include[[:space:]]+|[[:space:]]*;.*$/, " ", include_file)
27 |
28 | file = include_files_in_block[current_block_index]
29 | if ( file ) {
30 | include_files_in_block[current_block_index] = file " " include_file
31 | } else {
32 | include_files_in_block[current_block_index] = include_file
33 | }
34 | }
35 | }
36 | close(cmd)
37 |
38 | for ( i = 1; i <= content_lines_index; i++ ) {
39 | line = content_lines[i]
40 | listen_directive_block_index = listen_directive_block_indexes[i]
41 |
42 | if ( ! ( listen_directive_block_index > 0 ) ) {
43 | print line
44 | continue
45 | }
46 |
47 | listen_directive = line
48 | # listen 443 ssl; # ssl enabled
49 | if ( ! match(listen_directive, /[[:space:]]+ssl.*;|;[[:space:]]+#[[:space:]]+ssl enabled/) ) {
50 | print listen_directive
51 | continue
52 | }
53 |
54 | include_files = include_files_in_block[listen_directive_block_index]
55 |
56 | is_ssl_exists = ssl_listen_enable_blocks[listen_directive_block_index] == "true"
57 | if ( ! is_ssl_exists && include_files ) {
58 | # The function 'is_server_ssl_existing_in' is defined in /usr/bin/nginx-utils.sh
59 | ## https://unix.stackexchange.com/questions/72935/using-bash-shell-function-inside-awk#answer-417232
60 | cmd = "bash -c 'is_server_ssl_existing_in " include_files "'"
61 | cmd | getline ssl_exists_checking
62 | close(cmd)
63 |
64 | if ( ssl_exists_checking == "true" ) {
65 | is_ssl_exists = 1 == 1
66 | }
67 | }
68 |
69 | if ( is_ssl_exists ) {
70 | ssl_listen_enable_blocks[listen_directive_block_index] = "true"
71 |
72 | if ( ! match(listen_directive, /[[:space:]]+ssl.*;/) ) {
73 | gsub(/[[:space:]]*;/, " ssl;", listen_directive)
74 | }
75 | } else {
76 | if ( match(listen_directive, /[[:space:]]+ssl.*;/) ) {
77 | gsub(/[[:space:]]+ssl/, "", listen_directive)
78 | }
79 | }
80 | gsub(/;.*/, "; # ssl enabled", listen_directive)
81 |
82 | print listen_directive
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/examples/epage.d/all/13_Clock.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{status}} - {{status_msg}}
8 |
47 |
48 |
49 |
50 |
{{status}} {{status_msg}}
51 |
56 |
57 |
58 |
59 |
115 |
116 |
--------------------------------------------------------------------------------
/examples/epage.d/all/11_Matrix_Rain.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{status}} - {{status_msg}}
8 |
61 |
62 |
63 |
64 |
An error has occurred: {{status}} {{status_msg}}
65 |
66 | Boy: Do not try and bend the website. That's impossible. Instead... only try to realize the truth.
67 |
68 | Neo: What truth?
69 |
70 | Boy: Perhaps, the error cannot be fixed in a short time.
71 |
72 | Neo: Oh, No!
73 |
74 | Boy: Then you'll see, that it is not the website that bends, it is only yourself.
75 |
76 |
83 |
84 |
85 |
86 |
106 |
107 |
--------------------------------------------------------------------------------
/bin/nginx-utils.sh:
--------------------------------------------------------------------------------
1 | get_include_files_from() {
2 | local source="$1"
3 |
4 | for file in $(sed -E '/^\s*include /!d; s/^\s*include\s+([^ ;]+)\s*;/\1/g;' "$source"); do
5 | ls -1 $file 2>/dev/null
6 | done | sort | uniq
7 | }
8 |
9 | get_include_files_deeply_from() {
10 | local source="$1"
11 |
12 | for file in $(get_include_files_from "$source"); do
13 | echo "$file"
14 |
15 | get_include_files_deeply_from "$file"
16 | done | sort | uniq
17 | }
18 |
19 | get_server_names_from() {
20 | local source="$1"
21 |
22 | if [[ -d "$source" ]]; then
23 | source_content="$(cat "$source"/*.conf)"
24 | else
25 | source_content="$(cat "$source")"
26 | fi
27 | # https://stackoverflow.com/questions/32400933/how-can-i-list-all-vhosts-in-nginx#answer-46230868
28 | echo "$source_content" \
29 | | sed -r -e 's/[ \t]*$//' -e 's/^[ \t]*//' -e 's/^#.*$//' -e 's/[ \t]*#.*$//' -e '/^$/d' \
30 | | sed -e ':a;N;$!ba;s/\([^;\{\}]\)\n/\1 /g' \
31 | | grep -E 'server_name[ \t]' | grep -v '\$' | grep '\.' \
32 | | sed -r -e 's/(\S)[ \t]+(\S)/\1\n\2/g' -e 's/[\t ]//g' -e 's/;//' -e 's/server_name//' \
33 | | sed -e '/^$/d' -e 's/^\*\.//g' | sort | uniq
34 | }
35 |
36 | is_server_ssl_existing_in() {
37 | local ssl_files=( $(
38 | grep -Eh '^\s*(ssl_certificate|ssl_certificate_key|ssl_trusted_certificate)\s+/' "$@" \
39 | | sed -E 's/^\s*(ssl_certificate|ssl_certificate_key|ssl_trusted_certificate)\s+([^ ;]+).*;/\2/g;' \
40 | | sort | uniq
41 | ) )
42 |
43 | if [[ "${#ssl_files[@]}" = "0" ]]; then
44 | return
45 | fi
46 |
47 | for file in "${ssl_files[@]}"; do
48 | if [[ ! -f "$file" ]]; then
49 | return
50 | fi
51 | done
52 | echo "true"
53 | }
54 |
55 | check_log_files_for() {
56 | local source="$1"
57 |
58 | echo "Check log files for '$source'"
59 | local files=( "$source" )
60 | files+=( $(get_include_files_deeply_from "$source") )
61 |
62 | for log in $(grep -Eh '^\s*(error_log|access_log)\s+/' "${files[@]}" \
63 | | sed -E 's/^\s*(error_log|access_log)\s+([^ ;]+).*;/\2/g;' \
64 | | sort | uniq); do
65 | if [[ -f "$log" ]]; then
66 | echo " - '$log' exists."
67 | continue
68 | fi
69 |
70 | local log_dir="$(dirname "$log")"
71 | if [[ "x$(echo "$log_dir" | grep '\$')" != "x" ]]; then
72 | echo " - '$log_dir' is ignored."
73 | continue
74 | fi
75 |
76 | mkdir -p "$log_dir"
77 |
78 | if [[ "x$(echo "$log" | grep '\$')" != "x" ]]; then
79 | echo " - '$log' is ignored."
80 | continue
81 | fi
82 | echo " - '$log' is creating..."
83 | touch "$log" && chown nginx "$log_dir" && chmod go-rwx "$log_dir"
84 | done
85 | }
86 |
87 | update_server_ssl_for() {
88 | local source="$1"
89 |
90 | # export bash function to awk scripts
91 | export -f is_server_ssl_existing_in
92 |
93 | echo "Check ssl configuration for '$source'"
94 | local files=( "$source" )
95 | files+=( $(get_include_files_deeply_from "$source") )
96 |
97 | for conf in $(grep -El '^\s*server\s+\{' "${files[@]}" | sort | uniq); do
98 | local updated_conf_content="$(awk -v source_file="$conf" -f /usr/bin/nginx-utils.awk)"
99 |
100 | if [[ "$(cat "$conf")" != "$updated_conf_content" ]]; then
101 | echo " - '$conf' is updating ..."
102 | echo "$updated_conf_content" > "$conf"
103 | else
104 | echo " - '$conf' is ignored."
105 | fi
106 | done
107 | }
108 |
109 | update_host_config_for() {
110 | local source="$1"
111 |
112 | check_log_files_for "$source"
113 | update_server_ssl_for "$source"
114 | }
115 |
--------------------------------------------------------------------------------
/examples/vhost.d/nexus3.example.com.conf:
--------------------------------------------------------------------------------
1 | ##
2 | # Nexus3 service proxy settings, and enable Single-Sign-On (SSO)
3 | #
4 | # Note: You need to install the [Nexus3 Keycloak Plugin](https://github.com/flytreeleft/nexus3-keycloak-plugin) first
5 | ##
6 |
7 | server {
8 | listen 443 ssl;
9 | listen [::]:443 ssl;
10 |
11 | server_name nexus3.example.com;
12 |
13 | include /etc/nginx/vhost.d/nexus3.example.com/*.conf;
14 |
15 | set $oidc_logout_path "/logout";
16 | set $oidc_redirect_after_logout_uri "/";
17 |
18 | location / {
19 | # Note: $http_host contains ip and port, but $host just contains ip only
20 | proxy_set_header Host $http_host;
21 | proxy_set_header X-Keycloak-Sec-Auth $http_x_remote_user:$http_x_remote_user_access_token;
22 | # proxy_set_header Authorization $http_authorization;
23 | # Note: make the HTTP header to be smaller
24 | proxy_hide_header X-Remote-User-Access-Token;
25 |
26 | set $oidc_disabled "false";
27 | # Disable OIDC when using maven client
28 | if ($http_user_agent ~* "^(Apache-Maven|docker)/.+$") {
29 | set $oidc_disabled "true";
30 | }
31 | # And disable OIDC when the header Authorization was specified
32 | if ($http_authorization !~* "^$") {
33 | set $oidc_disabled "true";
34 | }
35 |
36 | set $oidc_realm "";
37 | # Note: change the client id and secret to the actual value
38 | set $oidc_client_id "";
39 | set $oidc_client_secret "";
40 | set $oidc_discovery "http://:/auth/realms/$oidc_realm/.well-known/openid-configuration";
41 | access_by_lua_file /etc/nginx/vhost.d/oidc.lua;
42 |
43 | client_max_body_size 500M;
44 | # Disable cache of assets
45 | proxy_cache off;
46 | proxy_read_timeout 600;
47 | proxy_connect_timeout 600;
48 |
49 | # Avoid to get address resolve error when starting
50 | set $target http://:;
51 | proxy_pass $target;
52 |
53 | sub_filter '
182 |
183 |
{{status}} {{status_msg}}
184 |
189 |
190 |
191 |
192 |
195 |
198 |
201 |
204 |
207 |
210 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 | ' '';
54 | sub_filter_once on;
55 |
56 | # Just for debugging, you may not want it
57 | # header_filter_by_lua_block {
58 | # for key, value in pairs(ngx.resp.get_headers()) do
59 | # local val = type(value) == 'string' and {value} or value
60 | # for k, v in ipairs(val) do
61 | # for i=0, v:len(), 1024 do
62 | # ngx.log(ngx.DEBUG, 'Response Header: '..key..' -> '..v:sub(i + 1, i + 1024))
63 | # end
64 | # end
65 | # end
66 | # for key, value in pairs(ngx.req.get_headers()) do
67 | # local val = type(value) == 'string' and {value} or value
68 | # for k, v in ipairs(val) do
69 | # for i=0, v:len(), 1024 do
70 | # ngx.log(ngx.DEBUG, 'Request Header: '..key..' -> '..v:sub(i + 1, i + 1024))
71 | # end
72 | # end
73 | # end
74 | # }
75 | }
76 |
77 | # Override the logout action of Nexus
78 | location /service/rapture/session {
79 | if ($request_method ~* "^DELETE$") {
80 | # Redirect to the internal logout url
81 | return 302 $scheme://$http_host$oidc_logout_path;
82 | }
83 | # Login forbidden
84 | return 403;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/examples/epage.d/all/10_Newton_Cradle.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |