Merge pull request #6662 from dokku/openresty-domain-limit

Allow limiting letsencrypt to certain domains when using openresty as a proxy
This commit is contained in:
Jose Diaz-Gonzalez
2024-03-06 05:14:31 -05:00
committed by GitHub
6 changed files with 127 additions and 4 deletions

View File

@@ -148,6 +148,50 @@ dokku openresty:set --global letsencrypt-server https://acme-staging-v02.api.let
After enabling, the OpenResty container will need to be restarted and apps will need to be rebuilt to retrieve certificates from the new server.
#### Limiting letsencrypt to certain domains
> [!WARNING]
> Changing this value may cause OpenResty to fail to start if the value is not valid. Caution should be exercised when changing this value from the defaults.
In cases where your server's IP may have invalid domains pointing at it, limiting letsencrypt to certain allowed domains may be desirable to reduce spam requests on the Letsencrypt servers. The default is to allow all domains to have certificates retrieved, but this can be limited by specifying the `allowed-letsencrypt-domains-func-base64` global property.
The default internal value for `allowed-letsencrypt-domains-func-base64` is the base64 representation of `return true`, and is meant to be the body of a lua function that return a boolean value.
```shell
value="$(echo 'return true' | base64 -w 0)"
dokku openresty:set --global allowed-letsencrypt-domains-func-base64 $value
```
As this is a global value, once changed, OpenResty should be stopped and started again for the value to take effect:
```shell
dokku openresty:stop
dokku openresty:start
```
A more complex example would be to limit provisioning of certificates to domains in a specific list. The body of the lua function has access to a variable `domain`, and we can use it like so:
```shell
body='allowed_domains = {"domain.com", "extra-domain.com"}
for index, value in ipairs(allowed_domains) do
if value == domain then
return true
end
end
return false
'
value="$(echo "$body" | base64 -w 0)"
dokku openresty:set --global allowed-letsencrypt-domains-func-base64 $value
```
To reset the value to the default, simply specify a blank value prior to restarting OpenResty:
```shell
dokku openresty:set --global allowed-letsencrypt-domains-func-base64
```
## Displaying OpenResty reports for an app
You can get a report about the app's OpenResty config using the `openresty:report` command:

View File

@@ -1 +1 @@
FROM dokku/openresty-docker-proxy:0.6.0
FROM dokku/openresty-docker-proxy:0.7.0

View File

@@ -37,6 +37,7 @@ cmd-openresty-report-single() {
local flag_map=(
"--openresty-access-log-format: $(fn-openresty-access-log-format "$APP")"
"--openresty-access-log-path: $(fn-openresty-access-log-path "$APP")"
"--openresty-allowed-letsencrypt-domains-func-base64: $(fn-openresty-allowed-letsencrypt-domains-func-base64)"
"--openresty-bind-address-ipv4: $(fn-openresty-bind-address-ipv4 "$APP")"
"--openresty-bind-address-ipv6: $(fn-openresty-bind-address-ipv6 "$APP")"
"--openresty-client-max-body-size: $(fn-openresty-client-max-body-size "$APP")"

View File

@@ -26,6 +26,12 @@ fn-openresty-access-log-path() {
fn-plugin-property-get-default "openresty" "$APP" "access-log-path" "${OPENRESTY_LOG_ROOT}/${APP}-access.log"
}
fn-fn-openresty-allowed-letsencrypt-domains-func-base64() {
declare desc="get the configured allowed domains func base64"
fn-plugin-property-get-default "openresty" "--global" "allowed-letsencrypt-domains-func-base64" "return true" | base64 -w 0
}
fn-openresty-bind-address-ipv4() {
declare desc="get the configured ipv4 bind address"
declare APP="$1"
@@ -221,6 +227,11 @@ fn-openresty-template-compose-file() {
OPENRESTY_LETSENCRYPT_EMAIL="$(fn-openresty-letsencrypt-email)"
OPENRESTY_LETSENCRYPT_SERVER="$(fn-openresty-letsencrypt-server)")
local ALLOWED_DOMAINS_FUNC_BASE64="$(fn-fn-openresty-allowed-letsencrypt-domains-func-base64)"
if [[ -n "$ALLOWED_DOMAINS_FUNC_BASE64" ]]; then
SIGIL_PARAMS+=(ALLOWED_DOMAINS_FUNC_BASE64="$ALLOWED_DOMAINS_FUNC_BASE64")
fi
sigil -f "$COMPOSE_TEMPLATE" "${SIGIL_PARAMS[@]}" | cat -s >"$OUTPUT_PATH"
}

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" "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")
local VALID_KEYS=("access-log-format" "access-log-path" "allowed-letsencrypt-domains-func-base64" "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=("allowed-letsencrypt-domains-func-base64" "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, underscore-in-headers, 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, allowed-letsencrypt-domains-func-base64, 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

@@ -138,6 +138,73 @@ teardown() {
assert_output "http:80:5000 https:443:5000"
}
@test "(openresty) allowed-domains" {
run /bin/bash -c "dokku proxy:set $TEST_APP openresty"
echo "output: $output"
echo "status: $status"
assert_success
value="$(echo 'return true' | base64 -w 0)"
run /bin/bash -c "dokku openresty:set --global allowed-letsencrypt-domains-func-base64 $value"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:start"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker exec openresty-openresty-1 /usr/local/openresty/nginx/sbin/nginx -t"
echo "output: $output"
echo "status: $status"
assert_success
body='allowed_domains = {"domain.com", "extra-domain.com"}
for index, value in ipairs(allowed_domains) do
if value == domain then
return true
end
end
return false
'
value="$(echo "$body" | base64 -w 0)"
run /bin/bash -c "dokku openresty:set --global allowed-letsencrypt-domains-func-base64 $value"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:stop"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:start"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "docker exec openresty-openresty-1 /usr/local/openresty/nginx/sbin/nginx -t"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:set --global allowed-letsencrypt-domains-func-base64"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:stop"
echo "output: $output"
echo "status: $status"
assert_success
run /bin/bash -c "dokku openresty:start"
echo "output: $output"
echo "status: $status"
assert_success
}
@test "(openresty) includes" {
run /bin/bash -c "dokku proxy:set $TEST_APP openresty"
echo "output: $output"