Skip to content

kunalGhoshOne/GateSSH

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GateSSH

A production-ready SSH/SFTP reverse proxy written in Go that provides dynamic backend routing with IP-based access control.

Features

  • Dynamic Routing: Route SSH/SFTP connections to different backend servers based on credentials
  • Multiple Backend Support:
    • HTTP API with flexible authentication (Bearer, Basic, None)
    • MySQL database queries
  • IP Access Control: Per-target whitelist/blacklist support with CIDR notation
  • Per-Target Host Keys: Persistent host keys prevent "host changed" warnings
  • Transparent Proxying: Full SSH and SFTP protocol support
  • Production Ready: Health checks, graceful shutdown, structured logging
  • Docker Support: Complete containerization with docker-compose

Quick Start

Using Docker Compose (Recommended)

  1. Clone the repository:
git clone https://github.com/klent/gatessh.git
cd gatessh
  1. Create environment file:
cp .env.example .env
# Edit .env with your configuration
  1. Start the proxy:
docker-compose -f deployments/docker-compose.yml up -d
  1. Test the connection:
ssh -p 2222 user@localhost

Using Go

  1. Install dependencies:
make install-deps
  1. Build:
make build
  1. Configure environment and run:
export GATESSH_BACKEND_TYPE=api
export GATESSH_API_URL=https://your-api.com/route
export GATESSH_API_AUTH_TYPE=bearer
export GATESSH_API_AUTH_TOKEN=your_token
./gatessh

Configuration

All configuration is done via environment variables with the GATESSH_ prefix.

Server Configuration

Variable Default Description
GATESSH_LISTEN_ADDR :2222 SSH proxy listen address
GATESSH_LOG_LEVEL info Log level (debug, info, warn, error)
GATESSH_LOG_FORMAT json Log format (json, text)

Backend Configuration

Variable Required Description
GATESSH_BACKEND_TYPE Yes Backend type (api or mysql)

API Backend

Variable Default Description
GATESSH_API_URL - API endpoint URL
GATESSH_API_METHOD POST HTTP method
GATESSH_API_AUTH_TYPE none Auth type (none, bearer, basic)
GATESSH_API_AUTH_TOKEN - Bearer token (if auth_type=bearer)
GATESSH_API_AUTH_USERNAME - Basic auth username
GATESSH_API_AUTH_PASSWORD - Basic auth password
GATESSH_API_TIMEOUT 10s Request timeout
GATESSH_API_RESPONSE_HOST_FIELD host JSON field for target host
GATESSH_API_RESPONSE_PORT_FIELD port JSON field for target port
GATESSH_API_RESPONSE_WHITELIST_FIELD ip_whitelist JSON field for IP whitelist
GATESSH_API_RESPONSE_BLACKLIST_FIELD ip_blacklist JSON field for IP blacklist

API Request Format:

POST /route
{
  "username": "user@example.com",
  "password": "secret123",
  "client_ip": "192.168.1.100"
}

Expected API Response:

{
  "host": "ssh-server-1.internal",
  "port": 22,
  "ip_whitelist": ["192.168.1.0/24", "10.0.0.0/8"],
  "ip_blacklist": ["192.168.1.50"]
}

MySQL Backend

Variable Default Description
GATESSH_MYSQL_DSN - MySQL connection string
GATESSH_MYSQL_QUERY - SQL query with placeholders
GATESSH_MYSQL_MAX_OPEN_CONNS 10 Max open connections
GATESSH_MYSQL_MAX_IDLE_CONNS 5 Max idle connections
GATESSH_MYSQL_CONN_MAX_LIFETIME 5m Connection max lifetime

MySQL Schema Example:

CREATE TABLE routes (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    target_host VARCHAR(255) NOT NULL,
    target_port INT NOT NULL DEFAULT 22,
    ip_whitelist TEXT COMMENT 'Comma-separated CIDRs',
    ip_blacklist TEXT COMMENT 'Comma-separated CIDRs',
    INDEX idx_username (username)
);

-- Example data
INSERT INTO routes (username, password, target_host, target_port, ip_whitelist, ip_blacklist)
VALUES ('alice', 'secret123', 'prod-server.internal', 22, '203.0.113.0/24', '');

Query Example:

GATESSH_MYSQL_QUERY="SELECT target_host, target_port, ip_whitelist, ip_blacklist FROM routes WHERE username = ? AND password = ?"

