SFTP avec chroot selon la clé publique de l'utilisateur connecté

9

Je veux construire un serveur (exécutant Debian ou FreeBSD) qui reçoit des sauvegardes de différents clients via sshfs. Chaque client doit pouvoir lire et écrire ses propres données de sauvegarde, mais pas les données des autres clients.

J'ai eu l'idée suivante: chaque client se connecte via l'authentification par clé publique à [email protected]. La sauvegarde utilisateur possède un fichier special_keys spécial, comme celui-ci:

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...

L'avantage serait que je n'aurais pas besoin d'utiliser un utilisateur distinct pour chaque client et que je pourrais facilement générer automatiquement le fichier authorized_keys avec un script.

Il n'y a qu'un seul problème: le chroot=...ne fonctionne pas. Le fichier authorized_keys d'OpenSSH ne semble pas avoir d'équivalent pour ChrootDirectory (qui fonctionne dans / etc / ssh / sshd_config, globalement ou dans un bloc Match User).

Existe-t-il un moyen raisonnablement simple d'accomplir ce que je veux en utilisant OpenSSH? Peut-être utiliser la command=...directive de manière intelligente? Sinon, existe-t-il d'autres serveurs SFTP qui peuvent faire ce que je veux?

EDIT : Pour rendre plus clair ce que je veux réaliser: je veux que plusieurs clients puissent stocker des fichiers sur mon serveur. Chaque client ne doit pas pouvoir voir les fichiers des autres clients. Et je ne veux pas surcharger mon serveur de dizaines de comptes d'utilisateurs, donc j'aimerais une solution facilement gérable pour que les clients partagent un compte d'utilisateur et n'aient toujours pas accès aux fichiers de chacun.

Xykon42
la source

Réponses:

5

Sinon, existe-t-il d'autres serveurs SFTP qui peuvent faire ce que je veux?

oui, vous pouvez utiliser proftpd

Préparez l'environnement utilisateur. Avec ProFTPD, il n'est pas nécessaire de donner à l'utilisateur un shell valide.

# 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/

Afin d'utiliser les clés publiques OpenSSH dans un SFTPAuthorizedUserKeys, vous devez les convertir au format RFC4716. Vous pouvez le faire avec l'outil ssh-keygen:

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

Configurer ProFTPD

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

Créez des paramètres de groupe DH (Diffie-Hellman).

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

Configurez n'importe quel client SFTP. J'ai utilisé FileZilla

Paramètres du serveur FileZilla SFTP

Si vous exécutez ProFPTD en mode débogage

# proftpd -n -d 3 

Dans la console, vous verrez quelque chose comme ce qui suit

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

Et les lignes suivantes dans un /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

Le chemin configuré pour un fichier contenant des clés autorisées ( SFTPAuthorizedUserKeys ) peut utiliser la variable % u , qui sera interpolée avec le nom de l'utilisateur authentifié. Cette fonctionnalité prend en charge la possession de fichiers par utilisateur de clés autorisées résidant dans un emplacement central, plutôt que d'obliger (ou d'autoriser) les utilisateurs à gérer leurs propres clés autorisées. Par exemple:

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

Je souhaite que plusieurs clients puissent stocker des fichiers sur mon serveur. Chaque client ne doit pas pouvoir voir les fichiers des autres clients. Et je ne veux pas surcharger mon serveur avec des dizaines de comptes d'utilisateurs, donc j'aimerais une solution facile à gérer pour que les clients partagent un compte d'utilisateur et n'aient toujours pas accès aux fichiers de chacun.

avec ProFTPD c'est possible aussi. Vous avez juste besoin de modifier un peu ma configuration initiale

<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>

Et créez un compte virtuel

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

C'est tout. Pour chaque compte supplémentaire, tout ce dont vous avez besoin est d'ajouter sa clé publique aux / etc / proftpd / sftp_authorized_keys

Remarque: le fichier doit contenir une nouvelle ligne à la fin! C'est important.

ALex_hha
la source
Merci pour votre réponse détaillée. Cependant, je ne vois pas comment cela pourrait m'aider à atteindre mon objectif principal d'utiliser un seul compte d'utilisateur pour de nombreux clients qui ne devraient pas pouvoir voir les fichiers de l'autre. (Et être facilement gérable par un script.) En relisant ma question d'origine, j'avoue que ce que je voulais réaliser n'était peut-être pas tout à fait évident. Désolé.
Xykon42
J'ai mis à jour la réponse
ALex_hha
1
D'accord, avec un petit changement, cela fonctionne vraiment bien, merci! Pour vous assurer que les utilisateurs ne peuvent pas accéder aux fichiers des autres utilisateurs en devinant leur nom d'utilisateur (ou pour inonder mon serveur en utilisant abusivement la fonction CreateHome), le fichier authorized_keys doit être spécifique à l'utilisateur, comme /foo/authorized_keys.d/%u.
Xykon42
6

le chroot=...ne fonctionne pas.

Non, il n'y a rien de tel dans la page de manuel pour sshd, décrivant le format du authorized_keysfichier.

Si vous mettiez chroot dedans command=, vous ne seriez pas en mesure de l'utiliser internal-sftp, car il s'agit d'une substitution d'appel de fonction interne à l'intérieur sshd.

La méthode recommandée est de configurer plus d'utilisateurs, si vous avez besoin d'une séparation. Vous pouvez également utiliser des arguments pour internal-sftp, si vous n'avez pas besoin d'une séparation stricte (par exemple uniquement des répertoires de travail différents), tels que

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

Il est également possible de limiter le nombre de demandes en utilisant l' -Poption comme dans la page de manuel pour sftp-server.

Jakuje
la source
0

Pendant ce temps, j'ai trouvé une autre solution simple qui fonctionne très bien, au moins dans mon cas d'utilisation:

Chaque client se connecte au serveur avec le même compte d'utilisateur et peut-être même la même clé (peu importe). OpenSSH chroote dans un répertoire qui a la structure suivante:

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

Avec la commande de sauvegarde, le serveur indique au client le nom du dossier dans lequel il doit placer ses fichiers. Les noms de dossier sont des chaînes aléatoires de 64 octets qui sont pratiquement impossibles à deviner, de sorte que chaque client ne peut vraiment accéder qu'à son propre dossier, même si les autres sont "quelque part dans le noir".

le mode d - x - x-- sur dark-folder garantit que chaque client peut entrer dans le dossier (et les dossiers ci-dessous), mais ne peut pas lister son contenu ni créer de nouvelles entrées.

Les sous-dossiers sont créés par le processus du serveur de sauvegarde et la connexion entre le client et le dossier est stockée (entre autres) dans une base de données sqlite.

Xykon42
la source