Ich habe zwei Benutzer und einen freigegebenen Ordner auf meinem Ubuntu-Server:
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.Der Benutzer
reader
wird 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 reader
Benutzer 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/shared
muss lesbar sein und muss ein Stammpfad sein, d. h. es muss nicht cd
hinein, es ist bereits /
in SFTP oder Rsync.
Wie schreibe ich ein Shell-Skript, das ich usermod -s
für Benutzer anwenden kann reader
, die ein solches Verhalten erzielen?Ich kann keine Beispiele finden. Wie kann ich dafür sorgen, writer
dass auch in "gesperrt" bleibt /var/share
, sodass die Pfade dieselben sind?
Anmerkungen:
sshd_config
Ich habe bereits dieMatch
undForceCommand internal-sftp
-Direktiven ausprobiertChrootDirectory
. Dies erfordert,ChrootDirectory
dass die im Besitz von root ist und nicht beschreibbar (755 oder weniger) ist, und unterstützt nichtrsync
.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.command=".." ssh-rsa....
Ich habe versucht, es in der Datei zu verwendenauthorized_keys
, habe aber nicht verstanden, wie ich das gewünschte Verhalten aktivieren kann. Ich überprüfe nurrrsync
das Skript in den rsync-Dokumenten. Diese Methode hat keinechroot
der 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 ChrootDirectory
muss es root gehören und darf nicht von anderen Benutzern geschrieben werden. /var/shared
In Ihrem Fall kann es also kein ChrootDirectory
Wert sein.
Ich würde empfehlen, ein Verzeichnis zu erstellen, das nur von Root-Benutzern beschreibbar ist, und /var/shared
den 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 sftp
oder müssen rsync
, müssen Sie SSH_ORIGINAL_COMMAND
die Umgebungsvariable auf dem Server mithilfe eines „Wrappers“ prüfen, der entweder über ForceCommand
oder über command
im ö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 sftp
es hätte sftp-server
darin, denn rsync
es hätte rsync
, für nur ssh
eine Sitzung wäre es, wenn ich mich recht entsinne, leer, denn ssh date
es wäre date
. SSH_ORIGINAL_COMMAND
wird 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 -v
erhalten Sie Informationen darüber, welcher Befehl vom Server ausgeführt wird. Sie können daher /tmp
auch 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/