sec-serv — Infrastructure Reference
Dedicated security host. Runs Wazuh SIEM/XDR and Velociraptor DFIR natively, with security, OSINT, identity, and utility services in Docker. Sits on the same LAN segment as home-serv.
Host
| Hostname | sec-serv |
| OS | Ubuntu 26.04 LTS |
| Hardware | GMKtec NucBox K6 |
| CPU | AMD Ryzen 7 7840HS |
| RAM | 32 GB DDR5 |
| Storage | 1 TB NVMe — root LV extended to full disk, 837 GB usable |
| NIC | Dual 2.5 Gbps, one in use |
| LAN | 10.0.4.110 (static, via netplan) |
| Container management | Dockge, stacks under /home/jeremy/docker/stacks/ |
| Wazuh | 4.14.6 |
Kernel tuning
Set permanently via /etc/sysctl.d/:
vm.swappiness=10vm.max_map_count=262144— required by the Wazuh indexer
Journal timezone
This host logs in UTC; home-serv logs in local time (UTC−05:00). Correlating events across the two hosts requires accounting for the five-hour offset.
Network
Traffic flow
flowchart LR
LAN[LAN clients 10.0.4.0/24]
TS[Tailscale clients]
CF[Cloudflare edge]
CFD[cloudflared daemon]
SVC[sec-serv services]
LAN -->|direct LAN| SVC
TS -->|Tailscale mesh| SVC
CF -->|outbound QUIC tunnel| CFD
CFD --> SVCThree access paths reach this host: direct LAN, the Tailscale mesh, and the Cloudflare tunnel. The tunnel is outbound-only — no ports are forwarded at the perimeter.
Mesh
sec-serv is a member of a four-machine Tailscale mesh alongside home-serv, jeremy-pc, and jeremy-lt.
Exposure tiers
| Tier | Binding | Reach |
|---|---|---|
| 1 | 127.0.0.1 | localhost only — most Docker services |
| 2 | via tunnel | public through Cloudflare Tunnel |
| 3 | 0.0.0.0 | LAN and Tailscale reachable — Wazuh components |
| 4 | no host port | internal only |
The majority of containerised services on this host bind to 127.0.0.1 and are reached exclusively through the tunnel. Wazuh components bind LAN-wide because agents connect over the local network.
Services
Security — native systemd
| Service | Access | Port |
|---|---|---|
| Wazuh dashboard | LAN, Tailscale, tunnel | 0.0.0.0:5601 |
| Wazuh indexer | LAN-only | 0.0.0.0:9200 |
| Wazuh manager | LAN-only | :1514–:1515 agents, :55000 API |
| Filebeat | internal | none |
| Velociraptor server | LAN, Tailscale, tunnel | 0.0.0.0:8000 agents, 127.0.0.1:8889 admin HTTPS |
Tor (tor@default) | localhost | 127.0.0.1:9050 SOCKS |
Wazuh is the SIEM/XDR plane. The indexer is OpenSearch 2.19.5 and stores all Wazuh data. The vulnerability-scanner module produces CVE data across all agent operating systems with a 60-minute feed interval. The inventory-harvester module ships package, process, network, hardware, service, browser-extension, user, group, hotfix, and protocol inventory into wazuh-states-inventory-* indexes.
Velociraptor is the DFIR and endpoint-hunting plane. Installed from a .deb package rather than Docker, with config at /etc/velociraptor/server.config.yaml. The admin GUI is tunnelled with noTLSVerify: true because it presents a self-signed certificate. Installer artifacts for client deployment — Linux .deb, Windows MSI, and raw binary — are kept at /home/jeremy/docker/stacks/velociraptor/.
Tor runs as a native systemd unit rather than inside any container, providing a SOCKS proxy for .onion reachability from SpiderFoot.
OSINT — Docker
| Service | Hostname | Host port | Containers |
|---|---|---|---|
| SpiderFoot | osint.lab.example | 127.0.0.1:5002 | spiderfoot |
| VIPERSHADOW | shadow.lab.example | 127.0.0.1:8733 frontend, :8732 API, :4444 Selenium, :7900 noVNC | vipershadow-frontend, vipershadow-backend, vipershadow-selenium |
| ViperScan | viperscan.lab.example | 127.0.0.1:8740 | viperscan |
SpiderFoot is built from source as the spiderfoot-local image, since the official Docker image is no longer publicly distributed. Source clone lives at stacks/spiderfoot/app/. It reaches .onion modules through the host Tor SOCKS proxy. Access is mediated at the tunnel edge — a documented risk acceptance rather than an application-layer control.
VIPERSHADOW is a dark web OSINT platform built in-house. Three containers: a FastAPI backend running Tor internally, an nginx frontend serving a built React/Vite application, and Selenium standalone-chromium for interactive handling of gated sites. Authentication is JWT-based. The stack is intentionally cold — started on demand through Dockge rather than running continuously.
ViperScan is an in-house scanning tool, single container, image built locally.
Endpoint management — Docker and native
| Service | Hostname | Host port | Type |
|---|---|---|---|
| MeshCentral server | mesh.lab.example | 127.0.0.1:8086 | Docker |
| MeshCentral host agent | — | none | Native systemd |
MeshCentral serves plain HTTP in tlsOffload mode, with TLS terminated at the Cloudflare edge. This host runs both the MeshCentral server and a client agent enrolled against its own server.
Velociraptor provides a second endpoint-management plane alongside MeshCentral.
DNS filtering — Docker
| Service | Hostname | Host port | Container |
|---|---|---|---|
| AdGuard Home | adguard-sec.lab.example | 127.0.0.1:3000 admin, 10.0.4.110:53 DNS | adguard |
Network-wide DNS ad and tracker filtering. The admin UI is tunnel-only; DNS binds to the LAN IP to serve local clients.
Password management — Docker
| Service | Hostname | Host port | Container |
|---|---|---|---|
| Vaultwarden | vault.lab.example | 127.0.0.1:8222 | vaultwarden |
IT and utilities — Docker
| Service | Hostname | Host port | Containers |
|---|---|---|---|
| ViperTools | tools.lab.example | 127.0.0.1:8083 main, :8001, :8002, :8004, :8081 | vipertools, vipertools-network-utils, vipertools-network-extra, vipertools-ws-bridge |
| Networking Toolbox | nettools.lab.example | 127.0.0.1:8080 | networking-toolbox |
| web-check | webcheck.lab.example | 127.0.0.1:8102 | web-check |
| Dozzle | dozzle.lab.example | 127.0.0.1:8890 | dozzle |
ViperTools is an in-house developer, IT, and networking toolkit, four containers, image built locally.
Networking Toolbox provides offline networking utilities — DNS lookups, subnet math, TLS and HTTP diagnostics, port checks. Access is mediated at the tunnel edge rather than by application-layer authentication.
Dozzle runs in hub mode, aggregating container logs from both sec-serv and home-serv through the agent on home-serv port 7007.
Monitoring — Docker
| Service | Hostname | Host port | Containers |
|---|---|---|---|
| Beszel hub | beszel.lab.example | 127.0.0.1:8090 | beszel |
| Beszel agent | internal | host 45876 | beszel-agent (network_mode: host) |
| Scrutiny | scrutiny.lab.example | 0.0.0.0:8084 | scrutiny, scrutiny-collector, scrutiny-influxdb |
Beszel is the hub for both servers. Scrutiny aggregates SMART data from local drives and receives home-serv telemetry from a collector cron on that host.
Stack management — Docker
| Service | Hostname | Host port | Container |
|---|---|---|---|
| Dockge | dockge-sec.lab.example | 127.0.0.1:5001 | dockge-dockge-1 |
Backup — native, pushes to home-serv
| Service | Type | Schedule | Target |
|---|---|---|---|
| BBS agent | bbs-agent.service | 01:00 daily, dispatched by BBS | backup.lab.example on home-serv |
| ReaR 2.9 | rear-backup.timer | 04:00 Sundays | rsync to /mnt/backup/rear/sec-serv on home-serv |
BBS is the primary backup path. Repository sec-serv-daily covers /etc, /home/jeremy/docker/stacks, /var/ossec, and /var/lib/wazuh-indexer.
ReaR produces bare-metal recovery images using BACKUP=RSYNC. It runs as root, so it authenticates from /root/.ssh rather than the jeremy user's key material — the root public key is present in jeremy@home-serv:~/.ssh/authorized_keys.
Cloudflare tunnel routes
Catch-all rule: http_status:404.
| Hostname | Target |
|---|---|
adguard-sec.lab.example | http://localhost:3000 |
beszel.lab.example | http://localhost:8090 |
dockge-sec.lab.example | http://localhost:5001 |
dozzle.lab.example | http://localhost:8890 |
mesh.lab.example | http://localhost:8086 |
nettools.lab.example | http://localhost:8080 |
osint.lab.example | http://localhost:5002 |
scrutiny.lab.example | http://localhost:8084 |
shadow.lab.example | http://localhost:8733 |
tools.lab.example | http://localhost:8083 |
vault.lab.example | http://localhost:8222 |
viperscan.lab.example | http://localhost:8740 |
vraptor.lab.example | https://localhost:8889 (noTLSVerify: true) |
wazuh.lab.example | http://localhost:5601 |
webcheck.lab.example | http://localhost:8102 |
Host port map
| Port | Binding | Process | Service |
|---|---|---|---|
22 | 0.0.0.0 | sshd | SSH — key authentication only |
53 | 10.0.4.110 | docker-proxy | AdGuard Home DNS (TCP+UDP) |
53 | 127.0.0.53/.54 | systemd-resolve | DNS stub |
1514 | 0.0.0.0 | wazuh-remoted | Agent event ingestion |
1515 | 0.0.0.0 | wazuh-authd | Agent enrollment |
3000 | 127.0.0.1 | docker-proxy | AdGuard Home admin UI |
4444 | 127.0.0.1 | docker-proxy | Selenium WebDriver |
5001 | 127.0.0.1 | docker-proxy | Dockge |
5002 | 127.0.0.1 | docker-proxy | SpiderFoot |
5601 | 0.0.0.0 | wazuh-dashboard | Wazuh dashboard |
7900 | 127.0.0.1 | docker-proxy | Selenium noVNC |
8000 | 0.0.0.0 | velociraptor | Velociraptor agent endpoint |
8001 | 127.0.0.1 | docker-proxy | ViperTools component |
8002 | 127.0.0.1 | docker-proxy | ViperTools network-utils |
8004 | 127.0.0.1 | docker-proxy | ViperTools network-extra |
8080 | 127.0.0.1 | docker-proxy | Networking Toolbox |
8081 | 127.0.0.1 | docker-proxy | ViperTools ws-bridge |
8083 | 127.0.0.1 | docker-proxy | ViperTools main UI |
8084 | 0.0.0.0 | docker-proxy | Scrutiny |
8086 | 127.0.0.1 | docker-proxy | MeshCentral |
8090 | 127.0.0.1 | docker-proxy | Beszel hub |
8102 | 127.0.0.1 | docker-proxy | web-check |
8222 | 127.0.0.1 | docker-proxy | Vaultwarden |
8732 | 127.0.0.1 | docker-proxy | VIPERSHADOW backend API |
8733 | 127.0.0.1 | docker-proxy | VIPERSHADOW frontend |
8740 | 127.0.0.1 | docker-proxy | ViperScan |
8889 | 127.0.0.1 | velociraptor | Velociraptor admin GUI (HTTPS) |
8890 | 127.0.0.1 | docker-proxy | Dozzle hub |
9050 | 127.0.0.1 | tor | Tor SOCKS |
9200 | 0.0.0.0 | wazuh-indexer | Indexer REST API |
20241 | 127.0.0.1 | cloudflared | Tunnel metrics |
41641 | Tailscale iface, UDP | tailscaled | Tailscale direct |
55000 | 0.0.0.0 | wazuh-manager | Wazuh API |
Compose projects
Stacks live under /home/jeremy/docker/stacks/, managed through Dockge.
adguard/ beszel/ dockge/
dozzle/ meshcentral/ networking-toolbox/
scrutiny/ spiderfoot/ vaultwarden/
velociraptor/ viperden/ vipershadow/
viperscan/ web-check/ it-tools/
Two directories do not match their container names, and should be resolved authoritatively rather than by inference:
it-tools/holds the live ViperTools stack. Containers are namedvipertools-*; the directory retains the original name from before the rebrand. There is novipertools/directory.viperden/holds ViperDen, but its compose file lives inviperden/deploy/rather than at the top level.
docker inspect <container> \
--format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}'velociraptor/ is not a compose stack — it holds installer artifacts for client deployment. Wazuh and Velociraptor both run natively as systemd units and are not managed by Dockge.
Native systemd services
| Service | Role | Port |
|---|---|---|
cloudflared | Tunnel daemon | outbound + 127.0.0.1:20241 |
docker, containerd | Docker Engine | sockets |
tailscaled | Tailscale mesh | UDP :41641 |
wazuh-indexer | OpenSearch 2.19.5 — Wazuh data store | 10.0.4.110:9200 |
wazuh-manager | SIEM manager — agent data ingestion | :1514, :1515, :55000 |
wazuh-dashboard | Wazuh web UI | 0.0.0.0:5601 |
filebeat | Ships manager logs to the indexer | outbound only |
velociraptor_server | Velociraptor DFIR server | 0.0.0.0:8000, 127.0.0.1:8889 |
meshagent | MeshCentral agent — enrolled with local server | outbound only |
tor@default | Tor SOCKS proxy for SpiderFoot | 127.0.0.1:9050 |
bbs-agent | Borg Backup Server client | outbound only |
rear-backup.timer | Weekly ReaR image push to home-serv | — |
ssh.socket | OpenSSH socket activator | 0.0.0.0:22 |
ufw | Firewall | — |
Wazuh agent deployment
Manager address selection follows endpoint mobility. Stationary endpoints — servers and desktops that never leave the network — connect over the LAN IP 10.0.4.110. Portable endpoints connect over the Tailscale IP so they continue reporting from any internet connection.
Five agents are enrolled across Ubuntu, Arch, and Windows 11, covering both servers and workstation endpoints.