Bezpieczeństwo
Stawiamy bezpieczny serwer plików
26
marzec 2007
Bezpieczeństwo
Stawiamy bezpieczny serwer plików
27
www.lpmagazine.org
lin
ux
@
so
ftw
ar
e.
co
m
.p
l
Stawiamy bezpieczny
serwer plików
Tradycyjnie do przesyłania plików między serwerami stosuje się protokół FTP. Niestety ma on
istotną wadę - zarówno hasło, jak i pliki przesyłane są w postaci jawnej, bez jakiegokolwiek
szyfrowania. Z tego powodu lepiej nie stosować protokołu FTP do łączenia się przez nie budzące
zaufania sieci, takie jak Internet.
Michał Miszewski
I
stnieją serwery i klienty FTP rozszerzające ten pro-
tokół o szyfrowanie SSL. My jednak postawimy bez-
pieczny serwer plików korzystając z innego rozwią-
zania - użyjemy SSH i podsystemu przesyłania pli-
ków SFTP.
W domyślnej konfiguracji OpenSSH zawiera obsłu-
gę SFTP. Odpowiada za nią program /usr/lib/sftp-server.
Otwarcie sesji SFTP polega na zestawieniu połączenia
SSH ze zdalnym hostem. Następnie uruchamiany jest prog-
ram sftp-server po zdalnej stronie. Interpretuje on polece-
nia wydawane przez klienta, m in. żądania operacji na
plikach.
Załóżmy, że nasz serwer będzie platformą do hostingu
stron WWW. Użytkownicy muszą mieć możliwość bezpiecz-
nego przesyłania plików do swojego katalogu domowego.
Dostęp do konta powinien jednak podlegać następującym
ograniczeniom:
• użytkownicy nie mają dostępu do shella
• nie jest dostępny forwarding portów oferowany przez
SSH
• dostęp tylko do własnego katalogu domowego
• brak dostępu do pozostałej części systemu plików
(katalogi /proc, /tmp, /etc itp.)
O ile postawienie SFTP jest proste, ograniczenie go w po-
wyższy sposób wymaga więcej pracy. Program sftp-server
dostarczany wraz z pakietem OpenSSH nie zapewnia taki-
ej możliwości. Na szczęście istnieje patch chrootssh rozwi-
jany przez Jamesa Dennisa. Wykorzystuje on mechanizm
chroot systemu operacyjnego do zamknięcia użytkownika
w „klatce“. Więcej na temat jego działania znajdziesz w ram-
ce „jak działa chroot“. Źródła OpenSSH z nałożonym pa-
tchem znajdują się na stronie projektu chrootssh.
SSH w klatce
Zacznijmy od skompilowania zmodyfikowanej wersji
OpenSSH. Procedura jest standardowa - rozpakowujemy
archiwum i konfigurujemy źródła skryptem ./configure.
Należy zwrócić uwagę na opcje, które mogą różnić się
w zależności od rodzaju wykorzystywanej dystrybucji
systemu. W moim przypadku (system Debian GNU/Li-
nux) należało wywołać skrypt z parametrami --with-pam
--sysconfdir=/etc/ssh --without-zlib-version-check (włączenie
Bezpieczeństwo
Stawiamy bezpieczny serwer plików
26
marzec 2007
Bezpieczeństwo
Stawiamy bezpieczny serwer plików
27
www.lpmagazine.org
mechanizmu PAM, wskazanie katalogu z pli-
kami konfiguracyjnymi oraz pominięcie spra-
wdzania wersji biblioteki zlib). Następnie
wykonujemy polecenia make i make install.
Podczas logowania przez SSH kod doda-
ny przez chrootssh sprawdza w /etc/passwd, czy
katalog domowy użytkownika zawiera ciąg
znaków /./. Jeśli tak jest, następuje wywołanie
funkcji chroot() dla katalogu przed kropką. Dru-
ga część ścieżki (po kropce) to katalog domo-
wy użytkownika względem nowego katalogu
głównego.
Utwórzmy zamknięte środowisko, w któ-
rym będzie działał nasz serwer SFTP. Zakła-
damy katalog dla chroot: mkdir /home/chroot.
Muszą się tam znaleźć wszystkie pliki binarne
i biblioteki potrzebne do działania SFTP. Two-
rzymy katalogi bin, etc, home, lib, lib/tls, usr, usr/
lib i usr/lib/i686/cmov. Do katalogu bin kopiu-
jemy podstawowe pliki binarne potrzebne do
działania SFTP: ls, mkdir, mv, rm, rmdir i chmod.
Potrzebujemy też samego serwera sftp - kopiu-
jemy /usr/lib/sftp-server do /home/chroot/usr/lib/.
Należy jeszcze dodać wymagane bibli-
oteki dynamiczne. Korzystamy w tym celu
z narzędzia ldd. Sprawdzamy, jakich biblio-
tek wymaga każdy z programów i kopiujemy
je do odpowiednich katalogów. Przykład, jak
należy to zrobić, znajduje się na Listingu 1.
Czynności powtarzamy dla wszystkich pli-
ków wykonywalnych w chroot.
Program sftp-server wymaga jeszcze jed-
nej biblioteki: libnss_files. Biblioteka ta jest łado-
wana później i ldd nie pokazuje jej na liście.
Bez niej sftp-server zakończy działanie nie zwra-
cając żadnego komunikatu o błędzie. Tego ro-
dzaju brakujące pliki można odnaleźć np. tym-
czasowo umieszczając w chroocie shell (np.
/bin/bash) i program strace. Następnie wpisuje-
my polecenie chroot /home/chroot /bin/bash
(uzyskamy ograniczoną interaktywną powło-
kę), a następnie używamy narzędzia strace do
przeanalizowania, jakie pliki otwiera dany pro-
gram.
Sftp-server wymaga dostępu do sysloga po-
przez socket /dev/log. Ze względu na ograni-
czone środowisko standardowa lokalizacja
gniazdka nie jest dostępna. Musimy więc do-
dać socket w naszym chroocie - można to zrobić
uruchamiając syslogd z parametrem -a /home/
chroot/dev/log. Plik specjalny zostanie utworzo-
ny automatycznie przez program syslogd.
Potrzebny jest jeszcze plik urządzenia
/dev/null - możemy zwyczajnie skopiować go
z systemu: cp -p /dev/null /home/chroot/dev/
Konta użytkowników
Pozostaje utworzyć konto użytkownika (tutaj
przykładowo o nazwie jan). Jako katalog do-
mowy użytkownika powinna zostać ustawio-
na ścieżka /home/chroot/./home/jan. Jako shell
ustawiamy /usr/lib/sftp-server – pozwoli to jedy-
nie na połączenia SFTP, odbierając dostęp do
interaktywnej powłoki. Ostatecznie wpis w /etc/
passwd powinien wyglądać następująco:
jan:x:1003:100::/home/chroot/./home/
jan:/usr/lib/sftp-server
Plik /etc/passwd jest potrzebny do działania
także programowi sftp-server. Jako, że jest on
wywoływany już w zamkniętym środowisku,
potrzebuje drugiej kopii pliku passwd z od-
powiednim wpisem. Odpowiednie wpisy dla
Listing 1.
Kopiowanie bibliotek
$ ldd sftp-server
libresolv.so.2 => /lib/tls/libresolv.so.2 (0x40026000)
libcrypto.so.0.9.7 => /usr/lib/i686/cmov/libcrypto.so.0.9.7 (0x40038000)
libutil.so.1 => /lib/tls/libutil.so.1 (0x40138000)
libz.so.1 => /usr/lib/libz.so.1 (0x4013b000)
libnsl.so.1 => /lib/tls/libnsl.so.1 (0x4014d000)
libcrypt.so.1 => /lib/tls/libcrypt.so.1 (0x40161000)
libc.so.6 => /lib/tls/libc.so.6 (0x4018e000)
libdl.so.2 => /lib/tls/libdl.so.2 (0x402c3000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$ cp /lib/tls/libresolv.so.2 lib/tls/
$ cp /lib/tls/libutil.so.1 lib/tls/
$ cp /usr/lib/libz.so.1 usr/lib/
$ cp /lib/tls/libnsl.so.1 lib/tls/
$ cp /lib/tls/libcrypt.so.1 lib/tls/
$ cp /lib/tls/libc.so.6 lib/tls/
$ cp /lib/tls/libdl.so.2 lib/tls/
$ cp /lib/ld-linux.so.2 lib/
$ cp /usr/lib/i686/cmov/libcrypto.so.0.9.7 usr/lib/i686/cmov/
Rysunek 1.
Drzewo katalogów w środowisku chroot
Listing 2.
Przykładowa sesja sftp
jkowalski@galaxy:tmp$ sftp jan@box
Connecting to box...
jan@box's password:
sftp> pwd
Remote working directory: /home/jan
sftp> put info.txt
Uploading info.txt to /home/jan/info.txt
info.txt 100% 153 0.2KB/s 00:00
sftp> ls -l
drwxr-xr-x 0 1003 100 4096 Dec 26 23:28 .
drwxr-xr-x 0 0 0 4096 Dec 26 19:38 ..
-rw-r--r-- 0 1003 100 153 Dec 26 23:28 info.txt
sftp> cd /
sftp> ls
. .. bin dev etc home lib usr
sftp> ls etc
etc/. etc/.. etc/passwd
sftp> exit
28
Bezpieczeństwo
Stawiamy bezpieczny serwer plików
marzec 2007
29
Bezpieczeństwo
Stawiamy bezpieczny serwer plików
www.lpmagazine.org
wszystkich użytkowników trzeba więc dodać
do /home/chroot/etc/passwd np. poleceniem:
getent passwd jan >> /home/chroot/etc/passwd. Jest
to jedyny plik w /etc w chroot wymagany do
działania naszego serwera plików. Oczywiście
tworzymy także katalog /home/chroot/home/jan
i ustawiamy właściciela „jan“.
Należy upewnić się, że w pliku konfigura-
cyjnym demona SSH (w tym przypadku /etc/
ssh/sshd_config) znajduje się linijka:
Subsystem sftp /usr/lib/sftp-server
Po uruchomieniu demona sshd powinna ist-
nieć możliwość zalogowania na ograniczone
konto. Przykładowa sesja SFTP znajduje się
na listingu 2.
Ograniczenie port forwardingu można
rozwiązać także w inny sposób – wyłączając
je całkowicie (opcja
AllowTcpForwarding no
)
i ewentualnie włączając dla wybranych użyt-
kowników z pełnym dostępem do shella. Kon-
ta dla pozostałych użytkowników zakładamy
analogicznie.
W tym momencie bezpieczny serwer pli-
ków można uznać za skonfigurowany. Sesje
SFTP powinny działać w ograniczonym śro-
dowisku, a dostęp do shella i forwardowania
portów został zablokowany. Ewentualne pro-
blemy możemy zdiagnozować na podstawie
komunikatów sysloga. Należy jeszcze ws-
zystko dokładnie sprawdzić i można wpuścić
użytkowników.
Chroot to mechanizm służący do ogranic-
zania procesom dostępu do części syste-
mu plików. Proces, którego katalog główny
(root directory) został zmieniony, nie może
odwoływać się do plików znajdujących się
poza tym katalogiem. Zamknięte w chroo-
cie procesy mogą jednak tworzyć nowe de-
skryptory plików, połączenia sieciowe itp.
Mogą też czytać i modyfikować wszystkie
pliki, które otworzyły jeszcze przed wywo-
łaniem funkcji chroot(). Uruchamianie prog-
ramu w środowisku chroot jest dość kłopot-
liwe, ponieważ wybrany katalog musi za-
wierać wszystkie wymagane do jego dzi-
ałania pliki. Trzeba więc utworzyć strukturę
katalogów podobną do '/' i skopiować tam
potrzebne binarki, pliki urządzeń i biblioteki.
Aby sprawdzić, jakich bibliotek wymaga da-
ny program, korzystamy z narzędzia ldd(1).
Jeśli zamknięty w chroot program nie działa
poprawnie, możemy skorzystać z narzędzia
strace w celu sprawdzenia, czy nie próbuje
on otwierać jakichś brakujących plików.
Mechanizm chroot ma swoje słabe strony
- jedną z nich jest możliwość "wydostania
się" z zamkniętego środowiska procesów
działających z prawami użytkownika root.
Z tego powodu należy unikać umieszcza-
nia w chroocie plików wykonywalnych z usta-
wionym bitem SUID i właścicielem root.
Chroot nie ogranicza listy wywołań syste-
mowych, jakie mogą uruchamiać działające
procesy. Nie chroni także przed nadmier-
nym wykorzystaniem CPU, pamięci, miej-
sca na dysku i innych zasobów.
Jak działa chroot?
Użycie poniższej dyrektywy w pliku konfi-
guracyjnym httpd.conf umożliwi dostęp do
stron WWW znajdujących się na ogranic-
zonych kontach.
<IfModule mod_userdir.c>
UserDir /home/chroot/home
</IfModule>
Taka konfiguracja spowoduje, że przy pró-
bie wczytania adresu URL http://serwer.pl/
~jan/strona.html Apache wyświetli plik /ho-
me/chroot/home/jan/strona.html. Możemy
także dodać wirtualny host odpowiadający
katalogowi użytkownika:
<VirtualHost *:80>
ServerAdmin jan@serwer.pl
DocumentRoot /home/chroot/home/jan
ServerName jan.serwer.pl
ErrorLog /var/log/apache/jan-
error.log
CustomLog /var/log/apache/jan-
access.log common
</VirtualHost>
Spowoduje to, że ta sama strona będzie
dostępna pod adresem http://jan.serwer.pl/
strona.html (oczywiście domena jan.ser-
wer.pl musi wskazywać na adres IP nasze-
go serwera).
Przykład konfiguracji Apache
dla kont w chroocie
• Strona projektu OpenSSH:
http://openssh.org/
• Strona projektu chrootssh:
http://chrootssh.sourceforge.net/ -
W Sieci
Rysunek 2.
Sesja SFTP w programie WinSCP
Port forwarding
potencjalna luka
Każde konto należy zabezpieczyć przed uży-
ciem mechanizmów, takich jak port forwar-
ding. Można to zrobić umieszczając następu-
jące linie w pliku konfiguracyjnym sshd:
• Match User jan
• AllowTcpForwarding no
Należy pamiętać o dopisywaniu po przecinku
wszystkich dodawanych użytkowników. Jeśli
tego nie zrobimy, właściciel konta będzie mógł
otworzyć szyfrowany tunel TCP i połączyć się
od wewnątrz na dowolny port naszego serwe-
ra lub dowolnego innego hosta dostępnego
z naszej maszyny.