System Architecture
A visual explanation of Nginx Proxy Guard's internal structure and data flow.
Architecture Diagram
┌─────────────────────────────────────────────────────────────────────┐
│ Internet │
└─────────────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Nginx Proxy (Port 80/443) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ Rate Limit │ │ModSecurity │ │ Bot Filter │ │ Geo Block │ │
│ │ │ │ WAF+CRS4 │ │ 130+ Sigs │ │ GeoIP2 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ SSL/TLS │ │ Fail2ban │ │ Challenge │ │ URI Block │ │
│ │HTTP/2 HTTP/3│ │ Auto-Ban │ │ CAPTCHA │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ Headers │ │ Cloud IP │ │ Caching │ │ Exploit │ │
│ │ Security │ │ Block │ │ Compression │ │ Block │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │
└─────────────────────────────┬───────────────────────────────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Backend 1 │ │ Backend 2 │ │ Backend N │
│ │ │ │ │ │
└───────────┘ └───────────┘ └───────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ Management Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────────┐ │
│ │ React UI │◄─│ Go API │◄─│ PostgreSQL │ │ Valkey │ │
│ │ (Port 81) │ │ (Port 8080) │ │ 17 │ │ (Redis) │ │
│ │ TypeScript │ │ Echo v4 │ │ │ │ Cache │ │
│ │ Tailwind │ │ JWT+TOTP │ │ │ │ Ban List │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Docker Services
| Service | Container | Image | Description | Ports |
|---|---|---|---|---|
nginx | npg-proxy | Custom Build | Reverse proxy + WAF + GeoIP + HTTP/3 (host network mode) | 80, 443 (TCP/UDP) |
ui | npg-ui | Custom Build | React web interface | 81→443 |
api | npg-api | Custom Build | Go backend API | 127.0.0.1:9080→8080 (internal) |
db | npg-db | timescale/timescaledb:latest-pg17 | Database (TimescaleDB) | 5432 (internal) |
valkey | npg-valkey | valkey/valkey:9-alpine | Cache (Redis compatible) | 6379 (internal) |
Note: The
nginxcontainer runs in host network mode so it sees real client IPs directly without a proxy protocol. The other services run on thenpg-networkbridge network.
Technology Stack
Backend
| Technology | Version | Purpose |
|---|---|---|
| Go | 1.26 | Backend API server |
| Echo | v4.15 | Web framework |
| PostgreSQL | 17 | Relational database |
| Valkey | 9 | Cache and session management |
| JWT | - | Stateless authentication |
| TOTP | - | Two-factor authentication |
Frontend
| Technology | Version | Purpose |
|---|---|---|
| React | 19 | UI framework |
| TypeScript | 6 | Type safety |
| Vite | 8 (Rolldown) | Build tooling |
| Tailwind CSS | 4 | Styling |
| TanStack Query | v5 | Server state management |
| React Router | v7 | Client-side routing |
| Recharts | - | Data visualization |
| react-simple-maps | - | GeoIP map |
Proxy & Security
| Technology | Version | Purpose |
|---|---|---|
| Nginx | 1.30.2 | Web server / reverse proxy |
| ModSecurity | v3.0.15 | WAF engine |
| OWASP CRS | v4.26.0 | WAF rule set |
| MaxMind GeoIP2 | - | Region-based access control |
| Brotli/Zstd | - | Advanced compression |
| HTTP/3 (QUIC) | - | Next-generation protocol |
Key Libraries
| Library | Purpose |
|---|---|
| lego/v4 | ACME/Let's Encrypt client |
| geoip2-golang | MaxMind GeoIP2 parsing |
| go-redis/v9 | Redis/Valkey client |
| gopsutil/v3 | System monitoring |
| lib/pq | PostgreSQL driver |
Data Flow
Request Processing Flow
Client Request
↓
┌──────────────────────────────────────────┐
│ Nginx (Layer 1) │
│ 1. Rate Limiting Check │
│ 2. Check IP blocklist │
│ 3. Check GeoIP geo-restriction │
│ 4. Bot Filter check │
│ 5. Challenge (CAPTCHA) check │
│ 6. Cloud Provider IP block │
│ 7. Check URI block rules │
└──────────────────────────────────────────┘
↓ (if passed)
┌──────────────────────────────────────────┐
│ ModSecurity WAF (Layer 2) │
│ 1. OWASP CRS rule check │
│ 2. SQL Injection detection │
│ 3. XSS detection │
│ 4. Path Traversal detection │
│ 5. Command Injection detection │
└──────────────────────────────────────────┘
↓ (if passed)
┌──────────────────────────────────────────┐
│ Proxy Handling (Layer 3) │
│ 1. SSL/TLS termination │
│ 2. Caching and compression │
│ 3. Add security headers │
└──────────────────────────────────────────┘
↓
Backend Server
Management Interface Flow
Admin Browser
↓
┌──────────────────────────────────────────┐
│ React UI (Port 81) │
│ - SPA rendering │
│ - TanStack Query state management │
└──────────────────────────────────────────┘
↓ (API request)
┌──────────────────────────────────────────┐
│ Go API (Port 8080) │
│ - JWT authentication │
│ - TOTP 2FA verification │
│ - Business logic │
└──────────────────────────────────────────┘
↓
┌──────────────────────────────────────────┐
│ Data Layer │
│ PostgreSQL: config, logs, certificates │
│ Valkey: cache, blocklist, sessions │
└──────────────────────────────────────────┘
↓
┌──────────────────────────────────────────┐
│ Nginx Config Apply │
│ - Generate conf.d/ files │
│ - nginx -s reload │
└──────────────────────────────────────────┘
Security Layers
Layer 1: Network Level
- Rate Limiting (requests per second)
- IP blocking (Fail2ban, WAF, manual)
- GeoIP region restriction
- Cloud provider IP blocking
Layer 2: Application Level
- Bot filtering (130+ signatures)
- URI blocking
- CAPTCHA challenge
- Security headers
Layer 3: WAF Level
- ModSecurity v3
- OWASP CRS v4.26.0
- Paranoia Level 1-4
- Custom rules
Layer 4: Authentication/Authorization
- JWT token authentication
- TOTP 2FA
- API token permission management
- Audit logging
Scheduler (Background Jobs)
| Job | Interval | Description |
|---|---|---|
| Certificate Renewal | 6 hours | Let's Encrypt automatic renewal |
| Log Partitioning | Daily | Create monthly log table partitions |
| Log Rotation | Daily | Rotate raw log files |
| GeoIP Update | As configured | MaxMind DB automatic update |
| IP Block Expiry | 1 minute | Release expired IP blocks |
| Challenge Token Cleanup | 1 hour | Delete expired CAPTCHA tokens |
| DDNS Sync | As configured (min 1 minute) | Check public IP and update DDNS records |
| Filter Subscription Refresh | Per-subscription interval | Re-fetch external IP/CIDR blocklists |
| Backup | As configured | Automatic DB + config backup |
Database Partitioning
Monthly partitioning is used to efficiently manage large volumes of log data.
-- Log table structure
logs (parent table)
├── logs_2024_01
├── logs_2024_02
├── ...
└── logs_2024_12
system_logs (parent table)
├── system_logs_2024_01
└── ...
Network Configuration
┌─────────────────────────────────────────┐
│ Docker Network │
│ (npg-network, bridge) │
│ │
│ api ◄──► db │
│ ▲ │
│ └───► valkey │
│ ▲ │
│ └──────────► ui │
│ │
└─────────────────────────────────────────┘
│ (nginx runs in host network mode)
▼
nginx (host network) ──► api
Host ports: 80, 443 (nginx), 81 (ui)