Einen SSH-Bastion-Host einrichten

Ein Bastion ist ein kleiner Server, der SSH von außen annimmt und nur an Ihre internen Server weiterleitet. Geben Sie seinen Benutzern eine Gruppe mit AllowTcpForwarding local, PermitOpen mit den erlaubten Zielen, PermitTTY no und ForceCommand /usr/sbin/nologin in einem Match Group-Block, und schalten Sie die Weiterleitung für alle anderen ab. Benutzer verbinden sich dann mit ssh -J user@bastion user@internal. Setzen Sie für sie nicht DisableForwarding yes, denn das blockiert auch den Sprung.

Sie wollen nur Server hinter einem vorhandenen Bastion erreichen? In Wardterm ist der Sprung eine Einstellung, keine Konfigurationsdatei. Zeigen

Aktualisiert am . Diese Konfiguration lief mit OpenSSH 10.0 unter Debian 13, mit zwei Wegwerf-Containern als Bastion und Ziel.

Wie er sein sollte

  • Ein kleiner, separater Server, der SSH ausführt und sonst nichts: keine Datenbank, keine Website, keine Entwicklerwerkzeuge.
  • Nur Schlüssel, mit automatischen Sicherheitsupdates.
  • Keine privaten Schlüssel darauf. Ein Sprung macht das unnötig. Die Anmeldung am internen Server ist von Ihrem eigenen Rechner aus verschlüsselt, und der Bastion reicht die Daten nur weiter.
  • Der einzige Weg hinein. Interne Server sollten SSH an der Firewall nur von der Adresse des Bastions annehmen.

Für die übrigen SSH-Einstellungen des Servers siehe wie Sie sshd_config absichern.

Die Benutzer anlegen

sudo groupadd jump
sudo useradd -m -G jump -s /bin/bash alice
sudo install -d -m 700 -o alice -g alice /home/alice/.ssh
sudo install -m 600 -o alice -g alice alice.pub /home/alice/.ssh/authorized_keys

Halten Sie Ihr eigenes Admin-Konto außerhalb der Gruppe jump, damit Sie weiterhin eine Shell haben.

Die sshd-Konfiguration

# /etc/ssh/sshd_config.d/10-bastion.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowAgentForwarding no
AllowTcpForwarding no
AllowStreamLocalForwarding no
X11Forwarding no
PermitTunnel no
GatewayPorts no
LogLevel VERBOSE

Match Group jump
    AllowTcpForwarding local
    PermitOpen 10.0.1.10:22 10.0.1.11:22
    PermitTTY no
    ForceCommand /usr/sbin/nologin

Jede Einstellung im Block hat eine Aufgabe:

  • AllowTcpForwarding local erlaubt Sprünge und -L, aber nicht -R.
  • PermitOpen nennt, wohin sie gehen dürfen. Listen Sie jeden Server auf: * kann für einen ganzen Host oder Port stehen, aber nicht für einen Teil einer Adresse wie 10.0.1.*.
  • PermitTTY no und ForceCommand entfernen die Shell. ForceCommand allein stoppt die Weiterleitung nicht, und deshalb funktioniert es hier.

Legen Sie das in eine eigene Datei unter /etc/ssh/sshd_config.d/ und prüfen Sie zuerst, dass keine andere Datei dieselben Optionen früher setzt: sshd behält den ersten gelesenen Wert. Ein Match-Block in einer solchen Datei endet mit der Datei. Prüfen Sie dann und laden Sie neu, mit einer offen gelassenen Sitzung:

sudo sshd -t
sudo sshd -T -C user=alice,host=client,addr=203.0.113.10 | grep -iE '^(allowtcpforwarding|permitopen|permittty|forcecommand) '
sudo systemctl reload ssh
permittty no
allowtcpforwarding local
forcecommand /usr/sbin/nologin
permitopen 10.0.1.10:22 10.0.1.11:22

Der Pfad von nologin kann auf anderen Systemen /sbin/nologin sein, prüfen Sie ihn also mit command -v nologin.

DisableForwarding ist für andere Benutzer

DisableForwarding yes schaltet jede Weiterleitung ab und überstimmt die anderen Einstellungen, es ist also praktisch für eine Gruppe, die nie etwas weiterleiten darf. Verwenden Sie es nicht für Jump-Benutzer. Ein Sprung ist eine Weiterleitung, und in unserem Test scheiterte er mit stdio forwarding failed.

