Aktivieren Sie den SSH-Shell-Zugriff, aber deaktivieren Sie den SFTP-Zugriff

21

Ich habe nach einer brauchbaren Antwort auf diese Frage gesucht, und die meisten Antworten enthalten Ratschläge, warum ich es nicht tun soll. Hier ist jedoch das Szenario und was es erforderlich macht:

Ich habe eine Konsolen-App, und in jedem Benutzerprofil gibt es einen Startbefehl für die App, und direkt nach dem Befehl, der sie startet, gibt es einen "exit" -Befehl, mit dem sie vom System abgemeldet werden. Ich möchte nur, dass sie über die von ihr bereitgestellte Oberfläche auf diese Konsolen-App zugreifen können. Beim Start zeigt die App dem Benutzer eine Liste von Clients an, auf die über die App zugegriffen werden kann, wobei jeder Client über ein eigenes Datenverzeichnis verfügt. Benutzern wird nur der Zugriff auf die Clients gewährt, auf die sie Zugriff benötigen.

Hier ist das Problem: Wenn ich den Benutzern SSH-Zugriff gewähre, können sie sich auch mit einem SFTP-Client anmelden, wodurch sie direkten Zugriff auf die Datenverzeichnisse für die App erhalten, was SEHR unerwünscht ist, da dies ebenfalls zur Folge hat Sie greifen auf die Datenverzeichnisse zu, auf die sie keinen Zugriff haben sollten.

Dies war so einfach, wenn eine Telnet / FTP-Kombination verwendet wurde, aber da ich den Benutzern nun Zugriff von überall im Internet gewähren möchte, war es mir nicht möglich, sie von SFTP auszuschließen Sie können weiterhin auf die Shell zugreifen, in der sie die App ausführen können.

Sosaisapunk
quelle
8
Ich vergesse die Details, aber ich denke, mit SSH können Sie die Ausführung eines einzelnen Befehls durch Benutzer einschränken, wenn diese sich anmelden. Sie erhalten keinen vollständigen Shell-Zugriff, wenn Sie dies einrichten. Dies kann für Ihren Anwendungsfall hilfreich sein. (Immerhin ist es möglich, den SFTP-Zugriff mit SSHFS zu emulieren. Durch das Deaktivieren von SFTP kann ein mäßig bestimmter Benutzer nicht auf Dateien zugreifen, auf die sein Benutzerkonto Zugriff hat.)
David Z
3
Darüber hinaus möchten Sie möglicherweise erwägen, Ihre Benutzer zu "chrooten". und für Ersatzdatenzugriff sieht es aus wie ein Designproblem
Dennis Nolte
2
Verwenden .profilefür das klingt nach der falschen Lösung. Ich glaube, dass es viel sinnvoller wäre, den Benutzer mit einer alternativen Shell einzurichten.
Kasperd
3
Versuchen Sie nicht, den .profileTrick zu verwenden, um den Zugriff einzuschränken, da das Umgehen trivial ist. (Siehe meine Antwort für Details)
Aleksi Torhamo

Antworten:

22

Bearbeiten:

Falls dies nicht offensichtlich ist, ist die folgende Antwort nicht als sichere Methode gedacht, um zu verhindern, dass SFTP von Personen mit Shell-Zugriff auf den Server verwendet wird. Es ist nur eine Antwort, die erklärt, wie Sie die externe Sichtbarkeit deaktivieren können. Weitere Informationen zur Sicherheit auf Benutzerebene finden Sie in den Antworten von @cpast und @Aleksi Torhamo. Wenn Sicherheit im Mittelpunkt steht, ist diese Antwort nicht die richtige. Wenn einfache Service-Sichtbarkeit Ihr Fokus ist, dann ist dies Ihre Antwort.

Wir fahren nun mit der ursprünglichen Antwort fort:


Kommentieren Sie die SFTP-Unterstützung in sshd_config aus (und starten Sie sie natürlich neu sshd):

#Subsystem sftp /usr/lib/openssh/sftp-server

