diff --git a/Dockerfile b/Dockerfile index b866935..2be1b7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,8 @@ RUN set -eux; \ mkdir -p /freebsd-sysroot; \ tar -xJf base.txz -C /freebsd-sysroot ./lib ./usr/include ./usr/lib +FROM golang:1.26-bookworm AS go-toolchain + FROM rockylinux:9 ARG RUST_TOOLCHAIN=stable @@ -68,8 +70,12 @@ RUN set -eux; \ rustc "+${FREEBSD_RUST_TOOLCHAIN}" --version COPY --from=freebsd-sysroot /freebsd-sysroot /opt/freebsd-sysroot +COPY --from=go-toolchain /usr/local/go /usr/local/go -ENV FREEBSD_RUST_TOOLCHAIN=${FREEBSD_RUST_TOOLCHAIN} \ +ENV PATH=/usr/local/go/bin:${PATH} \ + GOPATH=/var/lib/package-builder/go \ + GOCACHE=/var/lib/package-builder/go/cache \ + FREEBSD_RUST_TOOLCHAIN=${FREEBSD_RUST_TOOLCHAIN} \ CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_LINKER=clang \ CC_x86_64_unknown_freebsd=clang \ CXX_x86_64_unknown_freebsd=clang++ \ diff --git a/README.md b/README.md index 83b2c6d..2c9c0a9 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ Jeden kontener buildera buduje z jednego commita RustProxy: -- Linux x86_64: DEB + podpisane repo APT, -- Linux x86_64: RPM + podpisane repo DNF/YUM, +- Linux x86_64: DEB + podpisane repo APT (`rustproxy` **oraz osobny** `rustproxy-docker-agent`), +- Linux x86_64: RPM + podpisane repo DNF/YUM (`rustproxy` **oraz osobny** `rustproxy-docker-agent`), - FreeBSD x86_64: cross-build bez VM FreeBSD, - OPNsense: `os-rustproxy-_.pkg` + statyczne repo `pkg`, - **natywne FreeBSD** (opcjonalnie): `rustproxy-_.pkg` + osobny katalog repo `pkg` pod `/freebsd/` (bez zależności OPNsense). -Nie ma Docker-in-Docker, SCP ani osobnego watchera repo OPNsense. FreeBSD sysroot, clang/lld i Rust target są częścią głównego obrazu buildera. OPNsense dostaje osobny publiczny adres. Gałąź Linux, gałąź OPNsense i opcjonalna gałąź natywnego FreeBSD są budowane oraz publikowane niezależnie, więc błąd testów Linux nie blokuje pakietu FreeBSD. +**Agent Docker jest pakowany wyłącznie na Linux (DEB/RPM); brak paczki FreeBSD pkg dla agenta.** Nie ma Docker-in-Docker, SCP ani osobnego watchera repo OPNsense. FreeBSD sysroot, clang/lld i Rust target są częścią głównego obrazu buildera. OPNsense dostaje osobny publiczny adres. Gałąź Linux, gałąź OPNsense i opcjonalna gałąź natywnego FreeBSD są budowane oraz publikowane niezależnie, więc błąd testów Linux nie blokuje pakietu FreeBSD. ## Szybki start @@ -53,7 +53,8 @@ opn-rustproxy.linuxiarz.pl -> http://builder:18766 Linux branch FreeBSD cross-build cargo test | cargo build +---+---+ - DEB + RPM | | + go test/build agent | | + 2x DEB + 2x RPM | | APT + DNF OPNsense FreeBSD native* | | | v v v @@ -63,7 +64,45 @@ opn-rustproxy.linuxiarz.pl -> http://builder:18766 * FreeBSD native: FREEBSD_NATIVE_ENABLED=1 ``` -`cargo test` należy tylko do gałęzi Linux. Jeśli testy nie przejdą, DEB/RPM nie są publikowane, ale builder nadal uruchamia cross-build FreeBSD i może opublikować repo OPNsense. Stan jest śledzony osobno w `last_linux_commit`, `last_opnsense_commit` i (jeśli włączone) `last_freebsd_commit`; kolejny cykl ponawia tylko brakującą gałąź. +`cargo test` i `go test ./...` (agenta) należą tylko do gałęzi Linux. Jeśli testy nie przejdą, DEB/RPM nie są publikowane, ale builder nadal uruchamia cross-build FreeBSD i może opublikować repo OPNsense. Stan jest śledzony osobno w `last_linux_commit`, `last_opnsense_commit` i (jeśli włączone) `last_freebsd_commit`; kolejny cykl ponawia tylko brakującą gałąź. + +## Docker Agent: osobne pakiety Linux + +Builder sprawdza `docker-agent/go.mod`, uruchamia `go test ./...`, kompiluje statyczny agent z `CGO_ENABLED=0` dla `linux/amd64` i pakuje **niezależnie od głównego RustProxy**. Wersja paczki oraz wydrukowana wersja Go agenta są zgodne z `Cargo.toml` danego commita; `PACKAGE_RELEASE` jest wspólne dla obu produktów w jednym wydaniu. Build gałęzi Linux kończy się błędem, jeśli budowanie/testy agenta nie przejdą, więc nie opublikuje repo z niekompletną parą. OPNsense i natywne FreeBSD pozostają niezależne i bez agenta. + +Zawartość katalogu `data/packages/` po udanym cyklu: + +```text +data/packages/deb/rustproxy_-_amd64.deb +data/packages/deb/rustproxy-docker-agent_-_amd64.deb +data/packages/rpm/x86_64/rustproxy--.x86_64.rpm +data/packages/rpm/x86_64/rustproxy-docker-agent--.x86_64.rpm +``` + +Obie paczki są podpisane istniejącym kluczem GPG repozytorium, a repo APT/DNF automatycznie zawiera oba produkty. Zmiana rewizji pakowania Linux (`PACKAGING_REVISION=4`) wymusza przebudowę także dla niezmienionego commita. + +Instalacja na hoście Docker (uruchom Docker Engine wcześniej): + +```bash +# Debian / Ubuntu, po dodaniu repo APT +sudo apt update +sudo apt install rustproxy-docker-agent + +# RHEL / Rocky / Alma / Fedora, po dodaniu repo DNF +sudo dnf install rustproxy-docker-agent + +# Konfiguracja w panelu RustProxy: Settings -> Docker agents +sudo rustproxy-docker-agent info +sudo rustproxy-docker-agent info --show-token +sudo rustproxy-docker-agent print-fingerprint +sudo systemctl status rustproxy-docker-agent +``` + +Instalacja z lokalnego pliku: `sudo apt install ./rustproxy-docker-agent_*.deb` lub `sudo dnf install ./rustproxy-docker-agent-*.rpm` (jedna pasująca wersja w katalogu). Dla pakietu nie trzeba mieć kompilatora Go. Skrypty `postinstall` zakładają konto systemowe, zabezpieczają `/etc/rustproxy/docker-agent.env`, inicjalizują długi losowy token oraz samopodpisany certyfikat i uruchamiają systemd, jeśli Docker socket jest dostępny. Tokenu **nie wypisują do logów dpkg/rpm**. `info --show-token` wywołuje administrator świadomie, lokalnie. + +Konfiguracja i klucze pozostają po aktualizacji: `/etc/rustproxy/docker-agent.env` (`config|noreplace`, finalnie `0600`) oraz `/var/lib/rustproxy-docker-agent/agent.crt` i `agent.key` (klucz `0600`). Rotacja przez `sudo rustproxy-docker-agent rotate-token` wymaga `sudo systemctl restart rustproxy-docker-agent` i aktualizacji tokenu w panelu RustProxy. Do ręcznej instalacji, bez pakietu, pozostaje `cd docker-agent && sudo ./install.sh` po sklonowaniu projektu z Go 1.22+; instrukcje: `docker-agent/README.md` w repo RustProxy. + +W przypadku przechodzenia z instalacji ręcznej na paczkę: jednostka w `/etc/systemd/system/rustproxy-docker-agent.service` ma pierwszeństwo przed jednostką paczkowaną w `/usr/lib/systemd/system`. Należy zachować token/certyfikat, zatrzymać usługę, przenieść ręczną jednostkę poza katalog systemd i wykonać `systemctl daemon-reload` przed zainstalowaniem paczki. Głównego `rustproxy` i jego konfiguracji to nie dotyczy. ## OPNsense repo @@ -210,7 +249,7 @@ configctl rustproxy start ``` Obsługa miękkiego przeładowania zwiększa `OPNSENSE_PACKAGING_REVISION` do `4`. -Pakowanie Linux ma `PACKAGING_REVISION=3`, a natywne FreeBSD `FREEBSD_NATIVE_PACKAGING_REVISION=1`. Każdy kanał otrzymuje osobną aktualizację przy zmianie swojej rewizji. +Pakowanie Linux ma `PACKAGING_REVISION=4`, a natywne FreeBSD `FREEBSD_NATIVE_PACKAGING_REVISION=1`. Każdy kanał otrzymuje osobną aktualizację przy zmianie swojej rewizji. ## Rotacja logów RustProxy @@ -219,7 +258,7 @@ Pakowanie Linux ma `PACKAGING_REVISION=3`, a natywne FreeBSD `FREEBSD_NATIVE_PAC **Uwaga FreeBSD:** `newsyslog` działa przez zmianę nazwy pliku, nie ma `copytruncate`. Pliki JSONL i inne logi otwarte bezpośrednio przez aplikację muszą być przez nią ponownie otwierane po rotacji. W przeciwnym razie proces może pisać do poprzedniego (przeniesionego) pliku; zachowanie nie jest identyczne z Linux. Reguły są instalowane, ale na działającym OPNsense należy zweryfikować sposób otwierania plików przez RustProxy. -Wersja buildera z obsługą reload zwiększa `PACKAGING_REVISION=3` i `OPNSENSE_PACKAGING_REVISION=4`; nowy kanał używa `FREEBSD_NATIVE_PACKAGING_REVISION=1`. `check-and-build.sh` sprawdza osobno rewizje pakowania Linux, OPNsense i FreeBSD native; nowa wersja samej wtyczki przebudowuje **tylko OPNsense**, nawet przy niezmienionym SHA aplikacji. Rewizja pakietu PKG zwiększy się automatycznie. W przypadku zmiany rewizji Linux analogicznie odświeżane są DEB/RPM. Konfiguracja w `/etc/logrotate.d/rustproxy` jest oznaczona jako `noreplace`, więc lokalna wersja zmodyfikowana przez administratora może zostać zachowana (zależnie od menedżera pakietów). +Bieżąca rewizja pakowania Linux z obsługą Docker Agenta wynosi `PACKAGING_REVISION=4` i `OPNSENSE_PACKAGING_REVISION=4`; nowy kanał używa `FREEBSD_NATIVE_PACKAGING_REVISION=1`. `check-and-build.sh` sprawdza osobno rewizje pakowania Linux, OPNsense i FreeBSD native; nowa wersja samej wtyczki przebudowuje **tylko OPNsense**, nawet przy niezmienionym SHA aplikacji. Rewizja pakietu PKG zwiększy się automatycznie. W przypadku zmiany rewizji Linux analogicznie odświeżane są DEB/RPM. Konfiguracja w `/etc/logrotate.d/rustproxy` jest oznaczona jako `noreplace`, więc lokalna wersja zmodyfikowana przez administratora może zostać zachowana (zależnie od menedżera pakietów). Kontrola po zainstalowaniu: diff --git a/SHA256SUMS b/SHA256SUMS new file mode 100644 index 0000000..8187e12 --- /dev/null +++ b/SHA256SUMS @@ -0,0 +1,62 @@ +182435de9baadbda78d22b4b84a2c61063b3b1c01f60fbe04523d00d9de814a2 .env.example +17298e7669ed82b4c98abfce803e1a3f0a265b0abdc2567bf1316aa15e98aad3 Dockerfile +6f52356e3aca7ce12d81fe04b1cc27c6153d66af8414870399e9fa962b71d84b README.md +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 data/.gitkeep +654795adee13eb3b86f01b32f4e87ee628e3154a7f04923f7226756136be5fd7 docker-compose.yml +e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 gpg/.gitkeep +21cfe2c222905dabbf2cb8f64e12d5175c425312679fd873d64098b23a3e9dcc http/nginx.conf +77e898aebb54f8acf39d3eb1fb348e7f41532da1b0a9e1820a717fdcde406f71 opnsense/patches/0.20.0/0001-opnsense-build.patch +80bb419b980793f3a57b4fda0dc132a872186b3a07e0e6db2585c6057ab4f882 opnsense/plugin/+POST_INSTALL.pre +af4bc0ab259df3a0681fea0fcc7d84e08c8b1a1a1eb34300c4a01eccb49fa537 opnsense/plugin/+PRE_DEINSTALL.pre +07b99ecfd2437ee1e9e337c10ad31280c7c1d8a2c9254e3e2dc9eb5fbeba1a36 opnsense/plugin/Makefile +3acf504f1e6a4414f43f051cd1b28f595add3ed7301da091a1379813bef72059 opnsense/plugin/pkg-descr +ca979a78c1eef6ebdba9ec89504f5dc9c11d4977b3af999298a0c1a1eb3aba15 opnsense/plugin/src/etc/newsyslog.conf.d/rustproxy.conf +3d00d4319af64803f4620f8d5b837a33857f9682ed480b4fa8edf4988e88d014 opnsense/plugin/src/etc/rc.d/rustproxy +9bfd871eebb3e499587cf19ddb604f50001b3097f3ae20ecc511f3a1067654e4 opnsense/plugin/src/etc/rc.syshook.d/start/50-rustproxy.start +41d5c3d555d57c17d756f80ca0c30bbd256a68e2dcf51dc2d4dc2674a614a3dd opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/ServiceController.php +85833df45b327bb5d403db252ff25734b9d442f54cee51a9004ee1f889e9a74d opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/Api/SettingsController.php +747ee1fa625b0862c0de248d9cd181a600310fb893bb965d70ebaf617203c081 opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/IndexController.php +f25006f6743c5f7119ff1f56335c42f2f2b73c832d555c8ae0494857a4bdad9d opnsense/plugin/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml +8c1232f2b32158abab5e6fa465064b5e7d155faadfa8192aa2a7397f13d8b5c5 opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/ACL/ACL.xml +e8f29912261155366d3ce06dd640786cd37d4860de3b57481e9e2573ec6ef174 opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/Menu/Menu.xml +8682e5bbaadc49a66c9e99044ec649b89c1d79cf5a44ec595d162f2f18f6f5f9 opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_4_0.php +cb0b51313d0e5c22c8a192a359c94b3dec1d1e00ec0db6b3d8e46c8c3c03f2ea opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/Migrations/M1_5_0.php +01fbc85f40663dff4309f34c3c03dee293f36a0b2d79bcf89d6318a2be473cee opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.php +4f3c4f92972b27f2bc07721d67be331320985d3563c9da1df8e9bb0cfe143636 opnsense/plugin/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml +3d2581da5c9ceafef9b6348e06beb78165eea9f06f0dd71fbcd7467142be8b41 opnsense/plugin/src/opnsense/mvc/app/views/OPNsense/RustProxy/index.volt +96a6cdcfe5150fb8687d47fe9f8a63f664ff4e3006a8441d3f065b61b4922df9 opnsense/plugin/src/opnsense/scripts/rustproxy/service.sh +d4fc4b261c8252afbc6f403f828656cb7a49174de8cd239a233f5475d4cfeacd opnsense/plugin/src/opnsense/service/conf/actions.d/actions_rustproxy.conf +32c1c3ed725c59d7850770e86bb3eab6bb2edc045bfa3e3be567d6468645e3bd opnsense/plugin/src/opnsense/service/templates/OPNsense/RustProxy/+TARGETS +5faeb5e371bfbf38497b2c49ee128120b99c371c19c3cc520a92a3f0b1d797e3 opnsense/plugin/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf +6a5b546163c5a57e8df0aa270bcaf5c08c7d786d427e24eea9bba88de83dedd9 packaging/freebsd/+POST_INSTALL +43004e4dd882bb89b35cfd5ee7c0a844de2ed4f5833bd5c4e57b61f4fd124119 packaging/freebsd/+PRE_DEINSTALL +173c204b5a3071cef2563881ac9f52437141a3303bc5c3f3a50fd637a045b4cf packaging/freebsd/rustproxy.newsyslog +c8dde46217c008bfc31420c19ecbd31e3db6d71ee48f99be856ad40ca3c7f490 packaging/freebsd/rustproxy.rc +0f7970888117b4bc810ad3f6abc6796f189d34e4863875b2501785e689471be6 packaging/rustproxy.logrotate +eee3cb8959cb90cd1b5b320ec4674892e5d1a987049d1028dae39c3bdc9f3dc7 scripts/apply-freebsd-patches.sh +33246bb1645d443b0554559e0140695a3e8aafb316c84a90ae670eb2941dce23 scripts/build-freebsd-release.sh +2655a96edff5bc07e6a689963c4398fb8c8aabd56014cf1c7edc50211fb883cf scripts/build-linux-release.sh +08b0eafa713935ffde6096fe1f371235b07b949c171b8c1674ef747635a8b93c scripts/build-opnsense-release.sh +5db9f6e5c782bb9afcf455688dea7c1de1d6070c510bbedc9408af5b0fe509b1 scripts/build-opnsense.sh +b795c04884f75cae9154af80dfa5ec418b95c8991ed2927b8953c39e3f01a4e8 scripts/build-release.sh +1e43a0e6706c0457ab04b155fa566edd509fc52bc4023eb8c44d4271a944e62c scripts/check-and-build.sh +cba164bde8967045bfb76de7eff46d4407dfb7ed2bc861fbc600782551d1629e scripts/ensure-rust-toolchain.sh +62d45e193b06c8fae02705b5214092f13a916cf0c637bbc793b4c46eac6a39fd scripts/entrypoint.sh +621bc5e0bba15cba16271d7a02e7d34ea3652b88fb481a46b134f2dac01b7f4f scripts/generate-freebsd-index.sh +4220710396d0670d5c9ebcc31c6c4d59073d2b1c192f08268a3ea49164d1dcbd scripts/generate-index.sh +80f49932346268f2cd63cbfe4814c666cd665661e82c25f2e99883929ecae0c0 scripts/generate-opnsense-index.sh +a21afa240ca0869c2f92af7a73899f270361b2b8677b897646479452185196fe scripts/generate-opnsense-repo.py +40186599540f6886188abda5dac72bc85d15b9b71ce20788061131bfcd519cb7 scripts/init-storage.sh +97929a54424faf1827b2e75919cb1ed26fe5614ef96df77e540738e6340ea137 scripts/lib.sh +0eca8ef60f15dce0c5651fc8a55de10e0d9a11f3816f04153608abcbe2e2e1d8 scripts/package-freebsd.sh +b098fa629f9fcc1a54baab3d46b28721eb582c314e084b3210259bf157c124a6 scripts/package-opnsense.sh +4ad289bc2c0e400b39a8d1bcf86395d7576c88e71b678ba8b893ccb72ac35465 scripts/prepare-agent-package.sh +6210bb3d5732c66b181db02f4d54cd9d2653b969ad6afb48356248a6930b4b34 scripts/prepare-package.sh +56b90f4844b55cdfeba341e9d0133114bd28046542611a38c996cc0bb8c5e2a2 start.sh +f0bde843d75330bc49e3ab5547e739d8fbda8d74d0b12dfdbdb7648847e91e88 tests/check-rustproxy-source.sh +a55cc19cba2729ea3e8d82e8e5e90d734ba77c0e0d3f56a1b432e2e7e5316dc5 tests/docker-agent-linux.sh +e82c52ef15183a539e96909a39e44db68c8301543950e145008b563524b0b9b9 tests/freebsd-native.sh +5f84d297b9e673b347af6ae2d0a311e6cd699e0103822e2e0561ae4613b3503b tests/log-rotation.sh +aab57cd66dc157dc2359d8d57612c174570a7ea09fe753428dce8faad231ba3c tests/opnsense-plugin.sh +0ceaa84d06e7b5fcfb8cab6c76db7d0a3e6f7baa673e3a1b634be2fdca171fbf tests/static.sh +c8de9ebbf51e017643d0735f27b960a6cf3c9b7122f6de32858f6b7dcc7ba9e9 tests/toolchains.sh diff --git a/scripts/build-linux-release.sh b/scripts/build-linux-release.sh index 6c1081f..cc0990f 100755 --- a/scripts/build-linux-release.sh +++ b/scripts/build-linux-release.sh @@ -104,25 +104,48 @@ if [[ -n "$MAX_GLIBC_FOUND" ]]; then log "glibc compatibility check: <= $MAX_GLIBC_FOUND" fi +# The Go agent is packaged ONLY for Linux. A failure aborts the Linux branch +# before either APT or RPM metadata is published; OPNsense/FreeBSD are separate. +AGENT_SRC="$SRC/docker-agent" +[[ -f "$AGENT_SRC/go.mod" ]] || fatal "RustProxy source is missing docker-agent/go.mod" +AGENT_BINARY="$OUT/rustproxy-docker-agent" +AGENT_PKG="$WORK/package-agent" +log "Linux Docker Agent tests started" +(cd "$AGENT_SRC" && GOWORK=off CGO_ENABLED=0 go test ./...) +log "Linux Docker Agent build started" +(cd "$AGENT_SRC" && GOWORK=off CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \ + go build -trimpath -ldflags="-s -w -X main.version=$VERSION" -o "$AGENT_BINARY" .) +[[ -x "$AGENT_BINARY" ]] || fatal "built Go agent not found: $AGENT_BINARY" + /opt/rust-package-builder/scripts/prepare-package.sh "$SRC" "$PKG" "$BINARY_PATH" +/opt/rust-package-builder/scripts/prepare-agent-package.sh "$SRC" "$AGENT_PKG" "$AGENT_BINARY" DEB_FILE="$OUT/${PACKAGE_NAME}_${VERSION}-${PACKAGE_RELEASE}_amd64.deb" RPM_FILE="$OUT/${PACKAGE_NAME}-${VERSION}-${PACKAGE_RELEASE}.x86_64.rpm" +AGENT_DEB_FILE="$OUT/rustproxy-docker-agent_${VERSION}-${PACKAGE_RELEASE}_amd64.deb" +AGENT_RPM_FILE="$OUT/rustproxy-docker-agent-${VERSION}-${PACKAGE_RELEASE}.x86_64.rpm" -log "creating deb package" +log "creating RustProxy and Docker Agent deb packages" nfpm package --config "$PKG/nfpm-deb.yaml" --packager deb --target "$DEB_FILE" -log "creating rpm package" +nfpm package --config "$AGENT_PKG/nfpm-deb.yaml" --packager deb --target "$AGENT_DEB_FILE" +log "creating RustProxy and Docker Agent rpm packages" nfpm package --config "$PKG/nfpm-rpm.yaml" --packager rpm --target "$RPM_FILE" +nfpm package --config "$AGENT_PKG/nfpm-rpm.yaml" --packager rpm --target "$AGENT_RPM_FILE" -ar t "$DEB_FILE" | grep '^_gpgorigin$' >/dev/null || fatal "DEB package does not contain nFPM GPG origin signature" -rpm -qpi "$RPM_FILE" | awk -F: '/^Signature/ && $0 !~ /\(none\)/ {ok=1} END{exit !ok}' || fatal "RPM package is not signed" +for deb in "$DEB_FILE" "$AGENT_DEB_FILE"; do + ar t "$deb" | grep '^_gpgorigin$' >/dev/null || fatal "DEB package is not signed: $deb" +done +for rpm_file in "$RPM_FILE" "$AGENT_RPM_FILE"; do + rpm -qpi "$rpm_file" | awk -F: '/^Signature/ && $0 !~ /\(none\)/ {ok=1} END{exit !ok}' \ + || fatal "RPM package is not signed: $rpm_file" +done log "Linux package signatures verified" -cp -f "$DEB_FILE" "$DATA_DIR/packages/deb/" -cp -f "$RPM_FILE" "$DATA_DIR/packages/rpm/x86_64/" +cp -f "$DEB_FILE" "$AGENT_DEB_FILE" "$DATA_DIR/packages/deb/" +cp -f "$RPM_FILE" "$AGENT_RPM_FILE" "$DATA_DIR/packages/rpm/x86_64/" log "updating aptly internal repository" -aptly -config="$APTLY_CONF" repo add -force-replace package-builder "$DEB_FILE" >/dev/null +aptly -config="$APTLY_CONF" repo add -force-replace package-builder "$DEB_FILE" "$AGENT_DEB_FILE" >/dev/null SNAPSHOT="linux-${VERSION}-${SHORT_SHA}-$(date +%s)" aptly -config="$APTLY_CONF" snapshot create "$SNAPSHOT" from repo package-builder >/dev/null @@ -181,6 +204,7 @@ cat > "$RELEASE_DIR/LINUX-BUILD-INFO.txt" < +
+

