Endlessh: SSH Tarpit einrichten - Angreifer aussperren
Jeder Server mit einem öffentlichen SSH-Port wird früher oder später von Bots besucht. Brute-Force-Scanner klopfen rund um die Uhr an Port 22. Statt diese Verbindungen einfach abzulehnen, kannst du mit Endlessh die Bots kurz aufhalten - und ihnen dabei in Echtzeit zuschauen.
Gleich vorweg: Endlessh ist kein Sicherheitstool. Es ersetzt weder Fail2ban noch eine vernünftige Firewall. Aber es macht unglaublich viel Spaß, die Verbindungsdaten in Grafana zu beobachten. In diesem Artikel zeige ich dir, wie du endlessh-go mit Docker einrichtest, per Ansible ausrollst und ein Grafana-Dashboard dafür baust.
DarkWolfCave.de
ℹ️ Hinweis: Endlessh ist ein Spaßprojekt, kein Sicherheitstool. Es ersetzt weder eine Firewall noch Fail2ban oder CrowdSec. Die hier gezeigten Konfigurationen stammen aus meiner eigenen Praxis — teste sie in deiner Umgebung, bevor du sie produktiv einsetzt.
Was ist ein SSH Tarpit?
Wenn du einen Server im Internet betreibst, kennst du das Problem: Kaum ist der Server online, hämmern Bots aus aller Welt auf Port 22. Sie probieren Benutzernamen wie root, admin oder ubuntu mit tausenden Passwörtern durch. Fail2ban hilft, aber die Bots kommen einfach mit der nächsten IP zurück.
Ein SSH Tarpit dreht den Spieß um. Statt die Verbindung abzulehnen, akzeptiert Endlessh sie - und nutzt dann einen Trick im SSH-Protokoll aus:
Bot → Port 22 → Endlessh → Hängt in der Banner-Phase
Du → Port XXXXX → Echter SSH → Normaler Zugang ✅
Wie funktioniert das technisch?
Laut RFC 4253 (dem SSH-Transportprotokoll) darf ein SSH-Server vor dem eigentlichen Version-String beliebig viele zusätzliche Zeilen senden. Der Client muss diese Zeilen lesen und auf den Version-String warten, bevor der SSH-Handshake überhaupt beginnen kann.
Genau das nutzt Endlessh aus:
- Endlessh lauscht auf Port 22 (dem Standard-SSH-Port)
- Ein Bot verbindet sich und erwartet den SSH-Version-String (z.B.
SSH-2.0-OpenSSH_9.6) - Stattdessen sendet Endlessh alle 10 Sekunden eine zufällige Zeile - gültig laut RFC, aber kein Version-String
- Der Bot wartet brav auf den Version-String, der niemals kommt
- Es kommt nie zu einem SSH-Handshake, keiner Kryptografie, keiner Authentifizierung
- Irgendwann greift der Timeout des Bots und die Verbindung wird getrennt
💡 Wichtig: Endlessh ist kein Honeypot. Ein Honeypot wie Cowrie simuliert einen echten SSH-Login und zeichnet Passwörter und Befehle auf. Endlessh tut nichts davon - es hängt in der Banner-Phase fest, noch bevor irgendeine Kryptografie stattfindet. Deshalb braucht Endlessh auch keine kryptografischen Bibliotheken.
Die meisten Scan-Bots haben Timeouts und ziehen nach Sekunden bis wenigen Minuten weiter. Die Betreiber der Botnets werden das kaum bemerken - die haben tausende IPs und scannen Millionen von Servern. Ob ein Bot 20 Sekunden an deinem Tarpit hängt, fällt in deren Statistik nicht auf. Der eigentliche Mehrwert: Du bekommst Monitoring-Daten darüber, wer versucht auf deinen Server zu kommen.
Warum endlessh-go?
Es gibt das originale Endlessh in C und die erweiterte Go-Version endlessh-go. Ich nutze die Go-Version, weil sie ein paar wichtige Vorteile hat:
- Prometheus-Metriken - Alle Verbindungsdaten werden als Metriken exportiert
- GeoIP-Erkennung - Zeigt aus welchem Land die Angreifer kommen
- Docker-Image - Einfaches Deployment als Container
- Distroless - Minimales Image ohne Shell oder Tools (Sicherheit!)
- ~600 Zeilen Code - Überschaubar und auditierbar
🔒 Sicherheit: Das Docker-Image von endlessh-go basiert auf einem distroless Container. Es gibt keine Shell, keine Tools, keine Angriffsfläche. Der Prozess läuft als unprivilegierter User mit
no-new-privileges:true.
Voraussetzungen
Bevor wir loslegen, stelle sicher dass folgendes gegeben ist:
- Docker ist auf deinem Server installiert (Docker auf dem Raspberry Pi installieren)
- SSH läuft auf einem anderen Port (z.B. 2222) - nicht auf Port 22!
- Optional: Telegraf + InfluxDB + Grafana für Monitoring (Anleitung: InfluxDB, Telegraf und Grafana einrichten)
⚠️ Wichtig: Ändere zuerst deinen SSH-Port, bevor du Endlessh auf Port 22 startest! Sonst sperrst du dich selbst aus. In der
/etc/ssh/sshd_configeinfachPort 2222setzen und den SSH-Dienst neu starten. Teste die Verbindung über den neuen Port, bevor du den alten freigibst!
Die Docker-Compose Konfiguration
So sieht die Docker-Compose-Datei für Endlessh aus:
services:
endlessh:
image: shizunge/endlessh-go:latest
container_name: endlessh
restart: unless-stopped
command:
- -conn_type=tcp
- -interval_ms=10000
- -line_length=32
- -max_clients=4096
- -enable_prometheus
- -prometheus_port=2112
- -geoip_supplier=ip-api
ports:
- "22:2222" # SSH Tarpit (offen für Angreifer)
- "127.0.0.1:2112:2112" # Prometheus Metriken (nur lokal!)
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
security_opt:
- no-new-privileges:true
Kurze Erklärung zu den Parametern:
| Parameter | Wert | Beschreibung |
|---|---|---|
-conn_type | tcp | IPv4 + IPv6 gleichzeitig |
-interval_ms | 10000 | 10 Sekunden zwischen jedem gesendeten Byte |
-line_length | 32 | Länge der zufälligen Banner-Zeilen |
-max_clients | 4096 | Maximal 4096 gleichzeitig gefangene Verbindungen |
-enable_prometheus | - | Prometheus-Metriken aktivieren |
-geoip_supplier | ip-api | Kostenloser GeoIP-Dienst (max 45 Requests/Minute) |
💡 Wichtig: Die Metriken sind nur auf
127.0.0.1gebunden. Sie sind von außen nicht erreichbar. Das ist gewollt - Prometheus-Metriken sollten nie öffentlich sein.
Du wirst hier einen groben Überblick finden.
Allerdings biete ich dir auch noch etwas mehr Support an:
- Du benötigst persönlichen Support
- Du möchtest von Beginn an Unterstützung bei deinem Projekt
- Du möchtest ein hier vorgestelltes Plugin durch mich installieren und einrichten lassen
- Du würdest gerne ein von mir erstelltes Script etwas mehr an deine Bedürfnisse anpassen
Für diese Punkte und noch einiges mehr habe ich einen limitierten VIP-Tarif eingerichtet.
Falls der Tarif gerade nicht verfügbar ist, kontaktiere mich auf Discord!
Deployment per Hand oder mit Ansible
Manuelle Installation
Für einen einzelnen Server ist die manuelle Installation am schnellsten:
# Verzeichnis erstellen
mkdir -p /opt/endlessh
# docker-compose.yml erstellen (Inhalt von oben)
nano /opt/endlessh/docker-compose.yml
# Container starten
cd /opt/endlessh && docker compose up -d
# Prüfen ob der Container läuft
docker ps | grep endlessh
Nach dem Start kannst du direkt die Metriken prüfen:
curl http://localhost:2112/metrics
Du solltest dort Zeilen wie endlessh_client_open_count_total und endlessh_trapped_time_seconds_total sehen.
Automatisiert mit Ansible
Wenn du wie ich mehrere Server betreibst, willst du das nicht auf jedem einzeln einrichten. Dafür habe ich eine Ansible-Role erstellt. Ansible installierst du mit sudo apt install ansible. Hier sind alle Dateien, die du brauchst - du kannst die komplette Role direkt übernehmen.
Rollenstruktur
roles/endlessh/
├── defaults/main.yml # Variablen mit Standardwerten
├── handlers/main.yml # Restart-Handler
├── tasks/main.yml # Hauptlogik
└── templates/
├── docker-compose.yml.j2 # Docker-Compose Template
└── telegraf-endlessh.conf.j2 # Telegraf Scrape-Config
defaults/main.yml
Hier definierst du alle Variablen. Die Standardwerte passen für die meisten Setups direkt:
---
# Container settings
endlessh_enabled: true
endlessh_container_name: "endlessh"
endlessh_image: "shizunge/endlessh-go:latest"
endlessh_config_dir: "/opt/endlessh"
# Ports
endlessh_ssh_port: 22 # Port für den Tarpit (Standard-SSH-Port)
endlessh_metrics_port: 2112 # Prometheus-Metriken (nur lokal!)
# Tarpit-Verhalten
endlessh_conn_type: "tcp" # "tcp" (IPv4+IPv6), "tcp4", "tcp6"
endlessh_delay_ms: 10000 # Millisekunden zwischen gesendeten Zeilen
endlessh_max_line_length: 32 # Länge der zufälligen Banner-Zeilen
endlessh_max_clients: 4096 # Max. gleichzeitig gefangene Verbindungen
# GeoIP (Ländererkennung)
endlessh_geoip_enabled: true
endlessh_geoip_supplier: "ip-api" # Kostenlos, kein API-Key nötig (max 45 Req/Min)
# Prometheus-Metriken
endlessh_metrics_enabled: true
# Telegraf-Integration
endlessh_telegraf_scrape: true
tasks/main.yml
Die Tasks machen alles in der richtigen Reihenfolge - Firewall, Config, Container, Telegraf:
---
- name: Allow endlessh port in UFW
community.general.ufw:
rule: allow
port: "{{ endlessh_ssh_port }}"
proto: tcp
comment: "endlessh SSH tarpit"
when: endlessh_enabled
- name: Create endlessh config directory
ansible.builtin.file:
path: "{{ endlessh_config_dir }}"
state: directory
mode: '0755'
when: endlessh_enabled
- name: Deploy endlessh docker-compose file
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ endlessh_config_dir }}/docker-compose.yml"
mode: '0644'
when: endlessh_enabled
notify: Restart endlessh
- name: Start endlessh container
community.docker.docker_compose_v2:
project_src: "{{ endlessh_config_dir }}"
state: present
when: endlessh_enabled
- name: Add Telegraf prometheus scrape config for endlessh
ansible.builtin.template:
src: telegraf-endlessh.conf.j2
dest: /etc/telegraf/telegraf.d/endlessh.conf
mode: '0644'
when:
- endlessh_enabled
- endlessh_telegraf_scrape
notify: Restart telegraf
handlers/main.yml
Die Handler starten Container bzw. Telegraf nur bei Änderungen neu:
---
- name: Restart endlessh
community.docker.docker_compose_v2:
project_src: "{{ endlessh_config_dir }}"
state: restarted
services:
- endlessh
- name: Restart telegraf
ansible.builtin.systemd:
name: telegraf
state: restarted
templates/docker-compose.yml.j2
Das Jinja2-Template für die Docker-Compose-Datei. Ansible füllt die Variablen automatisch:
# Managed by Ansible - do not edit manually
services:
endlessh:
image: {{ endlessh_image }}
container_name: {{ endlessh_container_name }}
restart: unless-stopped
command:
- -conn_type={{ endlessh_conn_type }}
- -interval_ms={{ endlessh_delay_ms }}
- -line_length={{ endlessh_max_line_length }}
- -max_clients={{ endlessh_max_clients }}
{% if endlessh_metrics_enabled %}
- -enable_prometheus
- -prometheus_port=2112
{% endif %}
{% if endlessh_geoip_enabled %}
- -geoip_supplier={{ endlessh_geoip_supplier }}
{% endif %}
ports:
- "{{ endlessh_ssh_port }}:2222"
- "127.0.0.1:{{ endlessh_metrics_port }}:2112"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
security_opt:
- no-new-privileges:true
templates/telegraf-endlessh.conf.j2
# Managed by Ansible
[[inputs.prometheus]]
urls = ["http://127.0.0.1:{{ endlessh_metrics_port }}/metrics"]
[inputs.prometheus.tags]
source = "endlessh"
service = "ssh-tarpit"
Das Playbook
Zum Schluss das Playbook, das die Role auf deine Server ausrollt:
---
- name: Deploy endlessh SSH Tarpit
hosts: vps_servers # Passe die Gruppe an dein Inventory an
become: yes
roles:
- endlessh
Deployment:
# Auf alle Server der Gruppe deployen
ansible-playbook playbooks/deploy_endlessh.yml
# Oder nur auf einen bestimmten Server
ansible-playbook playbooks/deploy_endlessh.yml --limit mein-server
💡 Tipp: Wenn du die Variablen pro Server anpassen willst, überschreibe sie in deinen
host_varsodergroup_vars. Die Defaults passen aber für die meisten Setups direkt.
Monitoring mit Telegraf und Grafana
Hier wird es richtig interessant. Das Beste an endlessh-go sind die Prometheus-Metriken. Damit kannst du beobachten, welche Bots gerade auf Port 22 aufschlagen - und das ist der eigentliche Grund, warum sich das Setup lohnt. Falls du den Monitoring-Stack noch nicht hast: In meiner Anleitung zu InfluxDB, Telegraf und Grafana findest du alles dazu.
Telegraf-Konfiguration
Telegraf scrapt die Metriken und schreibt sie in InfluxDB:
[[inputs.prometheus]]
## Endlessh-go Prometheus Metriken scrapen
urls = ["http://127.0.0.1:2112/metrics"]
[inputs.prometheus.tags]
source = "endlessh"
service = "ssh-tarpit"
Diese Konfiguration wird automatisch durch die Ansible-Role unter /etc/telegraf/telegraf.d/endlessh.conf erstellt.
Grafana Dashboard
Für Grafana habe ich ein Dashboard erstellt, das dir auf einen Blick zeigt:
- Gesamtzahl der Verbindungsversuche über die Zeit
- Aktuell verbundene Bots
- Aufgehaltene Zeit - wie lange Bots in der Verbindung geblieben sind (meist Sekunden bis Minuten)
- Verbrauchte Bytes - wie viel Bandbreite der Tarpit generiert hat
- Top 20 IPs nach Verbindungsversuchen und Herkunftsland
- Länder-Verteilung als Pie-Chart - woher kommen die meisten Scans
💡 Tipp: Die GeoIP-Daten sind das eigentliche Highlight. Bei meinen Servern kommen die meisten Scans aus China, Russland und den USA. Keine große Überraschung - aber die Muster live in Grafana zu beobachten, macht einfach Spaß.
Meine Erfahrungen
Ich betreibe Endlessh auf mehreren VPS-Servern. Was mir dabei aufgefallen ist:
- Hunderte Verbindungsversuche pro Tag - das Grundrauschen ist hoch
- Die meisten Bots brechen nach 10-30 Sekunden ab - Timeout eben
- Manche bleiben tatsächlich einige Minuten hängen, stundenlang aber eher selten
- Der Ressourcenverbrauch auf meinen Servern ist dabei praktisch null
- Die GeoIP-Daten zeigen interessante Muster: Wellenweise kommen Scans aus bestimmten Regionen
Die Botbetreiber werden das kurze Aufhalten wahrscheinlich nicht einmal bemerken. Die haben tausende IPs und scannen Millionen von Servern. Ob ein einzelner Bot 20 Sekunden an deinem Tarpit hängt, fällt in deren Statistik nicht auf.
Aber darum geht es auch gar nicht. Der eigentliche Spaß ist das Beobachten. In Grafana live zu sehen, wie Bots aus China, Russland oder den USA auf deinem Port 22 auflaufen und wie sich die Angriffsmuster über den Tag verteilen - das macht einfach Spaß. Es ist wie ein Aquarium, nur mit Botnetzen.
Sicherheitshinweise
Ein paar Dinge solltest du beachten:
- SSH-Port vorher ändern! Dein echter SSH-Dienst darf nicht auf Port 22 laufen
- Teste die Verbindung über den neuen Port, bevor du den alten freigibst
- Firewall konfigurieren - Port 22 offen für Endlessh, neuer SSH-Port nur für deine IP
- SSH-Verbindung merken - Nach dem Port-Wechsel kannst du dir den Zugang per SSH-Config unter einem Namen speichern
- Fail2ban kann parallel weiterlaufen - die beiden Systeme ergänzen sich
- Metriken nicht exponieren - Port 2112 bleibt auf localhost
⚠️ Warnung: Ändere niemals den SSH-Port auf einem Remote-Server, ohne vorher sicherzustellen, dass du über den neuen Port eine Verbindung herstellen kannst. Sonst sperrst du dich aus!
Endlessh ist kein Sicherheitstool. Es wird dich nicht vor gezielten Angriffen schützen und die Botbetreiber dieser Welt werden deswegen nicht schlecht schlafen. Aber das muss es auch gar nicht. Was Endlessh wirklich gut kann: Dir einen Einblick geben, was auf Port 22 deiner Server so passiert. Die Kombination aus Docker-Deployment, Ansible-Automatisierung und Grafana-Monitoring macht das Setup wartungsfrei und liefert dir nebenbei ein informatives Dashboard voller Daten über das Grundrauschen des Internets.
Wenn du Spaß an Monitoring hast und sehen willst, wer so alles an deinem Server anklopft - probier es aus. Der Aufwand ist minimal, der Unterhaltungswert überraschend hoch. Falls du Fragen hast oder wissen möchtest, was mein Tarpit so alles einfängt - schreib gerne einen Kommentar!
Hardware-Keys für 2FA und deutschsprachige Security-Bücher
Security Tools & Literatur
| Bild | Produkt | Preis | |
|---|---|---|---|
| Produktdaten werden geladen... | |||
Die komplette Artikelserie
Diese sechs Artikel bilden zusammen einen Leitfaden für Linux-Server-Sicherheit:
- SSH-Server absichern — Die Eingangstür härten
- Netzwerk-Sicherheit & Firewall — Den Perimeter schützen
- Linux-Server härten — Die Angriffsfläche minimieren
- Monitoring & Intrusion Detection — Angriffe erkennen
- Endlessh SSH Tarpit (dieser Artikel) — Bots aufhalten und beobachten
- Backup & Defense-in-Depth — Das Sicherheitsnetz und die Gesamtstrategie
Kommentare