background image

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 

background image

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

background image

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.