Tenho dois usuários e uma pasta compartilhada no meu servidor Ubuntu:
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.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 reader
usuá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/shared
deve ser legível e deve ser um caminho raiz, por exemplo, não há necessidade de cd
entrar nele, já está /
em sftp ou rsync.
Como escrevo um script de shell para poder aplicá-lo usermod -s
ao usuário reader
que apresentará tal comportamento?Não consigo encontrar nenhuma amostra. Como faço para que writer
também permaneçam "presos" para /var/share
que os caminhos sejam os mesmos?
Notas:
Eu já tentei
sshd_config
'sMatch
eForceCommand internal-sftp
diretivasChrootDirectory
. Isso exige que oChrootDirectory
arquivo seja de propriedade do root e não seja gravável (755 ou menos) e não oferece suporte arsync
.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.Tentei usar
command=".." ssh-rsa....
noauthorized_keys
arquivo, mas não entendi como ativar o comportamento que preciso, só verificorrsync
o script nos documentos do rsync. Este método não possui nenhumchroot
recurso 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, ChrootDirectory
deve ser de propriedade do root e não pode ser gravado por outros usuários. Portanto, /var/shared
no seu caso não pode haver ChrootDirectory
valor.
Eu recomendaria criar um diretório que pudesse ser gravado apenas pelo root e tornado /var/shared
acessí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 sftp
ou rsync
, você precisa verificar SSH_ORIGINAL_COMMAND
a variável de ambiente no servidor com a ajuda de um "wrapper" aplicado via ForceCommand
ou via command
chave 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 sftp
teria sftp-server
dentro, pois rsync
teria rsync
, para apenas ssh
sessão teria, IIRC, a variável vazia, pois ssh date
seria 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 -v
fornece informações sobre qual comando seria executado pelo servidor. Assim, você /tmp
també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/