Wesley
quelle
1
Manchmal kann Linie seinSubsystem sftp internal-sftp
Kondybas
1
Ich habe Subsystem sftp /usr/libexec/sftp-server Aber das hat den Trick getan. Vielen Dank
sosaisapunk
16
Das klingt nicht plausibel. Wenn Sie beliebige Befehle auf dem Server ausführen können, können Sie das serverseitige Programm sftp ausführen. Auch wenn es nicht installiert ist, können Sie es als langen Shell-Befehl erneut implementieren und den sftp-Client veranlassen, diesen Befehl anstelle von sftp zu senden. Diese Methode macht die Verwendung von sftp möglicherweise weniger bequem, aber es gibt keine Möglichkeit, einen Benutzer, der beliebige Befehle ausführen kann, daran zu hindern, diese Befehle für Dateiübertragungen zu verwenden.
R ..
1
@sosaisapunk Das stimmt nicht. Die Benutzer können jeden Befehl ausführen, den sie möchten ssh user@host command, da er .profilein diesem Fall überhaupt nicht ausgeführt wird und Ihre App daher überhaupt nicht startet. Sie können vollen Shellzugriff erhalten, indem sie einfach sagen ssh -t user@host bash. Probieren Sie es einfach aus und Sie werden sehen. Das Subsystem ist nur ein Befehlsalias. Wenn sie zuvor sftp verwenden konnten, können sie es weiterhin verwenden - und jeden anderen gewünschten Befehl. Lies meine Antwort unten.
Aleksi Torhamo
1
@sosaisapunk: Nein, der Punkt ist, dass Sie dies mit ssh tun können, aber nicht mit, .profileda es nicht für die Sicherheit gedacht ist und leicht umgangen werden kann. In meiner Antwort habe ich drei verschiedene Methoden aufgelistet, um dies mit ssh zu tun. Kurz gesagt, verschieben Sie einfach den Aufruf Ihrer App von .profilein ein Shell-Skript und entweder 1) legen Sie das Shell-Skript als Shell des Benutzers fest 2) legen Sie das Shell-Skript als (richtig zugeordnet) fest ForceCommandin sshd_config3) wechseln Sie zur Authentifizierung mit öffentlichem Schlüssel und legen Sie das fest Shell-Skript wie commandin .ssh/authorized_keys. (Außerdem sollten Sie @name verwenden, damit die Leute über die Kommentare informiert werden.)
Aleksi Torhamo
28

