[OpenBSD]

[Wstecz: Wydajność] [Spis treści] [Dalej: Authpf: powłoka dla bramek uwierzytelniających]

PF: Problemy z FTP


Spis treści


Tryby pracy FTP

Powstanie protokołu FTP miało miejsce gdy Internet był jeszcze małą, przyjazną siecią i każdy wiedział wszystko o wszystkich, a więc wtedy gdy filtrowanie pakietów i nadzwyczajne środki ostrożności nie były jeszcze potrzebne. Protokół ten nie jest więc zaprojektowany tak aby umożliwić jego łatwe filtrowanie lub przekazywanie jego datagramów poprzez ściany ogniowe, a także do współpracy z translacją adresów.

Z FTP można korzystać na dwa sposoby: pasywnie lub aktywnie. Wybór trybu aktywnego lub pasywnego zależy w głównej mierze od określenia kto ma problemy z filtrowaniem pakietów. Najlepszym rozwiązaniem byłoby umożliwić korzystanie z obu metod.

Kiedy użytkownik łączy się z serwerem przy pomocy aktywnego FTP i wysyła żądanie otrzymania informacji lub pliku, serwer FTP tworzy nowe połączenie z powrotem do klienta i przesyła dane. nazywa się to połączeniem przesyłania danych (ang. data connection). Aby zacząć, klient FTP wybiera losowy port, przesyła jego numer do serwera FTP i wtedy zaczyna nasłuchiwać na tym porcie wybrał. Serwer FTP inicjuje wówczas połączenie na adres i otrzymany port klienta, po czym rozpoczyna transmisję danych. Stanowi to problem dla użytkowników starających się uzyskać dostęp do serwerów FTP z za bramek realizujących NAT. Ponieważ NAT działa, jak działa, serwer FTP inicjuje połączenie przesyłania danych poprzez łączenie się na zewnętrzny adres bramki oraz wybrany port. Maszyna realizująca NAT otrzyma połączenie, lecz ponieważ nie wie, jak zmapować pakiet w swojej tabeli stanów, porzuci pakiet i nie dostarczy go do klienta.

W trybie pasywnym (jest to domyślne zachowanie programu ftp(1)), dostarczonego wraz z OpenBSD), klient żąda aby to serwer określił losowy port na którym będzie oczekiwał na połączenie dla przesłania danych. Serwer informuje klienta, który port został wybrany, a klient łączy się z tym portem i następuje transfer danych. Niestety, z powodu możliwości istnienia zapory ogniowej przed serwerem FTP, która będzie blokować nadchodzące połączenia przesyłania danych. W OpenBSD ftp(1) używa tego trybu domyślnie, wymuszenie trybu aktywnego można uzyskać na dwa sposoby: opcja -A podczas wywołania ftp, lub wyłączenie trybu pasywnego komendą "passive off" w linii poleceń programu "ftp>".

Klient FTP za firewallem

Jak to zostało opisane wcześniej, protokół FTP ma problemy z współpracą z NAT i firewallami.

Packet Filter dostarcza rozwiązanie tego problemu, jakim jest przekierowanie ruchu FTP na serwer proxy FTP. W procesie tym twój ruch FTP jest "przeprowadzany" przez twoją bramę/firewall NAT, poprzez dynamiczne dodawanie niezbędnych reguł do PF, i usuwanie ich gdy nie są potrzebne, za pomocą systemu zakotwiczeń (ang. anchors). FTP proxy wykorzystywanym przez PF w OpenBSD 3.9 i pożniejszych jest ftp-proxy(8). (uwaga: wcześniejsze wersje OpenBSD korzystały z innego proxy o tej samej nazwie, który został udokumentowany na stronie manuala OpenBSD 3.8 ftp-proxy(8)v3.8).

Aby go aktywować, umieść coś takiego w sekcji NAT pliku pf.conf:

nat-anchor "ftp-proxy/*"
rdr-anchor "ftp-proxy/*"
rdr on $int_if proto tcp from any to any port 21 -> 127.0.0.1 \
   port 8021

Pierwsze dwie linie są parą zakotwiczeń, które są wykorzystywane przez ftp-proxy do dodawania reguł, wymaganych do zarządzania ruchem FTP, "w locie". Ostatnia linia kieruje FTP od twoich klientów do programu ftp-proxy(8), który nasłuchuje na twojej maszynie na porcie 8021.

Potrzebne jest także zakotwiczenie w sekcji reguł:

anchor "ftp-proxy/*"

Oczywiście powyższe przekierowanie zakłada, że serwer proxy jest uruchomiony na tym komputerze. Możesz go uruchomić umieszczając w pliku /etc/rc.local.conf, jest następującą linię:

ftpproxy_flags=""

Program ftp-proxy może być także uruchomiony jako root bez konieczności restartu komputera.

ftp-proxy nasłuchuje na porcie 8021, na ten sam port wysyła ruch FTP podane wyżej wyrażenie rdr.

