DarkWolfCave
linux

Endlessh: SSH Tarpit einrichten - Angreifer aussperren

Wolf bewacht Serverraum - Endlessh SSH Tarpit fängt Angreifer in der Falle
DarkWolf mit Glühbirne KI-Bild Generiert mit Gemini

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:

  1. Endlessh lauscht auf Port 22 (dem Standard-SSH-Port)
  2. Ein Bot verbindet sich und erwartet den SSH-Version-String (z.B. SSH-2.0-OpenSSH_9.6)
  3. Stattdessen sendet Endlessh alle 10 Sekunden eine zufällige Zeile - gültig laut RFC, aber kein Version-String
  4. Der Bot wartet brav auf den Version-String, der niemals kommt
  5. Es kommt nie zu einem SSH-Handshake, keiner Kryptografie, keiner Authentifizierung
  6. 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:

⚠️ Wichtig: Ändere zuerst deinen SSH-Port, bevor du Endlessh auf Port 22 startest! Sonst sperrst du dich selbst aus. In der /etc/ssh/sshd_config einfach Port 2222 setzen 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:

ParameterWertBeschreibung
-conn_typetcpIPv4 + IPv6 gleichzeitig
-interval_ms1000010 Sekunden zwischen jedem gesendeten Byte
-line_length32Länge der zufälligen Banner-Zeilen
-max_clients4096Maximal 4096 gleichzeitig gefangene Verbindungen
-enable_prometheus-Prometheus-Metriken aktivieren
-geoip_supplierip-apiKostenloser GeoIP-Dienst (max 45 Requests/Minute)

💡 Wichtig: Die Metriken sind nur auf 127.0.0.1 gebunden. Sie sind von außen nicht erreichbar. Das ist gewollt - Prometheus-Metriken sollten nie öffentlich sein.

VIP Support
Wolf Support Avatar

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_vars oder group_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

Werbung

Security Tools & Literatur

Bild Produkt Preis
Produktdaten werden geladen...
Letzte Aktualisierung: - | Infos zu Affiliate Links | Bilder von der Amazon Product Advertising API

Die komplette Artikelserie

Diese sechs Artikel bilden zusammen einen Leitfaden für Linux-Server-Sicherheit:

  1. SSH-Server absichern — Die Eingangstür härten
  2. Netzwerk-Sicherheit & Firewall — Den Perimeter schützen
  3. Linux-Server härten — Die Angriffsfläche minimieren
  4. Monitoring & Intrusion Detection — Angriffe erkennen
  5. Endlessh SSH Tarpit (dieser Artikel) — Bots aufhalten und beobachten
  6. Backup & Defense-in-Depth — Das Sicherheitsnetz und die Gesamtstrategie
FAQ - Frequently Asked Questions DarkWolfCave
DarkWolf hilft bei FAQs

Häufig gestellte Fragen

Was ist ein SSH Tarpit?
Ein SSH Tarpit nutzt eine Erlaubnis im SSH-Protokoll (RFC 4253) aus: Vor dem eigentlichen Version-String darf ein Server beliebig viele Zeilen senden. Endlessh sendet endlos zufällige Zeilen, sodass der Client ewig auf den Version-String wartet. Es kommt nie zu einem SSH-Handshake oder einer Authentifizierung. Die meisten Bots haben Timeouts und brechen nach Sekunden bis wenigen Minuten ab. Endlessh ist kein Sicherheitstool und kein Honeypot, sondern ein Spaßprojekt mit interessanten Monitoring-Daten.
Ist endlessh-go sicher?
Ja. Endlessh-go hat nur ca. 600 Zeilen Code, läuft als unprivilegierter User in einem distroless Docker-Container ohne Shell oder Tools. Es gibt keine bekannten CVEs und kein Read() im Code, das Dateien vom Host lesen könnte.
Verlangsamt Endlessh meinen Server?
Nein. Endlessh ist extrem ressourcenschonend. Selbst mit 4096 gleichzeitig gefangenen Verbindungen verbraucht der Container nur wenige MB RAM. Die Angreifer verbrauchen ihre eigenen Ressourcen, nicht deine.
Kann ich Endlessh auf mehreren Servern gleichzeitig betreiben?
Ja, genau dafür ist die Ansible-Role gedacht. Du definierst eine Server-Gruppe und rollst Endlessh mit einem einzigen Befehl auf alle Server aus. Jeder Server bekommt seine eigene Docker-Compose-Konfiguration.
Welche Daten sehe ich im Grafana Dashboard?
Das Dashboard zeigt dir: Gesamtzahl der Verbindungsversuche, aktuell verbundene Bots, kumulative Verbindungsdauer, verbrauchte Bytes, Top-20 IPs nach Herkunftsland und eine Länder-Verteilung als Pie-Chart.
Funktioniert Endlessh auch mit IPv6?
Ja. Mit der Einstellung conn_type: tcp lauscht Endlessh sowohl auf IPv4 als auch auf IPv6. Du kannst auch gezielt nur IPv4 (tcp4) oder IPv6 (tcp6) aktivieren.
Muss ich meinen echten SSH-Port ändern?
Ja, das ist Voraussetzung. Dein echter SSH-Dienst muss auf einem anderen Port laufen (z.B. 2222), damit Endlessh Port 22 übernehmen kann. Das konfigurierst du in deiner /etc/ssh/sshd_config mit Port 2222.
Wie aktualisiere ich Endlessh?
Da Endlessh als Docker-Container läuft, reicht ein einfaches docker compose pull && docker compose up -d im Verzeichnis /opt/endlessh. Alternativ kannst du Watchtower für automatische Updates nutzen.

Kommentare

URLs werden automatisch verlinkt
Kommentare werden geladen...