diff --git a/10-systems/servers/external-vps.md b/10-systems/servers/external-vps.md new file mode 100644 index 0000000..b3e60ae --- /dev/null +++ b/10-systems/servers/external-vps.md @@ -0,0 +1,36 @@ +--- +owner: gmikcon +status: active +last_reviewed: 2026-05-09 +review_interval: 90d +confidence: medium +source_of_truth: owner-confirmed +--- + +# External VPS + +External public VPS used as the public entrypoint for `gnexus.space` and its subdomains. + +## Provider + +- Provider: s-host.com.ua. +- Location: Ukraine. +- Hostname: `vpslklyc.s-host.host`. +- OS: Ubuntu Server 22.04. + +## Addresses + +- Primary public IP: `194.61.53.43`. +- Assigned public IP: `194.61.53.92`. + +## Limits + +- Monthly traffic limit: 20 TB. +- Port speed: 250 Mbit/s. +- Observed throughput through the VPN path to internal services: approximately 90-100 Mbit/s. + +## Role + +This host runs the external OpenVPN server. Public traffic for `gnexus.space` and subdomains reaches this VPS first, then continues through the OpenVPN tunnel to the internal proxy VPS. + +No raw credentials are documented here. diff --git a/10-systems/servers/internal-proxy-vps.md b/10-systems/servers/internal-proxy-vps.md new file mode 100644 index 0000000..fd3d265 --- /dev/null +++ b/10-systems/servers/internal-proxy-vps.md @@ -0,0 +1,96 @@ +--- +owner: gmikcon +status: active +last_reviewed: 2026-05-09 +review_interval: 90d +confidence: medium +source_of_truth: owner-confirmed-and-ssh-libvirt +--- + +# Internal Proxy VPS + +Internal proxy VPS that receives traffic from the external VPS through OpenVPN and forwards it to internal services. + +## Identity + +- Inventory id: `internal-proxy-vps`. +- VM id: `ovpn_reserv`. +- Hypervisor: `hp-proliant-dl380-g6`. +- OS: Ubuntu 20.04.6 LTS. +- Kernel: `5.4.0-216-generic`. +- nginx: `nginx/1.18.0`. + +## Addresses + +- LAN address: `192.168.1.226`. +- Libvirt/internal address: `192.168.105.181/24`. + +## Roles + +- OpenVPN client. +- Internal nginx reverse proxy. +- Main internal entrypoint for public `gnexus.space` traffic. + +## Active Services + +- `nginx.service` +- `openvpn@client.service` +- `ssh.service` + +## Listening TCP Ports + +- `22` +- `80` +- `443` + +## Proxy Scope + +The nginx proxy handles the `gnexus.space` domain family. + +Enabled nginx sites: + +- `git.gnexus.space` +- `jellyfin.gnexus.space` +- `auth.gnexus.space` +- `cloud.gnexus.space` +- `files.gnexus.space` +- `gnexus.space` +- `navi.gnexus.space` +- `transmission.gnexus.space` + +Available nginx site files that are not currently confirmed as enabled: + +- `anicusi.gnexus.space` +- `cats.gnexus.space` +- `fdroid.gnexus.space` +- `ferumina.gnexus.space` +- `lytvak.gnexus.space` +- `mail.gnexus.space` +- `minecraft.gnexus.space` +- `ollama.gnexus.space` +- `sups.gnexus.space` +- `topics.gnexus.space` + +## Confirmed Proxy Mappings + +| Domain | Upstream | +| --- | --- | +| `auth.gnexus.space` | `http://192.168.1.167` | +| `cloud.gnexus.space` | `http://192.168.1.152` | +| `files.gnexus.space` | `http://192.168.1.157` | +| `git.gnexus.space` | `http://192.168.1.156` | +| `gnexus.space` | `http://192.168.1.151` | +| `jellyfin.gnexus.space` | `http://192.168.1.153:8096` | +| `navi.gnexus.space` | `http://192.168.1.168:8000` | +| `transmission.gnexus.space` | `http://192.168.1.154:3000` | + +Known available but not confirmed enabled mappings: + +| Domain | Upstream | +| --- | --- | +| `lytvak.gnexus.space` | `http://192.168.1.167` | +| `minecraft.gnexus.space` | `tcp://192.168.1.218:25565` | + +Proxying is mixed by hostname, path, and ports. SSH forwarding to the internal `alex` VPS on a custom port is believed to exist and still needs confirmation from nginx or firewall configuration. + +No raw credentials are documented here. diff --git a/10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md b/10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md index 28203d0..d271d8c 100644 --- a/10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md +++ b/10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md @@ -17,9 +17,11 @@ Internet -> gnexus.space -> external VPS - -> VPN tunnel - -> internal VPS - -> nginx + -> external OpenVPN server + -> OpenVPN tunnel + -> internal OpenVPN client + -> internal proxy VPS + -> internal nginx reverse proxy -> target VPS or internal machine -> target service ``` @@ -27,18 +29,55 @@ ## Exposure - Exposure: public. -- Public-facing entry: external VPS. -- Internal routing: VPN tunnel to internal VPS. -- Proxy layer: nginx. +- Public-facing entry: `external-vps`. +- Internal routing: OpenVPN tunnel to `internal-proxy-vps`. +- Proxy layer: `internal-nginx-proxy`. +- Main public web ports: `80`, `443`. ## Purpose The route lets public traffic terminate on an external VPS and then pass into selected internal services through a VPN tunnel. The internal nginx proxy decides which target VPS or machine receives the request. +## Known Public Domains + +- `git.gnexus.space` +- `jellyfin.gnexus.space` +- `lytvak.gnexus.space` +- `minecraft.gnexus.space` +- `auth.gnexus.space` +- `cloud.gnexus.space` +- `files.gnexus.space` +- `gnexus.space` +- `navi.gnexus.space` +- `transmission.gnexus.space` + +## Known Hosts + +- External VPS: `external-vps`, s-host.com.ua, Ukraine, Ubuntu Server 22.04. +- Internal proxy VPS: `internal-proxy-vps`, VM `ovpn_reserv`, LAN address `192.168.1.226`, libvirt address `192.168.105.181/24`. + +## Confirmed Enabled Proxy Targets + +| Domain | Upstream | +| --- | --- | +| `auth.gnexus.space` | `http://192.168.1.167` | +| `cloud.gnexus.space` | `http://192.168.1.152` | +| `files.gnexus.space` | `http://192.168.1.157` | +| `git.gnexus.space` | `http://192.168.1.156` | +| `gnexus.space` | `http://192.168.1.151` | +| `jellyfin.gnexus.space` | `http://192.168.1.153:8096` | +| `navi.gnexus.space` | `http://192.168.1.168:8000` | +| `transmission.gnexus.space` | `http://192.168.1.154:3000` | + +## Available But Not Confirmed Enabled + +These nginx site files exist on `internal-proxy-vps`, but they were not listed as enabled symlinks during the last check: + +- `lytvak.gnexus.space` -> `http://192.168.1.167` +- `minecraft.gnexus.space` -> `tcp://192.168.1.218:25565` + ## Unknowns -- External VPS hostname and provider. -- VPN technology and tunnel addresses. -- Internal VPS identity. -- nginx configuration location. -- Mapping of hostnames to target services. +- OpenVPN public port. +- nginx configuration file paths. +- SSH forwarding details to the internal `alex` VPS. diff --git a/40-inventory/domains.yml b/40-inventory/domains.yml index 87d6495..b6d2f09 100644 --- a/40-inventory/domains.yml +++ b/40-inventory/domains.yml @@ -3,11 +3,129 @@ - id: gnexus-space fqdn: gnexus.space status: active - registrar: unknown - dns_provider: unknown + registrar: OVHcloud + dns_provider: OVHcloud points_to: - external-vps - used_by: [] + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: git-gnexus-space + fqdn: git.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: jellyfin-gnexus-space + fqdn: jellyfin.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: lytvak-gnexus-space + fqdn: lytvak.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: minecraft-gnexus-space + fqdn: minecraft.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: auth-gnexus-space + fqdn: auth.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: cloud-gnexus-space + fqdn: cloud.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: files-gnexus-space + fqdn: files.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: navi-gnexus-space + fqdn: navi.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy + docs: ../10-systems/domains/gnexus.space.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: transmission-gnexus-space + fqdn: transmission.gnexus.space + status: active + registrar: OVHcloud + dns_provider: OVHcloud + points_to: + - external-vps + used_by: + - internal-nginx-proxy docs: ../10-systems/domains/gnexus.space.md last_reviewed: 2026-05-09 source_of_truth: owner-confirmed diff --git a/40-inventory/hosts.yml b/40-inventory/hosts.yml index 8669038..4c5fdf8 100644 --- a/40-inventory/hosts.yml +++ b/40-inventory/hosts.yml @@ -1,3 +1,60 @@ # Operating-system hosts and runtime environments. --- -[] +- id: external-vps + name: External VPS + type: vps + status: active + environment: production + provider: s-host.com.ua + location: Ukraine + os: Ubuntu Server 22.04 + hostname: vpslklyc.s-host.host + addresses: + public: + primary: 194.61.53.43 + assigned: + - 194.61.53.92 + network_limits: + monthly_traffic_tb: 20 + port_speed_mbps: 250 + observed_vpn_throughput_mbps: 90-100 + roles: + - public-entrypoint + - openvpn-server + - domain-target + docs: ../10-systems/servers/external-vps.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: internal-proxy-vps + name: Internal Proxy VPS + type: vm + status: active + environment: production + provider: home-libvirt + location: home + vm_id: ovpn_reserv + hardware_node: hp-proliant-dl380-g6 + os: Ubuntu 20.04.6 LTS + kernel: 5.4.0-216-generic + addresses: + lan: + - 192.168.1.226 + local: + - 192.168.105.181/24 + roles: + - openvpn-client + - nginx-reverse-proxy + - internal-traffic-entrypoint + active_services: + - nginx.service + - openvpn@client.service + - ssh.service + listening_ports: + tcp: + - 22 + - 80 + - 443 + docs: ../10-systems/servers/internal-proxy-vps.md + last_reviewed: 2026-05-09 + source_of_truth: ssh-host-and-owner-confirmed diff --git a/40-inventory/networks.yml b/40-inventory/networks.yml index c752b14..af9a6dc 100644 --- a/40-inventory/networks.yml +++ b/40-inventory/networks.yml @@ -1,5 +1,13 @@ # Network segments, virtual networks, and routing domains. --- +- id: internet + name: Internet + type: external-network + status: active + docs: ../10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md + last_reviewed: 2026-05-09 + source_of_truth: documentation-convention + - id: libvirt-default name: default type: libvirt-network @@ -39,3 +47,17 @@ docs: ../10-systems/networks/libvirt-networks.md last_reviewed: 2026-05-09 source_of_truth: ssh-libvirt + +- id: openvpn-tunnel + name: OpenVPN tunnel from external VPS to internal proxy VPS + type: vpn-tunnel + status: active + owner_host: external-vps + endpoints: + - external-vps + - internal-proxy-vps + server: external-openvpn-server + client: internal-openvpn-client + docs: ../10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed diff --git a/40-inventory/services.yml b/40-inventory/services.yml index 58c250d..9ffbc5b 100644 --- a/40-inventory/services.yml +++ b/40-inventory/services.yml @@ -1,3 +1,105 @@ # Applications, websites, infrastructure services, workers, and daemons. --- -[] +- id: external-openvpn-server + name: External OpenVPN Server + type: vpn + status: active + host: external-vps + domains: [] + ports: [] + criticality: high + docs: ../10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md + runbook: "" + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: internal-openvpn-client + name: Internal OpenVPN Client + type: vpn-client + status: active + host: internal-proxy-vps + domains: [] + ports: [] + criticality: high + docs: ../10-systems/servers/internal-proxy-vps.md + runbook: "" + last_reviewed: 2026-05-09 + source_of_truth: owner-confirmed + +- id: internal-nginx-proxy + name: Internal nginx Reverse Proxy + type: reverse-proxy + status: active + host: internal-proxy-vps + domains: + - gnexus-space + - git-gnexus-space + - jellyfin-gnexus-space + - lytvak-gnexus-space + - minecraft-gnexus-space + - auth-gnexus-space + - cloud-gnexus-space + - files-gnexus-space + - navi-gnexus-space + - transmission-gnexus-space + ports: + - 80 + - 443 + nginx: + version: nginx/1.18.0 + enabled_sites: + - auth.gnexus.space + - cloud.gnexus.space + - files.gnexus.space + - git.gnexus.space + - gnexus.space + - jellyfin.gnexus.space + - navi.gnexus.space + - transmission.gnexus.space + available_sites_not_confirmed_enabled: + - anicusi.gnexus.space + - cats.gnexus.space + - fdroid.gnexus.space + - ferumina.gnexus.space + - lytvak.gnexus.space + - mail.gnexus.space + - minecraft.gnexus.space + - ollama.gnexus.space + - sups.gnexus.space + - topics.gnexus.space + proxy_mappings: + - domain: auth.gnexus.space + upstream: http://192.168.1.167 + enabled: true + - domain: cloud.gnexus.space + upstream: http://192.168.1.152 + enabled: true + - domain: files.gnexus.space + upstream: http://192.168.1.157 + enabled: true + - domain: git.gnexus.space + upstream: http://192.168.1.156 + enabled: true + - domain: gnexus.space + upstream: http://192.168.1.151 + enabled: true + - domain: jellyfin.gnexus.space + upstream: http://192.168.1.153:8096 + enabled: true + - domain: navi.gnexus.space + upstream: http://192.168.1.168:8000 + enabled: true + - domain: transmission.gnexus.space + upstream: http://192.168.1.154:3000 + enabled: true + - domain: lytvak.gnexus.space + upstream: http://192.168.1.167 + enabled: false + - domain: minecraft.gnexus.space + upstream: tcp://192.168.1.218:25565 + enabled: false + criticality: high + docs: ../10-systems/servers/internal-proxy-vps.md + runbook: "" + last_reviewed: 2026-05-09 + source_of_truth: ssh-nginx-and-owner-confirmed diff --git a/40-inventory/traffic-routes.yml b/40-inventory/traffic-routes.yml index e1c61e2..6d2fd2c 100644 --- a/40-inventory/traffic-routes.yml +++ b/40-inventory/traffic-routes.yml @@ -6,12 +6,14 @@ source: internet entrypoint: external-vps path: - - gnexus.space + - gnexus-space - external-vps - - vpn-tunnel - - internal-vps - - nginx - destination: target-vps-or-internal-machine + - external-openvpn-server + - openvpn-tunnel + - internal-openvpn-client + - internal-proxy-vps + - internal-nginx-proxy + destination: internal-nginx-proxy protocols: - http - https @@ -19,7 +21,8 @@ - 80 - 443 exposure: public - used_by: [] + used_by: + - internal-nginx-proxy docs: ../10-systems/traffic-routes/public-gnexus-space-to-internal-nginx.md last_reviewed: 2026-05-09 source_of_truth: owner-confirmed diff --git a/40-inventory/virtual-machines.yml b/40-inventory/virtual-machines.yml index c3f810a..e4e61ee 100644 --- a/40-inventory/virtual-machines.yml +++ b/40-inventory/virtual-machines.yml @@ -166,11 +166,14 @@ memory_mib: 4096 autostart: true addresses: + - 192.168.1.226 - 192.168.105.181/24 - runs_services: [] + runs_services: + - internal-openvpn-client + - internal-nginx-proxy docs: ../10-systems/virtualization/libvirt-vms.md last_reviewed: 2026-05-09 - source_of_truth: ssh-libvirt + source_of_truth: owner-confirmed-and-ssh-libvirt - id: home name: home diff --git a/server/tests/test_api.py b/server/tests/test_api.py index 809ef44..f868f2f 100644 --- a/server/tests/test_api.py +++ b/server/tests/test_api.py @@ -90,11 +90,17 @@ "target": "hardware/hp-proliant-dl380-g6", "relation": "runs_on", } in response["edges"] - assert any( - item["source"] == "traffic-routes/public-gnexus-space-to-internal-nginx" - and item["target"] == "external-vps" - for item in response["unresolved_references"] - ) + assert { + "source": "traffic-routes/public-gnexus-space-to-internal-nginx", + "target": "hosts/external-vps", + "relation": "entrypoint", + } in response["edges"] + assert { + "source": "traffic-routes/public-gnexus-space-to-internal-nginx", + "target": "services/internal-nginx-proxy", + "relation": "destination", + } in response["edges"] + assert response["unresolved_references"] == [] def test_validate_endpoint_is_clean() -> None: