2026-11-04 23:19:10 +01:00
2026-11-04 23:19:10 +01:00
2026-10-30 10:56:13 +01:00
2026-10-30 10:56:13 +01:00
2026-11-04 23:19:10 +01:00
2026-11-04 23:19:10 +01:00
2026-11-04 14:57:48 +01:00
2026-11-04 23:19:10 +01:00
2026-11-04 14:57:48 +01:00
2026-11-04 14:57:48 +01:00
2026-10-30 10:56:13 +01:00
2026-10-30 10:56:13 +01:00
2026-10-30 10:56:13 +01:00
2026-10-30 10:56:13 +01:00
2026-11-04 14:57:48 +01:00
2026-11-04 14:57:48 +01:00
2026-11-04 23:19:10 +01:00

TS3 monolith (Go)

Jedna aplikacja zastępująca stare sk.linuxiarz.pl i ts3stats.linuxiarz.pl. Wygląd dashboardu (topbar + sidebar, karty, panele, jasny/ciemny motyw) jest celowo spójny ze stylem PostfixAdminRS — ten sam układ tokenów kolorów, te same komponenty UI.

Funkcjonalność

  • wykrycie klienta TeamSpeak po IP widzianym przez HTTP i ServerQuery;
  • utworzenie permanentnego kanału z nazwą, tematem, opcjonalnym hasłem, limitem użytkowników (channel_maxclients) i jakością kodeka (channel_codec_quality, 1–10);
  • setclientchannelgroup dla wskazanego client_database_id;
  • clientmove wskazanego clid do nowego kanału;
  • dashboard statystyk: liczba online na żywo (auto-odświeżanie co 60 s przez GET /stats/live), uptime/wersja/platforma serwera (serverinfo), wykresy RRD: 12h, 24h, 72h, tydzień, miesiąc, rok — w kolorystyce dopasowanej do motywu aplikacji (ciemne tło, akcentowa linia, watermark);
  • przełącznik jasny/ciemny motyw (zapamiętywany w localStorage);
  • formularz pod /embed/channel, przeznaczony do osadzenia na innej domenie.

Przy jednym kliencie pod danym IP wszystko działa automatycznie. Jeżeli kilka klientów TS3 ma ten sam publiczny IP (NAT), aplikacja prosi o wybór nicku i wysyła 6-cyfrowy kod prywatną wiadomością TS3. Dzięki temu nie przenosi przypadkowej osoby i nie nadaje jej Channel Admina.

Szybki development

cp .env.example .env    # uzupełnij sekrety
make quick               # najszybszy build (bez testów/trimpath) -> bin/ts3monolith
make dev                 # quick build + start z lokalnym .env
make test                # go test ./...
make build                # pełny build produkcyjny (testy + trimpath + bez symboli)

Uruchomienie — Docker

  1. Skopiuj .env.example do .env i ustaw sekrety oraz dozwoloną domenę iframe.
  2. Zachowaj data/linuxiarz.rrd (kopia dotychczasowej bazy z archiwum) albo zainicjuj nową bazę — patrz sekcja RRD.
  3. Zapewnij zapis do katalogu data dla UID 10001: chown -R 10001:10001 data.
  4. Uruchom: docker compose up -d --build.
  5. Reverse proxy kieruje HTTPS do 127.0.0.1:8080.

Uruchomienie — pakiet .deb + systemd

Alternatywa dla Dockera, zalecana na dedykowanym hoście Debian/Ubuntu:

make deb                 # scripts/build-deb.sh -> packages/ts3monolith_<wersja>_amd64.deb
sudo dpkg -i packages/ts3monolith_*.deb
sudo nano /etc/default/ts3monolith          # APP_SECRET, TS_QUERY_USER, TS_QUERY_PASSWORD, ...
sudo -u ts3monolith /usr/lib/ts3monolith/init-rrd   # tylko przy świeżej instalacji, bez starej bazy
sudo systemctl enable --now ts3monolith

scripts/build-deb.sh buduje wszystko w kontenerze Docker — dokładnie tak samo jak odpowiadający skrypt w PostfixAdminRS — więc host nie potrzebuje lokalnie zainstalowanego Go ani żadnych zależności poza samym Dockerem. Wersja obrazu (golang:<wersja z go.mod>-bookworm) jest odczytywana z go.mod, a sam moduł nie ma żadnych zewnętrznych zależności, więc build jest w pełni offline po ściągnięciu obrazu. Wynikowy pakiet trafia do packages/. Pakiet instaluje:

  • /usr/bin/ts3monolith — binarka;
  • /etc/default/ts3monolith — zmienne środowiskowe (conffile);
  • /lib/systemd/system/ts3monolith.service — jednostka z pełnym hardeningiem (ProtectSystem=strict, NoNewPrivileges, RestrictAddressFamilies, MemoryDenyWriteExecute, SystemCallFilter=@system-service, ...), takim samym duchem jak w PostfixAdminRS;
  • /usr/lib/ts3monolith/init-rrd — jednorazowy skrypt tworzący świeżą bazę RRD z RRA pokrywającymi wszystkie zakresy wykresów (12h…rok), gdy nie ma archiwalnego pliku do skopiowania;
  • dedykowanego użytkownika systemowego ts3monolith (bez loginu, bez home).

