SFTP mit Chroot abhängig vom öffentlichen Schlüssel des verbindenden Benutzers

9

Ich möchte einen Server (mit Debian oder FreeBSD) erstellen, der Backups von verschiedenen Clients über sshfs empfängt. Jeder Client sollte in der Lage sein, seine eigenen Sicherungsdaten zu lesen und zu schreiben, jedoch nicht die Daten der anderen Clients.

Ich hatte die folgende Idee: Jeder Client stellt über die Authentifizierung mit öffentlichem Schlüssel eine Verbindung zu [email protected] her. Der Benutzer Backup verfügt über eine spezielle Datei authorized_keys, wie folgt aus :

command="internal-sftp" chroot="/backup/client-1/data" ssh-rsa (key1)
command="internal-sftp" chroot="/backup/client-2/data" ssh-rsa (key2)
command="internal-sftp" chroot="/backup/client-3/data" ssh-rsa (key3)
etc...

Dies hätte den Vorteil, dass ich nicht für jeden Client einen eigenen Benutzer verwenden müsste und die Datei "authorized_keys" problemlos mit einem Skript automatisch generieren könnte.

Es gibt nur ein Problem: Das chroot=...funktioniert nicht. Die autorisierte_keys-Datei von OpenSSH scheint keine Entsprechung für ChrootDirectory zu haben (die in / etc / ssh / sshd_config entweder global oder in einem Match User-Block funktioniert).

Gibt es eine einigermaßen einfache Möglichkeit, mit OpenSSH das zu erreichen, was ich möchte? Vielleicht die command=...Richtlinie auf clevere Weise verwenden? Gibt es alternativ andere SFTP-Server, die tun können, was ich will?

BEARBEITEN : Um klarer zu machen, was ich erreichen möchte: Ich möchte, dass mehrere Clients Dateien auf meinem Server speichern können. Jeder Client sollte nicht in der Lage sein, die Dateien eines anderen Clients zu sehen. Und ich möchte meinen Server nicht mit Dutzenden von Benutzerkonten verunreinigen, daher möchte ich eine einfach zu verwaltende Lösung für die Clients, um ein Benutzerkonto freizugeben und trotzdem keinen Zugriff auf die Dateien des jeweils anderen zu haben.

Xykon42
quelle

Antworten:

5

Gibt es alternativ andere SFTP-Server, die tun können, was ich will?

Ja, Sie können proftpd verwenden

Benutzerumgebung vorbereiten. Mit ProFTPD muss dem Benutzer keine gültige Shell angegeben werden.

# useradd -m -d /vhosts/backup/user1/ -s /sbin/nologin user1
# passwd --lock user1
Locking password for user user1.
passwd: Success

# mkdir /vhosts/backup/user1/.sftp/
# touch /vhosts/backup/user1/.sftp/authorized_keys

# chown -R user1:user1 /vhosts/backup/user1/
# chmod -R 700 /vhosts/backup/user1/

Um öffentliche OpenSSH-Schlüssel in SFTPAuthorizedUserKeys zu verwenden, müssen Sie diese in das RFC4716-Format konvertieren. Sie können dies mit dem Tool ssh-keygen tun:

# ssh-keygen -e -f user1.public.key > /vhosts/backup/user1/.sftp/authorized_keys

Richten Sie ProFTPD ein

ServerName "ProFTPD Default Installation"
ServerType standalone
DefaultServer off

LoadModule mod_tls.c
LoadModule mod_sftp.c
LoadModule mod_rewrite.c

TLSProtocol TLSv1 TLSv1.1 TLSv1.2

# Disable default ftp server
Port 0

UseReverseDNS off
IdentLookups off

# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask 022

# PersistentPasswd causes problems with NIS/LDAP.
PersistentPasswd off

MaxInstances 30

# Set the user and group under which the server will run.
User nobody
Group nobody

# Normally, we want files to be overwriteable.
AllowOverwrite                  on

TimesGMT off
SetEnv TZ :/etc/localtime

<VirtualHost sftp.example.net>
    ServerName "SFTP: Backup server."
    DefaultRoot ~
    Umask 002
    Port 2121

    RootRevoke on

    SFTPEngine on
    SFTPLog /var/log/proftpd/sftp.log

    SFTPHostKey /etc/ssh/ssh_host_rsa_key
    SFTPHostKey /etc/ssh/ssh_host_dsa_key
    SFTPDHParamFile /etc/pki/proftpd/dhparam_2048.pem
    SFTPAuthorizedUserKeys file:~/.sftp/authorized_keys

    SFTPCompression delayed
    SFTPAuthMethods publickey
