SFTP with chroot depending on public key of connecting user

I want to build a server (running Debian or FreeBSD) that receives backups from different clients via sshfs. Each client should be able to read and write its own backup data, but not the data of any of the other clients.

I had the following idea: each client connects via public key auth to backup@backupserver.local. The user backup has a special authorized_keys file, like this:

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

The advantage of this would be that I would not need to use a separate user for every client, and I could easily autogenerate the authorized_keys file with a script.

There is just one problem: the chroot=... does not work. OpenSSH's authorized_keys file does not seem to have an equivalent for ChrootDirectory (which works in /etc/ssh/sshd_config, either globally or in a Match User block).

Is there a reasonably simple way to accomplish what I want using OpenSSH? Maybe using the command=... directive in a clever way? Alternatively, are there other SFTP servers that can do what I want?

EDIT: To make it more clear what I want to achieve: I want several clients to be able to store files on my server. Each client should not be able to see any other client's files. And I do not want to litter my server with dozens of user accounts, so I'd like an easily manageable solution for the clients to share a user account and still have no access to eachother's files.

9
задан 23 February 2016 в 00:01
3 ответа

В качестве альтернативы, существуют ли другие серверы SFTP, которые могут делать то, что я хочу?

да, вы можете использовать proftpd

Подготовить среду пользователя. С ProFTPD нет необходимости предоставлять пользователю действительную оболочку.

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

Чтобы использовать открытые ключи OpenSSH в SFTPAuthorizedUserKeys, вы должны преобразовать их в формат RFC4716. Это можно сделать с помощью инструмента ssh-keygen:

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

Настройка 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

Создание параметров группы DH (Diffie-Hellman).

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

Настройка любого клиента SFTP. Я использовал FileZilla

FileZilla SFTP server settings

. Если вы запустите ProFPTD в режиме отладки

# proftpd -n -d 3 

В консоли вы увидите что-то вроде следующего

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

И следующие строки в файле /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

В сконфигурированном пути к файлу, содержащему авторизованные ключи ( SFTPAuthorizedUserKeys ), может использоваться переменная % u , которая будет интерполирована с именем аутентифицируемого пользователя. Эта функция поддерживает наличие файлов авторизованных ключей для каждого пользователя, которые находятся в центральном месте, вместо того, чтобы требовать (или позволять) пользователям управлять своими собственными авторизованными ключами. Например:

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

Я хочу, чтобы несколько клиентов могли хранить файлы на моем сервере. Каждый клиент не должен видеть файлы других клиентов. И я не хочу засорять свой сервер десятками учетных записей пользователей, поэтому мне нужно легко управляемое решение, позволяющее клиентам использовать учетную запись пользователя и при этом не иметь доступа к файлам друг друга.

С ProFTPD это тоже возможно. Вам просто нужно немного изменить мою первоначальную конфигурацию

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

и создать одну виртуальную учетную запись

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

Вот и все. Для каждой дополнительной учетной записи все, что вам нужно, это добавить его открытый ключ в / etc / proftpd / sftp_authorized_keys

Примечание: файл должен содержать новую строку в конце! Это важно.

5
ответ дан 2 December 2019 в 22:30

chroot = ... не работает.

Нет, ничего подобного нет на странице руководства для sshd , описывающей формат файла authorized_keys .

Если вы поместите chroot в command = , вы не сможете использовать internal-sftp , потому что это замена внутреннего вызова функции внутри sshd .

Настроен рекомендуемый способ больше пользователей, если нужно разделение. Вы также можете использовать аргументы для internal-sftp , если вам не нужно строгое разделение (например, только разные рабочие каталоги), например

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

. Также можно ограничить количество запросов с помощью ] -P как на странице руководства для sftp-server .

6
ответ дан 2 December 2019 в 22:30

Тем временем, я придумал еще одно простое решение, которое тоже отлично работает, по крайней мере, в моем случае использования:

Каждый клиент подключается к серверу с той же учетной записью пользователя и, возможно, даже с тем же ключом (не имеет значения). OpenSSH chroots в директорию, которая имеет следующую структуру:

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

Вместе с командой резервного копирования сервер сообщает клиенту имя папки, в которую он должен поместить свои файлы. Имена папок - это 64-байтовые случайные строки, которые практически неосуществимы, поэтому каждый клиент может получить реальный доступ только к своей собственной папке, даже если остальные находятся "где-то там, в темноте".

режим d--x--x-- на темной папке гарантирует, что каждый клиент может войти в папку (и в папки ниже), но не может перечислить ее содержимое или создать новые записи.

Вложенные папки создаются процессом резервного копирования, а связь между клиентом и папкой хранится (помимо всего прочего) в sqlite db.

.
0
ответ дан 2 December 2019 в 22:30

Теги

Похожие вопросы