SSH com chroot e funcionando apenas "sftp", "rsync" (ambos)?

SSH com chroot e funcionando apenas "sftp", "rsync" (ambos)?

Tenho dois usuários e uma pasta compartilhada no meu servidor Ubuntu:

  1. Usuário writer, que tem acesso de gravação a /var/shared. É um aplicativo que faz alterações regulares em arquivos nesta pasta remotamente, com uma chave SSH.

  2. O usuário readeré usado por vários clientes com uma chave SSH, uma chave que eles podem obter sem minha permissão, por isso preciso restringir os comandos disponíveis neste shell.

Pergunta:

Preciso restringir comandos acessíveis ao readerusuário para que ele possa usar apenas os protocolos sftp e rsync (sem comandos padrão como mkdir, ls, top, ...). Somente o diretório /var/shareddeve ser legível e deve ser um caminho raiz, por exemplo, não há necessidade de cdentrar nele, já está /em sftp ou rsync.

Como escrevo um script de shell para poder aplicá-lo usermod -sao usuário readerque apresentará tal comportamento?Não consigo encontrar nenhuma amostra. Como faço para que writertambém permaneçam "presos" para /var/shareque os caminhos sejam os mesmos?

Notas:

  1. Eu já tentei sshd_config's Matche ForceCommand internal-sftpdiretivas ChrootDirectory. Isso exige que o ChrootDirectoryarquivo seja de propriedade do root e não seja gravável (755 ou menos) e não oferece suporte a rsync.

  2. Eu tentei rssh, mas simplesmente não funciona para diretórios fora do diretório inicial do usuário conectado. Portanto, não consegui fazer chroot de usuários no mesmo diretório com permissões diferentes.

  3. Tentei usar command=".." ssh-rsa....no authorized_keysarquivo, mas não entendi como ativar o comportamento que preciso, só verifico rrsynco script nos documentos do rsync. Este método não possui nenhum chrootrecurso que eu precise.

Posso ter pelo menos uma amostra dessas conchas? Isso é possível com scripts?

Bash e C++ (se necessário) são bem-vindos. Saída de 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)

Responder1

Primeiro de tudo, ChrootDirectorydeve ser de propriedade do root e não pode ser gravado por outros usuários. Portanto, /var/sharedno seu caso não pode haver ChrootDirectoryvalor.

Eu recomendaria criar um diretório que pudesse ser gravado apenas pelo root e tornado /var/sharedacessível dentro deste diretório por meio da montagem de ligação do Linux ou de algum tipo de solução alternativa de links simbólicos.

Se você precisar restringir sftpou rsync, você precisa verificar SSH_ORIGINAL_COMMANDa variável de ambiente no servidor com a ajuda de um "wrapper" aplicado via ForceCommandou via commandchave pública ssh, esta variável é preenchida após o usuário ser autenticado e contém informações sobre que tipo de conexão os clientes estão indo para estabelecer. Pois sftpteria sftp-serverdentro, pois rsyncteria rsync, para apenas sshsessão teria, IIRC, a variável vazia, pois ssh dateseria date. SSH_ORIGINAL_COMMANDé executado sob usuário autenticado no servidor!

Este poderia ser o início do wrapper:

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

Como você pode ver, ssh -vfornece informações sobre qual comando seria executado pelo servidor. Assim, você /tmptambém pode mudar para outra coisa em seu wrapper.

$ rsync -a -e "ssh -v" bin localhost:/tmp/ 2>&1 | grep '^debug.*Sending command:'
debug1: Sending command: rsync --server -logDtpre.iLsfxC . /tmp/

informação relacionada