SFTP com chroot dependendo da chave pública do usuário conectado

8

Eu quero construir um servidor (rodando Debian ou FreeBSD) que receba backups de diferentes clientes via sshfs. Cada cliente deve poder ler e gravar seus próprios dados de backup, mas não os dados de nenhum dos outros clientes.

Eu tive a seguinte ideia: cada cliente se conecta via auth de chave pública para [email protected]. O usuário backup tem um arquivo especial authorized_keys, assim:

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

A vantagem disso seria que eu não precisaria usar um usuário separado para cada cliente, e eu poderia facilmente autogerar o arquivo authorized_keys com um script.

Há apenas um problema: o chroot=... não funciona. O arquivo authorized_keys do OpenSSH não parece ter um equivalente para o ChrootDirectory (que funciona em / etc / ssh / sshd_config, seja globalmente ou em um bloco de Match User).

Existe uma maneira razoavelmente simples de realizar o que eu quero usando o OpenSSH? Talvez usando a diretiva command=... de uma maneira inteligente? Alternativamente, existem outros servidores SFTP que podem fazer o que eu quero?

EDITAR : Para deixar mais claro o que eu quero alcançar: Eu quero que vários clientes consigam armazenar arquivos no meu servidor. Cada cliente não deve poder ver os arquivos de qualquer outro cliente. E eu não quero colocar no meu servidor com dezenas de contas de usuário, então eu gostaria de uma solução facilmente gerenciável para os clientes compartilharem uma conta de usuário e ainda não terem acesso aos arquivos uns dos outros.

    
por Xykon42 21.02.2016 / 15:41

3 respostas

5

Alternatively, are there other SFTP servers that can do what I want?

sim, você pode usar o proftpd

Prepare o ambiente do usuário. Com o ProFTPD, não há necessidade de fornecer ao usuário um shell válido.

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

Para usar as chaves públicas do OpenSSH em um SFTPAuthorizedUserKeys, você deve convertê-las no formato RFC4716. Você pode fazer isso com a ferramenta ssh-keygen:

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

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

Crie os parâmetros do grupo DH (Diffie-Hellman).

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

Configure qualquer cliente SFTP. Eu usei o FileZilla

Se você executar o ProFPTD no modo de depuração

# proftpd -n -d 3 

No console, você verá algo parecido com o seguinte

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

E as linhas seguintes em um /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

P.S.

O caminho configurado para um arquivo contendo chaves autorizadas ( SFTPAuthorizedUserKeys ) pode usar a variável % u , que será interpolada com o nome do usuário que está sendo autenticado. Esse recurso suporta ter arquivos por usuário de chaves autorizadas que residem em um local central, em vez de exigir (ou permitir) que os usuários gerenciem suas próprias chaves autorizadas. Por exemplo:

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

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.

com o ProFTPD também é possível. Você só precisa modificar um pouco minha configuração inicial

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

E crie uma conta virtual

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

Isso é tudo. Para cada conta adicional, tudo o que você precisa é adicionar sua chave pública ao arquivo / etc / proftpd / sftp_authorized_keys

Nota: o arquivo deve conter nova linha no final! É importante.

    
por 21.02.2016 / 23:20
6

the chroot=... does not work.

Não, não há nada parecido na página de manual de sshd , descrevendo o formato do arquivo authorized_keys .

Se você colocasse o chroot em command= , não seria possível usar internal-sftp , porque é a substituição da chamada de função interna em sshd .

A maneira recomendada é configurar mais usuários, se você precisar de separação. Você também pode usar argumentos para internal-sftp , se não precisar de separação estrita (para exaxmple apenas diretórios de trabalho diferentes), como

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

Também é possível limitar a quantidade de solicitações usando a opção -P , como na página de manual para sftp-server .

    
por 21.02.2016 / 16:24
0

Enquanto isso, desenvolvi outra solução simples que funciona bem, pelo menos no meu caso de uso:

Todo cliente se conecta ao servidor com a mesma conta de usuário e, possivelmente, até mesmo a mesma chave (não importa). O OpenSSH faz um chroot em um diretório que possui a seguinte estrutura:

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

Juntamente com o comando backup, o servidor informa ao cliente o nome da pasta na qual ele deve colocar seus arquivos. Os nomes das pastas são seqüências aleatórias de 64 bytes que são praticamente impossíveis de serem consideradas, de modo que cada cliente pode realmente acessar sua própria pasta, mesmo que os outros estejam "em algum lugar no escuro".

O modo d-x-x-- na pasta escura garante que cada cliente possa entrar na pasta (e nas pastas abaixo), mas não pode listar seu conteúdo ou criar novas entradas.

As subpastas são criadas pelo processo do servidor de backup e a conexão entre o cliente e a pasta é armazenada (entre outras coisas) em um banco de dados sqlite.

    
por 12.03.2016 / 00:12