Wie erstelle ich einen eingeschränkten SSH-Benutzer für die Portweiterleitung?

106

ændrük schlug eine umgekehrte Verbindung vor, um eine einfache SSH-Verbindung mit einer anderen Person herzustellen (für Remote-Hilfe). Damit dies funktioniert, ist ein zusätzlicher Benutzer erforderlich, um die Verbindung zu akzeptieren. Dieser Benutzer muss in der Lage sein, seinen Port über den Server weiterzuleiten (der Server fungiert als Proxy).

Wie erstelle ich einen eingeschränkten Benutzer, der nicht mehr als die oben beschriebenen Aktionen ausführen kann?

Der neue Benutzer darf nicht in der Lage sein:

  • Shell-Befehle ausführen
  • auf Dateien zugreifen oder Dateien auf den Server hochladen
  • benutze den Server als Proxy (zB Webproxy)
  • Zugriff auf lokale Dienste, die ansonsten aufgrund einer Firewall nicht öffentlich zugänglich waren
  • Töte den Server

Zusammengefasst, wie erstelle ich einen eingeschränkten SSH-Benutzer, der nur ohne Berechtigungen eine Verbindung zum SSH-Server herstellen kann, damit ich über diese Verbindung eine Verbindung mit seinem Computer herstellen kann?

Lekensteyn
quelle

Antworten:

166

TL; DR - Gehen Sie zum Ende der Antwort "Anwenden der Einschränkungen".

Das Hinzufügen eines eingeschränkten Benutzers besteht aus zwei Teilen: 1. Erstellen des Benutzers 2. Konfigurieren des SSH-Dämons (sshd)

Sshd konfigurieren

Der beste Ort, um sich mit den Möglichkeiten von SSH vertraut zu machen, ist das Lesen der entsprechenden Handbuchseiten:

Wo kann der SSH-Client Aktionen ausführen?

Bevor Sie etwas einschränken können, müssen Sie die Funktionen von SSH kennen. Das Durchblättern der Manualseiten ergibt:

  • Ausführung von Shell-Befehlen
  • Datei-Upload über SFTP
  • Port-Weiterleitung
    • Der Client leitet einen (nicht) genutzten Port an den Server weiter
    • Der Server leitet seinen Port an den Client weiter
    • Der Server leitet einen Port eines anderen Hosts an den Client weiter (proxy-ish)
  • X11-Weiterleitung (Display-Weiterleitung)
  • Weiterleitung des Authentifizierungsagenten
  • Weiterleitung eines Tunnelgerätes

Von dem Authentifizierung Abschnitt der Manpage von sshd (8) :

Wenn der Client sich erfolgreich authentifiziert hat, wird ein Dialogfeld zum Vorbereiten der Sitzung aufgerufen. Zu diesem Zeitpunkt fordert der Client möglicherweise die Zuweisung einer Pseudotty, die Weiterleitung von X11-Verbindungen, die Weiterleitung von TCP-Verbindungen oder die Weiterleitung der Authentifizierungsagentenverbindung über den sicheren Kanal an.

Danach fordert der Client entweder eine Shell an oder führt einen Befehl aus . Die Seiten wechseln dann in den Sitzungsmodus. In diesem Modus kann jede Seite jederzeit Daten senden, und diese Daten werden an die Shell oder den Befehl auf der Serverseite und an das Benutzerterminal auf der Clientseite weitergeleitet.

Optionen zum Einschränken der SSH-Funktionen