Aby uaktywnić połączenia w trybie aktywnym, musisz podać flagę "-r" dla ftp-proxy(8) (w poprzedniej wersji proxy musiałeś korzystać z "-u root").

"Samozabezpieczenie" PF serwera FTP

W tym przypadku, filtr PF jest uruchomiony na tym samym komputerze co serwer FTP, a nie na osobnej maszynie. Kiedy serwer obsługuje pasywne sesje FTP, otwiera wysoki port TCP dla danych. Domyślnie, natywny serwer OpenBSD ftpd(8) używa w tym celu portów z zakresu od 49152 do 65535. Oczywiście ruch na tych portach musi być przepuszczany wraz z portem 21 (który jest portem kontrolnym FTP):
pass in on $ext_if proto tcp from any to any port 21 keep state
pass in on $ext_if proto tcp from any to any port > 49151 \
   keep state

Proszę zauważyć, że jeśli zaistnieje potrzeba ograniczenia zakresu wysokich portów, których będzie używał natywny serwer ftpd(8) OpenBSD, można to osiągnąć poprzez zmianę wartości zmiennych sysctl(8) net.inet.ip.porthifirst i net.inet.ip.porthilast.

Zabezpieczanie serwera FTP poprzez dedykowany firewall z NAT

Ta sytuacja zmusza ścianę ogniową do przekierowania ruchu FTP do serwera FTP, dodatkowo nie blokując wymaganych, nowo otwartych portów. Aby to zrealizować wrócimy do ftp-proxy(8).

ftp-proxy(8) może pracować w trybie w którym przekierowuje wszystkie połączenia FTP do określonego serwera FTP. Ustawimy proxy tak by nasłuchiwało na porcie 21 firewall-a i przekierowywał połączenia do innego serwera.

W pliku /etc/rc.conf.local dodaj linię:

ftpproxy_flags="-R 10.10.10.1 -p 21 -b 192.168.0.1"

W tym przypadku 10.10.10.1 jest IP aktualnego serwera FTP, 21 jest portem na którym chcemy by słuchał ftp-proxy(8), natomiast 192.168.0.1 jest adresem firewall-a na ktorym chcemy ustawić proxy.

Teraz reguły firewall-a:

ext_ip = "192.168.0.1"
ftp_ip = "10.10.10.1"

nat-anchor "ftp-proxy/*"
nat on $ext_if inet from $int_if -> ($ext_if)
rdr-anchor "ftp-proxy/*"

pass in on $ext_if inet proto tcp to $ext_ip port 21 \
    flags S/SA keep state
pass out on $int_if inet proto tcp to $ftp_ip port 21 \
    user proxy flags S/SA keep state
anchor "ftp-proxy/*"

W ten sposób zezwalamy na przychodzące połączenia na port 21 na zewnętrznym interfejsie, a także na odpowiadające im połączenia wychodzące na serwer FTP. Opcja "user proxy" dodana do reguły dla pakietów wychodzących, gwarantuje, że przepuszczane są tylko połączenia inicjowane przez ftp-proxy(8).

Zwróć uwagę, że w sytuacji w której chcesz korzystać z ftp-proxy(8) zarówno do ochrony serwera FTP i aby dać użytkownikom dostep do serwera FTP za firewall-em, będziesz musiał uruchomić dwie instancje ftp-proxy(8).

Więcej informacji o FTP

Więcej informacji o filtrowaniu protokołu FTP oraz o tym, jak ogólnie działa FTP znajdziesz w tym opracowaniu:

Proxy TFTP

Trivial File Transfer Protocol (TFTP) podlega w pewnej mierze tym samym ograniczeniom jakim podlega FTP gdy ruch odbywa się poprzez firewall. Na szczęście PF posiada użyteczne proxy dla TFTP nazwane tftp-proxy(8).

tftp-proxy(8) jest konfigurowane w znaczny sposób podobnie jak ftp-proxy(8), opisany powyżej w sekcji Klient FTP za firewall-em.

nat on $ext_if from $int_if -> ($ext_if)
rdr-anchor "tftp-proxy/*"
rdr on $int_if proto udp from $int_if to port tftp -> \
    127.0.0.1 port 6969

anchor "tftp-proxy/*"

Powyższe reguły zezwalają na ruch wyjściowy TFTP z sieci wewnętrznej do serwerów TFTP w sieci zewnętrznej.

Ostatnim krokiem jest włączenie tftp-proxy w inetd.conf(5), w taki sposób, że nasłuchuje on na tym samym porcie do którego odnosi się reguła rdr powyżej, w tym przypadku 6969.

127.0.0.1:6969 dgram udp wait root /usr/libexec/tftp-proxy tftp-proxy

W przeciwieństwie do ftp-proxy(8), tftp-proxy(8) wywoływany jest z inetd.

[Wstecz: Wydajność] [Spis treści] [Dalej: Authpf: powłoka dla bramek uwierzytelniających]


[wstecz] www@openbsd.org
$OpenBSD$