add v6proxy docs

This commit is contained in:
goeranh 2026-03-13 17:32:05 +01:00
parent 18f4d0c65f
commit 6ea1a37bef
No known key found for this signature in database
2 changed files with 353 additions and 2 deletions

View file

@ -8,6 +8,7 @@ Declarative infrastructure management for StuRa HTW Dresden using NixOS and a fl
This infrastructure uses a flake-based approach with automatic host discovery: This infrastructure uses a flake-based approach with automatic host discovery:
- **Centralized reverse proxy**: HAProxy at 141.56.51.1 routes all traffic via SNI inspection and HTTP host headers - **Centralized reverse proxy**: HAProxy at 141.56.51.1 routes all traffic via SNI inspection and HTTP host headers
- **IPv6 gateway**: Hetzner VPS at 2a01:4f8:1c19:96f8::1 forwards IPv6 traffic to the IPv4 proxy
- **Automatic host discovery**: Each subdirectory in `hosts/` becomes a NixOS configuration via `builtins.readDir` - **Automatic host discovery**: Each subdirectory in `hosts/` becomes a NixOS configuration via `builtins.readDir`
- **Global configuration**: Settings in `default.nix` are automatically applied to all hosts - **Global configuration**: Settings in `default.nix` are automatically applied to all hosts
- **ACME certificates**: All services use Let's Encrypt certificates managed locally on each host - **ACME certificates**: All services use Let's Encrypt certificates managed locally on each host
@ -31,6 +32,11 @@ stura-infra/
│ │ ├── hardware-configuration.nix │ │ ├── hardware-configuration.nix
│ │ ├── hetzner-disk.nix │ │ ├── hetzner-disk.nix
│ │ └── README.md │ │ └── README.md
│ ├── v6proxy/ # IPv6 gateway (Hetzner VPS)
│ │ ├── default.nix
│ │ ├── hardware-configuration.nix
│ │ ├── hetzner-disk.nix
│ │ └── README.md
│ ├── git/ # Forgejo git server │ ├── git/ # Forgejo git server
│ │ └── default.nix │ │ └── default.nix
│ ├── wiki/ # MediaWiki instance │ ├── wiki/ # MediaWiki instance
@ -47,6 +53,7 @@ stura-infra/
| Host | IP | Type | Services | Documentation | | Host | IP | Type | Services | Documentation |
|------|-----|------|----------|---------------| |------|-----|------|----------|---------------|
| proxy | 141.56.51.1 | VM | HAProxy, SSH Jump | [hosts/proxy/README.md](hosts/proxy/README.md) | | proxy | 141.56.51.1 | VM | HAProxy, SSH Jump | [hosts/proxy/README.md](hosts/proxy/README.md) |
| v6proxy | 178.104.18.93 (IPv4)<br>2a01:4f8:1c19:96f8::1 (IPv6) | Hetzner VPS | HAProxy (IPv6 Gateway) | [hosts/v6proxy/README.md](hosts/v6proxy/README.md) |
| git | 141.56.51.7 | LXC | Forgejo, Nginx | [hosts/git/README.md](hosts/git/README.md) | | git | 141.56.51.7 | LXC | Forgejo, Nginx | [hosts/git/README.md](hosts/git/README.md) |
| wiki | 141.56.51.13 | LXC | MediaWiki, MariaDB, Apache | [hosts/wiki/README.md](hosts/wiki/README.md) | | wiki | 141.56.51.13 | LXC | MediaWiki, MariaDB, Apache | [hosts/wiki/README.md](hosts/wiki/README.md) |
| redmine | 141.56.51.15 | LXC | Redmine, Nginx | [hosts/redmine/README.md](hosts/redmine/README.md) | | redmine | 141.56.51.15 | LXC | Redmine, Nginx | [hosts/redmine/README.md](hosts/redmine/README.md) |
@ -193,9 +200,9 @@ The following DNS records must be configured for the current infrastructure:
|------|------|-----|---------| |------|------|-----|---------|
| *.htw.stura-dresden.de | CNAME | proxy.htw.stura-dresden.de | Reverse proxy | | *.htw.stura-dresden.de | CNAME | proxy.htw.stura-dresden.de | Reverse proxy |
| proxy.htw.stura-dresden.de | A | 141.56.51.1 | Proxy IPv4 | | proxy.htw.stura-dresden.de | A | 141.56.51.1 | Proxy IPv4 |
| proxy.htw.stura-dresden.de | AAAA | 2a01:4f8:1c19:96f8::1 | Proxy IPv6 | | proxy.htw.stura-dresden.de | AAAA | 2a01:4f8:1c19:96f8::1 | IPv6 Gateway (v6proxy) |
**Note**: All public services point to the proxy IP (141.56.51.1). The proxy handles SNI-based routing to backend hosts. Backend IPs are internal and not exposed in DNS. **Note**: All public services point to the proxy IPs. The IPv4 proxy (141.56.51.1) handles SNI-based routing to backend hosts. The IPv6 gateway (v6proxy at 2a01:4f8:1c19:96f8::1) forwards all IPv6 traffic to the IPv4 proxy. Backend IPs are internal and not exposed in DNS.
Additional services managed by the proxy (not in this repository): Additional services managed by the proxy (not in this repository):
- stura.htw-dresden.de → Plone - stura.htw-dresden.de → Plone