Dateien und ihre Optionen, die das Verhalten ändern, sind:

  • ~/.ssh/authorized_keys - enthält Schlüssel, die eine Verbindung herstellen dürfen und denen Optionen zugewiesen werden können:
    • command="command"- Der vom Benutzer eingegebene Befehl (falls vorhanden) wird ignoriert. Beachten Sie, dass der Client TCP- und / oder X11-Weiterleitungen festlegen kann, sofern dies nicht ausdrücklich untersagt ist . Beachten Sie, dass diese Option für die Ausführung von Shell-, Befehls- oder Subsystemen gilt.
    • no-agent-forwarding - Verbietet die Weiterleitung von Authentifizierungsagenten, wenn dieser Schlüssel zur Authentifizierung verwendet wird.
    • no-port-forwarding - Verbietet die TCP-Weiterleitung, wenn dieser Schlüssel zur Authentifizierung verwendet wird
    • no-X11-forwarding - "Verbietet X11-Weiterleitung, wenn dieser Schlüssel zur Authentifizierung verwendet wird."
    • permitopen="host:port" - Begrenzen Sie die lokale 'ssh-L'-Portweiterleitung so, dass nur eine Verbindung zum angegebenen Host und Port hergestellt werden kann.
  • ~/.ssh/environment- Diese Datei wird beim Login in die Umgebung eingelesen (falls vorhanden). Die Umgebungsverarbeitung ist standardmäßig deaktiviert und wird über die Option PermitUserEnvironment gesteuert
  • ~/.ssh/rc - Enthält Initialisierungsroutinen, die ausgeführt werden müssen, bevor auf das Basisverzeichnis des Benutzers zugegriffen werden kann.
  • /etc/ssh/sshd_config - die systemweite Konfigurationsdatei
    • AllowAgentForwarding - Gibt an, ob die Weiterleitung von ssh-agent (1) zulässig ist.
    • AllowTcpForwarding
    • ForceCommand - "Erzwingt die Ausführung des von ForceCommand angegebenen Befehls, wobei alle vom Client und ~ / .ssh / rc (sofern vorhanden) bereitgestellten Befehle ignoriert werden. Der Befehl wird mithilfe der Anmeldeshell des Benutzers mit der Option -c aufgerufen."
    • GatewayPorts - "Gibt an, ob Remotehosts Verbindungen zu für den Client weitergeleiteten Ports herstellen dürfen. Standardmäßig bindet sshd (8) Remoteportweiterleitungen an die Loopback-Adresse. Dadurch wird verhindert, dass andere Remotehosts Verbindungen zu weitergeleiteten Ports herstellen. GatewayPorts kann zum Festlegen verwendet werden dass sshd zulassen sollte, dass Remote-Port-Weiterleitungen an Nicht-Loopback-Adressen gebunden werden, damit andere Hosts eine Verbindung herstellen können. "
    • PermitOpen:

      Gibt die Ziele an, an die die TCP-Portweiterleitung zulässig ist. Die Speditionsspezifikation muss eine der folgenden Formen haben:

      PermitOpen host:port
      PermitOpen IPv4_addr:port
      PermitOpen [IPv6_addr]:port
      

      Mehrere Weiterleitungen können durch Leerzeichen getrennt angegeben werden. Ein Argument von 'any' kann verwendet werden, um alle Einschränkungen zu entfernen und Weiterleitungsanforderungen zuzulassen. Standardmäßig sind alle Portweiterleitungsanforderungen zulässig.

    • PermitTunnel- Gibt an, ob die Weiterleitung von tun (4) -Geräten zulässig ist. Der Standardwert ist "Nein".
    • X11Forwarding- Gibt an, ob die X11-Weiterleitung zulässig ist. Der Standardwert ist "Nein".

Anwenden der Einschränkungen

Durch Ändern der systemweiten Konfigurationsdatei /etc/ssh/sshd_configkann die Konfiguration auch dann angewendet werden, wenn die kennwortbasierte Authentifizierung angewendet wird oder wenn die Einschränkungen ~/.ssh/authorized_keysversehentlich entfernt wurden. Wenn Sie die globalen Standardeinstellungen geändert haben, sollten Sie die Optionen entsprechend auskommentieren.

Match User limited-user
   #AllowTcpForwarding yes
   #X11Forwarding no
   #PermitTunnel no
   #GatewayPorts no
   AllowAgentForwarding no
   PermitOpen localhost:62222
   ForceCommand echo 'This account can only be used for [reason]'

Fügen Sie nun einen Benutzer hinzu:

sudo useradd -m limited-user

Die Option ForceCommandkann weggelassen werden, wenn die Shell auf eine Nicht-Shell wie /bin/false(oder /bin/true) gesetzt ist, da /bin/false -c [command]sie nichts bewirkt.

Jetzt kann der Client nur über SSH eine Verbindung zu Port 62222 über die Loopback-Adresse des Servers herstellen (die öffentliche IP-Adresse wird nicht überwacht).

Das Deaktivieren AllowTcpForwardingwürde auch die Verwendung von verbieten -Rund somit die Verwendung eines solchen eingeschränkten Kontos zum Weiterleiten eines einzelnen Ports verhindern. PermitOpen localhost:62222Es wird davon ausgegangen, dass der Port 62222 auf dem Server nie verwendet wird, da der Client eine Verbindung herstellen und diese auch überwachen kann.

