diff options
Diffstat (limited to 'deploy')
| -rw-r--r-- | deploy/Caddyfile | 47 | ||||
| -rw-r--r-- | deploy/Dockerfile.cross | 8 | ||||
| -rwxr-xr-x | deploy/bokftui-web | 40 | ||||
| -rw-r--r-- | deploy/cross-build.sh | 12 | ||||
| -rwxr-xr-x | deploy/web-entrypoint.sh | 26 |
5 files changed, 125 insertions, 8 deletions
diff --git a/deploy/Caddyfile b/deploy/Caddyfile new file mode 100644 index 0000000..c86f4e5 --- /dev/null +++ b/deploy/Caddyfile @@ -0,0 +1,47 @@ +# Web frontend routing inside the bokf-web container: the login gate +# (bokfweb, 127.0.0.1:7682) and the browser terminal (ttyd, 127.0.0.1:7681). +# Nothing reaches ttyd without the gate's OK. +# +# Plain HTTP on :8790, published on the host's loopback only. TLS for +# https://bokf.makandra.eu is the host's reverse proxy (the NAS Caddy): +# +# bokf.makandra.eu { +# tls { dns inwx ... } # as for the other sites +# reverse_proxy 127.0.0.1:8790 +# } +{ + auto_https off + admin off + servers { + # the host proxy's X-Forwarded-For names the real client (the + # gate limits failed logins per client address) + trusted_proxies static private_ranges + } +} + +:8790 { + header { + Strict-Transport-Security "max-age=31536000" + -Server + } + + redir / /web/ 302 + + # the terminal: only with a live login whose handle is in the URL + @tty path /web/tty /web/tty/* + handle @tty { + forward_auth 127.0.0.1:7682 { + uri /auth + } + reverse_proxy 127.0.0.1:7681 + } + + # login page, login and logout + handle /web* { + reverse_proxy 127.0.0.1:7682 + } + + handle { + respond "not found" 404 + } +} diff --git a/deploy/Dockerfile.cross b/deploy/Dockerfile.cross index ab0504c..a14ac0f 100644 --- a/deploy/Dockerfile.cross +++ b/deploy/Dockerfile.cross @@ -1,12 +1,12 @@ -# Cross-compile the static arm64 backend binaries on an amd64 host. The -# runtime image is assembled later on the target host from the produced -# binaries; there is no TUI in the runtime image. +# Cross-compile the static arm64 binaries on an amd64 host: the backend +# (bokfd, bokfctl) and the web frontend's bokftui and bokfweb. The images +# are assembled later on the target host from the produced binaries. FROM debian:bookworm RUN dpkg --add-architecture arm64 \ && apt-get update \ && apt-get install -y --no-install-recommends \ make ca-certificates gcc-aarch64-linux-gnu \ - libc6-dev:arm64 libssl-dev:arm64 \ + libc6-dev:arm64 libssl-dev:arm64 libncurses-dev:arm64 \ && rm -rf /var/lib/apt/lists/* COPY cross-build.sh /usr/local/bin/cross-build RUN chmod 0755 /usr/local/bin/cross-build diff --git a/deploy/bokftui-web b/deploy/bokftui-web new file mode 100755 index 0000000..b6ec9b5 --- /dev/null +++ b/deploy/bokftui-web @@ -0,0 +1,40 @@ +#!/bin/sh +# Started by ttyd for every browser terminal, with the terminal handle from +# the URL (?arg=) as $1. Trades the handle for the bokfd session at the +# gate (bokfweb /redeem, internal only), then runs bokftui already logged +# in, in a private throwaway HOME, in web mode (no local files), with +# resource limits. No shell is ever offered: when bokftui exits, the +# terminal ends. +set -u +gate="${BOKFWEB_INTERNAL:-http://127.0.0.1:7682}" + +msg() { + printf '\r\n %s\r\n\r\n' "$1" + sleep 4 + exit 1 +} + +handle="${1:-}" +case "$handle" in + "" | *[!A-Za-z0-9_-]*) msg "Ogiltig länk. Öppna /web/ och logga in igen." ;; +esac + +session=$(wget -q -O - --post-data "handle=$handle" "$gate/redeem" 2>/dev/null) || + msg "Sessionen har gått ut. Öppna /web/ och logga in igen." +case "$session" in + "" | *[!A-Za-z0-9_-]*) msg "Sessionen har gått ut. Öppna /web/ och logga in igen." ;; +esac + +home=$(mktemp -d /tmp/bokf-web.XXXXXXXX) || msg "Kunde inte starta sessionen." +trap 'rm -rf "$home"' EXIT HUP INT TERM +chmod 0700 "$home" + +# per-session limits: memory, CPU time, open files (the process count is +# capped per container in compose.yaml: every session runs as one uid) +ulimit -v 524288 2>/dev/null || true +ulimit -t 7200 2>/dev/null || true +ulimit -n 256 2>/dev/null || true + +HOME="$home" XDG_CONFIG_HOME="$home/.config" XDG_CACHE_HOME="$home/.cache" \ +BOKF_WEB=1 BOKFD_SESSION="$session" \ + bokftui --socket "${BOKFD_SOCKET:-/run/bokfd/bokfd.sock}" diff --git a/deploy/cross-build.sh b/deploy/cross-build.sh index 19d07b7..54a2929 100644 --- a/deploy/cross-build.sh +++ b/deploy/cross-build.sh @@ -1,16 +1,20 @@ #!/bin/sh -# Cross-compile the static aarch64 backend binaries (bokfd, bokfctl). +# Cross-compile the static aarch64 binaries: bokfd, bokfctl and, for the +# web image, bokftui and bokfweb. # Expects the source read-only at /src, writes the binaries to /out and takes # the version from $VERSION. Run through deploy/Dockerfile.cross. OpenSSL and # glibc are linked statically, so the Alpine runtime image needs no shared # libraries (the kernel ABI is all that matters). set -eu -make -C /src -j"$(nproc)" BUILD=/tmp/build backend \ +# ncursesw needs its tinfo half spelled out for a static link +make -C /src -j"$(nproc)" BUILD=/tmp/build \ + backend /tmp/build/bokftui /tmp/build/bokfweb \ CC=aarch64-linux-gnu-gcc \ CFLAGS="-O2 -g -static -L/usr/lib/aarch64-linux-gnu" \ - SSL_LIBS="-l:libssl.a -l:libcrypto.a -ldl -lpthread" \ + SSL_LIBS="-l:libssl.a -l:libcrypto.a -l:libtinfo.a -ldl -lpthread" \ VERSION="${VERSION:-0.1.0-dev}" mkdir -p /out -cp /tmp/build/bokfd /tmp/build/bokfctl /out/ +cp /tmp/build/bokfd /tmp/build/bokfctl /tmp/build/bokftui \ + /tmp/build/bokfweb /out/ diff --git a/deploy/web-entrypoint.sh b/deploy/web-entrypoint.sh new file mode 100755 index 0000000..38e07f9 --- /dev/null +++ b/deploy/web-entrypoint.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# Web frontend container: bokfweb (login gate), ttyd (browser terminal) +# and Caddy (routing on :8790, behind the host's TLS proxy). The gate and +# ttyd listen on 127.0.0.1 only. Each helper is restarted if it dies; Caddy +# is the main process, so the container stops (and compose restarts it) +# when Caddy does. +set -eu + +export BOKFD_SOCKET="${BOKFD_SOCKET:-/run/bokfd/bokfd.sock}" +export XDG_DATA_HOME=/tmp/caddy-data XDG_CONFIG_HOME=/tmp/caddy-config + +keep() { + while :; do + "$@" || true + echo "web: $1 exited, restarting" >&2 + sleep 1 + done +} + +keep bokfweb & +keep ttyd -i 127.0.0.1 -p 7681 -b /web/tty -a -W -O \ + -m "${BOKF_WEB_MAX_SESSIONS:-20}" \ + -t titleFixed=bokf -t fontSize=15 -t disableLeaveAlert=true \ + bokftui-web & + +exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile |
