SSH Absicherung

  • Hallo,

    wie sichert ihr euren SSH Zugang gegen Bruteforce Angriffe ab?

    Ich hatte zunächst den Port auf 49xxx gelegt und Passwort Zugriff verboten also nur per ed25519 Public/Privatkey.

    Habe nach einigen Wochen im Fail2Ban Log gesehen, dass ich teilweise stundenlange Bruteforce Angriffe hatte.

    Die sind natürlich Sinn- und Zwecklos dank Privatkey, stören mich aber trotzdem.

    Fail2Ban wirkt leider auch nicht, da die IP Adresse des Angreifers im Sekundentakt wechselt.

    Habe dann in meiner Firewall chain inbound folgendes geändert:

    ip6 saddr { fd00:aaaa::/64, fd00:bbbb::/64, fd00:cccc::/64, fd08::/64, 2003::/19, 2a00:6020::/32, 2a02:8206::/32 } tcp dport 49022 ct state new limit rate 5/minute accept

    Damit habe ich den SSH Zugriff a) auf nur IPv6 limitiert und b) nur auf die Netzwerke wo ich mich grundsätzlich aufhalte: Telekom, DG und EWE, sowie die (internen) Wireguard Netzwerke.

    Bisher ist der SSH Log komplett ruhig.

    Wie sehen eure Strategien aus würde mich interessieren !?

  • Damit habe ich den SSH Zugriff a) auf nur IPv6 limitiert und b) nur auf die Netzwerke wo ich mich grundsätzlich aufhalte

    Genauso mache ich es auch. Aktuell logge ich mich nur von Zuhause aus ein, weshalb ich mein /64-Präfix als einzige Quelle zulasse. Das Präfix habe ich in der netcup-Firewall eingetragen - so kommt erst gar nichts anderes beim Server an. Trotzdem macht es Sinn, das auch in der Server-Firewall zusätzlich zu konfigurieren, falls die netcup-FW mal nicht greift (weil z. B. testweise deaktiviert).

    Für SSH verwende ich eine zufallsgenerierte IPv6-Adresse, die ausschließlich für SSH benutzt wird. Die preferred lifetime der Adresse steht auf 0, so dass sie als deprecated gilt und somit auch nicht für ausgehende Verbindungen genutzt werden sollte (die valid lifetime ist unendlich). Auf anderen IP-Adressen lauscht sshd nicht.

    P.S.: Damit die SSH-Adresse nicht für ausgehende IPv6-Verbindungen genutzt wird, muss es natürlich mindestens eine andere IPv6-Adresse geben, die dafür verwendet werden kann.

    [Suche] RS Piccolo gesucht

    2 Mal editiert, zuletzt von terence (4. August 2026 um 19:55) aus folgendem Grund: PS ergänzt

  • Also ich benutze für genau dieses Szenario gerne Netbird (selbst gehostet), aber man kann auch Tailscale sehr gut dafür benutzen.

    Der Ansatz, SSH komplett aus dem öffentlichen Internet auszusperren, ist meiner Meinung nach die eleganteste Lösung. Statt Firewalls mit IP-Bereichen von Providern zu pflegen, gehe ich einen Schritt weiter:

    SSH lauscht nur noch auf der internen IP des Mesh-VPNs (Netbird/Tailscale), nicht mehr auf der öffentlichen IP.

    Dank Wireguard und NAT-Traversal bleibt der SSH-Port nach außen komplett geschlossen.

    Im Log ist danach absolute Ruhe, weil Angreifer den Port ohne aktives VPN überhaupt nicht mehr erreichen können.

  • Ich fahre mehrgleisig:

    • Für Zugriffe aus dem Office sind in der Firewall feste IP-Adressen bzw. Präfixe freigegeben.
    • Für Zugriffe aus dem Homeoffice werden über einen Cron-Job entsprechende DynDNS-Einträge getrackt und Firewall-Regeln aktualisiert.
      Das ist diskussionswürdig, weil man sich hier auf die Sicherheit der DynDNS-Dienste bzw. DNS allgemein verlassen muss.
    • Für Zugriffe über Mobilgeräte - aber auch aus dem Homeoffice - wird ein VPN-Tunnel verwendet.
      Der VPN-Zugang seinerseits wird natürlich auch wieder angegriffen, sollte also entsprechend mit Zertifikaten abgesichert sein.

    SSH ist zusätzlich mit dem Public-Key-Verfahren abgesichert und der Root-Zugang ist gesperrt.

  • Ich arbeite schon lange nur noch mit Jumphosts. Ich habe mehrere kleine Server, die nichts machen, außer einen SSH Zugriff bereitzustellen.

    Server, die dann tatsächliche Services hosten (Webserver, Mailserver, ...) sind grundsätzlich dann nur von den Jumphosts erreichbar. Diese Jumphosts sind dann nochmal extra gehärtet und abgesichert. Das hat den großen Vorteil, dass diese gar nicht so sehr im Fokus stehen, weil dort gar keine Services laufen. Server, auf denen eine Webseite, ein Mailservice oder gar ein Gaming Server oder Teamspeak läuft, sind schon allein durch die bekannte IP Adresse viel stärker im Fokus durch Angriffe als ein Server, der sonst nichts hostet. Klar bekommt dieser immer noch das übliche Grundrauschen ab, das ist aber deutlich weniger als das, was ein produktiver Server abbekommen würde.

    Ich versuche auch auf extra Tools oder komplizierte Setups zu verzichten, kein VPN, keine dynamischen Firewall Regeln, keine Cronjobs, die Zugriffe verwalten (Keep it simple ;-)).

  • Wenn man nicht so häufig per SSH zugreifen muss: Was spricht denn dagegen Port 22 in der Firewall komplett zu blocken und sich vor dem Zugriff einfach in das SCP einzuloggen und temporär einzig für die eigene IP freizugeben?

    SUCHE Mini-Web-/Mailhosting: https://forum.netcup.de/thread/21928

    Einmal editiert, zuletzt von notfound404 (4. August 2026 um 11:24)

  • Ich arbeite beim Mailserver auch mit Jumphosts und schränke SSH per Firewall auf die IPs der Jumphosts und zusätzlich dem IPv6 Präfix von zuhause ein. Trotzdem kein Root-Login zugelassen und andere User nur Login mit Public Key. Das SSH-Jail von fail2ban ist zwar zu Kontrolle auch noch mit verschärften Einstellungen aktiv, ein Login-Versuch reicht bereits - die obigen IPs sind davon ausgenommen (ignoreip). In das Jail hat es aber, seitdem ich das so eingerichtet habe, keiner mehr geschafft. Scheint also zu klappen.

    Die anderen Server werde ich irgenwann nachziehen, obwohl die Login-Versuche bei mir nur einen winzigen Teil der Ressourcen verbrauchen, also kein Problem für den normalen Betrieb sind. Kein Root-Login und ansonsten nur mit Public Key ist an sich schon ziemlich sicher. Aber man weiss ja nie, was die KIs da schon im sshd und sonstigen Komponenten an Sicherheitslücken entdeckt haben oder noch entdecken werden, die nicht bekanntgemacht wurden.

    Ok, viel mehr als Enttäuschung ist für einen erfolgreichen Hacker bei meinen Servern eigentlich sowieso nicht zu ernten. Es geht dabei nur darum, dass ich meine Server ungern als Bots erleben würde. Das kann ich natürlich trotzdem nicht ausschliessen, aber wenn, dann werden sie mit sehr hoher Wahrscheinlichkeit ohnehin nicht über den SSH-Zugang gehackt werden.

  • Da ich Angriffe auf Layer 7 (Anwendungssoftware, Webserver) auch verstärkt schützen möchte (weil ich dort die größeren Gefahren sehe) und nicht nur ssh, habe ich mich verlegt auf Geoblocking der üblichen verdächtigen Länder plus das Blockieren von über 200k bösartigen IPs (von AbuseIPDB) die täglich aktualisiert werden. Das hat mir relative Ruhe gebracht, nicht nur auf ssh.
    ssh selbst sichere nur ab durch fail2ban mit gestaffelten jails. (Und Verlegung auf einen anderen Port)

    Eine Zeitlang hatte ich auf 22 dann eine Tarpit laufen, die mit viel Zeitverzögerung als Antwort Zitate aus "Warten auf Godot" zurückgegeben hat. Aber das war nur just for fun. :S

  • Ich habe einen pico als Jumphost der SSH über's CloudVLAN weiterleitet.

    Temporäre Private Keys werden mit opkssh + Pocket ID generiert und validiert.

    RS 1000 SSDx4 G8 / VPS 2000 G8 Plus / RS 2000 G9 / VPS 1000 ARM G11 x2 / VPS 1000 G12 Pro x2 / VPS 2000 G12 Pro / RS 1000 G12 Ultra / ERROR SERVER HOARDING DETECTED

  • Danke für die vielen Antworten :thumbup:

    verlegt auf Geoblocking der üblichen verdächtigen Länder plus das Blockieren von über 200k bösartigen IPs (von AbuseIPDB) die täglich aktualisiert werden.

    Würde mich interessieren wie genau du das machst (selber geschriebenes Script?) und an welche FW du diese übergibst (nftables?).

    Auf meinem Heimserver (Mailcow & Webserver) nutze ich https://lists.blocklist.de/lists/all.txt diese, alle 3h wird sie in nftables aktualisiert. Dadurch habe ich deutlich weniger nginx Banns als auf dem Netcup Mail- und Webserver (ohne Blocklist).

    Hier mal zum Vergleich Netcup:

    image.png


    VS Home:

    image.png

  • Würde mich interessieren wie genau du das machst (selber geschriebenes Script?) und an welche FW du diese übergibst (nftables?)

    Ja, mit einem eigenen Skript.
    Ich lese alle IPs jeden Tag neu in ein ipset ein und das habe ich in die ufw before.rules eingebaut:

    -A ufw-before-input -m set --match-set IPSETNAME src -j DROP

    ufw übergibt das dann an nftables

  • Ich versuche auch auf extra Tools oder komplizierte Setups zu verzichten, kein VPN, keine dynamischen Firewall Regeln, keine Cronjobs, die Zugriffe verwalten (Keep it simple ;-)).

    +1
    Daher werde ich wohl auch den Jumpserver in Rente schicken, den ich noch für einige VPS verwende. :D
    Dann habe ich einen Server (und einen Single-Point-Of-Failure) weniger um den ich mich kümmern muss. Und die Konfiguration der VLANs entfällt auch. Jeder Server hat dann seine eigene dedizierte IPv6-Adresse für SSH (siehe meinen obigen Post).

    Es ist aber mittlerweile ja so, daß auch IPv6-Adressen gescannt werden, weshalb man u. a. keine leicht zu erratenen Adressen verwenden sollte. So gibt es beispielsweise auf https://ipv6hitlist.github.io/ eine Liste mit aktuell rund 32 Millionen gefundenen IPv6-Adressen. Diese enthält 6587 Adressen mit dem netcup-Präfix 2a0a:4cc0::/32 und 115337 Adressen mit 2a03:4000::/32.

    Für die SSH-Anmeldung verwende ich einen Public Key und zusätzlich ein Passwort (AuthenticationMethods publickey,password).
    Der Benutzer, mit dem ich mich anmelde, hat keine Berechtigung, Befehle als root via doas (sudo) auszuführen. Dazu wechsle ich in einen Admin-Account.

  • Ich betreibe meine SSH-Zugänge weiter auf Port 22 mit jeweils einem 60-stelligen Passwort. Zugriffe sind für den Port nur aus DE möglich, ich habe generell die Crawler von Censys und Shodan gesperrt und mein Fail2Ban blockiert bei einer findtime von 3 Stunden nach drei Fehlversuchen für 24 Stunden.

    Auf Servern mit fester IP habe ich in der Woche vielleicht 5-10 gesperrte IP-Adressen, bei meinem Homeserver mit dynamischer IP seit Wochen keine einzige.

    Stirbt der Elternprozess, während das Kind noch als Zombie herumsteht, wird das Kind an PID 1 weitergereicht.

  • Bei mir ist nur Fail2ban fleißig…

    Kleine Auswertung der Jails:

    Code
    for jail in $(sudo fail2ban-client status | grep "Jail list:" | sed "s/ //g" | tr ',' '\n' | cut -d: -f2); do echo -n "$jail: "; sudo fail2ban-client status $jail | grep "Currently banned:" | grep -oE '[0-9]+'; done

    Derzeit:
    dovecot: 0
    postfix: 59
    postfix-sasl: 1504
    sshd: 191

    bantime = 1h

    findtime = 60 min

    maxretry = 2

    Und als besonderes Schmankerl für die besonders Hartnäckigen:

    bantime.increment = true
    bantime.rndtime = 30m
    bantime.maxtime = 5w
    bantime.factor = 4

    Am Anfang gab es noch manchen User der noch irgendwo einen halbkonfigurierten Email-Account hatte und plötzlich keine Mails mehr senden konnte. Da ist jetzt aber Ruhe.