Monitoring SSH login attempts and geolocating remote hosts who failed to login and gathering used credentials.
The main idea is that you don't use default SSH port to connect to your remote server/VPS. This Docker Compose configuration maps fake server's port 22 to Docker host's public IP and stores unsuccesful login details in the database.
Example docker-compose.yml (see docker-compose.example.yml)
Don't forget to generate private_key.pem first using following command:
openssl genrsa -out private_key.pem 4096And build with sudo docker compose up -d!
For deploying behind a reverse proxy see nginx configuration.
Example .env environmental variables (see .env.example)
| Variable | Description |
|---|---|
| GIN_MODE | release (default). Use debug only for local development. |
| POSTGRES_USER | PostgreSQL user |
| POSTGRES_PASSWORD | PostgreSQL password (use a strong, unique value) |
| POSTGRES_SERVER | PostgreSQL server |
| POSTGRES_PORT | PostgreSQL port |
| POSTGRES_DB | PostgreSQL database |
| VALKEY_PASSWORD | Valkey password (use a strong, unique value) |
| VALKEY_SERVER | Valkey server |
| VALKEY_PORT | Valkey port |
| ALLOWED_ORIGINS | Comma separated cross-origin allowlist. Empty = same-origin only. |
| TRUSTED_PROXIES | Comma separated reverse proxy IPs/CIDRs allowed to set X-Forwarded-For. Empty = ignore the header. |
| API_RATE_LIMIT_PER_MINUTE | Per-IP limit for /api/* and /ws (default 120) |
| WEBSOCKET_MAX_CLIENTS | Maximum concurrent WebSocket clients (default 1000) |
| SSH_MAX_CONNECTIONS | Maximum concurrent SSH connections (default 1024) |
| SSH_KEY_PATH | Path to the SSH host key (default private_key.pem) |
GIN_MODEdefaults torelease. Debug mode exposes Swagger/OpenAPI and enables verbose SQL logging (which contains captured credentials), so only enable it locally.- The container runs as unprivileged user/group
10001:10001. The mountedprivate_key.pemmust be readable by it:sudo chown 10001:10001 private_key.pem && sudo chmod 600 private_key.pem. If the file is missing, the app generates one inside/app(persist it with a volume if you want a stable host key). - When running behind nginx, set
TRUSTED_PROXIESto the proxy address and keep127.0.0.1:8080bound to localhost (as in the example compose file). - Generate all secrets with
openssl rand -base64 32; never deploy thechange-meplaceholders from.env.example.
sudo docker compose -f docker-compose.dev.yml --env-file .env.dev up -d./test.sh number_of_attemptsSwagger UI is available at http://localhost:8080/swagger after starting development mode. Set GIN_MODE=debug (the .vscode launch configuration does this via .env.dev); it is disabled in the default release mode.
