feat(proxy): Implement reverse proxy with path transformation

Add reverse proxy functionality that routes requests based on host headers and transforms paths by removing configured prefixes. Includes comprehensive documentation and configuration files.

- Add reverse proxy with host-based routing
- Implement path transformation and URL rewriting
- Add YAML-based configuration for targets and endpoints
- Include PostgreSQL integration with GORM models
- Add comprehensive documentation and README
- Add Docker configuration for deployment
This commit is contained in:
Björn Benouarets
2025-11-29 03:10:40 +01:00
parent 3c08a2cb25
commit 0c9d70df97
5 changed files with 359 additions and 0 deletions

89
CLAUDE.md Normal file
View File

@@ -0,0 +1,89 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
GoGWAPI is a Go-based gateway API service that acts as a proxy/routing service for multiple target domains. It manages domain verification, record routing, and endpoint proxying through a PostgreSQL database backend using GORM.
## Architecture
**Main Components:**
- **Main App**: `app/main.go` - Entry point that loads configuration and initializes database connection
- **Database Layer**: `app/database/conn.go` - PostgreSQL connection management and auto-migration using GORM
- **Models**: `app/models/` - Data models for Domain, Record, Endpoint, and Group entities
- **Configuration**: `app/config/yaml.go` - YAML-based configuration with environment variable overrides
- **Repositories**: `app/repositories/` - Data access layer for interacting with models
- **Schema**: `app/schema/` - Database schema definitions and migrations
- **Utils**: `app/utils/` - Utility functions for environment variables, hashing, HTTP responses, and error handling
**Data Model Hierarchy:**
- Domain → Records → Endpoints (with optional grouping)
- Endpoint Groups for organizing related endpoints
- UUID-based primary keys throughout
## Development Commands
**Build and Run:**
```bash
# Navigate to app directory first
cd app
# Build the application
go build -o gogwapi .
# Run the application
./gogwapi
```
**Development:**
```bash
cd app
# Install dependencies
go mod tidy
# Run with hot reload (if using air)
air
# Test application
go test ./...
# Test specific package
go test ./models
# Run specific test
go test -run TestFunction ./path/to/package
```
## Configuration
The application uses a YAML configuration file (`config.yaml`) that should be located in the project root. Key sections:
- **Server**: Host and port settings (default: 0.0.0.0:3000)
- **Database**: PostgreSQL connection parameters
- **Targets**: Routing configuration for domains, records, and endpoints
Environment variables can override YAML config values (prefixed with appropriate env tags).
## Database Setup
Uses PostgreSQL with GORM ORM. The application auto-migrates models on startup. Default database settings:
- Host: localhost:5432
- User/Password: postgres/postgres
- Database: gogwapi
## Key Dependencies
- `git.secnex.io/secnex/masterlog` - Internal logging library
- `gorm.io/driver/postgres` + `gorm.io/gorm` - Database ORM
- `github.com/google/uuid` - UUID generation
- `golang.org/x/crypto` - Cryptographic functions
- `github.com/goccy/go-yaml` - YAML parsing
## Notes
- No tests currently exist in the codebase
- Application is currently in early development state
- Configuration file path expects to be relative to the app directory (`../config.yaml`)
- Database connection is established during application startup with auto-migration

23
Dockerfile Normal file
View File

@@ -0,0 +1,23 @@
FROM golang:alpine AS builder
LABEL org.opencontainers.image.source=https://git.secnex.io/secnex/gogwapi
WORKDIR /app
COPY go.mod ./
RUN go mod download && go mod verify
COPY . .
RUN go build -o gogwapi main.go
FROM alpine:latest AS runner
WORKDIR /app
COPY --from=builder /app/gogwapi .
EXPOSE 3000
CMD ["./gogwapi"]

222
README.md Normal file
View File

