#!/bin/sh # ═══════════════════════════════════════════════════════════════════════════════ # Het startscript van de server-container van Electrum Gate. # # Tot 0.0.29 stond dit als inline command-blok in docker-compose.yml, omdat de # compose in de update-whitelist van umbreld staat en een los script niet. Dat # betekende shell in een YAML-string, met elk dollarteken verdubbeld omdat # umbreld anders elke ${...} leegmaakt. Sinds de eigen image is het een gewoon # bestand; wat het doet is niet veranderd. # # Drie dingen die hier gebeuren en waarom ze hier gebeuren en niet in de agent: # # 1. de TLS-poort aan- of uitzetten naar de toestand van cert.conf. nginx weigert # te starten met een 'listen ssl' zonder certificaat, en de pagina waarop je # dat certificaat kiest moet juist altijd omhoog komen; # 2. de open verbindingen tellen. Dat kan alleen in deze netwerk-namespace; # 3. nginx herladen als de agent een vlag neerzet. De agent kan dat niet zelf, # want dat zou de Docker-socket vragen en die is er bewust uit. # ═══════════════════════════════════════════════════════════════════════════════ set -eu STATE=/var/lib/gate mkdir -p "$STATE" "$STATE/tls" # ── Het stream-blok invullen ────────────────────────────────────────────────── # Het backend-adres komt uit de omgeving, dezelfde twee variabelen die de agent # krijgt. Tot 0.0.29 vulde umbreld ze in via stream.conf.template; nu de # configuratie in de image zit, gebeurt dat hier. nginx kan in een proxy_pass van # het stream-blok zelf geen omgevingsvariabele lezen. # # Twee plaatshouders zonder dollarteken, zodat het bestand zelf nooit door een # envsubst-stap beschadigd kan worden, ook niet als iemand het ooit weer als # template in de app-map zet. if [ -n "${GATE_ELECTRUM_HOST:-}" ] && [ -n "${GATE_ELECTRUM_PORT:-}" ]; then sed -e "s|__GATE_ELECTRUM_HOST__|${GATE_ELECTRUM_HOST}|g" \ -e "s|__GATE_ELECTRUM_PORT__|${GATE_ELECTRUM_PORT}|g" \ /etc/nginx/stream.conf.in > /etc/nginx/stream.conf else # Zonder backend is er niets om naar door te sturen. De pagina komt wel omhoog # en de agent meldt daar dat het adres ontbreekt; TLS blijft uit. rm -f /etc/nginx/stream.conf echo "GATE_ELECTRUM_HOST of GATE_ELECTRUM_PORT ontbreekt; TLS blijft uit, de pagina werkt." fi # ── De TLS-poort aan of uit ─────────────────────────────────────────────────── # Hier zat tot 0.0.3 een lus die wachtte tot de agent een certificaat gekozen had, # en dat was fout: nginx startte dan niet, dus de pagina kwam niet omhoog, en de # pagina is juist waar je dat certificaat kiest. # # Nu start nginx altijd. Het stream-blok komt erbij zodra cert.conf er is, en # verdwijnt weer als de agent zijn keuze intrekt. nginx.conf haalt de map tls/ op # met een jokerteken; die matcht dan niets en dat is geen fout. # # Deze functie eindigt altijd geslaagd, en dat is met opzet: het script draait # onder 'set -e', dus een mislukte cp zou de aanroeper afbreken. In de lus # hieronder is die aanroeper de wachtlus, en die mag om geen enkele reden stoppen. sync_tls() { if [ -f "$STATE/cert.conf" ] && [ -f /etc/nginx/stream.conf ]; then # Kopiëren en niet linken: nginx opent dit pad als de gebruiker nginx, en een # symlink is hier nodeloos fragiel. if cp /etc/nginx/stream.conf "$STATE/tls/stream.conf"; then echo "Certificaat aanwezig, TLS luistert op 50022." else echo "stream.conf kon niet worden weggezet; TLS blijft uit." fi else rm -f "$STATE/tls/stream.conf" echo "Nog geen certificaat gekozen; TLS staat uit, de pagina werkt." fi } sync_tls # ── De verbindingsteller ────────────────────────────────────────────────────── # nginx stream schrijft zijn logregel pas bij het sluiten van een sessie, en een # wallet houdt zijn verbinding uren open; zonder deze teller lijkt een actieve # wallet dus afwezig. Dat was de vraag van de gebruiker op 20-08-2026. # # /proc/net/tcp geldt per netwerk-namespace, dus dit ziet alleen de sockets van # deze container, en daarom staat de teller hier en niet in de agent: die zit in # een andere namespace en kan er niet bij. Kolom 2 is het lokale adres met de # poort in hex, kolom 4 de toestand. C366 is 50022 en 01 is ESTABLISHED, dus de # luisterende socket (0A) en de verbindingen naar de backend en naar de pagina # vallen er buiten. # # Geteld wordt alleen het aantal. Geen adres en geen bronpoort, net als in het # log_format in stream.conf. count_sessions() { cat /proc/net/tcp /proc/net/tcp6 2>/dev/null \ | awk '$4 == "01" && $2 ~ /:C366$/ { n++ } END { print n+0 }' } # Meteen een 0 neerzetten, zodat de pagina "geen verbindingen" kan tonen in # plaats van "onbekend" in het minuutje voor de eerste ronde. count_sessions > "$STATE/sessions" # ── De herlaadlus ───────────────────────────────────────────────────────────── # Draait op de achtergrond; nginx wordt hieronder met exec het hoofdproces. # Andersom gaat twee keer mis: de shell blijft dan PID 1 en geeft signalen niet # door, en als nginx omvalt eindigt het script met exitcode 0, waardoor Docker een # geslaagde afsluiting ziet en 'restart: on-failure' niet ingrijpt. reload_nginx() { # Een certificaat dat nginx niet aanneemt laat de reload falen. Dat mag niet # met 'set -e' meegaan, want dan verdwijnt de lus en wordt geen enkele latere # wijziging meer opgepikt, zonder dat er iets te zien is. if ! nginx -s reload; then echo "Herladen mislukt; nginx houdt de vorige configuratie." fi } ( while true; do sleep 10 # Eerst schrijven, dan mv: de agent leest dit bestand op zijn eigen moment en # mag geen half bestand zien. count_sessions > "$STATE/sessions.tmp" mv "$STATE/sessions.tmp" "$STATE/sessions" if [ -f "$STATE/reload" ]; then echo "Certificaat gewijzigd, nginx herladen ..." # Eerst wegzetten, dan herladen. Andersom zou een herlading die mislukt de # vlag toch opruimen, en dan probeert hij het nooit meer. mv "$STATE/reload" "$STATE/reload.done" # Voor de herlading, niet erna: een reload leest de configuratie opnieuw, # dus het stream-blok moet er dan al liggen. sync_tls reload_nginx elif [ -f "$STATE/cert.conf" ] && [ ! -f "$STATE/tls/stream.conf" ]; then # De vangnetregel. De agent zet de vlag bij elke wijziging, dus normaal komt # hier niets langs; wel als de vlag verloren gaat of als cert.conf van een # vorige installatie al klaarlag. Zonder deze tak zou TLS dan uit blijven # staan tot de volgende wijziging. echo "Certificaat gevonden zonder herlaadvlag, TLS aanzetten ..." sync_tls reload_nginx fi done ) & exec nginx -g 'daemon off;'