20 KiB
RustProxy unified package builder
Jeden kontener buildera buduje z jednego commita RustProxy:
- Linux x86_64: DEB + podpisane repo APT (
rustproxyoraz osobnyrustproxy-docker-agent), - Linux x86_64: RPM + podpisane repo DNF/YUM (
rustproxyoraz osobnyrustproxy-docker-agent), - FreeBSD x86_64: cross-build bez VM FreeBSD,
- OPNsense:
os-rustproxy-<version>_<revision>.pkg+ statyczne repopkg, - natywne FreeBSD (opcjonalnie):
rustproxy-<version>_<revision>.pkg+ osobny katalog repopkgpod/freebsd/(bez zależności OPNsense).
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
cp .env.example .env
nano .env
./start.sh
Minimalnie ustaw:
SOURCE_REPO=https://git.linuxiarz.pl/gru/RustProxy.git
REPOSITORY_URL=http://192.168.1.100
OPNSENSE_REPOSITORY_URL=https://opn-rustproxy.linuxiarz.pl
Dla http:// bez portu start.sh dopisze domyślny port. Dla https:// zakładany jest zewnętrzny reverse proxy/TLS.
Domyślne lokalne porty:
APT/RPM: 18765 -> nginx :8080
OPNsense: 18766 -> nginx :8081
Przykładowo reverse proxy może kierować:
packages.example.net -> http://builder:18765
opn-rustproxy.linuxiarz.pl -> http://builder:18766
Pipeline
Git RustProxy
|
wspólny checkout
/ \
/ \
Linux branch FreeBSD cross-build
cargo test |
cargo build +---+---+
go test/build agent | |
2x DEB + 2x RPM | |
APT + DNF OPNsense FreeBSD native*
| | |
v v v
publikacja Linux os-rustproxy rustproxy.pkg
pkg repo pkg repo
* FreeBSD native: FREEBSD_NATIVE_ENABLED=1
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:
data/packages/deb/rustproxy_<version>-<release>_amd64.deb
data/packages/deb/rustproxy-docker-agent_<version>-<release>_amd64.deb
data/packages/rpm/x86_64/rustproxy-<version>-<release>.x86_64.rpm
data/packages/rpm/x86_64/rustproxy-docker-agent-<version>-<release>.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):
# 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
Publiczny root OPNSENSE_REPOSITORY_URL zawiera m.in.:
/
├── meta.conf
├── packagesite.pkg
├── data.pkg
├── RustProxy.conf
├── BUILD-INFO.txt
├── SHA256
├── os-rustproxy-latest.pkg
└── 26.7/
└── amd64/
├── os-rustproxy-0.20.0_123.pkg
└── ...
RustProxy.conf jest generowany automatycznie i wskazuje na OPNSENSE_REPOSITORY_URL. Repo OPNsense jest obecnie niesygnowane, zgodnie z wcześniejszym builderem/repo (signature_type: "none"). Repo APT/RPM pozostaje podpisane GPG.
Ręczna konfiguracja na OPNsense:
mkdir -p /usr/local/etc/pkg/repos
fetch -o /usr/local/etc/pkg/repos/RustProxy.conf \
https://opn-rustproxy.linuxiarz.pl/RustProxy.conf
pkg update -f
pkg install os-rustproxy
Konfiguracja
Najważniejsze zmienne:
SOURCE_REPO=https://git.linuxiarz.pl/gru/RustProxy.git
SOURCE_BRANCH=master
REPOSITORY_URL=http://192.168.1.100
HTTP_PORT=18765
OPNSENSE_REPOSITORY_URL=https://opn-rustproxy.linuxiarz.pl
OPNSENSE_HTTP_PORT=18766
POLL_INTERVAL=300
PACKAGE_RELEASE=auto
MAX_GLIBC_VERSION=2.34
RUN_LINUX_TESTS=1
OPNSENSE_ABI=26.7
OPNSENSE_RETENTION=10
FREEBSD_RELEASE=15.1-RELEASE
FREEBSD_ABI=FreeBSD:15:amd64
FREEBSD_ARCH=freebsd:15:x86:64
FREEBSD_RUST_TOOLCHAIN=1.88.0
APPLY_FREEBSD_PATCHES=1
RUN_LINUX_TESTS=1 jest domyślne. Testy są bramką tylko dla DEB/RPM i nie wpływają na gałąź OPNsense. Ustaw 0, jeśli chcesz całkowicie pominąć testy Linux.
OPNSENSE_RETENTION=10 zachowuje ostatnie 10 wersji pakietu dla danej serii/architektury OPNsense. 0 wyłącza usuwanie starych wersji.
FREEBSD_NATIVE_ENABLED=0 wyłącza natywny pakiet FreeBSD (domyślnie, bez zmian istniejącej instalacji). Włączenie 1 tworzy oddzielny kanał publikacji i dodaje go do cyklicznego buildera. FREEBSD_NATIVE_RETENTION=10 ogranicza liczbę zachowanych wersji. Repo używa tego samego publicznego hosta/portu co OPNsense, ale pod oddzielnym prefiksem OPNSENSE_REPOSITORY_URL/freebsd/.
Automatyczny Rust toolchain podczas budowania
Builder sprawdza rust-version w Cargo.toml pobranego commita i opcjonalny
rust-toolchain.toml/rust-toolchain przed kompilacją każdej gałęzi.
- Linux DEB/RPM: używa istniejącego
stable; wywołujerustuptylko, gdy brakuje toolchainu albo wersja jest starsza od wymaganej przez projekt. - FreeBSD/OPNsense:
FREEBSD_RUST_TOOLCHAINpozostaje bazowym toolchainem. Gdy jest starszy odrust-version, builder automatycznie dobiera wersję minimalną projektu oraz doinstalowuje targetx86_64-unknown-freebsd. - Jeśli projekt przypina konkretny toolchain, builder respektuje pin.
Sprzeczny pin i
rust-versionpowodują czytelny błąd zamiast cichej zmiany. - Testy i build danej gałęzi używają tego samego wybranego toolchainu.
- Aktualizacja nie zmienia globalnego
rustup default, systemowych pakietów ani wersji już opublikowanych pakietów RustProxy. - Toolchainy pobrane w trakcie działania są w warstwie kontenera
(
/opt/rustup); po odtworzeniu kontenera mogą wymagać ponownego pobrania. Cache Cargo wdata/cargopozostaje trwały. - Jeśli pobranie toolchainu lub kompilacja się nie powiedzie, dany kanał nie zostaje opublikowany; pozostały kanał builder obsługuje niezależnie.
Działanie nie wymaga nowej opcji w .env. Uruchom ./start.sh, żeby
przebudować obraz z nowym skryptem. Aktualizacje toolchainu na podstawie
źródeł będą potem automatyczne przy kolejnych buildach.
FreeBSD cross-build
Obraz buildera pobiera i weryfikuje base.txz dla FREEBSD_RELEASE, a następnie używa:
/opt/freebsd-sysroot
clang / lld / llvm
Rust target x86_64-unknown-freebsd
Poprawki tylko dla builda OPNsense są w:
opnsense/patches/<wersja-RustProxy>/*.patch
Są nakładane na izolowaną kopię źródła. Build Linux nie jest modyfikowany.
Kod pluginu OPNsense znajduje się w:
opnsense/plugin/
OPNsense: autostart i sprawdzanie aktualizacji aplikacji
W Services -> RustProxy zaznacz Enabled i naciśnij Apply. Pakiet
instaluje wykonywalny syshook w
/usr/local/etc/rc.syshook.d/start/50-rustproxy.start. Po restarcie systemu,
gdy sieć już działa, hook odświeża konfigurację z OPNsense i uruchamia usługę
tylko wtedy, gdy jest włączona. Powtórny start nie tworzy drugiego procesu.
Pole Update check interval (seconds) steruje argumentem RustProxy
--update-check-interval-secs. Domyślnie 3600 (godzina); dopuszczalny zakres
to 60–604800 sekund. Wartość nie dotyczy POLL_INTERVAL buildera,
który nadal odpowiada wyłącznie za sprawdzanie repozytorium kodu.
Sprawdzenie po restarcie OPNsense:
ls -l /usr/local/etc/rc.syshook.d/start/50-rustproxy.start
configctl rustproxy status
cat /var/run/rustproxy/command.txt
W command.txt powinien wystąpić aktualnie ustawiony parametr
--update-check-interval-secs <liczba>. Jeśli usługa nie wystartuje, sprawdź
/var/log/rustproxy/rustproxy.log oraz uruchom ręcznie:
configctl template reload OPNsense/RustProxy
configctl rustproxy start
Obsługa miękkiego przeładowania zwiększa OPNSENSE_PACKAGING_REVISION do 4.
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
- DEB/RPM: builder zawsze umieszcza
packaging/rustproxy.logrotatew/etc/logrotate.d/rustproxy(nFPM:config|noreplace). Logrotate jest zależnością obu pakietów. Reguła obejmuje/var/log/rustproxy/*.jsonl,*.logivhosts/*.jsonl, z rotacją codzienną lub po przekroczeniu 100 MiB, 14 archiwami, gzip z opóźnioną kompresją,copytruncateorazsu rustproxy rustproxy. - OPNsense / natywne FreeBSD PKG: pakiet dostarcza
/usr/local/etc/newsyslog.conf.d/rustproxy.confdla tych samych ścieżek;newsyslogwykonuje rotację codziennie lub przy rozmiarze 100 MiB, przechowuje 14 archiwów, pomija puste pliki i używa gzip z niekompresowanym najnowszym archiwum. Plik*.logjest ponownie otwierany przezdaemon(8)poSIGHUP(opcja-Hw skrypcie rc.d). OPNsense uruchamia usługę jakoroot(root:wheelwnewsyslog); natywne FreeBSD działa jakorustproxy(rustproxy:rustproxywnewsyslog).
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.
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:
# DEB / RPM (nie wykonuje rotacji)
logrotate -d /etc/logrotate.d/rustproxy
# OPNsense (nie wykonuje rotacji)
newsyslog -n -v -f /usr/local/etc/newsyslog.conf.d/rustproxy.conf
Pakietowe testy integracyjne (lokalnie, bez budowy aplikacji):
./tests/log-rotation.sh
Dane
data/
├── aptly/
├── cargo/
├── packages/
│ ├── deb/
│ └── rpm/x86_64/
├── repository/
│ ├── current -> releases/<build>
│ ├── apt -> current/apt
│ ├── rpm -> current/rpm
│ ├── opnsense -> current/opnsense
│ ├── freebsd -> current/freebsd
│ └── releases/
├── state/
└── work/
Każda publikacja tworzy nowy snapshot repository/releases/... i atomowo przełącza current. Przy publikacji jednego kanału poprzednie katalogi pozostałych kanałów są zachowywane. Dzięki temu wszystkie aktywne kanały są niezależne, ale nginx nadal serwuje jeden spójny snapshot katalogu.
HTTP i logi
Jeden kontener nginx obsługuje repo Linux i repo OPNsense na dwóch lokalnych portach; natywne FreeBSD jest serwowane jako /freebsd/ na porcie OPNsense:
docker compose logs -f rust-package-builder
docker compose logs -f repository-http
curl -f http://127.0.0.1:18765/healthz
curl -f http://127.0.0.1:18766/healthz
Testy statyczne
./tests/static.sh
./tests/check-rustproxy-source.sh /sciezka/do/RustProxy
Klucz GPG
./start.sh generuje trwały klucz GPG przy pierwszym uruchomieniu. Katalogu gpg/ nie należy usuwać po publikacji APT/RPM.
Migracja ze starszego buildera Linux-only
Builder używa osobnych stanów:
data/state/last_linux_commit
data/state/last_opnsense_commit
Jeżeli istnieje starsze last_commit oraz poprawne APT/RPM dla tego SHA, zostanie ono potraktowane jako stan gałęzi Linux. Brak repo OPNsense uruchomi wyłącznie gałąź OPNsense. Po udanym OPNsense kolejny cykl nie będzie ponownie kompilował FreeBSD, nawet jeśli testy Linux nadal nie przechodzą.
FreeBSD patch version detection
The OPNsense branch reuses the Cargo package VERSION already detected by the main build pipeline. If apply-freebsd-patches.sh is run manually, it falls back to RUST_PROXY_PYTHON (/usr/bin/python3.11) so Rocky Linux 9's default Python 3.9 does not cause a missing tomllib error.
Czyszczenie cache Cargo
Po udanym opublikowaniu pakietów każdej gałęzi (Linux/OPNsense/FreeBSD native) builder
usuwa target/**/incremental i target/debug, a także pliki starsze
niż 30 dni z target/release/deps oraz
target/x86_64-unknown-freebsd/release/deps. Zachowuje aktualne artefakty
release, fingerprinty oraz cache zależności, więc kolejne buildy nie startują
od zera. Starsze usunięte zależności mogą wymagać pojedynczej rekompilacji.
Ustawienia środowiskowe: CLEAN_TARGET_AFTER_BUILD=0 wyłącza czyszczenie;
TARGET_CACHE_MAX_AGE_DAYS=30 określa wiek nieużywanych plików.
RustProxy 0.34.x: plik --config i miękki reload
- Linux DEB/RPM: gdy usługa systemd nie ma własnego
ExecReload, builder dodaje wywołanierust-proxy --data-dir /var/lib/rustproxy --admin-listen 127.0.0.1:9090 reload.systemctl reload rustproxywykonuje przeładowanie przez administracyjne API, nie restartuje procesu. Usługi zProtectSystem=strictotrzymują dodatkowo zapis do-/etc/rustproxy. Aby panel mógł zapisywać wskazany--config, plik i jego katalog muszą być własnością użytkownika usługi. Przykładowo można ustawićRUST_PROXY_CONFIG=/etc/rustproxy/config.jsonw/etc/rustproxy/environment, po uprzednim utworzeniu poprawnego pliku JSON. - OPNsense:
configctl rustproxy reloadwykonuje miękkie przeładowanie z CLI. Skryptservice.shnie robi już stop/start dlareload. Listener GUI po zmianie adresu/portu wymaga nadalrestart, ponieważ samo przeładowanie nie zmienia gniazd nasłuchujących. Opcjonalna ścieżkarustproxy_config_pathwrc.conf(absolutna, bez spacji) jest przekazywana jako--config; panel OPNsense nie ma jeszcze osobnego pola do jej edycji. CLI wymaga osiągalnego adresu administratora na loopback. - Czystemu FreeBSD służy osobna paczka
rustproxy, bez modeli MVC, configd, syshooków i pluginu OPNsense. Jej natywnerc.duruchamia usługę na koncierustproxy, domyślnie nasłuchuje na HTTP8080, admin na127.0.0.1:9090, a TLS jest domyślnie wyłączony. Posysrc rustproxy_enable=YESmożna wykonaćservice rustproxy start,service rustproxy reloadiservice rustproxy restart. Ścieżkę JSON można przekazać przezsysrc rustproxy_config=/usr/local/etc/rustproxy/config.jsonpo przygotowaniu prawidłowego pliku z uprawnieniami użytkownikarustproxy.
Ważne: CLI reload wymaga uruchomionego RustProxy, zainicjalizowanego administratora i API osiągalnego przez adres loopback. Zmiana adresów/portów nasłuchujących wymaga restart, a nie reload.
Natywne repo FreeBSD — wersja developerska
W pliku .env ustaw:
FREEBSD_NATIVE_ENABLED=1
FREEBSD_NATIVE_RETENTION=10
Następnie ./start.sh. Automatyczna publikacja katalogu pkg pojawi się pod:
${OPNSENSE_REPOSITORY_URL}/freebsd/
RustProxy-FreeBSD.conf
meta.conf
packagesite.pkg
data.pkg
rustproxy-latest.pkg
FreeBSD:15:amd64/rustproxy-<wersja>_<revision>.pkg
Na czystym FreeBSD 15 amd64:
mkdir -p /usr/local/etc/pkg/repos
fetch -o /usr/local/etc/pkg/repos/RustProxy-FreeBSD.conf \
https://YOUR-OPNSENSE-REPO-HOST/freebsd/RustProxy-FreeBSD.conf
pkg update -f
pkg install rustproxy
sysrc rustproxy_enable=YES
service rustproxy start
service rustproxy reload
To osobny pakiet od os-rustproxy: nie należy instalować obu pakietów naraz, bo oba używają nazwy usługi i ścieżek RustProxy.
Bezpieczeństwo repo: aktualnie katalog pkg jest niesygnowany, analogicznie do istniejącego repo OPNsense (signature_type: none). To nadaje się do testów DEV na zaufanej infrastrukturze. Przed produkcyjnym wdrożeniem należy dodać podpis katalogu pkg, bezpieczną dystrybucję klucza publicznego i wykonać instalację oraz aktualizację na rzeczywistym FreeBSD. Generator katalogu i testy offline nie zastępują testu klienta pkg na FreeBSD.
Pakietowe testy offline:
./tests/static.sh
./tests/opnsense-plugin.sh
./tests/log-rotation.sh
./tests/freebsd-native.sh
./tests/toolchains.sh