344
hosts/v6proxy/README.md Normal file
View file

@ -0,0 +1,344 @@
# v6proxy Host - IPv6 Gateway
IPv6 gateway proxy hosted on Hetzner VPS, forwarding all IPv6 traffic to the main IPv4 proxy.
## Overview
- **Hostname**: v6proxy
- **IPv4 Address**: 178.104.18.93/32
- **IPv6 Address**: 2a01:4f8:1c19:96f8::1/64
- **Type**: Hetzner VPS (Full VM)
- **Services**: HAProxy (IPv6 to IPv4 forwarding)
- **Role**: IPv6 gateway for StuRa HTW Dresden infrastructure
## Architecture
The v6proxy serves as an IPv6 gateway because the main infrastructure at 141.56.51.0/24 is IPv4-only:
- All IPv6 DNS records (AAAA) point to this host (2a01:4f8:1c19:96f8::1)
- HAProxy forwards all IPv6 HTTP/HTTPS traffic to the main proxy at 141.56.51.1
- The main proxy then handles routing to backend services
- Simple pass-through configuration - no SNI inspection or routing logic
## Why This Host Exists
The HTW Dresden network (141.56.51.0/24) does not have native IPv6 connectivity. This Hetzner VPS provides:
1. **IPv6 connectivity**: Public IPv6 address for all services
2. **Transparent forwarding**: All traffic is forwarded to the IPv4 proxy
3. **No maintenance overhead**: Simple configuration, no routing logic
This allows all StuRa services to be accessible via IPv6 without requiring IPv6 support in the HTW network.
## Services
### HAProxy
HAProxy runs in simple TCP forwarding mode:
**HTTP (Port 80)**
- Binds to IPv6 `:::80`
- Forwards all traffic to `141.56.51.1:80`
- No HTTP inspection or routing
**HTTPS (Port 443)**
- Binds to IPv6 `:::443`
- Forwards all traffic to `141.56.51.1:443`
- No SNI inspection or TLS termination
**Key features:**
- Logging: All connections logged to systemd journal
- Stats page: Available at http://127.0.0.1:8404/stats (localhost only)
- Max connections: 50,000
- Buffer size: 32,762 bytes
- Timeouts: 5s connect, 30s client/server
### Configuration Philosophy
Unlike the main proxy at 141.56.51.1, this proxy is **intentionally simple**:
- No SNI inspection
- No HTTP host header routing
- No ACME challenge handling
- Just pure TCP forwarding
All routing logic happens at the main IPv4 proxy. This keeps the v6proxy configuration minimal and reduces maintenance burden.
## Deployment Type
The v6proxy is a **Hetzner VPS** (full VM):
- Hosted outside HTW network
- Uses Hetzner-specific disk layout (hetzner-disk.nix)
- Network interface: `eth0`
- Both IPv4 and IPv6 connectivity
## Network Configuration
### IPv4
- **Address**: 178.104.18.93/32
- **Gateway**: 172.31.1.1
- **Interface**: eth0
### IPv6
- **Address**: 2a01:4f8:1c19:96f8::1/64
- **Gateway**: fe80::1 (link-local)
- **Route**: Default route via fe80::1
- **Interface**: eth0
### DNS
- **Nameservers**: 9.9.9.9, 1.1.1.1 (Quad9 and Cloudflare)
- Uses public DNS servers (not HTW internal DNS)
### Firewall
- **Firewall**: nftables enabled
- **Open ports**: 22, 80, 443
## DNS Configuration
For IPv6 support, configure AAAA records pointing to this host:
```
proxy.htw.stura-dresden.de AAAA 2a01:4f8:1c19:96f8::1
*.htw.stura-dresden.de CNAME proxy.htw.stura-dresden.de
```
This provides IPv6 access to all services while IPv4 traffic continues to use the main proxy (141.56.51.1).
## Deployment
See the [main README](../../README.md) for deployment methods.
### Initial Installation
**Using nixos-anywhere (recommended):**
```bash
nix run github:nix-community/nixos-anywhere -- --flake .#v6proxy --target-host root@178.104.18.93
```
This handles disk partitioning via disko automatically.
### Updates
```bash
# From local machine
nixos-rebuild switch --flake .#v6proxy --target-host root@178.104.18.93
# Or use auto-generated script
nix run .#v6proxy-update
```
## Disko Configuration
The v6proxy uses the Hetzner-specific disk layout (hetzner-disk.nix):
- **Filesystem**: Btrfs or Ext4 (Hetzner default)
- Declarative disk management via disko
- Automatic partitioning on installation
## Traffic Flow
IPv6 request flow:
1. Client connects to `2a01:4f8:1c19:96f8::1` (v6proxy)
2. v6proxy forwards to `141.56.51.1:443` (main IPv4 proxy)
3. Main proxy performs SNI inspection and routes to backend
4. Backend responds through the chain
For the client, the IPv6 connectivity is transparent - they don't know the backend infrastructure is IPv4-only.
## HAProxy Configuration
The HAProxy configuration is minimal:
```haproxy
frontend http-in
bind :::80
use_backend http_80
frontend sni_router
bind :::443
mode tcp
use_backend http_443
backend http_80
mode http
server proxy 141.56.51.1:80
backend http_443
mode tcp
server proxy 141.56.51.1:443
```
This is intentionally simple - all routing intelligence is at 141.56.51.1.
## HAProxy Stats
Access HAProxy statistics page (localhost only):
```bash
# SSH into v6proxy
ssh root@178.104.18.93
# Access stats via curl
curl http://127.0.0.1:8404/stats
# Or forward port to your local machine
ssh -L 8404:127.0.0.1:8404 root@178.104.18.93
# Then browse to http://localhost:8404/stats
```
The stats page shows:
- Current connections to main proxy backend
- Traffic statistics
- Connection status
## Monitoring
### Check HAProxy Status
```bash
# HAProxy service status
systemctl status haproxy
# View HAProxy logs
journalctl -u haproxy -f
# Check configuration
haproxy -c -f /etc/haproxy/haproxy.cfg
```
### Test Connectivity
```bash
# Test IPv6 HTTP forwarding
curl -6 -v http://[2a01:4f8:1c19:96f8::1]/
# Test IPv6 HTTPS forwarding
curl -6 -vk https://[2a01:4f8:1c19:96f8::1]/
# Test backend connectivity (IPv4 to main proxy)
curl -v http://141.56.51.1/
curl -vk https://141.56.51.1/
# Check IPv6 routing
ip -6 route show
ping6 2a01:4f8:1c19:96f8::1
```
## Troubleshooting
### HAProxy not starting
```bash
# Check HAProxy status
systemctl status haproxy
# Check configuration syntax
haproxy -c -f /etc/haproxy/haproxy.cfg
# View HAProxy logs
journalctl -u haproxy -f
```
### IPv6 connectivity issues
```bash
# Verify IPv6 address is configured
ip -6 addr show eth0
# Check IPv6 routing
ip -6 route show
# Test IPv6 connectivity
ping6 2606:4700:4700::1111 # Cloudflare DNS
# Check IPv6 firewall rules
nft list ruleset | grep ip6
```
### Backend (main proxy) unreachable
```bash
# Test IPv4 connectivity to main proxy
ping 141.56.51.1
curl -v http://141.56.51.1/
curl -vk https://141.56.51.1/
# Check HAProxy backend status
curl http://127.0.0.1:8404/stats | grep proxy
# View connection errors
journalctl -u haproxy | grep -i error
```
### DNS not resolving
```bash
# Check nameserver configuration
cat /etc/resolv.conf
# Test DNS resolution
dig git.adm.htw.stura-dresden.de A
dig git.adm.htw.stura-dresden.de AAAA
# Test with specific nameserver
dig @9.9.9.9 git.adm.htw.stura-dresden.de
```
## Security Considerations
- **No TLS termination**: Traffic is passed through encrypted to main proxy
- **No deep packet inspection**: Simple TCP forwarding only
- **Minimal attack surface**: No routing logic or service-specific configuration
- **Public IPv6 address**: Exposed to the internet, firewall must be properly configured
## Performance Considerations
- **Additional hop**: IPv6 traffic goes through an extra proxy hop
- **Latency**: Hetzner → HTW network adds some latency
- **Bandwidth**: Hetzner provides high bandwidth, unlikely to be a bottleneck
- **Connection limits**: HAProxy configured for 50,000 concurrent connections
For most use cases, the additional latency is negligible (typically <10ms within Germany).
## Cost and Hosting
- **Provider**: Hetzner Cloud
- **Type**: VPS (Virtual Private Server)
- **Location**: Germany (likely Falkenstein or Helsinki datacenter)
- **Cost**: Minimal - basic VPS tier sufficient for forwarding traffic
## Future Improvements
Possible improvements (not currently needed):
1. **Native IPv6 at HTW**: If HTW network gains IPv6, this proxy can be decommissioned
2. **GeoDNS**: Use GeoDNS to route IPv4 and IPv6 separately
3. **Monitoring**: Add automated monitoring and alerting
4. **Failover**: Add a second IPv6 proxy for redundancy
## Files and Directories
- **HAProxy config**: `/etc/haproxy/haproxy.cfg` (generated by Nix)
- **Disk config**: `./hetzner-disk.nix` (disko configuration)
- **Hardware config**: `./hardware-configuration.nix` (Hetzner VPS hardware)
- **NixOS config**: `./default.nix` (v6proxy configuration)
## Relationship to Main Proxy
| Feature | v6proxy (IPv6 Gateway) | proxy (Main Proxy) |
|---------|------------------------|-------------------|
| IP Version | IPv4 + IPv6 | IPv4 only |
| Location | Hetzner Cloud | HTW network (141.56.51.0/24) |
| Function | Simple forwarding | SNI routing, service routing |
| Complexity | Minimal | Complex routing logic |
| HAProxy Mode | TCP forwarding | TCP + HTTP with SNI inspection |
| TLS Handling | Pass-through | Pass-through (SNI inspection) |
| ACME Handling | None | Forwards challenges to backends |
The v6proxy is intentionally minimal - all intelligence lives at the main proxy.
## See Also
- [Main README](../../README.md) - Deployment methods and architecture
- [Proxy README](../proxy/README.md) - Main IPv4 proxy configuration
- [HAProxy Documentation](http://www.haproxy.org/#docs)
- [Hetzner Cloud Docs](https://docs.hetzner.com/cloud/)