Host Key Configuration

Variable Default Description
GATESSH_HOSTKEY_DIR /var/lib/gatessh/hostkeys Host key storage directory
GATESSH_HOSTKEY_ALGORITHM ed25519 Key algorithm (ed25519, rsa)
GATESSH_HOSTKEY_RSA_BITS 2048 RSA key size (if algorithm=rsa)

Upstream Configuration

Variable Default Description
GATESSH_UPSTREAM_TIMEOUT 30s Connection timeout
GATESSH_UPSTREAM_KEEPALIVE 15s SSH keepalive interval

Health Check Configuration

Variable Default Description
GATESSH_HEALTH_ENABLED true Enable health endpoint
GATESSH_HEALTH_ADDR :8080 Health check HTTP address
GATESSH_HEALTH_PATH /health Health check path

IP Filtering

GateSSH supports per-target IP whitelist and blacklist with CIDR notation.

Filtering Rules

  1. Whitelist only: Client IP must match at least one whitelist CIDR
  2. Blacklist only: Client IP must not match any blacklist CIDR
  3. Both: Whitelist is checked first (must pass), then blacklist (must not match)
  4. Neither: All IPs allowed (no filtering)

Examples

Example 1: Whitelist Only (Office Network)

{
  "host": "prod-server.internal",
  "port": 22,
  "ip_whitelist": ["203.0.113.0/24"],
  "ip_blacklist": []
}
  • 203.0.113.50 → Allowed (in whitelist)
  • 198.51.100.10 → Blocked (not in whitelist)

Example 2: Blacklist Only

{
  "host": "staging-server.internal",
  "port": 22,
  "ip_whitelist": [],
  "ip_blacklist": ["192.0.2.50"]
}
  • 192.0.2.50 → Blocked (in blacklist)
  • 10.0.0.100 → Allowed (not in blacklist)

Example 3: Combined

{
  "host": "sensitive-server.internal",
  "port": 22,
  "ip_whitelist": ["10.0.0.0/8"],
  "ip_blacklist": ["10.0.50.0/24"]
}
  • 10.0.1.100 → Allowed (in whitelist, not in blacklist)
  • 10.0.50.10 → Blocked (in blacklist)
  • 192.168.1.1 → Blocked (not in whitelist)

Usage Examples

SSH Connection

ssh -p 2222 user@proxy.company.com

SFTP File Transfer

sftp -P 2222 user@proxy.company.com

SCP File Copy

scp -P 2222 file.txt user@proxy.company.com:/remote/path/

Docker Deployment

Build and Run

# Build image
make docker-build

# Or manually
docker build -f deployments/docker/Dockerfile -t gatessh:latest .

Docker Compose

# Start
docker-compose -f deployments/docker-compose.yml up -d

# View logs
docker-compose -f deployments/docker-compose.yml logs -f gatessh

# Stop
docker-compose -f deployments/docker-compose.yml down

Health Check

curl http://localhost:8080/health

Response:

{
  "status": "healthy",
  "timestamp": "2026-01-10T14:30:00Z",
  "version": "1.0.0"
}

Development

Prerequisites

  • Go 1.23 or later
  • Make
  • Docker and Docker Compose

Build Commands

make help          # Show all available commands
make build         # Build binary
make test          # Run tests
make fmt           # Format code
make clean         # Clean artifacts

Architecture

Connection Flow

Client → GateSSH → Backend → Upstream
        (Port 2222) (Route)   (Target SSH)

Per-Target Host Keys

GateSSH generates unique host keys for each target, preventing "host changed" warnings.

Troubleshooting

Check Logs

# Docker
docker logs gatessh -f

# Parse JSON logs
docker logs gatessh 2>&1 | jq .

Common Issues

Connection Refused

  • Check if service is running
  • Verify port 2222 is accessible
  • Check firewall rules

Authentication Failures

  • Verify backend configuration
  • Check backend logs
  • Test backend connectivity

IP Blocked

  • Review whitelist/blacklist rules
  • Check logs for client IP
  • Verify CIDR notation

License

MIT License

Author

Created by klent

About

GateSSH is a secure SSH and SFTP reverse proxy that routes connections to Docker containers, Kubernetes pods, and private servers through a single gateway, controlled via API or MySQL.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors