# IP Subnet Allocator Jednoduchá interní webová aplikace pro evidenci a automatické přidělování IPv4 subnetů. ## Účel Aplikace slouží výhradně pro interní evidenci a automatické přidělování IPv4 subnetů. Není to obecný IPAM, monitoring, inventář zařízení, správa VLAN ani síťová topologie. Je navržena pro provoz pouze uvnitř LAN/VPN. **Aplikace neobsahuje autentizaci** – musí být zařazena za firewall/reverse proxy v důvěryhodné síti. ## Přehled funkcí - Dva přednastavené pooly: - VLAN / zákaznické subnety: `10.91.0.0/16` - VPN subnety: `10.200.0.0/16` - Automatické přidělování subnetů pomocí **first-fit** algoritmu pro prefixy /20 až /30. - Atomický zápis alokací přes SQLite transakci `BEGIN IMMEDIATE`. - Webové UI s retro TUI/terminál vzhledem, server-side renderované pomocí Askama. - Dynamické preview dalšího volného subnetu přes HTMX. - Historie alokací s filtrem, vyhledáváním a stránkováním. - Uvolňování subnetů (status `released`) s povinnou poznámkou. - Auditní log všech operací. - Exporty do Markdown, CSV a JSON. - SQLite migrace probíhají automaticky při startu. - Zálohovací a obnovovací skripty. ## Architektura - **Rust** edition 2024 - **Axum** + **Tokio** - **SQLx** s **SQLite** - **Askama** pro HTML šablony - **HTMX** z lokálního statického souboru - Vlastní CSS bez externích frameworků - CIDR/IP výpočty pomocí `ipnet` ## Rychlý start ```bash cd sub-aligator cp .env.example .env docker compose up -d --build ``` Otevřete prohlížeč na: ``` http://IP_SERVERU:8080 ``` Výchozí port lze změnit v `.env` pomocí proměnné `APP_PORT`. ## Persistentní data Docker Compose vytváří lokální adresáře: - `./data` – SQLite databáze - `./exports` – vygenerované exporty (Markdown, CSV, JSON) - `./backups` – zálohy databáze Tyto adresáře jsou bind mountovány do kontejneru, takže data přetrvávají i po odstranění kontejneru. ## Záloha a obnova ### Záloha ```bash ./scripts/backup.sh ``` Skript vytvoří konzistentní zálohu databáze pomocí `sqlite3 .backup` s UTC timestampem v názvu souboru. Zálohy se ukládají do `./backups`. ### Obnova ```bash ./scripts/restore.sh ./backups/subnet-allocator.db.20240930T120000Z.backup ``` **Upozornění:** obnova přepíše aktuální databázi. Před obnovou doporučujeme zastavit kontejner a vytvořit zálohu aktuálního stavu. ### Automatizace zálohy Na hostovi můžete použít systemd timer nebo cron. Příklad cron záznamu: ```cron 0 2 * * * /cesta/k/sub-aligator/scripts/backup.sh >> /var/log/subnet-allocator-backup.log 2>&1 ``` ## Exporty Po každém úspěšném vytvoření nebo uvolnění subnetu se vygenerují read-only exporty: - `/app/exports/allocations.md` - `/app/exports/allocations.csv` - `/app/exports/allocations.json` Ke stažení jsou dostupné přes endpointy: - `GET /exports/allocations.md` - `GET /exports/allocations.csv` - `GET /exports/allocations.json` Markdown export obsahuje samostatnou sekci pro každý pool s tabulkou aktivních a rezervovaných alokací. CSV a JSON obsahují všechny alokace včetně released. ## Bezpečnostní omezení - Aplikace **nemá autentizaci**. Používejte ji pouze za VPN/LAN/firewallem. - CSRF tokeny jsou povinné pro POST formuláře. - Nastaveny bezpečnostní hlavičky: `X-Content-Type-Options`, `X-Frame-Options`, `Referrer-Policy`, `Content-Security-Policy`. - Aplikace nemá žádný defaultní přístup z Internetu; bind portu se řeší přes Docker Compose. - `/healthz` vrací pouze `{"status":"ok"}`. ## Pozdější přidání autentizace přes Caddy + Authentik Aplikace je připravena pro autentizaci přes důvěryhodnou reverse proxy. Funkce `get_actor_from_request()` v `src/audit.rs` nyní vrací `local`, ale může být upravena pro čtení hlavičky, například `X-Authentik-Username`. Příklad konfigurace Caddy s Authentik: ```caddy subnet.example.com { reverse_proxy /outpost.goauthentik.io/* http://authentik:9000 forward_auth http://authentik:9000 { uri /outpost.goauthentik.io/auth/caddy copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email } reverse_proxy subnet-allocator:8080 } ``` Po úpravě `get_actor_from_request()` bude auditní log obsahovat skutečného uživatele. ## Příklad first-fit alokace 1. První požadavek `/30` získá `10.91.0.0/30`. 2. Následný požadavek `/24` získá `10.91.1.0/24` (vyhne se obsazenému `/30`). 3. Další požadavek `/30` zaplní mezeru a získá `10.91.0.4/30`. Algoritmus vždy respektuje CIDR zarovnání a najde první volný prostor dostatečné velikosti. ## Endpointy - `GET /` – hlavní stránka - `GET /healthz` – healthcheck - `GET /partials/pools/{slug}/preview?prefix_length=24` – HTMX preview - `POST /allocations` – vytvoření alokace - `GET /allocations` – seznam alokací (součást `/`) - `GET /allocations/{id}` – detail alokace - `POST /allocations/{id}/release` – uvolnění alokace - `GET /exports/allocations.{md,csv,json}` – exporty ## Troubleshooting ### Kontejner nenastartuje ```bash docker compose logs -f subnet-allocator ``` ### Databáze je uzamčena Pokud dojde k neočekávanému ukončení, může zůstat `-wal` nebo `-shm` soubor. Zastavte kontejner a zkontrolujte `./data`. ### Exporty se negenerují Zkontrolujte práva adresáře `./exports` a proměnnou `APP_EXPORTS_DIR`. ## Licence MIT. Viz soubor `LICENSE`.