Wenn die systemweite Konfiguration die TCP-Weiterleitung zulässt und die kennwortbasierte Authentifizierung deaktiviert ist, können Sie auch die Einstellungen für einzelne Schlüssel verwenden. Bearbeiten ~/.ssh/authorized_keysund fügen Sie die nächsten Optionen vor dem ssh-(mit einem Leerzeichen zwischen den Optionen und ssh-) hinzu:

command="echo 'This account can only be used for [reason]'",no-agent-forwarding,no-X11-forwarding,permitopen="localhost:62222"

Überprüfen

Um sicherzustellen, dass es wie erwartet funktioniert, müssen einige Testfälle ausgeführt werden. In den folgenden Befehlen hostsollte durch das tatsächliche Login ersetzt werden, wenn es nicht eingestellt ist ~/.ssh/config. Hinter dem Befehl wird ein Befehl angezeigt, der entweder auf dem Client oder auf dem Server ausgeführt werden soll (wie angegeben).

# connection closed:
ssh host
# connection closed (/bin/date is not executed):
ssh host /bin/date
# administratively prohibited (2x):
ssh host -N -D 62222 # client: curl -I --socks5 localhost:62222 example.com
ssh host -N -L 8080:example.com:80 # client: curl -I localhost:8080
sftp host
# should be possible because the client should forward his SSH server
ssh host -N -R 8080:example.com:80 # server: curl -I localhost:8080
# This works, it forwards the client SSH to the server
ssh host -N -R 62222:localhost:22
# unfortunately, the client can listen on that port too. Not a big issue
ssh host -N -L 1234:localhost:62222

Fazit

Checkliste: Der SSH-Benutzer sollte nicht in der Lage sein:

  • Shell-Befehle ausführen - fertig
  • auf Dateien zugreifen oder Dateien auf den Server hochladen - fertig
  • benutze den Server als Proxy (zB Webproxy) - fertig
  • Zugriff auf lokale Dienste, die ansonsten aufgrund einer Firewall nicht öffentlich zugänglich waren - teilweise kann der Client nicht auf andere Ports als 62222 zugreifen, sondern kann den Port 62222 auf dem Server überwachen und eine Verbindung herstellen
  • Server beenden - erledigt (Beachten Sie, dass diese Überprüfungen auf den SSH-Server beschränkt sind. Wenn auf dem Computer ein anderer anfälliger Dienst vorhanden ist, kann ein möglicher Angreifer Befehle ausführen, den Server beenden usw.)
Lekensteyn
quelle
3
Damit dies funktioniert, muss das von hinzugefügte Konto useraddentsperrt werden. /etc/shadowDies kann durch Ersetzen des Kennworts durch ein Sternchen ( *) oder durch Festlegen eines Kennworts mithilfe von erfolgen sudo passwd limited-user.
Lekensteyn
2
SFTP funktioniert, weil der SSH-Server den sftp-serverBefehl ausführt. Mit ForceCommandwird dieser Befehl nicht mehr ausgeführt.
Lekensteyn
2
Nützlich ist auch die from=Option in authorized_keys. Sie können die Verwendung des Schlüssels auf Quellen mit einer bestimmten IP-Adresse oder einem bestimmten Hostnamen beschränken. Beispiel from="1.1.1.1"oder from="10.0.0.?,*.example.com". Siehe Abschnitt "AUTHORIZED_KEYS-DATEIFORMAT" in der Manpage ( linux.die.net/man/8/sshd ) für alle authorized_keys-Optionen.
Donn Lee
2
"AllowTcpForwarding local" verbietet die Fernweiterleitung. (Ich weiß nicht, ob es das gab, als diese Antwort geschrieben wurde.)
Simon Sapin
1
Beachten Sie, dass diese durch anhaltende SSH - Verbindungen unterbrochen wird, so sollten Sie nicht so etwas wie haben Host * ControlMaster autoin Ihrer ~/.ssh/configDatei , wenn sie mit Anschluss ssh -N. Wenn Sie es brauchen, verwenden Siessh -N -o ControlMaster=no
nh2
3

Ich bin mir sicher, dass es dafür viele Lösungen gibt, die robuster sind als die, die ich vorschlage. Dies kann jedoch für Ihre Bedürfnisse ausreichend sein. Um dies zu tun, gehe ich davon aus, dass der Benutzer in der Lage ist, SSH-Schlüssel-basierte Authentifizierung durchzuführen (Putty oder irgendein Unix-SSH sollte dies unterstützen).

  • Fügen Sie einen Benutzer wie gewohnt hinzu ('adduser' oder ein anderes Tool)

  • Erstellen Sie die Benutzer .ssh dir und .ssh / authorized_keys