Docker discovery agent — separate Linux package

+

Install rustproxy-docker-agent on the Docker host (systemd, Docker Engine, amd64/x86_64). This is independent from the RustProxy server and has no FreeBSD pkg.

+
# Debian / Ubuntu (after adding the signed APT repo above)
+sudo apt install rustproxy-docker-agent
+
+# RHEL / Rocky / Alma / Fedora (after adding the DNF repo above)
+sudo dnf install rustproxy-docker-agent
+
+# Locally display the token and certificate fingerprint
+sudo rustproxy-docker-agent info --show-token
+sudo systemctl status rustproxy-docker-agent
+

Packages create persistent credentials and a systemd service; tokens are never printed to unattended package logs. Restrict the agent's HTTPS port to the RustProxy host.

+
+

OPNsense / FreeBSD pkg

The OPNsense plugin is published separately because it uses the FreeBSD pkg format.

diff --git a/scripts/lib.sh b/scripts/lib.sh index f1074c5..5054c09 100755 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -2,7 +2,7 @@ set -Eeuo pipefail # Increment when package payload/installation semantics change without a source commit. -PACKAGING_REVISION=3 +PACKAGING_REVISION=4 OPNSENSE_PACKAGING_REVISION=4 FREEBSD_NATIVE_PACKAGING_REVISION=1 diff --git a/scripts/prepare-agent-package.sh b/scripts/prepare-agent-package.sh new file mode 100755 index 0000000..6aa4b0c --- /dev/null +++ b/scripts/prepare-agent-package.sh @@ -0,0 +1,192 @@ +#!/usr/bin/env bash +set -Eeuo pipefail +BUILDER_ROOT=${BUILDER_ROOT:-/opt/rust-package-builder} +source "$BUILDER_ROOT/scripts/lib.sh" + +SRC=${1:?source path required} +PKG_AGENT=${2:?agent package workspace required} +AGENT_BINARY=${3:?agent binary path required} +: "${VERSION:?RustProxy source version is required}" +: "${PACKAGE_RELEASE:?package release is required}" +: "${GPG_PRIVATE_KEY_FILE:?GPG key path is required}" +[[ -x "$AGENT_BINARY" ]] || fatal "Go agent binary not found: $AGENT_BINARY" +[[ -r "$SRC/docker-agent/rustproxy-docker-agent.service" ]] || fatal 'missing Docker Agent systemd unit' +[[ -r "$SRC/docker-agent/docker-agent.env.example" ]] || fatal 'missing Docker Agent environment template' + +AGENT_NAME=rustproxy-docker-agent +rm -rf -- "$PKG_AGENT" +mkdir -p "$PKG_AGENT/payload" "$PKG_AGENT/scripts" +install -D -m 0755 "$AGENT_BINARY" "$PKG_AGENT/payload/usr/bin/$AGENT_NAME" +sed 's@/usr/local/bin/rustproxy-docker-agent@/usr/bin/rustproxy-docker-agent@g' \ + "$SRC/docker-agent/rustproxy-docker-agent.service" > "$PKG_AGENT/payload/agent.service" +install -D -m 0644 "$PKG_AGENT/payload/agent.service" "$PKG_AGENT/payload/usr/lib/systemd/system/$AGENT_NAME.service" +install -D -m 0600 "$SRC/docker-agent/docker-agent.env.example" "$PKG_AGENT/payload/etc/rustproxy/docker-agent.env" +install -D -m 0644 "$SRC/docker-agent/README.md" "$PKG_AGENT/payload/usr/share/doc/$AGENT_NAME/README.md" + +cat > "$PKG_AGENT/scripts/deb-postinstall.sh" <<'SCRIPT' +#!/bin/sh +set -e +if ! getent group rustproxy-docker-agent >/dev/null 2>&1; then + addgroup --system rustproxy-docker-agent >/dev/null +fi +if ! getent passwd rustproxy-docker-agent >/dev/null 2>&1; then + adduser --system --ingroup rustproxy-docker-agent --home /var/lib/rustproxy-docker-agent \ + --no-create-home --disabled-password --shell /usr/sbin/nologin rustproxy-docker-agent >/dev/null +fi +if getent group docker >/dev/null 2>&1; then + usermod -a -G docker rustproxy-docker-agent +fi +install -d -o rustproxy-docker-agent -g rustproxy-docker-agent -m 0750 /var/lib/rustproxy-docker-agent +install -d -m 0750 /etc/rustproxy +/usr/bin/rustproxy-docker-agent init +if command -v systemctl >/dev/null 2>&1; then + systemctl daemon-reload >/dev/null 2>&1 || true + systemctl enable rustproxy-docker-agent.service >/dev/null 2>&1 || true + if getent group docker >/dev/null 2>&1 && [ -S /var/run/docker.sock ]; then + systemctl restart rustproxy-docker-agent.service >/dev/null 2>&1 || true + else + echo 'RustProxy Docker Agent installed but not started: Docker group/socket unavailable.' >&2 + fi +fi +exit 0 +SCRIPT + +cat > "$PKG_AGENT/scripts/rpm-postinstall.sh" <<'SCRIPT' +#!/bin/sh +set -e +if ! getent group rustproxy-docker-agent >/dev/null 2>&1; then + groupadd --system rustproxy-docker-agent +fi +if ! getent passwd rustproxy-docker-agent >/dev/null 2>&1; then + useradd --system --gid rustproxy-docker-agent --home-dir /var/lib/rustproxy-docker-agent \ + --no-create-home --shell /sbin/nologin rustproxy-docker-agent +fi +if getent group docker >/dev/null 2>&1; then + usermod -a -G docker rustproxy-docker-agent +fi +install -d -o rustproxy-docker-agent -g rustproxy-docker-agent -m 0750 /var/lib/rustproxy-docker-agent +install -d -m 0750 /etc/rustproxy +/usr/bin/rustproxy-docker-agent init +if command -v systemctl >/dev/null 2>&1; then + systemctl daemon-reload >/dev/null 2>&1 || true + systemctl enable rustproxy-docker-agent.service >/dev/null 2>&1 || true + if getent group docker >/dev/null 2>&1 && [ -S /var/run/docker.sock ]; then + systemctl restart rustproxy-docker-agent.service >/dev/null 2>&1 || true + else + echo 'RustProxy Docker Agent installed but not started: Docker group/socket unavailable.' >&2 + fi +fi +exit 0 +SCRIPT + +cat > "$PKG_AGENT/scripts/deb-preremove.sh" <<'SCRIPT' +#!/bin/sh +set -e +case "${1:-}" in + remove|deconfigure) systemctl stop rustproxy-docker-agent.service >/dev/null 2>&1 || true ;; +esac +exit 0 +SCRIPT +cat > "$PKG_AGENT/scripts/rpm-preremove.sh" <<'SCRIPT' +#!/bin/sh +set -e +if [ "${1:-1}" -eq 0 ]; then + systemctl stop rustproxy-docker-agent.service >/dev/null 2>&1 || true + systemctl disable rustproxy-docker-agent.service >/dev/null 2>&1 || true +fi +exit 0 +SCRIPT +for kind in deb rpm; do + cat > "$PKG_AGENT/scripts/$kind-postremove.sh" <<'SCRIPT' +#!/bin/sh +set -e +systemctl daemon-reload >/dev/null 2>&1 || true +exit 0 +SCRIPT +done +chmod 0755 "$PKG_AGENT/scripts/"*.sh + +AGENT_NAME_Q=$(yaml_quote "$AGENT_NAME") +VERSION_Q=$(yaml_quote "$VERSION") +MAINTAINER_Q=$(yaml_quote "$MAINTAINER") +HOMEPAGE_Q=$(yaml_quote "$HOMEPAGE") +GPG_Q=$(yaml_quote "$GPG_PRIVATE_KEY_FILE") + +cat > "$PKG_AGENT/contents.yaml" < "$PKG_AGENT/nfpm-deb.yaml" < "$PKG_AGENT/nfpm-rpm.yaml" < "$SRC/docker-agent/rustproxy-docker-agent.service" <<'UNIT' +[Service] +User=rustproxy-docker-agent +Group=docker +EnvironmentFile=/etc/rustproxy/docker-agent.env +ExecStart=/usr/local/bin/rustproxy-docker-agent +StateDirectory=rustproxy-docker-agent +UNIT + cat > "$SRC/docker-agent/docker-agent.env.example" <<'ENV' +RUSTPROXY_DOCKER_AGENT_TOKEN=replace-with-at-least-24-random-characters +ENV + echo '# Docker Agent' > "$SRC/docker-agent/README.md" +fi +if [[ -f "$SRC/docker-agent/go.mod" && $(command -v go || true) ]]; then + (cd "$SRC/docker-agent" && GOWORK=off CGO_ENABLED=0 go test ./... && \ + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -trimpath -o "$WORK/agent" .) +else + cat > "$WORK/agent" <<'MOCK' +#!/bin/sh +exit 0 +MOCK + chmod 0755 "$WORK/agent" +fi +export BUILDER_ROOT="$ROOT" VERSION=0.34.2 PACKAGE_RELEASE=4 +export MAINTAINER='Package QA ' HOMEPAGE=https://example.invalid +export GPG_PRIVATE_KEY_FILE="$WORK/test-key.asc" +"$ROOT/scripts/prepare-agent-package.sh" "$SRC" "$WORK/package" "$WORK/agent" +PKG="$WORK/package" +test -x "$PKG/payload/usr/bin/rustproxy-docker-agent" +grep -Fqx 'ExecStart=/usr/bin/rustproxy-docker-agent' "$PKG/payload/usr/lib/systemd/system/rustproxy-docker-agent.service" +grep -Fq 'config|noreplace' "$PKG/nfpm-deb.yaml" +grep -Fq 'config|noreplace' "$PKG/nfpm-rpm.yaml" +grep -q 'type: origin' "$PKG/nfpm-deb.yaml" +grep -q 'signature:' "$PKG/nfpm-rpm.yaml" +! grep -q '\.pkg' "$PKG/nfpm-deb.yaml" +for script in "$PKG"/scripts/*; do sh -n "$script"; done +for script in "$PKG"/scripts/*postinstall.sh; do + grep -Fq '/usr/bin/rustproxy-docker-agent init' "$script" + grep -Fq 'systemctl enable rustproxy-docker-agent.service' "$script" +done +if python3 -c 'import yaml' >/dev/null 2>&1; then + python3 - "$PKG" <<'PY_YAML' +import yaml, pathlib, sys +pkg=pathlib.Path(sys.argv[1]) +for kind in ('deb','rpm'): + x=yaml.safe_load((pkg/f'nfpm-{kind}.yaml').read_text()) + assert x['name']=='rustproxy-docker-agent' + assert x['version']=='0.34.2' + assert x['arch']=='amd64' + assert len(x['contents'])==4 + assert x['scripts']['postinstall'] + assert any(c['dst']=='/etc/rustproxy/docker-agent.env' and c['type']=='config|noreplace' for c in x['contents']) +PY_YAML +fi +echo 'Docker Agent package manifests, service layout and lifecycle scripts: OK' diff --git a/tests/static.sh b/tests/static.sh index 65ead73..d8eb2fa 100755 --- a/tests/static.sh +++ b/tests/static.sh @@ -27,6 +27,13 @@ grep -q 'OPNsense branch will still run' "$ROOT/scripts/build-release.sh" # Linux tests gate Linux packaging only. grep -Fq 'cargo "+$LINUX_RUST_TOOLCHAIN" test --release' "$ROOT/scripts/build-linux-release.sh" +grep -Fq 'CGO_ENABLED=0 go test ./...' "$ROOT/scripts/build-linux-release.sh" +grep -Fq 'prepare-agent-package.sh' "$ROOT/scripts/build-linux-release.sh" +grep -Fq 'AGENT_DEB_FILE=' "$ROOT/scripts/build-linux-release.sh" +grep -Fq 'AGENT_RPM_FILE=' "$ROOT/scripts/build-linux-release.sh" +grep -Fq 'rustproxy-docker-agent' "$ROOT/scripts/generate-index.sh" +grep -Fq 'COPY --from=go-toolchain' "$ROOT/Dockerfile" +grep -q 'PACKAGING_REVISION=4' "$ROOT/scripts/lib.sh" grep -Fq 'ensure-rust-toolchain.sh' "$ROOT/scripts/build-linux-release.sh" grep -Fq 'ensure-rust-toolchain.sh' "$ROOT/scripts/build-opnsense.sh" grep -Fq 'nfpm package' "$ROOT/scripts/build-linux-release.sh" @@ -42,7 +49,7 @@ grep -q 'generate-opnsense-repo.py' "$ROOT/scripts/build-opnsense-release.sh" grep -q 'last_opnsense_commit' "$ROOT/scripts/build-opnsense-release.sh" test -f "$ROOT/opnsense/plugin/src/etc/rc.d/rustproxy" test -x "$ROOT/opnsense/plugin/src/etc/rc.syshook.d/start/50-rustproxy.start" -! test -e "$ROOT/opnsense/plugin/src/etc/rc.syshook.d/10-rustproxy.start" +[[ ! -e "$ROOT/opnsense/plugin/src/etc/rc.syshook.d/10-rustproxy.start" ]] grep -q 'OPNSENSE_PACKAGING_REVISION=4' "$ROOT/scripts/lib.sh" test -f "$ROOT/opnsense/patches/0.20.0/0001-opnsense-build.patch"