diff --git a/README.md b/README.md index 474f430..03f3327 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,22 @@ +
+ + gopher + # Tunnel Please -A lightweight SSH-based tunnel server written in Go that enables secure TCP and HTTP forwarding with an interactive terminal interface for managing connections and custom subdomains. +A lightweight SSH-based tunnel server + +

+ +[![Coverage](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=coverage&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) +[![Lines of Code](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=ncloc&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) +[![Quality Gate Status](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=alert_status&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) +[![Security Issues](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=software_quality_security_issues&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) +[![Maintainability Rating](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=software_quality_maintainability_rating&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) +[![Reliability Rating](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=software_quality_reliability_rating&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) +[![Security Rating](https://sonar.fossy.my.id/api/project_badges/measure?project=tunnel-please&metric=software_quality_security_rating&token=sqb_0feaed756b943aa75a79499d45d6610c1620830d)](https://sonar.fossy.my.id/dashboard?id=tunnel-please) + +
## Features @@ -17,108 +33,32 @@ A lightweight SSH-based tunnel server written in Go that enables secure TCP and The following environment variables can be configured in the `.env` file: -| Variable | Description | Default | Required | -|----------|-------------|---------|----------| -| `DOMAIN` | Domain name for subdomain routing | `localhost` | No | -| `PORT` | SSH server port | `2200` | No | -| `HTTP_PORT` | HTTP server port | `8080` | No | -| `HTTPS_PORT` | HTTPS server port | `8443` | No | -| `TLS_ENABLED` | Enable TLS/HTTPS | `false` | No | -| `TLS_REDIRECT` | Redirect HTTP to HTTPS | `false` | No | -| `ACME_EMAIL` | Email for Let's Encrypt registration | `admin@` | No | -| `CF_API_TOKEN` | Cloudflare API token for DNS-01 challenge | - | Yes (if auto-cert) | -| `ACME_STAGING` | Use Let's Encrypt staging server | `false` | No | -| `CORS_LIST` | Comma-separated list of allowed CORS origins | - | No | -| `ALLOWED_PORTS` | Port range for TCP tunnels (e.g., 40000-41000) | `40000-41000` | No | -| `BUFFER_SIZE` | Buffer size for io.Copy operations in bytes (4096-1048576) | `32768` | No | -| `PPROF_ENABLED` | Enable pprof profiling server | `false` | No | -| `PPROF_PORT` | Port for pprof server | `6060` | No | -| `MODE` | Runtime mode: `standalone` (default, no gRPC/auth) or `node` (enable gRPC + auth) | `standalone` | No | -| `GRPC_ADDRESS` | gRPC server address/host used in `node` mode | `localhost` | No | -| `GRPC_PORT` | gRPC server port used in `node` mode | `8080` | No | -| `NODE_TOKEN` | Authentication token sent to controller in `node` mode | - (required in `node`) | Yes (node mode) | +| Variable | Description | Default | Required | +|---------------------|-----------------------------------------------------------------------------|-------------------------|---------------------| +| `DOMAIN` | Domain name for subdomain routing | `localhost` | No | +| `PORT` | SSH server port | `2200` | No | +| `HTTP_PORT` | HTTP server port | `8080` | No | +| `HTTPS_PORT` | HTTPS server port | `8443` | No | +| `KEY_LOC` | Path to the private key file | `certs/privkey.pem` | No | +| `TLS_ENABLED` | Enable TLS/HTTPS | `false` | No | +| `TLS_REDIRECT` | Redirect HTTP to HTTPS | `false` | No | +| `TLS_STORAGE_PATH` | Path to store TLS certificates | `certs/tls/` | No | +| `ACME_EMAIL` | Email for Let's Encrypt registration | `admin@` | No | +| `CF_API_TOKEN` | Cloudflare API token for DNS-01 challenge | `-` | Yes (if auto-cert) | +| `ACME_STAGING` | Use Let's Encrypt staging server | `false` | No | +| `CORS_LIST` | Comma-separated list of allowed CORS origins | `-` | No | +| `ALLOWED_PORTS` | Port range for TCP tunnels (e.g., 40000-41000) | `40000-41000` | No | +| `BUFFER_SIZE` | Buffer size for io.Copy operations in bytes (4096-1048576) | `32768` | No | +| `MAX_HEADER_SIZE` | Maximum size of HTTP headers in bytes (4096-131072) | `4096` | No | +| `PPROF_ENABLED` | Enable pprof profiling server | `false` | No | +| `PPROF_PORT` | Port for pprof server | `6060` | No | +| `MODE` | Runtime mode: `standalone` or `node` | `standalone` | No | +| `GRPC_ADDRESS` | gRPC server address/host used in `node` mode | `localhost` | No | +| `GRPC_PORT` | gRPC server port used in `node` mode | `8080` | No | +| `NODE_TOKEN` | Authentication token sent to controller in `node` mode | `-` | Yes (node mode) | **Note:** All environment variables now use UPPERCASE naming. The application includes sensible defaults for all variables, so you can run it without a `.env` file for basic functionality. -### Automatic TLS Certificate Management - -The server supports automatic TLS certificate generation and renewal using [CertMagic](https://github.com/caddyserver/certmagic) with Cloudflare DNS-01 challenge. This is required for wildcard certificate support (`*.yourdomain.com`). - -**Certificate Storage:** -- TLS certificates are stored in `certs/tls/` (relative to application directory) -- User-provided certificates: `certs/tls/cert.pem` and `certs/tls/privkey.pem` -- CertMagic automatic certificates: `certs/tls/certmagic/` -- SSH keys are stored separately in `certs/ssh/` - -**How it works:** -1. If user-provided certificates exist at `certs/tls/cert.pem` and `certs/tls/privkey.pem` and cover both `DOMAIN` and `*.DOMAIN`, they will be used -2. If certificates are missing, expired, expiring within 30 days, or don't cover the required domains, CertMagic will automatically obtain new certificates from Let's Encrypt -3. Certificates are automatically renewed before expiration -4. User-provided certificates support hot-reload (changes detected every 30 seconds) - -**Cloudflare API Token Setup:** - -To use automatic certificate generation, you need a Cloudflare API token with the following permissions: - -1. Go to [Cloudflare Dashboard](https://dash.cloudflare.com/profile/api-tokens) -2. Click "Create Token" -3. Use "Create Custom Token" with these permissions: - - **Zone → Zone → Read** (for all zones or specific zone) - - **Zone → DNS → Edit** (for all zones or specific zone) -4. Copy the token and set it as `CF_API_TOKEN` environment variable - -**Example configuration for automatic certificates:** -```env -DOMAIN=example.com -TLS_ENABLED=true -CF_API_TOKEN=your_cloudflare_api_token_here -ACME_EMAIL=admin@example.com -# ACME_STAGING=true # Uncomment for testing to avoid rate limits -``` - -### SSH Key Auto-Generation - -The application will automatically generate a new 4096-bit RSA key pair at `certs/ssh/id_rsa` if it doesn't exist. This makes it easier to get started without manually creating SSH keys. SSH keys are stored separately from TLS certificates. - -### Memory Optimization - -The application uses a buffer pool with controlled buffer sizes to prevent excessive memory usage under high concurrent loads. The `BUFFER_SIZE` environment variable controls the size of buffers used for io.Copy operations: - -- **Default:** 32768 bytes (32 KB) - Good balance for most scenarios -- **Minimum:** 4096 bytes (4 KB) - Lower memory usage, more CPU overhead -- **Maximum:** 1048576 bytes (1 MB) - Higher throughput, more memory usage - -**Recommended settings based on load:** -- **Low traffic (<100 concurrent):** `BUFFER_SIZE=32768` (default) -- **High traffic (>100 concurrent):** `BUFFER_SIZE=16384` or `BUFFER_SIZE=8192` -- **Very high traffic (>1000 concurrent):** `BUFFER_SIZE=8192` or `BUFFER_SIZE=4096` - -The buffer pool reuses buffers across connections, preventing memory fragmentation and reducing garbage collection pressure. - -### Profiling with pprof - -To enable profiling for performance analysis: - -1. Set `PPROF_ENABLED=true` in your `.env` file -2. Optionally set `PPROF_PORT` to your desired port (default: 6060) -3. Access profiling data at `http://localhost:6060/debug/pprof/` - -Common pprof endpoints: -- `/debug/pprof/` - Index page with available profiles -- `/debug/pprof/heap` - Memory allocation profile -- `/debug/pprof/goroutine` - Stack traces of all current goroutines -- `/debug/pprof/profile` - CPU profile (30-second sample by default) -- `/debug/pprof/trace` - Execution trace - -Example usage with `go tool pprof`: -```bash -# Analyze CPU profile -go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30 - -# Analyze memory heap -go tool pprof http://localhost:6060/debug/pprof/heap -``` - ## Docker Deployment Three Docker Compose configurations are available for different deployment scenarios. Each configuration uses the image `git.fossy.my.id/bagas/tunnel-please:latest`. @@ -197,22 +137,6 @@ docker-compose -f docker-compose.tcp.yml up -d docker-compose -f docker-compose.root.yml down ``` -### Volume Management - -All configurations use a named volume `certs` for persistent storage: -- SSH keys: `/app/certs/ssh/` -- TLS certificates: `/app/certs/tls/` - -To backup certificates: -```bash -docker run --rm -v tunnel_pls_certs:/data -v $(pwd):/backup alpine tar czf /backup/certs-backup.tar.gz -C /data . -``` - -To restore certificates: -```bash -docker run --rm -v tunnel_pls_certs:/data -v $(pwd):/backup alpine tar xzf /backup/certs-backup.tar.gz -C /data -``` - ### Recommendation **Use `docker-compose.root.yml`** for production deployments if you need: diff --git a/docs/images/gopher.png b/docs/images/gopher.png new file mode 100644 index 0000000..bdc8fec Binary files /dev/null and b/docs/images/gopher.png differ