install.sh z korzenia repo zostaje jako prostszy, ręczny installer bez budowania pakietu .deb (np. do szybkiego postawienia na hoście bez uprawnień do dpkg).

Przykład iframe:

<iframe
  src="https://app.example.org/embed/channel"
  title="Utwórz kanał TeamSpeak"
  loading="lazy"
  referrerpolicy="no-referrer"
  style="width:100%;min-height:620px;border:0">
</iframe>

FRAME_ANCESTORS musi zawierać origin strony nadrzędnej, np. https://www.example.org.

TeamSpeak ServerQuery

Najbezpieczniej uruchamiać aplikację na tym samym hoście lub w prywatnej sieci z TS3 i ustawić TS_QUERY_HOST=127.0.0.1/adres prywatny. Nie wystawiaj portu 10011 publicznie. Query powinien mieć tylko prawa potrzebne do: clientlist -ip -uid, channelcreate, setclientchannelgroup, clientmove, sendtextmessage, channeldelete (rollback), serverinfo (karty uptime/wersji na dashboardzie).

RRD

Aplikacja używa systemowego rrdtool, a nie biblioteki Go, więc istniejący plik RRD pozostaje bez migracji. Co 60 s liczona jest liczba klientów client_type=0 na wybranym virtual serverze i zapisywana do DS online. Błąd ServerQuery nie zapisuje sztucznego zera.

Świeża instalacja bez archiwalnej bazy: packaging/ts3monolith-init-rrd (instalowany jako /usr/lib/ts3monolith/init-rrd w pakiecie .deb) tworzy nową bazę rrdtool create z RRA pokrywającymi 12h/24h/72h/tydzień/miesiąc/rok przy kroku 60 s — ten sam layout logiczny co istniejące wykresy aplikacji.

Wykresy renderowane są w kolorach dopasowanych do motywu dashboardu (--panel/--field/--accent z internal/web/assets/app.css), z cienkim wypełnieniem pod linią, watermarkiem z datą generacji i --slope-mode dla gładszej linii. Każdy zakres jest renderowany dwukrotnie — <zakres>.png (ciemna paleta) i <zakres>-light.png (jasna paleta) — a front-end (internal/web/assets/app.js) przełącza src na właściwy wariant przy zmianie motywu, więc wykresy zawsze dopasowane są do aktywnego trybu jasny/ciemny.

Jeżeli docelowy serwer ma inną architekturę/endianness niż źródłowy x86_64 little-endian, przenieś RRD przez rrdtool dump/rrdtool restore zamiast kopiowania binarnego pliku.

Bezpieczeństwo / fingerprinting

  • brak PHP, frameworków frontendowych, CDN i nagłówka X-Powered-By;
  • standardowy net/http nie dodaje nagłówka Server;
  • CSP z kontrolowanym frame-ancestors, HSTS, nosniff, restrykcyjne Permissions-Policy, style-src/script-src 'self' (bez inline — cały CSS/JS w plikach statycznych);
  • nagłówki proxy są ufane wyłącznie z TRUSTED_PROXIES;
  • stateless HMAC tokeny formularzy i klientów, sprawdzanie Origin, limity request body i rate limiting;
  • sekrety tylko przez środowisko, brak danych dostępowych w repo;
  • rollback kanału, jeśli nadanie grupy lub przeniesienie klienta się nie powiedzie;
  • kontener non-root, cap_drop: ALL, no-new-privileges, read-only root filesystem (Docker) albo analogiczny hardening jednostki systemd (pakiet .deb);
  • build z -trimpath i usuniętymi symbolami/debug info.

Nie da się zagwarantować, że stos technologiczny będzie całkowicie nierozpoznawalny na podstawie zachowania sieci/TLS. Celem jest brak prostych bannerów, wersji i sygnatur frameworka.

S
Description
No description provided
Readme
19 MiB
0 Stars 1 Watchers 0 Forks
Languages
Go 52.3%
HTML 14.5%
JavaScript 11.6%
CSS 11.2%
Shell 9.2%
Other 1.2%