SSH mit chroot und funktionieren nur „sftp“, „rsync“ (beides)?

SSH mit chroot und funktionieren nur „sftp“, „rsync“ (beides)?

Ich habe zwei Benutzer und einen freigegebenen Ordner auf meinem Ubuntu-Server:

  1. Benutzer writer, der Schreibzugriff auf hat /var/shared. Es handelt sich um eine Anwendung, die regelmäßig remote mit einem SSH-Schlüssel Dateiänderungen in diesem Ordner vornimmt.

  2. Der Benutzer readerwird von mehreren Clients mit einem SSH-Schlüssel verwendet, einem Schlüssel, den sie ohne meine Erlaubnis erhalten können. Deshalb muss ich die in dieser Shell verfügbaren Befehle einschränken.

Frage:

Ich muss die für den readerBenutzer zugänglichen Befehle einschränken, sodass nur SFTP- und Rsync-Protokolle verwendet werden können (keine Standardbefehle wie mkdir, ls, top, ...). Nur das Verzeichnis /var/sharedmuss lesbar sein und muss ein Stammpfad sein, d. h. es muss nicht cdhinein, es ist bereits /in SFTP oder Rsync.

Wie schreibe ich ein Shell-Skript, das ich usermod -sfür Benutzer anwenden kann reader, die ein solches Verhalten erzielen?Ich kann keine Beispiele finden. Wie kann ich dafür sorgen, writerdass auch in "gesperrt" bleibt /var/share, sodass die Pfade dieselben sind?

Anmerkungen:

  1. sshd_configIch habe bereits die Matchund ForceCommand internal-sftp-Direktiven ausprobiert ChrootDirectory. Dies erfordert, ChrootDirectorydass die im Besitz von root ist und nicht beschreibbar (755 oder weniger) ist, und unterstützt nicht rsync.

  2. Ich habe es versucht rssh, aber es funktioniert einfach nicht für Verzeichnisse außerhalb des Home-Verzeichnisses des angemeldeten Benutzers. Ich konnte Benutzer also nicht mit unterschiedlichen Berechtigungen in dasselbe Verzeichnis chrooten.

  3. command=".." ssh-rsa....Ich habe versucht, es in der Datei zu verwenden authorized_keys, habe aber nicht verstanden, wie ich das gewünschte Verhalten aktivieren kann. Ich überprüfe nur rrsyncdas Skript in den rsync-Dokumenten. Diese Methode hat keine chrootder Funktionen, die ich brauche.

Kann ich zumindest ein Beispiel für solche Shells bekommen? Ist das mit Skripten erreichbar?

Bash und C++ (falls erforderlich) sind willkommen. Ausgabe von ldd /bin/bash:

linux-vdso.so.1 =>  (0x00007fff7e9d1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f79dfd8b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f79dfb87000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f79df7bd000)
/lib64/ld-linux-x86-64.so.2 (0x000055bd0767c000)

Antwort1

Zunächst ChrootDirectorymuss es root gehören und darf nicht von anderen Benutzern geschrieben werden. /var/sharedIn Ihrem Fall kann es also kein ChrootDirectoryWert sein.

Ich würde empfehlen, ein Verzeichnis zu erstellen, das nur von Root-Benutzern beschreibbar ist, und /var/sharedden Zugriff innerhalb dieses Verzeichnisses entweder über Linux-Bind-Mounting oder eine Art Workaround über symbolische Links zu ermöglichen.

Wenn Sie einschränken müssen sftpoder müssen rsync, müssen Sie SSH_ORIGINAL_COMMANDdie Umgebungsvariable auf dem Server mithilfe eines „Wrappers“ prüfen, der entweder über ForceCommandoder über commandim öffentlichen SSH-Schlüssel erzwungen wird. Diese Variable wird nach der Authentifizierung des Benutzers gefüllt und enthält Informationen darüber, welche Art von Verbindung die Clients herstellen werden. Denn sftpes hätte sftp-serverdarin, denn rsynces hätte rsync, für nur ssheine Sitzung wäre es, wenn ich mich recht entsinne, leer, denn ssh datees wäre date. SSH_ORIGINAL_COMMANDwird unter einem authentifizierten Benutzer auf dem Server ausgeführt!

So könnte Ihr Wrapper beginnen:

#!/usr/bin/env bash

set -eu
set -o pipefail

[[ -z "${SSH_ORIGINAL_COMMAND:-}" ]] && exit 1

case "${SSH_ORIGINAL_COMMAND}" in
    "/usr/libexec/openssh/sftp-server")
        exec /usr/libexec/openssh/sftp-server
        ;;
    "rsync --server"*)
        exec ${SSH_ORIGINAL_COMMAND}
        ;;
    *)
        exit 1
        ;;
esac

Wie Sie sehen, ssh -verhalten Sie Informationen darüber, welcher Befehl vom Server ausgeführt wird. Sie können daher /tmpauch in Ihrem Wrapper etwas anderes ändern.

$ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/

verwandte Informationen