rvs-prxy/Design_Doc/architecture.md

317 lines
14 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
- SSH key at `~/.ssh/itl-devs1` for proxy server access
- 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)
- **Internal Service Port**: The port exposed by the target Docker container (e.g., 3000)
- **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 connecting to internal service container (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)
### Environment Configuration
The architecture supports environment-based configuration using `.env` files to provide default values:
- **Environment Files**: `.env`, `.env.development`, `.env.production`
- **Default Values**: Parameters from environment files are used as defaults during script execution
- **Interactive Fallback**: If parameters are missing from environment files, scripts will prompt for input
- **Auto-Persistence**: Answered parameters are automatically saved to the appropriate `.env` file for future use
- **Supported Variables**:
- `INSTANCE_NAME`: Default instance name
- `INTERNAL_SERVICE_PORT`: Port exposed by the target Docker container (e.g., 3000)
- `DOCKER_NETWORK`: Docker network for connecting to internal service container
- `FRP_SERVER_ADDR`: FRP server address
- `FRP_SERVER_PORT`: FRP server port (default 16999)
- `DOMAIN_NAME`: Default domain name
- `RAD_REMOTE_PORT`: Remote port for rad proxy (default 8779)
- `SSH_REMOTE_PORT`: Remote port for SSH proxy (default 13076)
- `WEB_REMOTE_PORT`: Remote port for web proxy (default 13077)
- `PROXY_*_PORT`: Dynamic proxy configuration (e.g., `PROXY_API_PORT=8080`)
- `PROXY_*_LOCAL_PORT`: Local port for the corresponding proxy (e.g., `PROXY_API_LOCAL_PORT=8000`)
### Dynamic Proxy Configuration
The system supports dynamic proxy configuration through environment variables:
- **Format**: Use `PROXY_*_PORT` format to define additional proxies
- **Examples**: `PROXY_API_PORT=8080`, `PROXY_DATABASE_PORT=5432`
- **Local Port Override**: Use `PROXY_*_LOCAL_PORT` to specify a different local port
- **Flexibility**: Allows configuration of any number of application-specific proxies
### Internal Service Connection
The architecture connects to internal services on the same computer as the script execution:
- **Connection Method**: FRP client connects to target service on the same physical/virtual machine
- **Local IP**: Connection made via 127.0.0.1 (localhost) to the service port
- **Port Configuration**: Target service must be accessible on the specified port (e.g., 3000)
- **Service Discovery**: No container name resolution needed, connects directly to localhost
- **Local IP Setting**: FRP client configuration uses 127.0.0.1 as the local IP
- **Naming Convention**: Container and volume names follow the format `{INSTANCE_NAME}-frpc`
## 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`
- **Command**: `./auto-sys-deploy.sh setup-rvs-prxy`
#### Interactive Configuration (from auto-sys-deploy.sh)
1. **Instance Name Selection**:
- Default: `setup-rvs-prxy-$(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. **Dynamic Proxy Configuration**:
- Proxies are configured dynamically based on environment variables following the format `PROXY_*_PORT`
- Default rad proxy (if `RAD_REMOTE_PORT` is set):
- Local Port: `8776` (default)
- Remote Port: Value of `RAD_REMOTE_PORT` environment variable
- Name: `rad-my-app-instance-20231005-143000`
- Default SSH proxy (if `SSH_REMOTE_PORT` is set):
- Local Port: `22` (default)
- Remote Port: Value of `SSH_REMOTE_PORT` environment variable
- Name: `ssh-my-app-instance-20231005-143000`
- Default Web proxy (if `WEB_REMOTE_PORT` is set):
- Local Port: Service port or `80` (default)
- Remote Port: Value of `WEB_REMOTE_PORT` environment variable
- Name: `web-my-app-instance-20231005-143000`
- Additional proxies can be configured using `PROXY_*_PORT` environment variables
- Format: `PROXY_API_PORT=8080`, `PROXY_DATABASE_PORT=5432`, etc.
- The script will create as many proxies as defined by the environment variables
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