diff --git a/nginx/Dockerfile b/nginx/Dockerfile index bafd105f..7177e77e 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -70,7 +70,9 @@ ENV \ NGINX_PROXY_CONNECT_TIMEOUT=60s \ NGINX_PROXY_READ_TIMEOUT=60s \ NGINX_PROXY_SEND_TIMEOUT=60s \ + NGINX_REAL_IP_HEADER=X-Forwarded-For \ NGINX_SEND_TIMEOUT=60s \ + NGINX_SET_REAL_IP_FROM=172.0.0.0/8 \ NGINX_WORKER_CONNECTIONS=1024 \ NGINX_WORKER_PROCESSES=auto \ PHP_DEFAULT_SOCKET_TIMEOUT=60 \ diff --git a/nginx/README.md b/nginx/README.md index 5a22e2fa..84757abb 100644 --- a/nginx/README.md +++ b/nginx/README.md @@ -22,22 +22,24 @@ Requires `islandora/base` docker image to build. Please refer to the ### Nginx Settings -| Environment Variable | Default | Description | -| :---------------------------- | :------ | :------------------------------------------------------------------------------------ | -| NGINX_CLIENT_BODY_TIMEOUT | 60s | Timeout for reading client request body | -| NGINX_CLIENT_MAX_BODY_SIZE | 1m | Specifies the maximum accepted body size of a client request | -| NGINX_ERROR_LOG_LEVEL | warn | Log Level of Error log | -| NGINX_FASTCGI_CONNECT_TIMEOUT | 60s | Timeout for establishing a connection with a FastCGI server | -| NGINX_FASTCGI_READ_TIMEOUT | 60s | Timeout for reading a response from the FastCGI server | -| NGINX_FASTCGI_SEND_TIMEOUT | 60s | Timeout for transmitting a request to the FastCGI server. | -| NGINX_KEEPALIVE_TIMEOUT | 75s | Timeout for keep-alive connections | -| NGINX_LINGERING_TIMEOUT | 5s | The maximum waiting time for more client data to arrive | -| NGINX_PROXY_CONNECT_TIMEOUT | 60s | Timeout for establishing a connection with a proxied server | -| NGINX_PROXY_READ_TIMEOUT | 60s | Timeout for reading a response from the proxied server | -| NGINX_PROXY_SEND_TIMEOUT | 60s | Timeout for transmitting a request to the proxied server | -| NGINX_SEND_TIMEOUT | 60s | Timeout for transmitting a response to the client | -| NGINX_WORKER_CONNECTIONS | 1024 | The maximum number of simultaneous connections that can be opened by a worker process | -| NGINX_WORKER_PROCESSES | auto | Set number of worker processes automatically based on number of CPU cores | +| Environment Variable | Default | Description | +| :---------------------------- | :-------------- | :------------------------------------------------------------------------------------ | +| NGINX_CLIENT_BODY_TIMEOUT | 60s | Timeout for reading client request body | +| NGINX_CLIENT_MAX_BODY_SIZE | 1m | Specifies the maximum accepted body size of a client request | +| NGINX_ERROR_LOG_LEVEL | warn | Log Level of Error log | +| NGINX_FASTCGI_CONNECT_TIMEOUT | 60s | Timeout for establishing a connection with a FastCGI server | +| NGINX_FASTCGI_READ_TIMEOUT | 60s | Timeout for reading a response from the FastCGI server | +| NGINX_FASTCGI_SEND_TIMEOUT | 60s | Timeout for transmitting a request to the FastCGI server. | +| NGINX_KEEPALIVE_TIMEOUT | 75s | Timeout for keep-alive connections | +| NGINX_LINGERING_TIMEOUT | 5s | The maximum waiting time for more client data to arrive | +| NGINX_PROXY_CONNECT_TIMEOUT | 60s | Timeout for establishing a connection with a proxied server | +| NGINX_PROXY_READ_TIMEOUT | 60s | Timeout for reading a response from the proxied server | +| NGINX_PROXY_SEND_TIMEOUT | 60s | Timeout for transmitting a request to the proxied server | +| NGINX_REAL_IP_HEADER | X-Forwarded-For | Request header field whose value will be used to replace the client address. | +| NGINX_SEND_TIMEOUT | 60s | Timeout for transmitting a response to the client | +| NGINX_SET_REAL_IP_FROM | 172.0.0.0/8 | Trusted addresses that are known to send correct replacement addresses | +| NGINX_WORKER_CONNECTIONS | 1024 | The maximum number of simultaneous connections that can be opened by a worker process | +| NGINX_WORKER_PROCESSES | auto | Set number of worker processes automatically based on number of CPU cores | ### PHP Settings diff --git a/nginx/rootfs/etc/confd/templates/nginx.conf.tmpl b/nginx/rootfs/etc/confd/templates/nginx.conf.tmpl index 4ede8774..4d62c5a1 100644 --- a/nginx/rootfs/etc/confd/templates/nginx.conf.tmpl +++ b/nginx/rootfs/etc/confd/templates/nginx.conf.tmpl @@ -153,6 +153,9 @@ http { # Sets the path, format, and configuration for a buffered log write. access_log /dev/stdout main; + # Sets the client IP to print in logs + real_ip_header {{ getenv "NGINX_REAL_IP_HEADER" }}; + set_real_ip_from {{ getenv "NGINX_SET_REAL_IP_FROM" }}; # Includes virtual hosts configs. include /etc/nginx/http.d/*.conf; diff --git a/nginx/tests/ServiceLogsClientIp/build.gradle.kts b/nginx/tests/ServiceLogsClientIp/build.gradle.kts new file mode 100644 index 00000000..2018ffb7 --- /dev/null +++ b/nginx/tests/ServiceLogsClientIp/build.gradle.kts @@ -0,0 +1,26 @@ +import plugins.TestsPlugin.DockerComposeUp +import java.io.ByteArrayOutputStream + +tasks.named("test") { + doLast { + // get the docker logs from our nginx service + val outputStream = ByteArrayOutputStream() + project.exec { + commandLine = baseArguments + listOf("logs") + standardOutput = outputStream + workingDir = project.projectDir + } + val output = outputStream.toString() + + // see if the log has a match for the IP we set in the test.sh cURL -H command + val pattern = "nginx-1 | 1.2.3.4" + val matchingLines = output.lines().filter { line -> + line.startsWith(pattern) + } + + // fail the test if we didn't find any logs with the IP + if (matchingLines.isEmpty()) { + throw GradleException("No lines found starting with '$pattern'") + } + } +} diff --git a/nginx/tests/ServiceLogsClientIp/docker-compose.yml b/nginx/tests/ServiceLogsClientIp/docker-compose.yml new file mode 100644 index 00000000..8c7f8e15 --- /dev/null +++ b/nginx/tests/ServiceLogsClientIp/docker-compose.yml @@ -0,0 +1,20 @@ +--- +version: "3.8" + +# Common to all services +x-common: &common + restart: "no" + +name: nginx-servicelogsclientip +services: + nginx: + <<: *common + image: ${NGINX:-islandora/nginx:local} + # Set realip as trusting only localhost + environment: + - NGINX_REAL_IP_HEADER=X-Forwarded-For + - NGINX_SET_REAL_IP_FROM=127.0.0.1/32 + volumes: + - ./test.sh:/test.sh + command: + - /test.sh diff --git a/nginx/tests/ServiceLogsClientIp/test.sh b/nginx/tests/ServiceLogsClientIp/test.sh new file mode 100755 index 00000000..7cc62486 --- /dev/null +++ b/nginx/tests/ServiceLogsClientIp/test.sh @@ -0,0 +1,13 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -eou pipefail + +# Wait for Nginx to be ready. +s6-svwait -U /run/service/nginx + +# hit localhost nginx with the proper header so that IP is logged +curl -s -o /dev/null -H "X-Forwarded-For: 1.2.3.4" http://localhost:80/ + +# Service must start for us to get to this point. +exit 0