Darüber verbinden

ssh -J alice@bastion.example.com user@10.0.1.10

Oder, um Tipparbeit zu sparen, in ~/.ssh/config auf Ihrem eigenen Rechner:

Host bastion
    HostName bastion.example.com
    User alice

Host app1
    HostName 10.0.1.10
    User user
    ProxyJump bastion

Führen Sie dann ssh app1 aus. Ihr Schlüssel muss auf dem Bastion und auf dem internen Server liegen. Mehr zur Client-Seite steht in Jump-Hosts und ProxyJump. Vermeiden Sie ForwardAgent, aus den Gründen in Risiken der Agent-Weiterleitung.

Testen, was abgelehnt wird

Das sind die Ergebnisse, die wir mit dieser Konfiguration erhielten, und Sie sollten dasselbe sehen:

TestErgebnis
ssh -J alice@bastion user@10.0.1.10Am internen Server angemeldet
ssh -W 10.0.1.10:80 alice@bastionstdio forwarding failed
ssh -tt alice@bastionPTY allocation request failed on channel 0
ssh alice@bastion idThis account is currently not available.
ssh -N -o ExitOnForwardFailure=yes -R 8080:localhost:22 alice@bastionError: remote port forwarding failed for listen port 8080

Logging: was Sie bekommen und was nicht

Schon auf der Standardstufe wird jede Anmeldung mit dem Fingerprint ihres Schlüssels protokolliert, woran Sie erkennen, wer sich verbunden hat. LogLevel VERBOSE protokolliert auch abgelehnte Schlüssel. Eine Anmeldung sieht so aus:

Accepted publickey for alice from 203.0.113.10 port 51018 ssh2: ED25519 SHA256:NxFS05Q+k1zf...

Abgelehnte Ziele werden ebenfalls protokolliert:

Received request from 203.0.113.10 port 51036 to connect to host 10.0.1.10 port 80, but the request was denied.

Erfolgreiche Ziele werden nicht protokolliert, weder bei INFO noch bei VERBOSE. Wir haben es geprüft: Das Log des Bastions zeigt, dass alice sich verbunden hat, aber nicht, zu welchem Server sie weitergegangen ist. In unserem Test erschien das erst bei LogLevel DEBUG1, und das Handbuch warnt, dass Debug-Stufen private Angaben der Benutzer aufzeichnen können:

debug1: server_request_direct_tcpip: originator 127.0.0.1 port 65535, target 10.0.1.10 port 22

Lesen Sie also beide Seiten. Das Log des internen Servers zeigt, wer sich angemeldet hat und mit welchem Schlüssel, mit der Adresse des Bastions als Quelle. Führen Sie beide nach der Uhrzeit zusammen und senden Sie beide an einen Rechner außerhalb des Bastions, denn ein Angreifer mit root dort könnte die lokale Kopie bearbeiten. Wie Sie diese Logs lesen, steht in Anmeldeversuche prüfen.

Zugang entfernen

Nehmen Sie den öffentlichen Schlüssel des Benutzers vom Bastion, und er verliert diesen Weg zu allen Servern dahinter. Er kann weiterhin jeden internen Server nutzen, den er auf anderem Weg erreicht, entfernen Sie den Schlüssel also auch dort. Siehe Schlüssel sperren.

Fragen

Was ist der Unterschied zwischen Bastion-Host und Jump-Host?

Gering. Ein Jump-Host ist jeder Server, über den Sie einen anderen erreichen. Ein Bastion ist ein Jump-Host, der nur für diese Aufgabe eingerichtet und abgesichert ist, und der einzige Zugang von außen.

Braucht der Bastion meinen privaten Schlüssel?

Nein. Mit ProxyJump beginnt die Anmeldung am internen Server auf Ihrem eigenen Rechner und ist durchgehend verschlüsselt. Der Bastion leitet die Verbindung nur weiter.

Warum scheitert ssh -J mit stdio forwarding failed?

Der Bastion hat die Weiterleitung abgelehnt. Prüfen Sie, ob AllowTcpForwarding sie für Ihren Benutzer erlaubt, ob das Ziel in PermitOpen steht und ob DisableForwarding gesetzt ist.

Quellen

Mehr zu Tunnel und Jump-Hosts

Alle Anleitungen