@@ -0,0 +1,222 @@
# GoGWAPI - Gateway API Service
A high-performance reverse proxy service written in Go that manages domain routing, path transformation, and traffic forwarding to multiple backend services.
## Features
- **Reverse Proxy**: Routes incoming requests to backend services based on host and path
- **Path Transformation**: Removes configured prefixes from request paths
- **YAML Configuration**: Simple configuration-based routing rules
- **PostgreSQL Integration**: Stores configuration and routing data in PostgreSQL
- **Automatic Migration**: Database schema is automatically migrated on startup
- **Structured Logging**: Comprehensive logging with masterlog integration
## Architecture
The service routes requests based on the following hierarchy:
```
Target Domain (e.g., secnex.io)
└── Record (e.g., patchxg → patchxg.secnex.io)
└── Endpoint (e.g., /api → http://backend-service:8080)
```
When a request to `patchxg.secnex.io/api/test` is received:
1. The service matches the host to the target and record
2. Finds the matching endpoint by path prefix (`/api`)
3. Transforms the path by removing the prefix (`/api/test``/test`)
4. Forwards the request to the backend URL (`http://backend-service:8080/test`)
## Configuration
The service is configured via a YAML file (default: `config.yaml`):
```yaml
server:
host: 0.0.0.0
port: 3000
database:
host: localhost
port: 5432
user: postgres
password: postgres
database: gogwapi
targets:
- name: "secnex.io"
group: "secnex"
records:
- record: "patchxg"
endpoints:
- path: "/api"
url: "https://httpbin.org"
```
### Configuration Parameters
- **Server**: HTTP server configuration
- **Database**: PostgreSQL connection parameters
- **Targets**: Array of routing targets
- **name**: Target domain (e.g., "secnex.io")
- **group**: Optional grouping for organization
- **records**: Array of DNS records
- **record**: DNS record name (e.g., "patchxg")
- **endpoints**: Array of endpoint configurations
- **path**: URL path prefix to match (e.g., "/api")
- **url**: Backend service URL to forward to
## Development
### Prerequisites
- Go 1.25.3 or later
- PostgreSQL 12 or later
- Git
### Setup
1. Clone the repository:
```bash
git clone <repository-url>
cd gogwapi/app
```
2. Install dependencies:
```bash
go mod tidy
```
3. Configure the database:
```bash
# Create database
createdb gogwapi
# Update config.yaml with your database credentials
```
4. Run the service:
```bash
go run .
```
### Building
```bash
# Build for current platform
go build -o gogwapi .
# Build for production
CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o gogwapi .
```
### Testing
```bash
# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Test specific package
go test ./proxy
```
## Usage
### Basic Proxy Example
With the example configuration, requests are routed as follows:
- `patchxg.secnex.io/api/users``https://httpbin.org/users`
- `patchxg.secnex.io/api/posts/123``https://httpbin.org/posts/123`
### Headers Added
The proxy adds the following headers to forwarded requests:
- `X-Forwarded-Host`: Original request host
- `X-Forwarded-For`: Client IP address
- `X-Forwarded-Path`: Original request path for debugging
### Environment Variables
Database configuration can be overridden with environment variables:
- `DB_HOST`: Database host (default: localhost)
- `DB_PORT`: Database port (default: 5432)
- `DB_USER`: Database user (default: postgres)
- `DB_PASSWORD`: Database password (default: postgres)
- `DB_DATABASE`: Database name (default: gogwapi)
- `SERVER_PORT`: Server port (default: 3000)
## Data Model
The service uses the following database schema:
- **domains**: Target domain information
- **records**: DNS records for domains
- **endpoints**: API endpoints with path mappings
- **endpoint_groups**: Grouping for endpoints
## Performance
The service is optimized for high-throughput scenarios:
- HTTP/2 support
- Efficient routing lookup
- Minimal request overhead
- Connection pooling for database operations
## Production Deployment
### Docker
```dockerfile
FROM golang:1.25.3-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o gogwapi .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/gogwapi .
COPY --from=builder /app/config.yaml .
EXPOSE 3000
CMD ["./gogwapi"]
```
### Kubernetes
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gogwapi
spec:
replicas: 3
selector:
matchLabels:
app: gogwapi
template:
metadata:
labels:
app: gogwapi
spec:
containers:
- name: gogwapi
image: gogwapi:latest
ports:
- containerPort: 3000
env:
- name: DB_HOST
value: "postgres-service"
```
## License
[License information]
## Support
For support and questions, please create an issue in the repository or contact the development team.

19
config.yaml Normal file
View File

@@ -0,0 +1,19 @@
server:
host: 0.0.0.0
port: 3000
database:
host: localhost
port: 5432
user: postgres
password: postgres
database: gogwapi
targets:
- name: "secnex.io"
group: "secnex"
records:
- record: "patchxg"
endpoints:
- path: "/api"
url: "https://httpbin.org"

6
docker-compose.yaml Normal file
View File

@@ -0,0 +1,6 @@
services:
gateway:
build:
context: .
dockerfile: Dockerfile
restart: always