heldercorreia.com

autodidata, programador e consultor

Configurar SFTP sem SSH

Tipicamente, para dar acesso FTP a um cliente precisamos de um servidor como o vsftp. O protocolo FTP não é seguro portanto o FTPS (FTP por SSL) é melhor escolha, mas é preciso pagar um certificado.

Eu prefiro usar o SFTP que usa uma ligação encriptada com SSH para a transferência de ficheiros. É ainda mais seguro e mais simples de configurar (não é preciso um servidor FTP). Porém, uma vez que o SFTP funciona através do SSH, como fazemos para dar acesso apenas ao SFTP sem a linha de comandos?

Há vários artigos na Internet sobre como dar acesso SFTP sem SSH, mas essas soluções geralmente implicam impedir qualquer tipo de login na conta do cliente. Eu queria dar acesso SFTP sem SSH, mas que eu conseguisse também fazer login localmente (su - <user>) para gerir os seus ficheiros. Assim evito ter que redefinir as permissões (chown) para qualquer ficheiro criado.

Para além disso também queria que o utilizador ficasse restrito a uma pasta e não conseguisse navegar para fora dela (chroot).

Com chroot em pasta dedicada

Primeiro a receita, depois a explicação.

  1. Criar um grupo e adicionar utilizadores e esse grupo (e.g. grupo sftp);
  2. Criar uma pasta como root para cada utilizador num sítio comum (e.g. /var/sftp);
  3. Editar /etc/ssh/sshd_config com o código abaixo;
  4. Reiniciar o serviço ssh.
#/etc/ssh/sshd_config

...

PasswordAuthentication no

#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp

Match Group sftp
    ChrootDirectory /var/sftp/%u
    ForceCommand internal-sftp
    PasswordAuthentication yes
    AllowTcpForwarding no
    X11Forwarding no

O SSH tem uma configuração ChrootDirectory (em /etc/ssh/sshd_config) que torna as coisas muito simples. Em conjunto com a diretiva Match podemos forçar um chroot apenas a um utilizador ou grupo de utilizadores (pode ser um ou mais critérios de User, Group, Host, LocalAddress, LocalPort, ou Address). O utilizador não conseguirá sair fora dessa pasta.

Importante

A diretiva Match precisa estar no final do ficheiro. Os comandos que a seguem estão indentados no exemplo para facilitar a leitura, mas o bloco de instruções continua até ao final do ficheiro ou até ao próximo Match.

O caminho definido em ChrootDirectory tem que pertencer ao root (a variável %u é substituída com o nome do utilizador, mas também existe o %h, substituído pelo caminho à sua home). Dentro dessa pasta é preciso criar outra com acessos de escrita para o nosso utilizador, pela qual ele conseguirá criar ou modificar ficheiros.

Eu prefiro desativar autenticação por password, necessitando adicionar chaves públicas para ter acesso por SSH. Só ativo para os utilizadores SFTP já que têm acessos limitados.

Comenta-se também a linha Subsystem com o sftp-server e adiciona-se outra para usar o internal-sftp que é usado para forçar todos os comandos dos utilizadores sftp pelo subsistema FTP do SSH. Acontece que o utilizador vai conseguir autenticar por SSH, mas não lhe é devolvida uma shell para interagir com o sistema, portanto não lhe serve de nada (ver Sem chroot nem login local mais abaixo). Ele é forçado a usar o sistema SFTP.

Impedir qualquer tipo de login

O SSH autentica porque eu mantenho a shell do utilizador com /bin/bash. Se quiser desativar qualquer tipo de login (exceto SFTP) com a configuração acima, eu mudo a shell para /bin/false.

Exemplo

Com a configuração em cima, para um utilizador someuser que precisa enviar vídeos por FTP, adiciona-se o utilizador ao grupo sftp, cria-se a pasta /var/sftp/someuser como root, e adiciona-se lá dentro a pasta videos com chown someuser videos e chmod u+w videos.

Com chroot na home do utilizador

Vamos supor que queremos dar acesso à home do utilizador. Poderíamos ter dentro do Match:

ChrootDirectory %h

Mas assim, a sua home tem que pertencer ao root.

Eu prefiro fazer o seguinte:

ChrootDirectory /home

É preciso não esquecer de retirar permissões de leitura e execução ao público: chmod o-rwx /home/*. Caso contrário seria possível um utilizador aceder aos ficheiros de outro utilizador. Este chroot protege portanto dos acessos ao sistema, mas não dos outros utilizadores. Temos que assegurar que as permissões estão corretas.

Outra alternativa é definir a home como /home/someuser/someuser, definir /home/%u no ChrootDirectory e mudar o owner e permissões de /home/someuser/someuser. Assim fica completamente isolado, e tem completo acesso à sua home.

Sem chroot nem login local

Se não for preciso limitar o utilizador por chroot, nem precisamos fazer login localmente, a forma mais simples de dar acesso SFTP sem SSH é mudar a sua shell. Típicamente, no ficheiro /etc/passwd temos:

someuser:x:1000:1000:someuser,,,:/home/someuser:/bin/bash

Então mudamos a shell para o sftp-server:

someuser:x:1000:1000:someuser,,,:/home/someuser:/usr/lib/openssh/sftp-server

Ou executar:

usermod -s /usr/lib/openssh/sftp-server someuser

E adicionar o sftp-server como shell válida:

echo '/usr/lib/openssh/sftp-server' >> /etc/shells

Comentários