Wie bereits erwähnt, reicht die Deaktivierung sftpbei weitem nicht aus. Ein Benutzer mit uneingeschränktem sshZugriff kann alle Dateien anzeigen, für die sein Konto Berechtigungen besitzt, und alle Änderungen vornehmen, die er ändern darf. Außerdem kann er problemlos alles herunterladen, was er lesen kann Maschine. Die einzige Möglichkeit, dies zu verhindern, besteht darin, den Zugriff tatsächlich einzuschränken. Es ist auch nicht ideal, sich darauf zu verlassen .profile, um Benutzer einzuschränken, da dies nicht der Grund ist (Bearbeiten: Wie Aleksi in seiner Antwort erwähnt, ist es in der Tat trivial, zu umgehen .profile; das Problem .profileist, dass es der Bequemlichkeit und nicht der Sicherheit dient, also nicht Verwenden Sie Dinge, die der Sicherheit dienen, wie die folgenden, um die Sicherheit zu gewährleisten.

Hierfür gibt es zwei grundlegende Möglichkeiten: Sie können sie über Dateiberechtigungen einschränken oder sie zwingen, nur Ihre Konsolen-App auszuführen. Der zweite Weg ist besser: Ordnen Sie Benutzer, die auf die Konsolen-App beschränkt sein sollen, einer Gruppe zu (z. B. customers). sshd_configFügen Sie dann in die folgenden Zeilen ein:

Match Group customers
ForceCommand /path/to/app

Dies bewirkt, dass alle Verbindungen von Benutzern in dieser Gruppe die Konsolen-App öffnen. Sie können nichts anderes starten, einschließlich des sftpServer-Tools. Dies hindert sie auch daran, mit dem System etwas anderes zu tun , und verwendet im Gegensatz .profiledazu den SSH-Server selbst ( .profileschränkt sie an der Shell ein und ForceCommandverhindert auch, dass andere Dinge ausgeführt werden, bei denen keine Shell gestartet wird). Auch im Gegensatz zu .profiledieser ist konzipiert als Sicherheits Sache; Es wurde speziell entwickelt, um einem böswilligen Benutzer das Ausweichen zu verwehren.

Die (wahrscheinlich minderwertige) Alternative wäre das Erstellen eines neuen Benutzers zum Ausführen der Konsolen-App. Sie würden dann die Datenverzeichnisse auf diesen Benutzer beschränken, die Konsolen-App festlegen, die diesem Benutzer gehört, und u+sim Programm festlegen . Das ist das setuidbisschen; Dies bedeutet, dass jemand, der das Konsolenprogramm ausführt, dies mit den Berechtigungen des Programmbesitzers tut. Auf diese Weise hat der Benutzer selbst keinen Zugriff auf die Verzeichnisse, sondern nur über das Programm. Sie sollten jedoch wahrscheinlich nur verwenden ForceCommand, da dies den gesamten Zugriff auf "Nur dieses Programm ausführen" einschränkt .

cpast
quelle
4
Ich möchte hinzufügen, ForceCommanddass SSH-Port-Weiterleitung nicht verhindert.
Nyuszika7h
1
Verlassen auf .profileist eigentlich mehr als "nicht ideal"; Es kann leicht umgangen werden (siehe meine Antwort für Details) und bietet daher keinerlei Schutz, sondern nur ein falsches Sicherheitsgefühl.
Aleksi Torhamo
@ AleksiTorhamo Ah. Ich habe vermutet, dass Sie es umgehen könnten, war mir aber nicht sicher, wie (ich vermute im Allgemeinen, dass Dinge, die nicht für die Sicherheit gedacht sind, umgangen werden können). Vielen Dank für die Details dazu, wie!
21.
15

Versuchen Sie nicht, dies zu tun, .profileda dies keinerlei Sicherheit bietet und genau nichts einschränkt!

Es spielt keine Rolle , was Sie setzen in .profile, da Sie Bypass kann es einfach durch einen Befehl geben auf der SSH - Befehlszeile auszuführen, wie folgt aus : ssh user@host command. Sie können weiterhin normalen Shell-Zugriff erhalten, indem Sie tun ssh -t user@host bash.

Das Deaktivieren des SFTP-Subsystems, wie in einer anderen Antwort erwähnt, hilft überhaupt nicht. Subsysteme sind im Wesentlichen nur Aliase zu Befehlen, und Sie können sftp weiterhin normal verwenden, indem Sie dies tun sftp -s /path/to/sftp-executable user@host.

Wie in cpast und einigen Kommentaren bereits erwähnt, sollten Sie die richtigen Mechanismen zur Einschränkung des Zugriffs verwenden. Das ist,

  • Verwenden Sie ForceCommandinsshd_config
  • Verwenden Sie die passwortlose Anmeldung und command="..."in.ssh/authorized_keys
  • Ändern Sie die Shell des Benutzers auf etwas, das die Möglichkeiten des Benutzers einschränkt

Anmerkungen:

  • command="..." Gilt nur für einen Schlüssel. Dadurch wird die SSH-Anmeldung für den Benutzer, der ein Kennwort oder einen anderen Schlüssel verwendet, nicht eingeschränkt
  • Möglicherweise möchten Sie auch die Portweiterleitung usw. einschränken (Portweiterleitung, X11-Weiterleitung, Agentenweiterleitung und Pty-Zuweisung sind diejenigen, von denen ich gehört habe).
    • AllowTcpForwarding usw. in sshd_config
    • no-port-forwarding usw. in .ssh/authorized_keys
  • Wenn andere Daemons (z. B. FTP) ausgeführt werden, sollten Sie sicherstellen, dass sie den Benutzer nicht hereinlassen.
  • Sie können die Shell des Benutzers in ein Skript ändern, das das tut, was Sie wollen. Es läuft entweder ohne Argumente oder ähnlichscript -c 'command-the-user-wanted-to-run'
  • Beide ForceCommandund command="..."führen den Befehl über die Shell des Benutzers aus, sodass sie nicht funktionieren, wenn die Shell des Benutzers auf z. /bin/falseoder/sbin/nologin

Haftungsausschluss: Ich bin auf keinen Fall ein Experte in dieser Angelegenheit. Obwohl ich sagen kann, dass die .profileSache nicht sicher ist, kann ich nicht versprechen, dass es bei den anderen Methoden, die ich nicht kenne, kein "gotcha" gibt Über. Soweit ich weiß, sind sie sicher, aber ich wäre nicht die erste Person, die sich im Internet irrt.

Aleksi Torhamo
quelle
1
Es scheint, dass zumindest für ForceCommandund erzwungene kennwortlose Anmeldung mit command=in authorized_keys, obwohl dies zuvor umgangen wurde, ein Fehler auf dem Server vorliegt: Es soll vor einem böswilligen Benutzer sicher sein, und ein Benutzer, der es umgeht, gilt als ernsthafte Sicherheitsanfälligkeit im SSH-Server (und ist damit ein Prioritätsfix). Wie Sie bereits .profilebetont haben, ist dies vom Design her umgangen: Da es sich nicht um ein Sicherheitsmerkmal handelt, ist es aus Sicht des Shell-Entwicklers vollkommen in Ordnung, wenn ein Benutzer es umgeht.
21.
1
@cpast: Ja, ich habe darüber nachgedacht, ob es noch mehr Funktionen wie die Portweiterleitung gibt. Ich meine, wenn Sie nicht wüssten, dass ssh Portweiterleitung zulässt und nur dazu verwendet wird ForceCommand, den Zugriff einzuschränken, und einen Daemon hatte, der nur lokale Verbindungen überwacht und keine Authentifizierung durchführt, könnte der ssh-Benutzer trotzdem auf den Daemon zugreifen. Die von mir aufgelisteten Funktionen sind diejenigen, z. Git-Hosting-Lösungen werden normalerweise deaktiviert, und ich habe keine zusätzlichen "böse aussehenden" in den Hilfeseiten gesehen, aber ich habe noch kein offizielles "So verwenden Sie ForceCommandsicher" -Dokument gefunden.
Aleksi Torhamo
Zwar ~/.profileist der Benutzer bearbeitbar und für die Sicherheit nicht hilfreich, aber könnten Sie die Technik von cpast sinnvoll machen, indem Sie sie in das Programm einfügen /etc/profile? Sie können die UID überprüfen, um sie auf die richtigen Benutzer zu beschränken.
Küken
1
@chicks: Nein, es hat genau das gleiche Problem. Das Problem ist nicht, dass die Datei vom Benutzer bearbeitet werden kann. Das Problem ist, dass beide Dateien vollständig umgangen werden können. Die Dateien werden nur für Login-Shells verwendet, die Sie erhalten, wenn Sie nur sagen ssh user@host, aber wenn Sie ssh anweisen, einen Befehl auszuführen - dh. ssh user@host command- Sie erhalten keine Login-Shell mehr und die Dateien werden überhaupt nicht berührt. Sie können also alle Einschränkungen, die jemand versucht hat, mit den Dateien zu umgehen, indem Sie einfach ein zusätzliches Argument an ssh übergeben.
Aleksi Torhamo
2
@chicks: Außerdem habe ich gerade festgestellt, dass Sie sich auf cpast bezogen haben. Die Methode in der Antwort von cpast wird nicht verwendet .profile, sie verwendet sshd_configund sollte sicher sein. Er erwähnt nur .profileals eine Methode, die Sie nicht verwenden sollten, um dies zu tun.
Aleksi Torhamo
1

Es ist möglich, SSH global und pro Benutzer / Gruppe zu aktivieren und SFTP zu deaktivieren.

Ich persönlich benötige dies, weil ich über SSH Zugriff auf einige Git-Repositorys gewähren möchte und ich nicht benötigte Systeme gerne deaktiviere. In diesem Fall wird SFTP nicht benötigt.

Global

Sie können SFTP auf verschiedene Arten für alle Benutzer deaktivieren.

Das fehlende Subsystem

Der von SSH verwendete SFTP-Dämon kann über das SubsystemSchlüsselwort konfiguriert werden . Aus dem sshd_config(5)Handbuch:

Subsystem
        Configures an external subsystem (e.g. file transfer daemon).
        Arguments should be a subsystem name and a command (with optional
        arguments) to execute upon subsystem request.

        The command sftp-server(8) implements the “sftp” file transfer
        subsystem.

        Alternately the name “internal-sftp” implements an in-process
        “sftp” server.  This may simplify configurations using
        ChrootDirectory to force a different filesystem root on clients.

        By default no subsystems are defined.

Die letzte Zeile schlägt vor, dass es ausreichen sollte, kein Subsystem für "sftp" zu definieren.

Eine falsche Lüge

Sie können SFTP auch deaktivieren, indem Sie den von SSH verwendeten SFTP-Dämon auf einen nicht verwendbaren Wert einstellen. Konfigurieren Sie das Subsystem "sftp" beispielsweise so, dass /bin/false:

Subsystem sftp /bin/false

Wenn etwas versucht, sich über SFTP anzumelden, versucht der SSH-Dämon, den "sftp-Dämon" zu erzeugen /bin/false. Das /bin/falseProgramm macht nur eine Sache, nämlich einen Fehlercode zurückzugeben. Der SFTP-Verbindungsversuch wird effektiv abgelehnt.

Pro Benutzer / Gruppe

Es ist auch möglich, SFTP pro Benutzer, Gruppe oder einige andere Kriterien zu deaktivieren.

Dies funktioniert nicht, wenn Ihr Benutzer eine reguläre Shell-Eingabeaufforderung erhalten soll. Es macht auch keinen Sinn, da Sie die meisten Dinge umgehen könnten, wenn Sie Shell-Zugriff haben. Dies funktioniert nur, wenn Sie nur Zugriff auf ein bestimmtes Programm gewähren möchten.

Passend

Um eine Gruppe von Benutzern abzugleichen, können Sie SSH mit dem MatchSchlüsselwort konfigurieren . Aus dem sshd_config(5)Handbuch:

Match
        ...

        The arguments to Match are one or more criteria-pattern pairs or the
        single token All which matches all criteria.  The available criteria
        are User, Group, Host, LocalAddress, LocalPort, and Address.  The
        match patterns may consist of single entries or comma-separated
        lists and may use the wildcard and negation operators described in
        the PATTERNS section of ssh_config(5).

        ...

Einige Beispiele:

  • Match User eva Entspricht dem Benutzer "eva"
  • Match User stephen,maria Entspricht den Benutzern "stephen" und "maria"
  • Match Group wheel,adams,simpsons Entspricht den Gruppen "Wheel", "Adams", "Simpsons"

Wenn Sie weitere Informationen wünschen, enthält das sshd_config(5)Handbuch zahlreiche Informationen .

Befehl erzwungen

Normalerweise erhalten Sie die Anmeldeshell des Benutzers, wenn Sie eine Verbindung über SSH herstellen. SSH kann jedoch so konfiguriert werden, dass ein bestimmter Befehl erzwungen wird. Der Befehl wird für jede SSH-Verbindung, einschließlich SFTP, erzwungen, sodass Sie möglicherweise die Option haben, den gewünschten Befehl zu erzwingen.

Der zu erzwingende Befehl kann mit dem ForceCommandSchlüsselwort konfiguriert werden . Aus dem sshd_config(5)Handbuch:

ForceCommand
        Forces the execution of the command specified by ForceCommand,
        ignoring any command supplied by the client and ~/.ssh/rc if
        present.  The command is invoked by using the user's login shell
        with the -c option.  This applies to shell, command, or subsystem
        execution.  It is most useful inside a Match block.  The command
        originally supplied by the client is available in the
        SSH_ORIGINAL_COMMAND environment variable.  Specifying a command of
        “internal-sftp” will force the use of an in-process sftp server that
        requires no support files when used with ChrootDirectory.  The
        default is “none”.

So können Sie den eingeschränkten Befehl erzwingen, den Sie verwenden möchten ForceCommand <your command>. Beispielsweise:

Match User kim
        ForceCommand echo 'successful login man, congrats'

Beispiel

In meinem Fall, in dem ich Git-Zugriff gewähren möchte, muss der Benutzer nur Zugriff auf haben git-shell. In diesem Abschnitt wird SFTP für meine Git-Benutzer zusammen mit einigen Sicherheitsoptionen deaktiviert:

Match Group git

        # have to do this instead of setting the login shell to `git-shell`,
        # to disable SFTP
        ForceCommand /usr/bin/git-shell -c "$SSH_ORIGINAL_COMMAND"

        # disable stuff we don't need
        AllowAgentForwarding no
        AllowTcpForwarding no
        AllowStreamLocalForwarding no
        PermitOpen none
        PermitTunnel no
        PermitTTY no
        X11Forwarding no
aude
quelle
In meinem Fall wollte ich MySQL-Zugriff nur für einen bestimmten autorisierten Schlüssel zulassen (dh keine Änderungen an der Datei sshd_config). Ich habe es mit den folgenden ~ / .ssh / authorized_keys-Optionen für den jeweiligen Schlüssel geschafft: command = "/ usr / bin / echo 'Nur MySQL-Zugriff ist erlaubt.'", No-pty, no-X11-forwarding, allowopen = "127.0.0.1:3306"
Martin_ATS