{"id":24351120,"url":"https://github.com/unkn0wn-root/terraster","last_synced_at":"2025-10-18T16:16:12.325Z","repository":{"id":260958874,"uuid":"882793345","full_name":"unkn0wn-root/terraster","owner":"unkn0wn-root","description":"Uncomplicated L7 Load Balancer/Reverse Proxy with Plugins support and Admin API","archived":false,"fork":false,"pushed_at":"2025-03-18T11:10:54.000Z","size":42406,"stargazers_count":32,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-18T12:24:06.496Z","etag":null,"topics":["go","golang","l7","l7-balancer","load-balancer","load-balancing","loadbalancer","networking","proxy","proxy-server"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unkn0wn-root.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-03T19:17:41.000Z","updated_at":"2025-03-18T11:10:57.000Z","dependencies_parsed_at":"2024-12-21T21:24:28.851Z","dependency_job_id":"13f1fb5b-7deb-471c-8413-2bf9040d29d7","html_url":"https://github.com/unkn0wn-root/terraster","commit_stats":null,"previous_names":["unkn0wn-root/go-load-balancer","unkn0wn-root/terraster"],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unkn0wn-root%2Fterraster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unkn0wn-root%2Fterraster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unkn0wn-root%2Fterraster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unkn0wn-root%2Fterraster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unkn0wn-root","download_url":"https://codeload.github.com/unkn0wn-root/terraster/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248127351,"owners_count":21052239,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","l7","l7-balancer","load-balancer","load-balancing","loadbalancer","networking","proxy","proxy-server"],"created_at":"2025-01-18T14:58:10.770Z","updated_at":"2025-10-18T16:16:12.319Z","avatar_url":"https://github.com/unkn0wn-root.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Terraster\n[![MIT License](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nA high-performance, feature-rich Layer 7 (L7) load balancer with a robust and user-friendly admin API.\n\n## Overview\n\n* Multiple load balancing methods including Round Robin, Weighted Round Robin, and IP Hash\n* Support for external plugins (third-party modules) for middleware (request, response)\n* TLS termination with certificate management\n* Path rewriting and service-to-service redirection\n* Dynamic configuration via comprehensive Admin API\n* Multiple host support on the same port\n* HTTP compression\n* Certificate expiration notifications via email\n* HTTP/1.1 \u0026 HTTP/2 support\n\n\n## Features\n\n### Load Balancing Algorithms\n- Round Robin\n- Weighted Round Robin\n- Least Connections\n- Weighted Least Connections\n- Response Time Based\n- IP Hash\n- Consistent Hashing\n- Adaptive Load Balancing\n- Sticky session\n- SSL/TLS Support\n- Dynamic Middleware Plug-in\n- Server Name Indication (SNI)\n- Connection Pooling\n- Circuit Breaker\n- Rate Limiting\n- Compression\n- Configurable Request Logging\n- Restrict access to API via IPs whitelist\n- Custom Request/Response Headers\n- Health Checking\n- Dynamic Configuration via Admin API\n\n## WIP\n- WebSocket Support (WIP)\n\n## Quick Start\n\n### Building from Source\n\n```bash\ngo build -o terraster cmd/terraster\n```\n\n## Configuration Guide\n\n### Configuration Methods\n\nTerraster offers three ways to manage your configuration:\n\n1. **Single Config File**\n   - Create a config file anywhere and use the `-config` flag\n   - Example: `./terraster -config /path/to/config.yaml`\n\n2. **Default Config**\n   - Place `config.yaml` in the root directory\n   - Terraster will load it automatically at startup\n\n3. **Multiple Services**\n   - Create a directory containing multiple service configs\n   - Use the `-services` flag to point to the directory\n   - Example: `./terraster -services /path/to/services/`\n\n### Basic Configuration\n\nThe minimal configuration requires only three fields:\n\n```yaml\nport: 8080\nhost: \"lb.domain.com\"\nbackends:\n  - url: http://localhost:8081\n  - url: http://localhost:8082\n```\n\n### Basic Configuration with Middleware and TLS\n\nThis configuration demonstrates TLS termination and basic middleware setup:\n\n```yaml\nport: 8080\nalgorithm: round-robin\nhost: \"lb.domain.com\"\nbackends:\n  - url: http://localhost:8081\n  - url: http://localhost:8082\n\n# Middleware Configuration\nmiddleware:\n  - rate_limit:\n      requests_per_second: 100\n      burst: 30\n  - security:\n      hsts: true\n      frame_options: DENY\n      xss_protection: true\n\n# TLS Configuration (optional)\ntls:\n  enabled: true\n  cert_file: \"./certificates/my_cert.pem\"\n  key_file: \"./certificates/my_cert_privatekey.key\"\n```\n\n### Advanced Configuration\n\nThis example demonstrates a comprehensive setup with multiple services, health checks, and advanced features:\n\n```yaml\n### GLOBAL CONFIG ###\nport: 443\n\n# Global Health Check Configuration\nhealth_check:\n  interval: 10s\n  timeout: 2s\n  path: /health\n\n# Global Middleware Configuration\nmiddleware:\n  - rate_limit:\n      requests_per_second: 100\n      burst: 150\n  - security:\n      hsts: true\n      hsts_max_age: 31536000\n      frame_options: DENY\n      content_type_options: true\n      xss_protection: true\n  - circuit_breaker:\n      threshold: 5\n      timeout: 60s\n\n# Global Connection Pool Settings\nconnection_pool:\n  max_idle: 100\n  max_open: 1000\n  idle_timeout: 90s\n\n### SERVICES CONFIGURATION ###\nservices:\n  # Backend API Service\n  - name: backend-api\n    host: internal-api1.local.com\n    port: 8455\n    log_name: backend-api  # Maps to logger configuration\n    headers:               # Custom headers\n      request_headers:\n        X-Custom-Header: \"custom-value\"\n      response_headers:\n        Cache-Control: \"no-cache\"\n      remove_request_headers:\n        - User-Agent\n        - Accept-Encoding\n      remove_response_headers:\n        - Server\n        - X-Powered-By\n\n    # Service-specific TLS\n    tls:\n      cert_file: \"/path/to/api-cert.pem\"\n      key_file: \"/path/to/api-key.pem\"\n\n    # Service-specific middleware (overrides global)\n    middleware:\n      - rate_limit:\n          requests_per_second: 2500\n          burst: 500\n\n    # Service-specific health check\n    health_check:\n      type: \"http\"\n      path: \"/\"\n      interval: \"5s\"\n      timeout: \"3s\"\n      skip_tls_verify: true # only if you don't want to health checker to verify SSL\n      thresholds:\n        healthy: 2\n        unhealthy: 3\n\n    # Path-based routing\n    locations:\n      - path: \"/api/\"\n        lb_policy: sticky-session # cookie based\n        redirect: \"/\"\n        backends:\n          - url: http://internal-api1.local.com:8455\n            weight: 5\n            max_connections: 1000\n            http2: false # use http1/1\n            sni: \"api.domain.com\"\n            # Backend-specific health check\n            health_check:\n              type: \"http\"\n              path: \"/api_health\"\n              interval: \"4s\"\n              timeout: \"3s\"\n              thresholds:\n                healthy: 1\n                unhealthy: 2\n          - url: http://internal-api2.local.com:8455\n            weight: 3\n            max_connections: 800\n            http2: false\n            sni: \"api.domain.com\"\n\n  # Frontend Service\n  - name: frontend\n    host: frontend.local.com\n    port: 443\n    locations:\n      - path: \"/\"\n        lb_policy: least_connections\n        rewrite: \"/frontend/\"\n        backends:\n          - url: http://frontend-1.local.com:3000\n            weight: 5\n            max_connections: 1000\n          - url: http://frontend-2.local.com:3000\n            weight: 3\n            max_connections: 800\n\n  # HTTP to HTTPS Redirect Service\n  - name: frontend_redirect\n    host: frontend.local.com\n    port: 80\n    http_redirect: true\n    redirect_port: 443\n\n  # Custom Port Redirect Service\n  - name: backend_api_redirect\n    host: internal-api1.local.com\n    port: 80\n    http_redirect: true\n    redirect_port: 8455\n```\n\n## Logging Configuration\n\n### 1. Default Logger\nIf no custom logging configuration is provided, Terraster will use the default logger configuration from `log.config.json`. Your services will use the `service_default` logger automatically.\n\n```json\n{\n  \"loggers\": {\n    \"terraster\": {\n      \"level\": \"debug\",\n      \"outputPaths\": [\"terraster.log\"],\n      \"errorOutputPaths\": [\"stderr\"],\n      \"development\": false,\n      \"logToConsole\": true\n    },\n    \"service_default\": {\n      \"level\": \"info\",\n      \"outputPaths\": [\"service_default.log\"],\n      \"errorOutputPaths\": [\"service_default_error.log\"],\n      \"development\": false,\n      \"logToConsole\": false\n    }\n  }\n}\n```\n\n### 2. Single Custom Logger Configuration\nCreate one custom logging configuration file for all services. Each service can reference a specific logger by name in its configuration.\n\n```json\n{\n  \"loggers\": {\n    \"api-services\": {\n      \"level\": \"info\",\n      \"outputPaths\": [\"api-services.log\"],\n      \"errorOutputPaths\": [\"api-errors.log\"],\n      \"development\": false,\n      \"logToConsole\": false,\n      \"logRotation\": {\n        \"enabled\": true,\n        \"maxSizeMB\": 50,\n        \"maxBackups\": 10,\n        \"maxAgeDays\": 30,\n        \"compress\": true\n      }\n    },\n    \"frontend-services\": {\n      \"level\": \"debug\",\n      \"outputPaths\": [\"frontend.log\"],\n      \"errorOutputPaths\": [\"frontend-errors.log\"],\n      \"development\": true,\n      \"logToConsole\": true\n    }\n  }\n}\n```\n\nUse in service configuration:\n```yaml\nservices:\n  - name: backend-api\n    log_name: api-services  # References logger name from config\n    # ... rest of service config\n\n  - name: frontend\n    log_name: frontend-services  # References logger name from config\n    # ... rest of service config\n```\n\n### 3. Separate Logger Configuration Per Service\nCreate individual log configuration files for each service. Each file must start with the `loggers` key.\n\n`backend-api.log.json`:\n```json\n{\n  \"loggers\": {\n    \"backend-api\": {\n      \"level\": \"info\",\n      \"outputPaths\": [\"backend-api.log\"],\n      \"errorOutputPaths\": [\"backend-api-error.log\"],\n      \"development\": false,\n      \"logToConsole\": false\n    }\n  }\n}\n```\n\n`frontend.log.json`:\n```json\n{\n  \"loggers\": {\n    \"frontend\": {\n      \"level\": \"debug\",\n      \"outputPaths\": [\"frontend.log\"],\n      \"errorOutputPaths\": [\"frontend-error.log\"],\n      \"development\": true,\n      \"logToConsole\": true\n    }\n  }\n}\n```\n\n### Running Terraster with Different Logging Configurations\n\n```bash\n# Using default logger\n./terraster --config config.yaml\n\n# Using single custom log config\n./terraster --config config.yaml --log_configs custom.log.json\n\n# Using separate log configs for each service\n./terraster --config config.yaml --log_configs backend-api.log.json,frontend.log.json\n\n# Using default logger and appending additional loggers\n./terraster --config config.yaml --log_configs additional.log.json\n```\n\n#### Important Notes:\n- All log config files must start with the `loggers` key\n- When using multiple config files, make sure logger names are unique\n- If no log_name is specified in service configuration, the service will use the `service_default` logger\n- You can append additional loggers to the default configuration by providing them via --log_configs\n\n## Admin API Setup\n\n### Database Configuration\n\n1. Create or use the provided API configuration file:\n\n```yaml\napi:\n  enabled: true\n  host: lb-api.domain.com\n  port: 8081\n  tls:\n    cert_file: \"./certs/admin.pem\"\n    key_file: \"./certs/admin_key.key\"\n  insecure: false # set it ONLY to true if you want to run your API via HTTP (unsecure, NOT RECOMMENDED)\n  allowed_ips:    # allow access to API only from those IP addresses (if not defined - no restrictions)\n    - 10.10.10.10\n\ndatabase:\n  path: \"./api.db\"\n\nauth:\n  jwt_secret: \"YourSecretKey\"\n  token_cleanup_interval: \"7h\"\n  password_expiry_days: 3\n```\n\n2. Create an admin user:\n\n```bash\ngo run scripts/database/api_util.go --config ./api.config.yaml \\\n  -username \"lb_admin\" \\\n  -password \"SecurePassword123\" \\\n  -role \"admin\"\n```\n\n### API Examples\n\n#### Get Backend Status\n```bash\ncurl http://localhost:8081/api/backends \\\n    -H \"Authorization: Bearer ${JWT_TOKEN}\" \\\n    -H \"Content-Type: application/json\"\n```\n\n#### Add Backend\n```bash\ncurl -X POST http://localhost:8081/api/backends?service_name=backend-api \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer ${JWT_TOKEN}\" \\\n  -d '{\n    \"url\": \"http://newbackend:8080\",\n    \"weight\": 5\n  }'\n```\n\n## Docker Deployment\n\n### Dockerfile\n```dockerfile\nFROM golang:1.21-alpine AS builder\n\nWORKDIR /app\nCOPY . .\nRUN go mod download\nRUN go build -o terraster cmd/main.go\n\nFROM alpine:latest\nRUN apk --no-cache add ca-certificates\nWORKDIR /root/\nCOPY --from=builder /app/terraster .\nCOPY config.yaml .\n\nEXPOSE 8080 8081 9090\nCMD [\"./terraster\", \"--config\", \"config.yaml\"]\n```\n\n### Docker Compose\n```yaml\nversion: '3.8'\n\nservices:\n  terraster:\n    build: .\n    ports:\n      - \"8080:8080\"\n      - \"8081:8081\"\n      - \"9090:9090\"\n    volumes:\n      - ./config.yaml:/root/config.yaml\n      - ./certs:/etc/certs\n    restart: unless-stopped\n```\n\n## Benchmarking\n\nA benchmarking script is included in the `tools/benchmark` directory. Run it with:\n\n```bash\ngo run tools/benchmark/main.go -url http://localhost:8080 -c 10 -n 1000\n```\n\nAvailable flags:\n- `-url`: Target URL (default: \"http://localhost:8080\")\n- `-c`: Number of concurrent requests (default: 10)\n- `-n`: Total number of requests (default: 1000)\n- `-d`: Duration of the test (e.g., \"30s\", \"5m\")\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funkn0wn-root%2Fterraster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funkn0wn-root%2Fterraster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funkn0wn-root%2Fterraster/lists"}