SSH-Tarpit
SSH honeypot capable of reading GeoIP databases and logging connection information to a SQLite or MySQL database. It can also be used as a tarpit to hold hackers' connections open indefinitely.
Configuration
All configuration is done via environment variables:
| Variable | Default | Description |
|---|---|---|
SSH_TARPIT_PORT |
2222 |
Port to listen on |
SSH_TARPIT_TARPIT |
false |
Enable tarpit mode (true, 1, yes, on) |
SSH_TARPIT_TARPIT_DELAY |
1s |
Delay between tarpit bytes |
SSH_TARPIT_TARPIT_MAX_DURATION |
0s |
Max tarpit duration (0 = unlimited) |
SSH_TARPIT_DB_PATH |
./data/logs.db |
Path to SQLite database |
SSH_TARPIT_GEOIP_PATH |
Path to GeoIP databases (GeoIP disabled if empty) | |
SSH_TARPIT_MYSQL_USER |
MySQL username (enables MySQL when set) | |
SSH_TARPIT_MYSQL_PASS |
MySQL password | |
SSH_TARPIT_MYSQL_HOST |
localhost |
MySQL host |
SSH_TARPIT_MYSQL_PORT |
3306 |
MySQL port |
SSH_TARPIT_MYSQL_DB |
sshtarpit |
MySQL database name |
SSH_TARPIT_BANNER |
SSH-2.0-OpenSSH_9.1p1 Debian-1 |
Fake SSH banner |
SSH_TARPIT_MAX_CONNS |
100 |
Maximum concurrent connections |
SSH_TARPIT_SHUTDOWN_TIMEOUT |
30s |
Max time to wait for active connections on shutdown |
SSH_TARPIT_PROXY_PROTOCOL |
false |
Enable PROXY protocol v1/v2 support (true, 1, yes, on) |
SSH_TARPIT_AUTH |
false |
Enable fake SSH authentication + command logging (true, 1, yes, on). Cannot be used with tarpit mode. |
SSH_TARPIT_AUTH_CREDENTIALS |
admin:admin,root:root,... |
Comma-separated user:pass pairs that bots can "crack" to reach the fake shell |
SSH_TARPIT_AUTH_IDLE_TIMEOUT |
5m |
Max idle time for authenticated SSH sessions |
Deployment
SQLite
Clone the repository start the container:
git clone https://git.rznet.fr/razian/ssh-tarpit.git
cd ssh-tarpit
docker compose up -d
MySQL
Create a .env file with the required passwords:
cat > .env <<EOF
MYSQL_ROOT_PASSWORD=your_db_root_password
MYSQL_PASS=your_db_root_password
EOF
Then start with the MySQL compose file:
git clone https://git.rznet.fr/razian/ssh-tarpit.git
cd ssh-tarpit
vim .env # set passwords
docker compose -f docker-compose-mysql.yml up -d
GeoIP
Use geoipupdate to download the GeoLite2 databases, then mount them and set SSH_TARPIT_GEOIP_PATH.
Database Schema
connections
CREATE TABLE connections (
ip TEXT,
country TEXT,
city TEXT,
latitude REAL,
longitude REAL,
isp TEXT,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
auth_attempts
CREATE TABLE auth_attempts (
ip TEXT NOT NULL,
username TEXT NOT NULL,
password TEXT,
public_key_fingerprint TEXT,
success INTEGER DEFAULT 0,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
commands
CREATE TABLE commands (
ip TEXT NOT NULL,
command TEXT NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Auth Mode
When SSH_TARPIT_AUTH=true (and tarpit is disabled), the honeypot runs a fake SSH server:
- Performs real SSH key exchange using
golang.org/x/crypto/ssh - Logs every authentication attempt (username, password, public key fingerprint) to the
auth_attemptstable - Only grants access if the credentials match one of the
SSH_TARPIT_AUTH_CREDENTIALSpairs - After successful auth, presents a fake
root@localhost:~#shell prompt - Every command typed is logged to the
commandstable
Default credentials include: admin:admin, root:root, root:123456, guest:guest, and others. Bots brute-forcing common passwords will eventually hit one and start issuing commands — all of which get logged.