Konto SFTP z chrootem z użyciem OpenSSH-Server na CentOS/RHEL6

Konta SFTP-only możemy chcieć użyć, gdy mamy zainstalowany na serwerze SSH (prawie zawsze) i udostępniamy dane  innemu systemowi, który loguje się i pobiera je (i ewentualnie usuwa), a nie chcemy instalować dodatkowej aplikacji jak FTPd czy HTTPd.

Zakładamy, że logowanie odbywa się automatycznie z użyciem klucza i bez hasła. Nazwa użytkownika na serwerze zdalnym to: copy z UID 2000, a grupa to sftponly z GID 2000. Serwer z SFTP to 10.7.18.2, a klient, z którego będziemy się logować to 10.7.18.1

Na pierwszy ogień musimy skongfigurować demona SSH, aby posiadał następujące wpisy:

Subsystem       sftp    internal-sftp
AuthorizedKeysFile      .ssh/authorized_keys
AllowUsers copy@10.7.18.1
Match user copy
        ChrootDirectory %h
        ForceCommand internal-sftp
        AllowTCPForwarding no
        X11Forwarding no

Oraz żeby nie posiadał takiego wpisu lub podobnego

#Subsystem      sftp    /usr/libexec/openssh/sftp-server

Następnym krokiem jest utworzenie katalogu, gdzie chcemy mieć katalogi w chroot, ja utworze katalog chroot w głównym drzewie

mkdir /chroot

Po utworzeniu katalogu a przed utworzeniem użytkownika warto utworzyć osobną grupę dla użytkownika

groupadd -g 2000 sftponly

Teraz naszym zadaniem jest utworzenie użytkownika z shellem ustawionym na /bin/false i z katalogiem domowym w wybranym miejscu.

adduser -u 2000 -g 2000 -s /bin/false -d /chroot/copy copy

Konto zostało utworzone z następującymi prawami dostępu

ls -ald /chroot/copy/
drwx------. 2 copy sftponly 4096 Mar  3 12:32 /chroot/copy/

Muszą one zostać zedytowane tak, aby właścicielem katalogu domowego konta chrootowanego był root i trzeba trochę poluzować dostępy

chown root /chroot/copy
chmod 755 /chroot/copy

Jeszcze musimy stworzyć katalog na klucze, nadać mu odpowiednie uprawnienia i wkopiować klucze publiczne, które będą mogły logować się do systemu, żeby skopiować jakieś dane za pomocą sftp

mkdir /chroot/copy/.ssh
chown root:root /chroot/copy/.ssh

Teraz czas na wkopiowanie klucza publicznego i ustawienie mu odpowiednich uprawnień

echo 'AAAA...== user@maszyna' > /chroot/copy/.ssh/authorized_keys
chown root:root /chroot/copy/.ssh/authorized_keys
chmod 644 /chroot/copy/.ssh/authorized_keys

Po tych operacjach możemy zrestartować SSHD

service sshd restart

Jeżeli wykorzystujemy selinux w trybie enforcing, to musimy jeszcze skonfigurować dla plików i katalogów odpowiednie konteksty z użyciem aplikacji semanage dostępnej w pakiecie

policycoreutils-python

Same ustawienia kontekstów

semanage fcontext -a -t home_root_t "/chroot(/.*)?"
semanage fcontext -a -t user_home_t "/chroot/copy(/.*)?"
semanage fcontext -a -t ssh_home_t "/chroot/copy/.ssh(/.*)?"
restorecon -FFrv /chroot

Po wykonaniu powyższych operacji konto copy powinno umożliwiać łączenie się do niego ze wskazanego klienta za pomocą komendy

sftp -o "IdentityFile=/sciezka/do/klucza/prywatnego" copy@10.7.18.2

Po zalogowaniu powinniśmy zobaczyć następujące okno

Connecting to 10.7.18.2...
sftp>

Jeżeli tak nie jest i system odrzuca połączenie lub prosi o hasło warto rozpocząć rozwiązywanie problemu od włączenia SSHD na serwerze w trybie debug poprzez dodanie do /etc/ssh/sshd_config wpisu

LogLevel DEBUG

i zrestartowanie usługi

service sshd restart

A po stronie klienta użyć sftp z opcją -v lub -vv

sftp -v -o "IdentityFile=/sciezka/do/klucza/prywatnego" copy@10.7.18.2
sftp -vv -o "IdentityFile=/sciezka/do/klucza/prywatnego" copy@10.7.18.2

Po stronie serwera logi czytać można wykorzystując taila

tail -fn0 /var/log/secure