feat: add support for setting underscores-in-headers for nginx, openresty, and k3s

Closes #6627
This commit is contained in:
Jose Diaz-Gonzalez
2024-02-27 11:23:23 -05:00
parent c2bc469d53
commit b99c25f090
13 changed files with 77 additions and 4 deletions

View File

@@ -323,6 +323,7 @@ Changing these value globally or on a per-app basis will require rebuilding the
| proxy-buffers | `8 8k` | string | Number and size of the buffers used for reading the proxied server response, for a single connection |
| proxy-busy-buffers-size | `16k` | string | Limits the total size of buffers that can be busy sending a response to the client while the response is not yet fully read. |
| proxy-read-timeout | `60s` | string | Timeout (with units) for reading response from your backend server |
| underscore-in-headers | `off` | string | Enables or disables the use of underscores in client request header fields. |
| x-forwarded-for-value | `$remote_addr` | string | Used for specifying the header value to set for the `X-Forwared-For` header |
| x-forwarded-port-value | `$server_port` | string | Used for specifying the header value to set for the `X-Forwared-Port` header |
| x-forwarded-proto-value | `$scheme` | string | Used for specifying the header value to set for the `X-Forwared-Proto` header |

View File

@@ -89,6 +89,9 @@ cmd-nginx-report-single() {
"--nginx-proxy-read-timeout: $(fn-nginx-proxy-read-timeout "$APP")"
"--nginx-computed-proxy-read-timeout: $(fn-nginx-computed-proxy-read-timeout "$APP")"
"--nginx-global-proxy-read-timeout: $(fn-nginx-global-proxy-read-timeout "$APP")"
"--nginx-underscore-in-headers: $(fn-nginx-underscore-in-headers "$APP")"
"--nginx-computed-underscore-in-headers: $(fn-nginx-computed-underscore-in-headers "$APP")"
"--nginx-global-underscore-in-headers: $(fn-nginx-global-underscore-in-headers "$APP")"
"--nginx-x-forwarded-for-value: $(fn-nginx-x-forwarded-for-value "$APP")"
"--nginx-computed-x-forwarded-for-value: $(fn-nginx-computed-x-forwarded-for-value "$APP")"
"--nginx-global-x-forwarded-for-value: $(fn-nginx-global-x-forwarded-for-value "$APP")"

View File

@@ -341,6 +341,7 @@ nginx_build_config() {
local NGINX_BIND_ADDRESS_IP4="$(fn-nginx-computed-bind-address-ipv4 "$APP")"
local NGINX_BIND_ADDRESS_IP6="$(fn-nginx-computed-bind-address-ipv6 "$APP")"
local NGINX_UNDERSCORE_IN_HEADERS="$(fn-nginx-computed-underscore-in-headers "$APP")"
local PROXY_X_FORWARDED_FOR="$(fn-nginx-computed-x-forwarded-for-value "$APP")"
local PROXY_X_FORWARDED_PORT="$(fn-nginx-computed-x-forwarded-port-value "$APP")"
local PROXY_X_FORWARDED_PROTO="$(fn-nginx-computed-x-forwarded-proto-value "$APP")"
@@ -372,6 +373,7 @@ nginx_build_config() {
PROXY_BUFFERING="$PROXY_BUFFERING"
PROXY_BUFFERS="$PROXY_BUFFERS"
PROXY_BUSY_BUFFERS_SIZE="$PROXY_BUSY_BUFFERS_SIZE"
NGINX_UNDERSCORE_IN_HEADERS="$NGINX_UNDERSCORE_IN_HEADERS"
# Deprecated: Remove this after a few versions
NGINX_PORT="$PROXY_PORT" NGINX_SSL_PORT="$PROXY_SSL_PORT"
PROXY_PORT="$PROXY_PORT" PROXY_SSL_PORT="$PROXY_SSL_PORT"

View File

@@ -347,6 +347,27 @@ fn-nginx-global-proxy-read-timeout() {
fn-get-property --app "$APP" --global "proxy-read-timeout"
}
fn-nginx-underscore-in-headers() {
declare desc="get the configured underscore in headers value"
declare APP="$1"
fn-get-property --app "$APP" "underscore-in-headers"
}
fn-nginx-computed-underscore-in-headers() {
declare desc="get the computed underscore in headers value"
declare APP="$1"
fn-get-property --app "$APP" --computed "underscore-in-headers"
}
fn-nginx-global-underscore-in-headers() {
declare desc="get the global underscore in headers value"
declare APP="$1"
fn-get-property --app "$APP" --global "underscore-in-headers"
}
fn-nginx-x-forwarded-for-value() {
declare desc="get the configured x-forwarded-for value"
declare APP="$1"

View File

@@ -298,6 +298,23 @@ func GlobalProxyReadTimeout() string {
return common.PropertyGetDefault("nginx", "--global", "proxy-read-timeout", "60s")
}
func AppUnderscoreInHeaders(appName string) string {
return common.PropertyGet("nginx", appName, "underscore-in-headers")
}
func ComputedUnderscoreInHeaders(appName string) string {
appValue := AppUnderscoreInHeaders(appName)
if appValue != "" {
return appValue
}
return GlobalUnderscoreInHeaders()
}
func GlobalUnderscoreInHeaders() string {
return common.PropertyGetDefault("nginx", "--global", "underscore-in-headers", "off")
}
func AppXForwardedForValue(appName string) string {
return common.PropertyGet("nginx", appName, "x-forwarded-for-value")
}

View File

@@ -69,6 +69,8 @@ func appValue(appName string, property string) string {
value = nginx_vhosts.AppProxyBusyBuffersSize(appName)
case "proxy-read-timeout":
value = nginx_vhosts.AppProxyReadTimeout(appName)
case "underscore-in-headers":
value = nginx_vhosts.AppUnderscoreInHeaders(appName)
case "x-forwarded-for-value":
value = nginx_vhosts.AppXForwardedForValue(appName)
case "x-forwarded-port-value":
@@ -119,6 +121,8 @@ func computedValue(appName string, property string) string {
value = nginx_vhosts.ComputedProxyBusyBuffersSize(appName)
case "proxy-read-timeout":
value = nginx_vhosts.ComputedProxyReadTimeout(appName)
case "underscore-in-headers":
value = nginx_vhosts.ComputedUnderscoreInHeaders(appName)
case "x-forwarded-for-value":
value = nginx_vhosts.ComputedXForwardedForValue(appName)
case "x-forwarded-port-value":
@@ -169,6 +173,8 @@ func globalValue(appName string, property string) string {
value = nginx_vhosts.GlobalProxyBusyBuffersSize()
case "proxy-read-timeout":
value = nginx_vhosts.GlobalProxyReadTimeout()
case "underscore-in-headers":
value = nginx_vhosts.GlobalUnderscoreInHeaders()
case "x-forwarded-for-value":
value = nginx_vhosts.GlobalXForwardedForValue()
case "x-forwarded-port-value":

View File

@@ -9,13 +9,13 @@ cmd-nginx-set() {
declare cmd="nginx:set"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" KEY="$2" VALUE="$3"
local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-max-body-size" "disable-custom-config" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "nginx-conf-sigil-path" "proxy-read-timeout" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-max-body-size" "disable-custom-config" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "nginx-conf-sigil-path" "proxy-read-timeout" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "underscore-in-headers" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local GLOBAL_KEYS=("hsts" "nginx-conf-sigil-path")
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, client-max-body-size, disable-custom-config, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, nginx-conf-sigil-path, proxy-read-timeout, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value, x-forwarded-ssl"
dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, client-max-body-size, disable-custom-config, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, nginx-conf-sigil-path, proxy-read-timeout, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, underscore-in-headers, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value, x-forwarded-ssl"
fi
if ! fn-in-array "$KEY" "${GLOBAL_KEYS[@]}"; then

View File

@@ -11,6 +11,7 @@ server {
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log {{ $.NGINX_ACCESS_LOG_PATH }}{{ if and ($.NGINX_ACCESS_LOG_FORMAT) (ne $.NGINX_ACCESS_LOG_PATH "off") }} {{ $.NGINX_ACCESS_LOG_FORMAT }}{{ end }};
error_log {{ $.NGINX_ERROR_LOG_PATH }};
underscores_in_headers {{ $.NGINX_UNDERSCORE_IN_HEADERS }};
{{ if (and (eq $listen_port "80") ($.SSL_INUSE)) }}
include {{ $.DOKKU_ROOT }}/{{ $.APP }}/nginx.conf.d/*.conf;
location / {
@@ -73,6 +74,7 @@ server {
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log {{ $.NGINX_ACCESS_LOG_PATH }}{{ if and ($.NGINX_ACCESS_LOG_FORMAT) (ne $.NGINX_ACCESS_LOG_PATH "off") }} {{ $.NGINX_ACCESS_LOG_FORMAT }}{{ end }};
error_log {{ $.NGINX_ERROR_LOG_PATH }};
underscores_in_headers {{ $.NGINX_UNDERSCORE_IN_HEADERS }};
ssl_certificate {{ $.APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key;
@@ -143,6 +145,7 @@ server {
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log {{ $.NGINX_ACCESS_LOG_PATH }}{{ if and ($.NGINX_ACCESS_LOG_FORMAT) (ne $.NGINX_ACCESS_LOG_PATH "off") }} {{ $.NGINX_ACCESS_LOG_FORMAT }}{{ end }};
error_log {{ $.NGINX_ERROR_LOG_PATH }};
underscores_in_headers {{ $.NGINX_UNDERSCORE_IN_HEADERS }};
location / {
grpc_pass grpc://{{ $.APP }}-{{ $upstream_port }};
}
@@ -159,6 +162,7 @@ server {
{{ if $.NOSSL_SERVER_NAME }}server_name {{ $.NOSSL_SERVER_NAME }}; {{ end }}
access_log {{ $.NGINX_ACCESS_LOG_PATH }}{{ if and ($.NGINX_ACCESS_LOG_FORMAT) (ne $.NGINX_ACCESS_LOG_PATH "off") }} {{ $.NGINX_ACCESS_LOG_FORMAT }}{{ end }};
error_log {{ $.NGINX_ERROR_LOG_PATH }};
underscores_in_headers {{ $.NGINX_UNDERSCORE_IN_HEADERS }};
ssl_certificate {{ $.APP_SSL_PATH }}/server.crt;
ssl_certificate_key {{ $.APP_SSL_PATH }}/server.key;

View File

@@ -55,6 +55,7 @@ cmd-openresty-report-single() {
"--openresty-proxy-buffers: $(fn-openresty-proxy-buffers "$APP")"
"--openresty-proxy-busy-buffers-size: $(fn-openresty-proxy-busy-buffers-size "$APP")"
"--openresty-proxy-read-timeout: $(fn-openresty-proxy-read-timeout "$APP")"
"--openresty-underscore-in-headers: $(fn-openresty-underscore-in-headers "$APP")"
"--openresty-x-forwarded-for-value: $(fn-openresty-x-forwarded-for-value "$APP")"
"--openresty-x-forwarded-port-value: $(fn-openresty-x-forwarded-port-value "$APP")"
"--openresty-x-forwarded-proto-value: $(fn-openresty-x-forwarded-proto-value "$APP")"

View File

@@ -160,6 +160,8 @@ trigger-openresty-vhosts-docker-args-process-deploy() {
[[ -n "$value" ]] && output="$output '--label=openresty.proxy-send-timeout=$value'"
value="$(fn-openresty-send-timeout "$APP")"
[[ -n "$value" ]] && output="$output '--label=openresty.send-timeout=$value'"
value="$(fn-openresty-underscore-in-headers "$APP")"
[[ -n "$value" ]] && output="$output '--label=openresty.underscore-in-headers=$value'"
value="$(fn-openresty-x-forwarded-for-value "$APP")"
[[ -n "$value" ]] && output="$output '--label=openresty.x-forwarded-for-value=$value'"
value="$(fn-openresty-x-forwarded-port-value "$APP")"

View File

@@ -224,6 +224,13 @@ fn-openresty-template-compose-file() {
sigil -f "$COMPOSE_TEMPLATE" "${SIGIL_PARAMS[@]}" | cat -s >"$OUTPUT_PATH"
}
fn-openresty-underscore-in-headers() {
declare desc="get the configured underscore in headers value"
declare APP="$1"
fn-plugin-property-get-default "openresty" "$APP" "underscore-in-headers" "off"
}
fn-openresty-x-forwarded-for-value() {
declare desc="get the configured x-forwarded-for value"
declare APP="$1"

View File

@@ -9,13 +9,13 @@ cmd-openresty-set() {
declare cmd="openresty:set"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" KEY="$2" VALUE="$3"
local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-max-body-size" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "image" "log-level" "letsencrypt-email" "letsencrypt-server" "proxy-read-timeout" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local VALID_KEYS=("access-log-format" "access-log-path" "bind-address-ipv4" "bind-address-ipv6" "client-max-body-size" "error-log-path" "hsts" "hsts-include-subdomains" "hsts-preload" "hsts-max-age" "image" "log-level" "letsencrypt-email" "letsencrypt-server" "proxy-read-timeout" "proxy-buffer-size" "proxy-buffering" "proxy-buffers" "proxy-busy-buffers-size" "underscore-in-headers" "x-forwarded-for-value" "x-forwarded-port-value" "x-forwarded-proto-value" "x-forwarded-ssl")
local GLOBAL_KEYS=("image" "log-level" "letsencrypt-email" "letsencrypt-server")
[[ -z "$KEY" ]] && dokku_log_fail "No key specified"
if ! fn-in-array "$KEY" "${VALID_KEYS[@]}"; then
dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, client-max-body-size, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, image, log-level, letsencrypt-email, letsencrypt-server, proxy-read-timeout, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value, x-forwarded-ssl"
dokku_log_fail "Invalid key specified, valid keys include: access-log-format, access-log-path, bind-address-ipv4, bind-address-ipv6, client-max-body-size, error-log-path, hsts, hsts-include-subdomains, hsts-preload, hsts-max-age, image, log-level, letsencrypt-email, letsencrypt-server, proxy-read-timeout, proxy-buffer-size, proxy-buffering, proxy-buffers, proxy-busy-buffers-size, underscore-in-headers, x-forwarded-for-value, x-forwarded-port-value, x-forwarded-proto-value, x-forwarded-ssl"
fi
if ! fn-in-array "$KEY" "${GLOBAL_KEYS[@]}"; then

View File

@@ -581,6 +581,15 @@ func getIngressAnnotations(appName string, processType string) (map[string]strin
annotation: "nginx.ingress.kubernetes.io/proxy-read-timeout",
getter: nginxvhosts.ComputedProxyReadTimeout,
},
"underscore-in-headers": {
getter: nginxvhosts.ComputedUnderscoreInHeaders,
locationSnippet: func(value string) string {
if value == "" {
return ""
}
return fmt.Sprintf("underscores_in_headers %s;", value)
},
},
"x-forwarded-for-value": {
getter: nginxvhosts.ComputedXForwardedForValue,
locationSnippet: func(value string) string {