From 3c38ff638c978bc1e466ffade6d80600a789e128 Mon Sep 17 00:00:00 2001 From: Donal Byrne Date: Mon, 15 Jul 2024 15:48:06 +0200 Subject: [PATCH] Adding docker image --- images/nginx-ingress/Dockerfile | 49 ++++++++++ images/nginx-ingress/docker_entrypoint.sh | 107 ++++++++++++++++++++++ images/nginx-ingress/error.html | 14 +++ images/nginx-ingress/lua/error_page.lua | 45 +++++++++ images/nginx-ingress/lua/url.lua | 29 ++++++ 5 files changed, 244 insertions(+) create mode 100644 images/nginx-ingress/Dockerfile create mode 100755 images/nginx-ingress/docker_entrypoint.sh create mode 100644 images/nginx-ingress/error.html create mode 100644 images/nginx-ingress/lua/error_page.lua create mode 100644 images/nginx-ingress/lua/url.lua diff --git a/images/nginx-ingress/Dockerfile b/images/nginx-ingress/Dockerfile new file mode 100644 index 0000000..a9d37c5 --- /dev/null +++ b/images/nginx-ingress/Dockerfile @@ -0,0 +1,49 @@ +FROM openresty/openresty:1.25.3.1-0-bookworm-fat + +MAINTAINER Donal Byrne + +ENV RESTY_ROOT=/usr/local/openresty + +RUN DEBIAN_FRONTEND=noninteractive \ + apt-get update -qq && \ + ( curl -f --location https://github.com/Orange-OpenSource/hurl/releases/download/2.0.1/hurl_2.0.1_$(dpkg --print-architecture).deb --output "/tmp/hurl.deb" && \ + DEBIAN_FRONTEND=noninteractive apt install -y /tmp/hurl.deb) || true && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + ca-certificates \ + build-essential \ + curl \ + unzip \ + make \ + bsdmainutils && \ + rm -rf /var/lib/apt/lists/* && \ + curl -L https://luarocks.org/releases/luarocks-3.11.1.tar.gz --output /tmp/luarocks-3.11.1.tar.gz && \ + cd /tmp && \ + tar -xzvf luarocks-3.11.1.tar.gz && \ + cd luarocks-3.11.1/ && \ + ./configure --prefix=/usr/local/openresty/luajit \ + --with-lua=/usr/local/openresty/luajit/ \ + --lua-suffix=jit \ + --with-lua-include=/usr/local/openresty/luajit/include/luajit-2.1 && \ + make && \ + make install && \ + DEBIAN_FRONTEND=noninteractive /usr/local/openresty/luajit/bin/luarocks install lua-resty-auto-ssl $RESTY_AUTO_SSL_VERSION && \ + opm get ledgetech/lua-resty-http && \ + opm get bungle/lua-resty-template && \ + mkdir /etc/resty-auto-ssl && \ + chown nobody /etc/resty-auto-ssl && \ + curl -L https://raw.githubusercontent.com/slomkowski/nginx-config-formatter/master/nginxfmt.py > /usr/local/bin/nginxfmt && \ + chmod +x /usr/local/bin/nginxfmt && \ + curl -L https://raw.githubusercontent.com/dehydrated-io/dehydrated/v0.7.1/dehydrated > /usr/local/openresty/luajit/bin/resty-auto-ssl/dehydrated && \ + chmod +x /usr/local/openresty/luajit/bin/resty-auto-ssl/dehydrated + +COPY docker_entrypoint.sh /docker_entrypoint.sh + +COPY error.html /etc/skate/ingress/ +#COPY nginx.conf.tmpl /etc/skate/ingress/ +#COPY test/ /etc/skate/ingress/test + + +COPY lua $RESTY_ROOT/nginx/lua + + +ENTRYPOINT ["/docker_entrypoint.sh"] diff --git a/images/nginx-ingress/docker_entrypoint.sh b/images/nginx-ingress/docker_entrypoint.sh new file mode 100755 index 0000000..e43fa11 --- /dev/null +++ b/images/nginx-ingress/docker_entrypoint.sh @@ -0,0 +1,107 @@ +#!/bin/bash +set -eu + + +# the path openresty will look for the nginx config +CONF_PATH="/etc/skate/ingress/nginx.conf" + +pidfile=/usr/local/openresty/nginx/logs/nginx.pid + +ensure_self_signed() { + domain=$1 + ssl_path="/usr/local/openresty/nginx/ssl/${domain}" + if [ ! -d "$ssl_path" ]; then + echo "generating self signed cert for $domain" + mkdir -p $ssl_path + country=SE + state=Kalmar + city=Kalmar + # This line generates a self signed SSL certificate and key without user intervention. + openssl req -x509 -newkey rsa:4096 -keyout "${ssl_path}/server.key" -out "${ssl_path}/server.crt" \ + -days 365 -nodes -subj "/C=$country/ST=$state/L=$city/O=Internet/OU=./CN=$domain/emailAddress=postmaster@$domain" + fi +} + +kill_child() { + pid="$(cat $pidfile 2>/dev/null || echo '')" + if [ -n "${pid:-}" ]; then + echo "killing child pid $pid" + kill -QUIT "$pid" + wait "$pid" + fi +} + +trap 'echo kill signal received; kill_child' INT TERM QUIT + +## Chown storage of ssl certs +mkdir -p /etc/resty-auto-ssl/storage +chown -R nobody /etc/resty-auto-ssl/storage + +## Hopefully fix bug +rm -f auto-ssl-sockproc.pid + +SYSTEM_RESOLVER=$(cat /etc/resolv.conf | grep -im 1 '^nameserver' | cut -d ' ' -f2) +export SYSTEM_RESOLVER + +prepare_config() { + # ensure self signed cert exists for base url + domains=$(grep "# anchor::domain" "$CONF_PATH" | awk '{print $3}' | sort -u) + for domain in $domains; do + ensure_self_signed $domain + done + + # Format it + echo "formatting..." + nginxfmt -v $CONF_PATH + + # Test config + echo "testing config..." + if ! /usr/local/openresty/bin/openresty -c $CONF_PATH -t; then + cat --number $CONF_PATH + # restore prev config + mv ${CONF_PATH}.old $CONF_PATH + fi + +} + +# hack to wait for pid to appear +wait_file_changed() { + tail -fn0 "$1" | head -n1 >/dev/null 2>&1 +} + +reload_and_wait() { + # lock + if { + set -C + 2>/dev/null >/tmp/ingressreload.lock + }; then + # have lock + pid="$(cat $pidfile 2>/dev/null || echo '')" + if [ -z "${pid:-}" ]; then + return + fi + + prepare_config + echo "sending HUP..." + kill -HUP "$pid" + # release + rm /tmp/ingressreload.lock + echo "waiting on $pid" + wait "$pid" + fi +} + +prepare_config + +echo "staring daemon..." +/usr/local/openresty/bin/openresty -c $CONF_PATH -g "daemon off;" & + +trap 'reload_and_wait' HUP + +echo 'waiting for pid to appear...' +wait_file_changed $pidfile +pid="$(cat $pidfile)" +echo "master process pid found ($pid)" + +echo "waiting on process" +wait $pid diff --git a/images/nginx-ingress/error.html b/images/nginx-ingress/error.html new file mode 100644 index 0000000..a00ee94 --- /dev/null +++ b/images/nginx-ingress/error.html @@ -0,0 +1,14 @@ + + + + + Error + + +

{{ title }}

+ +

+ {{ message }} +

+ + diff --git a/images/nginx-ingress/lua/error_page.lua b/images/nginx-ingress/lua/error_page.lua new file mode 100644 index 0000000..eafd51c --- /dev/null +++ b/images/nginx-ingress/lua/error_page.lua @@ -0,0 +1,45 @@ +local _M = {} + +local errors_map = { + ["default"] = { + title = "Something went wrong", + message = "We're very sorry for any inconvenience, our service team has been notified." + }, + --[502] = { + -- title = "Something went wrong", + -- message = "We're very sorry for any inconvenience, our service team has been notified." + --}, + --[503] = { + -- title = "Something went wrong", + -- message = "We're very sorry for any inconvenience, our service team has been notified." + --}, + --[504] = { + -- title = "Something went wrong", + -- message = "We're very sorry for any inconvenience, our service team has been notified." + --}, + [404] = { + title = "That site doesn't seem to exist", + message = "Sorry, but there's nothing to see." + } +} + +local function getVars(code) + if errors_map[code] then + return errors_map[code] + else + return errors_map["default"] + end +end + +local template = require "resty.template".new({ + root = "/etc/skate/ingress", + location = "/etc/skate/ingress" +}) + +function _M.go(err_code) + local vars = getVars(err_code) + template.render("error.html", { title = vars["title"], message = vars["message"] }) +end + +return _M + diff --git a/images/nginx-ingress/lua/url.lua b/images/nginx-ingress/lua/url.lua new file mode 100644 index 0000000..51f5228 --- /dev/null +++ b/images/nginx-ingress/lua/url.lua @@ -0,0 +1,29 @@ +local _M = {} +function _M.urldecode(s) + s = s:gsub('+', ' ') + :gsub('%%(%x%x)', function(h) + return string.char(tonumber(h, 16)) + end) + return s +end + +function _M.urlencode(str) + if (str) then + str = string.gsub (str, "\n", "\r\n") + str = string.gsub (str, "([^%w ])", + function (c) return string.format ("%%%02X", string.byte(c)) end) + str = string.gsub (str, " ", "+") + end + return str +end + +function _M.parseurl(s) + s = s:match('%s+(.+)') + local ans = {} + for k,v in s:gmatch('([^&=?]-)=([^&=?]+)' ) do + ans[ k ] = urldecode(v) + end + return ans +end + +return _M \ No newline at end of file