your_user $ sudo -Hu ssh_forwarder /bin/bash

ssh_forwarder $ cd ~
ssh_forwarder $ mkdir .ssh
ssh_forwarder $ ( umask 066 && cat > .ssh/authorized_keys ) <<EOF
no-agent-forwarding,no-X11-forwarding,command="read a; exit" ssh-rsa AAAB3NzaC1y....2cD/VN3NtHw== smoser@brickies
EOF
  • Deaktivieren Sie den Kennwortzugriff auf dieses Konto.
your_user $ sudo usermod --lock ssh_forwarder

Jetzt kann der Benutzer nur noch über den Zugriff auf den richtigen SSH-Schlüssel auf Ihr System zugreifen, und SSH führt "/ bin / bash -c 'read a'" für sie aus, unabhängig davon, was sie ausführen möchten. 'read a' liest einfach bis zu einer neuen Zeile und dann wird die Shell beendet, sodass der Benutzer nur die Eingabetaste drücken muss, um die Verbindung zu beenden.

Es gibt viele andere Dinge, die Sie in 'command =' tun können. man authorized_keysWeitere Informationen finden Sie unter und suchen Sie nach 'command'.

Wenn Ihnen die Tatsache nicht gefällt, dass durch Drücken der Eingabetaste die Verbindung getrennt wird, können Sie für den Eintrag 'command =' Folgendes verwenden:

command="f=./.fifo.$$ && mkfifo $f && trap \"rm -f $f\" EXIT && read a <$f && echo $a; exit;"

Dadurch wird nur ein temporäres FIFO im Home-Verzeichnis des Benutzers erstellt und versucht, daraus zu lesen. Es wird nichts in diese Datei geschrieben, sodass diese auf unbestimmte Zeit hängen bleibt. Wenn Sie diese Verbindung erzwingen möchten, können Sie außerdem Folgendes tun:

 your_user$ echo GOODBYE | sudo tee ~ssh_forwarder/.fifo.*

Dies sollte sehr wenig Ressourcen verbrauchen, und in diesem Skript sollte nichts schief gehen können, das nicht zum Beenden der Shell führen würde.

sleep 1h; echo You have been here too long. Good bye.

Ich habe nicht ohne weiteres gesehen, wie Sie dem Benutzer erlauben können, remote weiterzuleiten ( ssh -R), aber zu begrenzen ( ssh -L). Vielleicht könnte 'permitopen' verwendet werden. Googeln war nicht sehr hilfreich. Es scheint so, als ob etwas wie "Keine Portweiterleitung, permitremoteopen = 10001" sinnvoll wäre ssh -R 6901:localhost:6901.

Das ist eine Lösung. Es kann definitiv verbessert werden, und das Öffnen von Remote-Ports sollte überprüft werden. Wenn es mein Ziel wäre, meiner Großmutter die Verbindung zu meinem LAN zu ermöglichen, damit ich mit VNC ihren Bildschirm sehen kann und der Zugriff auf diese Schlüssel auf sie beschränkt ist, würde ich mich persönlich einigermaßen sicher fühlen. Wenn dies für ein Unternehmen wäre, wäre eine gründlichere Untersuchung erforderlich. Zu beachten ist, ssh -Ndass keine Shell angefordert wird, sodass der 'command =' - Code nicht ausgeführt wird.

Andere, möglicherweise sicherere Mechanismen können das Erstellen einer benutzerdefinierten Shell für den Benutzer und sogar das Sperren dieser Shell mit AppArmour umfassen.

smoser
quelle
3
Das sieht sehr hackisch aus, es ist nicht einmal notwendig, eine Shell zu haben, da kein Befehl ausgeführt werden muss. Siehe die Handbuchseite vonssh für die -NOption. Es muss einen saubereren Weg geben, um dies zu erreichen.
Lekensteyn
Das ist richtig. Ich hoffe, auch eine sauberere Lösung zu finden. Ich denke, dass authorized_keys in Verbindung mit No-Port-Forwarding eine ziemlich gute Lösung wäre, wenn es eine "permitremoteopen" -Option gäbe.
smoser
Ich habe ein paar Nachforschungen angestellt (siehe oben). Da ssh -Nüberhaupt kein Befehl ausgeführt wird, ist es kein Problem, command="something"die Sitzung zu schließen.
Lekensteyn
Vermisse ich etwas? Es schien, chsh ssh_forwarder -s /bin/false als ob das alles ist, was es braucht.
Typelogic