</VirtualHost>

<Global>
    RequireValidShell off
    AllowOverwrite yes

    DenyFilter \*.*/

    <Limit SITE_CHMOD>
        DenyAll
    </Limit>
</Global>

LogFormat default "%h %l %u %t \"%r\" %s %b"
LogFormat auth    "%v [%P] %h %t \"%r\" %s"
ExtendedLog /var/log/proftpd/access.log read,write

Erstellen Sie DH-Gruppenparameter (Diffie-Hellman).

# openssl dhparam -out /etc/pki/proftpd/dhparam_2048.pem 2048

Konfigurieren Sie einen SFTP-Client. Ich habe FileZilla verwendet

FileZilla SFTP-Servereinstellungen

Wenn Sie ProFPTD im Debug-Modus ausführen

# proftpd -n -d 3 

In der Konsole sehen Sie ungefähr Folgendes

2016-02-21 22:12:48,275 sftp.example.net proftpd[50511]: using PCRE 7.8 2008-09-05
2016-02-21 22:12:48,279 sftp.example.net proftpd[50511]: mod_sftp/0.9.9: using OpenSSL 1.0.1e-fips 11 Feb 2013
2016-02-21 22:12:48,462 sftp.example.net proftpd[50511] sftp.example.net: set core resource limits for daemon
2016-02-21 22:12:48,462 sftp.example.net proftpd[50511] sftp.example.net: ProFTPD 1.3.5a (maint) (built Sun Feb 21 2016 21:22:00 UTC) standalone mode STARTUP
2016-02-21 22:12:59,780 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): mod_cap/1.1: adding CAP_SETUID and CAP_SETGID capabilities
2016-02-21 22:12:59,780 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): SSH2 session opened.
2016-02-21 22:12:59,863 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): Preparing to chroot to directory '/vhosts/backup/user1'
2016-02-21 22:12:59,863 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): Environment successfully chroot()ed
2016-02-21 22:12:59,863 sftp.example.net proftpd[50512] sftp.example.net (192.168.1.2[192.168.1.2]): USER user1: Login successful

Und die folgenden Zeilen in einem /var/log/sftp.log

2016-02-21 22:12:48,735 mod_sftp/0.9.9[50309]: sending acceptable userauth methods: publickey
2016-02-21 22:12:48,735 mod_sftp/0.9.9[50309]: public key MD5 fingerprint: c2:2f:a3:93:59:5d:e4:38:99:4b:fd:b1:6e:fc:54:6c
2016-02-21 22:12:48,735 mod_sftp/0.9.9[50309]: sending publickey OK
2016-02-21 22:12:59,789 mod_sftp/0.9.9[50309]: public key MD5 fingerprint: c2:2f:a3:93:59:5d:e4:38:99:4b:fd:b1:6e:fc:54:6c
2016-02-21 22:12:59,790 mod_sftp/0.9.9[50309]: sending userauth success
2016-02-21 22:12:59,790 mod_sftp/0.9.9[50309]: user 'user1' authenticated via 'publickey' method

PS

Der konfigurierte Pfad für eine Datei mit autorisierten Schlüsseln ( SFTPAuthorizedUserKeys ) kann die Variable % u verwenden , die mit dem Namen des zu authentifizierenden Benutzers interpoliert wird. Diese Funktion unterstützt die Verwendung von Dateien mit autorisierten Schlüsseln pro Benutzer an einem zentralen Ort, anstatt dass Benutzer ihre eigenen autorisierten Schlüssel verwalten müssen (oder zulassen). Zum Beispiel:

SFTPAuthorizedUserKeys file:/etc/sftp/authorized_keys/%u

Ich möchte, dass mehrere Clients Dateien auf meinem Server speichern können. Jeder Client sollte nicht in der Lage sein, die Dateien eines anderen Clients zu sehen. Und ich möchte meinen Server nicht mit Dutzenden von Benutzerkonten verunreinigen, daher möchte ich eine einfach zu verwaltende Lösung für die Clients, um ein Benutzerkonto freizugeben und trotzdem keinen Zugriff auf die Dateien des jeweils anderen zu haben.

mit ProFTPD ist das auch möglich. Sie müssen nur meine anfängliche Konfiguration ein wenig ändern

