rvs-prxy/Design_Doc/architecture.md

276 lines
11 KiB
Markdown

# Generic Reverse Proxy Architecture
## Overview
This document describes a generic reverse proxy architecture that enables internal services to be accessible via public domains. The architecture uses FRP (Fast Reverse Proxy) for tunneling and Traefik for HTTP/HTTPS routing with automatic certificate management.
## Architecture Block Diagram
```
+-------------------+ SSH Commands +-------------------+
| Local Host | ------------------> | Proxy Server |
| | | |
| +-------------+ | FRP Tunnel | +-------------+ |
| | Application | | ------------------> | | FRPS | |
| | Service | | | | (Server) | |<--- Public IPs
| | | | | | | | Port: 16999
| +-------------+ | | +-------------+ |
| | | |
| +-------------+ | FRP Client | +-------------+ |
| | FRPC | | ------------------> | | Traefik | |<--- Domains
| | (Client) | | | | (Router) | | HTTPS/TLS
| | | | | | | |
| +-------------+ | | +-------------+ |
| | | |
| +-------------+ | | +-------------+ |
| | Docker | | | | Docker | |
| | Container | | | | Container | |
| +-------------+ | | +-------------+ |
+-------------------+ +-------------------+
| |
| |
+------------------ Volumes ------------------+
| rad-git-sshd-itl-frpc-<instance> |
+-------------------------------------------+
```
## Architecture Components
### Core Components
- **FRP (Fast Reverse Proxy)**: Handles TCP/UDP tunneling between internal and external networks
- FRPS (FRP Server): Runs on the public-facing server
- FRPC (FRP Client): Runs on internal service hosts
- **Traefik**: HTTP/HTTPS router with automatic Let's Encrypt certificate management
- **Docker & Docker Compose**: Container orchestration and deployment
- **SSH**: Secure communication for remote configuration management
### Supporting Elements
- **Configuration Storage**: Docker volumes for persistent configuration
- **DNS Management**: Domain-to-IP mapping for public access
- **Certificate Management**: Automatic SSL/TLS certificate provisioning and renewal
## Prerequisites
- FRP (Fast Reverse Proxy) service with frpc and frps
- Traefik reverse proxy
- Docker and Docker Compose installed
- SSH key for remote server access
- Environment variable for configuration source (DOWNLOAD_SOURCE)
- User permissions for Docker commands
- Authentication keys for secure access
## Parameters
### Required Parameters
- **Instance Name**: Unique identifier for the service instance (alphanumeric, hyphens, underscores only)
- **Application Port(s)**: Internal port(s) where the service is listening
- **Domain Name**: Public domain for Traefik routing rules
- **FRP Server Address**: Public IP address of the FRP server
- **FRP Server Port**: Port for FRP communication (default 16999)
### Optional Parameters
- **Docker Network**: Network for container isolation (default uses Docker bridge)
- **Proxy Ports**: Custom remote ports for external access (defaults: TCP ports matching internal ports)
- **Service Type**: Protocol specification (TCP/UDP/HTTP/HTTPS)
## Outcomes
- Public domain connectivity to internal service
- Secure encrypted tunnel between internal and external networks
- Automatic SSL/TLS certificates via Let's Encrypt
- Persistent configuration through Docker volumes
- Automated service discovery and routing
## Architecture Flow
### 1. Configuration Phase
1. User provides service parameters via interactive prompts or command-line
2. System validates parameters and checks for existing configurations
3. Generates appropriate FRP client configuration (frpc.toml)
4. Persists configuration to Docker volumes for continuity
### 2. Deployment Phase
1. Creates Docker container with FRP client
2. Establishes connection to FRP server
3. Sets up port forwarding rules
4. Updates proxy server to recognize new instance
### 3. Routing Phase
1. Traefik configuration updated with new routing rules
2. Domain name routes to appropriate internal service
3. Automatic SSL/TLS certificate provisioned
4. Health checks and monitoring established
### 4. Management Phase
1. Persistent configuration for service continuity
2. Backup and recovery mechanisms
3. Restart procedures for configuration changes
4. Service status monitoring
## Real-World Example: Using auto-sys-deploy.sh and update-compose-config.sh
### Example: Deploying a New FRP Client Instance
Based on `auto-sys-deploy.sh.md` and `update-compose-config.sh.md`, here's a real-world example of the architecture in action:
#### Initial Setup
- **Prerequisites**: Docker, SSH key at `~/.ssh/itl-devs1`, `DOWNLOAD_SOURCE` environment variable
- **Command**: `./auto-sys-deploy.sh setup-frpc`
#### Interactive Configuration (from auto-sys-deploy.sh)
1. **Instance Name Selection**:
- Default: `setup-frpc-$(date +%Y%m%d-%H%M%S)`
- User input: `my-app-instance-20231005-143000`
- Validation: alphanumeric, hyphens, underscores only
2. **Docker Network Selection**:
- Options: Select from existing networks, custom network, or default
- User input: Select network `bridge` or create custom
- Outcome: Container runs on specific Docker network
3. **FRP Server Configuration**:
- Server Address: `192.168.1.100` (example IP)
- Server Port: `16999` (default)
- Validation: Ensure server is accessible
4. **Proxy Configuration**:
- **Rad Proxy** (from auto-sys-deploy.sh):
- Local Port: `8776` (default)
- Remote Port: `8779` (user input)
- Name: `rad-my-app-instance-20231005-143000`
- **SSH Proxy** (from auto-sys-deploy.sh):
- Local Port: `22` (default)
- Remote Port: `13076` (user input)
- Name: `ssh-my-app-instance-20231005-143000`
- **Web Proxy** (from auto-sys-deploy.sh):
- Local Port: `80` (default)
- Remote Port: `13077` (user input)
- Name: `web-my-app-instance-20231005-143000`
5. **Domain Configuration**:
- Input: `myapp.example.com`
- Used for Traefik routing rules
#### Configuration Generation (from auto-sys-deploy.sh)
The script generates `frpc.toml` with:
```toml
serverAddr = "192.168.1.100"
serverPort = 16999
[[proxies]]
name = "rad-my-app-instance-20231005-143000"
type = "tcp"
localPort = 8776
localIP = "rad-git-sshd-my-app-instance-20231005-143000"
remotePort = 8779
[[proxies]]
name = "ssh-my-app-instance-20231005-143000"
type = "tcp"
localPort = 22
localIP = "rad-git-sshd-my-app-instance-20231005-143000"
remotePort = 13076
[[proxies]]
name = "web-my-app-instance-20231005-143000"
type = "tcp"
localPort = 80
localIP = "rad-git-sshd-my-app-instance-20231005-143000"
remotePort = 13077
```
#### Container Deployment (from auto-sys-deploy.sh)
- Creates Docker volume: `rad-git-sshd-itl-frpc-my-app-instance-20231005-143000`
- Starts container: `rad-git-sshd-frpc-my-app-instance-20231005-143000`
- Uses image: `snowdreamtech/frpc:0.62.0-alpine3.21`
- Mounts config volume: `/etc/frp`
#### Proxy Server Configuration (from update-compose-config.sh)
The script updates `docker-compose.app.yml` with:
**Ports Section:**
```yaml
ports:
# ... other ports ...
# my-app-instance-20231005-143000 Self-hosting ports ====
- "8779:8779/tcp"
- "13076:13076/tcp"
- "13077:13077/tcp"
# =========================
# ... other ports ...
```
**Labels Section:**
```yaml
labels:
# ... other labels ...
# my-app-instance-20231005-143000 Self-hosting labels ====
- "traefik.http.routers.frps-my-app-instance-20231005-143000-http.entrypoints=web"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-http.rule=Host(`myapp.example.com`)"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-http.service=frps-my-app-instance-20231005-143000"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-http.middlewares=http2https@file"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-https.entrypoints=websecure"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-https.rule=Host(`myapp.example.com`)"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-https.service=frps-my-app-instance-20231005-143000"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-https.tls=true"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-https.tls.certresolver=letsencrypt"
- "traefik.http.routers.frps-my-app-instance-20231005-143000-https.tls.domains[0].main=myapp.example.com"
- "traefik.http.services.frps-my-app-instance-20231005-143000.loadbalancer.server.port=13077"
# =========================
# ... other labels ...
```
#### Backup and Service Restart (from update-compose-config.sh)
- Creates backup: `docker-compose.app.yml.backup_YYYYMMDD_HHMMSS`
- Restarts service with: `./stop.sh && ./start.sh`
- Verifies deployment with: `docker logs --tail 50 frps_frps_1`
## Extensibility Points
### Protocol Support
- **TCP/UDP**: Native FRP support for any TCP/UDP based service
- **HTTP/HTTPS**: Enhanced routing via Traefik with automatic certificates
- **Custom Protocols**: Extensible architecture for proprietary protocols
### Service Types
- **Web Applications**: HTTP/HTTPS routing with domain-based access
- **Database Services**: Secure TCP tunneling for database connections
- **SSH Services**: Encrypted access to internal SSH servers
- **API Services**: Secure API endpoint exposure
### Scaling Options
- **Load Balancing**: Multiple instances behind single domain
- **Geographic Distribution**: Multiple proxy servers in different regions
- **Protocol Multiplexing**: Multiple services through single tunnel
## Security Considerations
- Encrypted tunnels between internal and external networks
- Access control through SSH keys and authentication
- Firewall isolation of internal services
- Automatic certificate management for HTTPS
- Docker container isolation
## Maintenance Requirements
- Regular backup of configuration files
- Certificate renewal monitoring
- Connection health monitoring
- Log aggregation and analysis
- Docker image updates
## Generic Application Examples
### Web Application Deployment
- **Parameters**: Instance name, internal web port (80/443), domain name
- **Outcome**: Public website accessible via configured domain
### Database Access
- **Parameters**: Instance name, internal database port, restricted domain
- **Outcome**: Secure external access to internal database
### Custom Service Exposure
- **Parameters**: Instance name, custom application port, specific domain
- **Outcome**: External access to internal custom service