<VirtualHost sftp.example.net>
    ...   
    SFTPAuthorizedUserKeys file:/etc/proftpd/sftp_authorized_keys
    AuthUserFile /etc/proftpd/sftp_users.passwd

    CreateHome on 0700 dirmode 0700 uid 99 gid 99

    RewriteHome on
    RewriteEngine on
    RewriteLog /var/log/proftpd/rewrite.log
    RewriteCondition %m REWRITE_HOME
    RewriteRule (.*) /vhosts/backup/%u
</VirtualHost>

Und erstellen Sie ein virtuelles Konto

# ftpasswd --passwd --file /etc/proftpd/sftp_users.passwd --sha512 --gid 99 --uid 99 --shell /sbin/nologin --name user1 --home /vhosts/backup

Das ist alles. Für jedes weitere Konto müssen Sie lediglich seinen öffentlichen Schlüssel zu den / etc / proftpd / sftp_authorized_keys hinzufügen

Hinweis: Die Datei muss am Ende eine neue Zeile enthalten! Es ist wichtig.

ALex_hha
quelle
Vielen Dank für Ihre detaillierte Antwort. Ich sehe jedoch nicht ein, wie dies mir helfen würde, mein Hauptziel zu erreichen, nur ein Benutzerkonto für viele Clients zu verwenden, die die Dateien des anderen nicht sehen können sollten. (Und mit einem Skript leicht zu handhaben sein.) Wenn ich meine ursprüngliche Frage noch einmal lese, gebe ich zu, dass es möglicherweise nicht ganz offensichtlich war, was ich erreichen wollte. Das tut mir leid.
Xykon42
Ich habe die Antwort aktualisiert
ALex_hha
1
Okay, mit einer kleinen Änderung funktioniert das tatsächlich gut, danke! Um sicherzustellen, dass Benutzer nicht auf die Dateien anderer Benutzer zugreifen können, indem sie ihren Benutzernamen erraten (oder meinen Server durch Missbrauch der CreateHome-Funktion überfluten), muss die Datei "authorized_keys" benutzerspezifisch sein, z. B. /foo/authorized_keys.d/%u.
Xykon42
6

das chroot=...funktioniert nicht.

Nein, auf der Handbuchseite gibt es nichts Vergleichbares sshd, das das Format der authorized_keysDatei beschreibt.

Wenn Sie chroot einsetzen command=würden, könnten Sie es nicht verwenden internal-sftp, da es den internen Funktionsaufruf im Inneren ersetzt sshd.

Empfohlener Weg ist, mehr Benutzer einzurichten, wenn Sie eine Trennung benötigen. Sie können auch Argumente verwenden, um internal-sftp, wenn Sie keine strikte Trennung benötigen (zum Beispiel nur verschiedene Arbeitsverzeichnisse), wie z

command="internal-sftp -d /backup/client-1/data" ssh-rsa (key1)

Es ist auch möglich, die Anzahl der Anfragen mithilfe der -POption wie auf der Handbuchseite für zu begrenzen sftp-server.

Jakuje
quelle
0

In der Zwischenzeit habe ich eine andere einfache Lösung gefunden, die zumindest in meinem Anwendungsfall auch gut funktioniert:

Jeder Client stellt mit demselben Benutzerkonto und möglicherweise sogar demselben Schlüssel eine Verbindung zum Server her (spielt keine Rolle). OpenSSH chroots in ein Verzeichnis mit der folgenden Struktur:

d--x--x---   dark-folder
drwxr-x---   |- verylongrandomfoldername1
drwxr-x---   |- verylongrandomfoldername2
drwxr-x---   `- ...

Zusammen mit dem Sicherungsbefehl teilt der Server dem Client den Ordnernamen mit, in den er seine Dateien ablegen soll. Die Ordnernamen sind zufällige 64-Byte-Zeichenfolgen, die praktisch nicht zu ermitteln sind, sodass jeder Client nur wirklich auf seinen eigenen Ordner zugreifen kann, obwohl sich die anderen "irgendwo da draußen im Dunkeln" befinden.

Der Modus d - x - x-- für dunkle Ordner stellt sicher, dass jeder Client den Ordner (und die Ordner darunter) betreten kann, jedoch nicht dessen Inhalt auflisten oder neue Einträge erstellen kann.

Die Unterordner werden vom Backup-Server-Prozess erstellt und die Verbindung zwischen Client und Ordner wird (unter anderem) in einer SQLite-Datenbank gespeichert.

Xykon42
quelle