_ _ _ _ | |_ ___ _ __ _ __ ___ (_)_ __ __ _| | | ___ __ _ | __/ _ \ '__| '_ ` _ \| | '_ \ / _` | | |/ _ \ / _` | | || __/ | | | | | | | | | | | (_| | | | (_) | (_| | \__\___|_| |_| |_| |_|_|_| |_|\__,_|_|_|\___/ \__, | |___/
☠ morketsmerke ☠
VPN (ang. Virtual Private Network) - Wirtualna Sieć Prywatna jest to usługa sieciowa, która pozwala na bezpieczne i swobodne (chyba, że konfiguracja stanowi inaczej) połączenie odległych hostów.
Ta strona jest oparta o książkę Marka Serfina pt. "Sieci VPN. Zdalna praca i bezpieczeństwo danych. Wydanie II rozszerzone.". Oznacza to tyle że mogą znaleźć się tu fragmenty, przykłady fragmenty kodu, a nawet całe rozdziały przepisane 1:1 z książki. Materiał na tej stronie został dostosowany tak, aby był jak najszybciej przyswajany oraz służył czytelnikowi za ściągę pod czas wdrażania/administracji technologią VPN.
Wstęp
Żyjemy w czasach ogromnej informatyzacji przedsiębiorstw. Trudno wyobrazić sobie obecnie działanie korporacji bez przynajmniej jednego serwera plików czy bazy danych. Współczesne aplikacje pisane są prawie zawsze w architekturze klient-serwer, co umożliwia łatwy dostęp do zasobów wielu użytkownikom z różnych komputerów. Budowa protokołu IP sprawia, że serwer w sieci wewnętrznej może w łatwy sposób stać się osiągalny z innej sieci lub Internetu. Popularyzacja stałego, a często także szybkiego dostępu do globalnej sieci sprawia, że miejsce, w którym się pracuje, przestaje mieć znaczenie. Liczy się za to stały dostęp do zasobów firmy, a co za tym idzie — możliwość pracy w dowolnym miejscu o każdej porze.
Słabość protokołów sieciowych i związane z tym problemy
Leżący u podstaw działania Internetu protokół IP nie zapewnia sam w sobie bezpiecznego przesyłu danych przez sieć. Podobnie rzecz ma się z protokołami warstwy transportowej TCP/UDP — nie zaimplementowano w nich żadnego algorytmu szyfrowania, uwierzytelniania i sprawdzania integralności danych. Na domiar złego w powszechnym użyciu są aplikacje zaprojektowane jeszcze na początku poprzedniej dekady — takie, jak POP3 czy IMAP, które przesyłają dane (w tym hasła) jawnym tekstem.
Mnogość aplikacji klienckich oraz skala Internetu sprawiają, że nie można z dnia na dzień wycofać z użycia danego protokołu i zastąpić go nowszym — łatwo wyobrazić sobie panujący w konsekwencji tego posunięcia chaos.
W odpowiedzi na przedstawione problemy specjaliści IT opracowali różne metody, a także standardy bezpiecznej transmisji danych w niezabezpieczonej sieci. Najpopularniejsze z nich to: tunele SSL — dla pojedynczych aplikacji, lub połączenia VPN — gdy potrzebujemy przepuścić cały ruch szyfrowanym kanałem (niezależnie od protokołu warstw wyższych).
SSL jako standard bezpiecznego przesyłania danych
SSL - Protokół bezpieczeństwa umożliwiający zabezpieczenie transmisji innych protokołów zapewniający podstawowe funkcje bezpieczeństwa tj.:
- uwierzytelnienie stron - czyli potwierdzenie ich autentyczności na podstawie certyfikatów,
- poufność i integralność przesyłu - tzn. ochronę przed podsłuchaniem i modyfikacją.
Historia i znacznie protokołu SSL
Protokół SSL został opracowany przez firmę Netscape Communications Corporation w odpowiedzi na brak zabezpieczeń w popularnych wtedy protokołach (tj. lata 90, ubiegłego wieku). Obecnie najpopularniejszą wersją jest TLS 1.3, który jest rozwinięciem SSL. Mówiąc w obecnych czasach o SSL, to tak naprawdę mówimy o TLS.
W założeniach SSL powstał jako zabezpieczenie do protokołu HTTP dla potrzeb usług e-commerce. Jednak dzięki jego uniwersalności można go wykorzystać do zabezpieczenia większości usług TCP, a nawet do tworzenia sieci VPN.
Przebieg nawiązania połączenia SSL
Zanim protokoły warstwy aplikacji będą mogły wymieniać dane w bezpieczny sposób, musi nastąpić nawiązanie sesji SSL (ang. SSL handshake). Na SSL handshake składa się kilka faz negocjacji, które przedstawiono w poniżej:
- Klient łączy się z serwerem i wysyła pakiet początkowy Hello, a wraz z nim numer obsługiwanej wersji SSL, obsługiwane algorytmy szyfrujące, algorytmy kompresji, oraz losowy numer związany z rozpoczętą sesja (ID).
- Serwer w odpowiedzi wysyła klientowi numer obsługiwanej wersji SSL, obsługiwane algorytmy szyfrujące, a także swój certyfikat (klucz publiczny).
- Na tym etapie klient sprawdza certyfikat serwera - czy jest on ważny oraz czy wystawił go zaufany urząd (CA). Protokół SSL przewiduje także możliwość wysłania przez serwer żądania uwierzytelnienia klienta. Uwierzytelnienie to jest opcjonalnie i stosuje się je w określonych warunkach.
- W przypadku pozytywnego uwierzytelnienia serwera klient generuje 48-bajtową liczbę zwaną pre-master secret i szyfruje ją, używając przy tym klucza publicznego serwera (zawartego w certyfikacie serwera). Liczba pre-master składa się z 2 bajtów identyfikujących klienta oraz 46 bajtów losowych.
- Serwer po otrzymaniu liczby pre-master odszyfrowuje ją, używając do tego swojego klucza prywatnego, i porównuje 2 bajty identyfikujące klienta z danymi, które otrzymał w inicjacyjnym pakiecie Hello
- Jeśli jest wymagane uwierzytelnienie klienta, jest to robione w tej chwili. Wówczas klient musi przesłać certyfikat.
- Na podstawie już wymienionych danych (m.in. pre-master key, losowe dane wygenerowane w punkcie 1.) serwer i klient generuje tzw. master-key (znany tylko im).
- Zarówno klient, jak i serwer na podstawie master-key generują symetryczne klucze sesyjne (sześć, trzy w kierunku serwer-klient i trzy w drugą stronę), które umożliwiają im szyfrowanie i sprawdzenie integralności przesyłanych danych.
- Kończąc handshake, klient przesyła do serwera wiadomość zaszyfrowaną ustalonym kluczem sesyjnym. Wiadomość ta nazywana końcowym uzgodnieniem (ang. finished handshake), jest jako pierwsza szyfrowana tajnym kluczem.
- Serwer odpowiada także wiadomością zaszyfrowaną za pomocą wspólnego klucza. Od tej widomości, sesja SSL jest nawiązna.
Znaczenie zaufanego certyfikatu
Zaufanym certyfikatem możemy określić każdy certyfikat, który został wystawiony przez wiarygodne (zaufane) Centrum Certyfikacji (CA). Każda aplikacja korzystająca z SSL, ma gdzieś w swoich zasobach lokalnych bazę zaufanych wystawców, przez co nie zostajemy w ogóle poinformowani o nawiązywaniu połączenia czy sesji SSL.
Certyfikaty wystawione przez zaufane CA mają znaczenie głównie dla publicznych serwerów, gdzie ludzie z różnych stron świata mają pewność, że serwera za który się łączą na pewno jest tym za który się podaje (np. bank czy sklep internetowy).
Z tego względu, iż będziemy korzystać z sesji SSL do tworzenia sieci VPN, nie ma przeciwwskazań aby twoja organizacja stała się CA (centrum certyfikacji) i aby można było samodzielnie generować certyfikaty i instalować je na hostach klienckich sieci. Przecież możemy zaufać przez nas wygenerowanym certyfikatom. W przeciwieństwie do HTTPS, SSL w zastosowaniach VPN-owych ważne jest uwierzytelnienie klienta przez serwer, dzięku temu z naszą siecią będą mogły łączyć się tylko osoby posiadające odpowiednie certyfikaty.
Generowanie certyfikatów przy użyciu programu OpenSSL
Zawarte w tej części informacje są niezwykle istotne, dla dalszych konfiguracji, czy to OpenVPN czy też technologii IPSec. Dlatego wiele innych zagadnień będzie tu linkować.
Niezwykle istotne dla samego uruchomienia sieci VPN jest umiejętność generowania kluczy i certyfikatów X.509. W systemach unixopodobnych narzędzie wykorzystywane do tego może się nieco różnić. W dystrybucjach systemu Linux raczej będziemy spotykać oryginalnym OpenSSL. Jeśli będziemy się decydować na skorzystanie z np. OpenBSD (co wg. mnie jest bardziej wskazane na bramę VPN niż np. Ubuntu. Dlatego że jest bardzo prosty system, ale oczywiście nie w swojej funkcjonalności raczej w architekturze czy też budowie, jest on również zorientowany na bezpieczeństwo jeśli ktoś jest fanem jądra GNU/Linux może Alpine Linux) to skorzystamy z pakietu LibreSSL, OpenSSL dla Alpine Linux.
Zanim jednak przejdziemy do generowania certyfikatów dla serwera i klientów, musimy stworzyć własny urząd certyfikacji (CA). Dwie uwagi.
Istotną rzeczą CA jest utworzenie go na jakimś bezpiecznym komputerze najlepiej odłączonym od Internetu lub przynajmniej za dodatkowym firewallem nie dopuszczającym żadnych innych połączeń poza jednym (tylko jednym) z swoich komputerów. Chodzi głównie aby nie był on widoczny w Internecie i ograniczyć komunikację z nim w sieci lokalnej.
Ważne jest aby robić kopie zapasowe, wystawionych certyfikatów oraz całego katalogu /etc/ssl, tak aby w razie potrzeby można było unieważnić, któryś z certyfikatów.
Tworzenie własnego CA
W pierwszej kolejności odnajdujemy plik openssl.cnf. Prawdopodobne lokalizacje tego pliku to:
- /etc/ssl/openssl.cnf - dla instalacji z pakietów dystrybucji,
- /usr/local/etc/openssl.cnf - w przypadkach ręcznej kompilacji,
- C:\OpenSSL\bin - dla systemów MS Windows.
W tym pliku musimy odnaleźć sekcje
[ CA_default ]
. Powinniśmy zmienić
wpisy tak jak poniżej.
[ CA_default ] dir = /etc/ssl # katalog główny, w którym zapisywane są pliki. certs = /etc/ssl/certs # katalog, w którym zapisywane są certyfikaty. crl_dir = $dir/crl # katalog z listą certyfikatów unieważnionych (CRL) private_key = $dir/private/cakey.pem # klucz prywatny CA database = $dir/index.txt # baza, w której przechowywane są informacje o wystawionych certyfikatach wraz ze statusem certficate = $dir/cacrt.pem # Certyfikat CA - do podpisu wniosków serial = $dir/serial # plik pomocniczy z bieżącym numerem - inkrementowany po każdym wystawieniu certyfikatu crl = $dir/crl.pem # bieżąca lista certyfikatów unieważnionych [ v3_ca ] # wykazujemy punkt dystrybucji listy CRL crlDistributionPoints=URI:http://example.com/crl.pem
Jeśli będziemy edytować istniejący wpis, opcje których nie ma w
sekcji [ CA_default ]
umieszczamy w komentarzu.
Upewniamy się czy istnieje katalog podany w zmiennej
dir
czyli /etc/ssl, oraz
wszystkie jego podkatalogi. Jeżeli nie, musimy je założyć. Dla
katalogu ssl/private należy ustawić uprawnienia tak, aby
tylko użytkownik root mógł do niego wejść.
Stwórzmy pliki /etc/ssl/index.txt oraz /etc/ssl/serial, używając podanych poniżej poleceń.
root@ca:~# touch /etc/ssl/index.txt #(ma być pusty) root@ca:~# echo 00 > /etc/ssl/serial #(ma zawierać wpis 00)
Przystępujemy do generowania klucza prywatnego centrum certyfikacji CA. Jest to czynność jednorazowa, tzn. po wygenerowaniu klucza prywatnego CA, a następnie odpowiadającego mu certyfikatu będziemy ich używać do podpisywania innych certyfikatów. Należy pamiętać aby zarchiwizować pliki z katalogi /etc/ssl w bezpiecznym miejscu.
Będąc w katalogu /etc/ssl, wydajemy następujące polecenie:
root@ca:/etc/ssl# openssl genrsa -des3 -out private/cakey.pem 1024 Generating RSA private key, 1024 bit long modulus .....++++++ ...++++++ e is 65537 (0x10001) Enter pass phrase for private/cakey.pem: <podaj hasło klucza prywatnego CA>
Po potwierdzeniu hasła do klucza prywatnego CA klucz zostanie zapisany w pliku private/cakey.pem. Nie możemy zapomnieć tego hasła, będzie nam nieraz potrzebne.
Kolejną czynnością jest wygenerowanie certyfikatu CA. W tym celu wpisujemy następujące polecenie:
root@ca:/etc/ssl# openssl req -new -x509 -days 365 -key private/cakey.pem -out cacert.pem
Zostaniemy poproszeni o podanie danych z kilku pól zawartych w certyfikacie.
Country Name (2 letter code) [AU]:PL State or Province Name (fuli name) [Some-State]:Wonderland Locality Name (eg. city) []: Liberty City Organization Name (eg, company) [Internet Widgits Pty Ltd]:morketsmerke.net Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []: ca.morketsmerke.net Email Address []:
Zwrócić należy uwagę na pole
Common Name
, które powinno zawierać nazwę podmiotu - np. nazwę
użytkownika lub jednostki. W przypadku gdy generujemy certyfikat dla
CA, wpisujemy nazwę domeny firmowej lub podajemy nazwę organizacji.
Po podaniu hasła do klucza prywatnego certyfikat zostanie zapisany w pliku cacert.pem. W powyższym przykładzie czas ważności certyfikatu będzie wynosić 1 rok. Można go oczywiście przedłużyć.
Na tym kończymy tworzenie własnego urzędu CA. Mając pliki cakey.pem i cacert.pem, czyli klucz prywatny i certyfikat CA. Teraz można rozpocząć wystawianie certyfikatów innym podmiotom.
Tworzenie klucza prywatnego dla serwera
Aby stworzyć klucz prywatny należy na urzędzie CA w katalogu /etc/ssl wydać polecenie:
root@ca:/etc/ssl# openssl genrsa -des3 -out private/serverkey.pem 1024
Openssl zapyta o hasło - będzie to hasło klucza prywatnego serwera. Klucz prywatny zapisany zostanie w pliku private/serverkey.pem
Generowanie wniosku o wystawienie certyfikatu
root@ca:/etc/ssl# openssl req -new -key private/serverkey.pem -out serverreq.pem
Potrzebne będzie hasło klucza prywatnego serwera, które podawaliśmy punkt wyżej. Jeśli hasło będzie poprawne, zostaniesz zapytani o dane do wniosku.
Country Name (2 letter code) [AU]:PL State or Province Name (fuli name) [Some-State]:Slask Locality Name (eg, city) []:G1iwice Organization Name (eg, company) [Internet Widgits Pty Ltd]:Moja Firma Sp. z o.o. Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []: server.firma.pl Email Address []:
Tutaj jako Common Name
powinniśmy
podać pełną nazwę domenową pod, którą serwer działa w Internecie,
czyli FQDN. Wniosek zostanie zapisany w pliku
/etc/ssl/serverreq.pem.
Generowanie certyfikatu dla serwera
W celu wystawienia certyfikatu dla podmiotu (serwera) musismy podpisać jego wniosek. Aby to uczynić, należy wpisać poniższe polecenie.
root@ca:/etc/ssl# openssl ca -notext -in serverreq.pem -out servercrt.pem
Zostaniemy zapytani o hasło do klucza prywatnego CA cakey.pem. Nie należy mylić go z hasłem klucza prywatnego serwera.
Następnie OpenSSL pokaże szczegóły certyfikatu i zapyta, czy chcemy go podpisać.
Signature ok Certificate Details: Serial Number: 5 (0x5) Validity Not Before: Sep 17 12:59:06 2007 GMT Not After : Sep 16 12:59:06 2008 GMT Subject: countryName = PL stateOrProvinceName = Slask organizationName = Moja Firma Sp. z o.o. organizationalUnitName = commonName = server.firma.pl X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 0E: CE: 3E: 06:C4:46:53:78: BO: 05: AB: 18:9B: BA: 90:79:9B: A l : A5 :C8 X509v3 Authority Key Identifier: keyid:FC:B 8 :73:29:C 6 :E4:50:B 2 :3 E :C E :0A:78:8C:62:90:A 5 :62:3 C :87:IB DirName:/C-PL/ST=Slask/L-Gliwice/0=Moja Firma Sp. z o.o./ CN=ca.fi rma.pl/emai 1 Address=admi n@firma.pl serial:97:1B:4E:CE:0B:5F:CE:E2 Certificate is to be certified until Sep 16 12:59:06 2008 GMT (365 days) Sign the certificate? [y/n]: y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Odnośnie pracy z tak wygenerowanym certyfikatem jest jeszcze jeden szczegół. Otóż każde uruchomienie aplikacji korzystającej z tego certyfikatu będzie nas prosić hasło kluczy prywatnego, użytego do jego wygenerowania. Co nie jest zbyt pożądane w środowiskach serwerowych, jest natomiast rozwiązanie tego problemu. Otóż możemy przepisać klucz pomijając hasło.
Ściąganie hasła z klucza prywatnego serwera
# openssl rsa -in private/serverkey.pem -out private/serverkey.pem_bezhasla
Nie zaleca się ściągania haseł z certyfikatów klientów, ze względu na możliwość kradzieży komputera, co umożliwi dostęp do VPN.
Unieważnianie certyfikatów
Powodów unieważnienia certyfikatów może być wiele. Jednak jeśli już
zachodzi taka potrzeba. Możemy użyć parametry
revoke
programu OpenSSL.
root@srv:/etc/ssl/# openssl ca -revoke jkowalskicert.pem
OpenSSL zapyta o hasło klucza CA i po podaniu prawidłowego unieważni certyfikat:
Using configuration from /usr/1ib/ssl/openssl.cnf Enter pass phrase for /etc/ssl/private/cakey.pem: DEBUG[load_index]: unique_subject = "yes" Revoking Certificate 04. Data Base Updated
Po unieważnieniu certyfikatu należy wygenerować jeszcze listę CRL, w której zapisane są unieważnione certyfikaty.
Generowanie listy CRL (Listy unieważnionych certyfikatów)
root@ca:/etc/ssl# openssl ca -gencrl -out crl.pem
Ważne, aby przenieść plik crl.pem do miejsca, które
wskazaliśmy jako crlDistributionPoint
w pliku konfiguracyjnym OpenSSL.
Sprawdzanie ważności certyfikatu
Aby sprawdzić datę ważności certyfikatu oraz wyświetlić szczegółowe informacje dla kogo został wystawiony możemy użyć polecenia:
root@ca:/etc/ssl# openssl x509 -noout -text -i
Różne formaty certyfikatów
Niestety wśród certyfikatów nie ma jednego standardu i różni producenci preferują różne formaty. Niemniej za pomocą programu OpenSSL możemy je przekonwertować z jednego formatu na inny. Klucze są najczęściej zapisywane w formie PEM lub DER (binarny). Dla certyfikatów używane są PEM, DER, PKCS12. Aplikacje bazujące na OpenSSL, czyli wszystkie unixowe, używają na ogół formatu PEM (Base64). Rozszerzenia dla formatu PEM to: *.crt *.pem, w systemach Windows *.cer
Aby przekonwertować certyfikat z jednej postaci na drugą, musimy przekazać programowi OpenSSL odpowiednie parametry.
Format wejściowy | Format wyjściowy | Składnia OpenSSL |
---|---|---|
PEM (cert) | DER (cert) |
openssl x509 -in cert.pem -out cert.der
-outform DER
|
DER (cert) | PEM (cert) |
openssl x509 -in cert.der -inform DER
-out cert.pem -outform PEM
|
PEM (key) | DER (key) |
openssl rsa -in input.key -inform PEM
-out output.key -outform DER
|
DER (key) | PEM (key) |
openssl rsa -in input.key -inform DER
-out output.key -outform PEM
|
PEM (key,cert) | PKCS #12 |
openssl pkcs12 -export -out cert.p12
-inkey userkey.pem -in usercert.pem
|
PKCS #12 | PEM (cert) |
openssl pkcs12 -clcerts -nokeys –in
cert.p12 -out usercert.pem
|
PKCS #12 | PEM (key) |
openssl pkcs12 -nocerts -in cert.p12 –out
userkey.pem
|
Aby wyświetlić informację o certyfikacie, np. informacje podane podczas tworzenia wniosku, należy uruchomić program OpenSSL z następującymi parametrami:
root@ca:/etc/ssl# openssl x509 -in servercert.pem -subject –noout subject= /C=PL/ST=Slask/O=Helion/CN=server1
Jeśli dodamy parametr -issuer
,
OpenSSL zwróci także informację o wystawcy (CA):
root@ca:/etc/ssl# openssl x509 -in servercert.pem -issuer -subject –noout subject= /C=PL/ST=Slask/O=Helion/CN=server1 issuer= /C=PL/ST=Slask/L=Gliwice/O=Helion/CN=CA
Jeżeli certyfikat jest w formie binarnej (DER), do powyższej składni
należy dodać parametr -inform DER
.
Kompilacja OpenSSL ze źródeł
Jeśli z jakichś powodów musimy skompilować OpenSSL, poniżej w punktach zamieszczono opis, jak to zrobić.
- Pobieramy ze strony http://www.openssl.org/source/ źródła najnowszej wersji pakietu i zapisz w katalogu /usr/src/,
- Porównujemy wartość MD5 pliku pobranego z sieci (polecenie md5sum) z wartością udostępnioną na stronie openssl.org,
-
Rozpakowujemy zawartość archiwum poleceniem
$ tar zxf openssl-nr_wersji.tar.gz
- Przechodzimy do katalogu openssl-nr_wersji.
-
Przed przystąpieniem do kompilacji musimy ustalić, w którym katalogu
program ma zostać zainstalowany oraz z jakimi dodatkowymi opcjami,
podając je jako parametry skryptu
./config
. W poniższym przykładzie skompilujemy program z obsługą biblioteki zlib, a wynikowy program zostanie zainstalowany w katalogu /usr/local/openssl. Wpisujemy polecenie:# ./config --prefix=/usr/local zlib
-
Jeśli skrypt
./config
nie zgłosi błędu, możemy przejść do właściwej kompilacji programu. W tym celu wpisujemy polecenie# make
-
Proces kompilacji może potrwać kilka minut, po jego zakończeniu
możemy przejść do ostatniego kroku — instalacji skompilowanych
plików we właściwych katalogach. Aby zakończyć instalację, wpisujemy
polecenie:
# make install
Nakładki graficzne na SSL
Aby nie męczyć się ze skomplikowanymi poleceniami OpenSSL, można zainstalować sobie jedną z nakładek graficznych dostępnych także dla systemu Windows.
- XCA - Dzięki tej nakładce możemy utworzyć własny urząd certyfikacji (Root CA), także generować klucze dla użytkowników i wystawiać im certyfikaty. Dostępna jest dla większości systemów, w tym BSD.
- My Certificate Wizard - Drugą nakładka co prawda nie jest przeznaczona dla administratorów. Tylko dla zwykłych użytkowników, służy ona bowiem do generowania kluczy prywatnych oraz wniosków o wydanie certyfikatu (pliki CSR). Program jest nieco stary. Jego ostatnia stabilna wersja pochodzi z 2004, a strona twórcy ostatni raz była aktualizowana w 2008 roku.
Tunelowanie portów
Tunel, Tunele - właść. Tunelowanie portów, technika pozwalając na przesłanie jednego połączenia wewnątrz drugiego (tunelu). Najczęstszym zastosowanie tuneli jest szyfrowanie połączeń, które nie zostały przystosowane do korzystania z SSL czy TLS, kompresja danych czy obejście blokad portów.
Tunelowania używa się też jako prostszej alternatywy dla sieci VPN. Jednak diametralna różnica między tunelami a siecią VPN jest taka, że przez VPN operując na warstwie 3 (IP) wprowadzają własną adresacje modyfikując tabele routingu tak, aby cały ruch niezależnie od aplikacji czy protokołu przechodził przez szyfrowany kanał.
Duża zaletą tuneli jest to, że działają one warstwie użytkownika to znaczy, że nie potrzeba uprawnień administratora aby zestawić tunel.
W praktyce tunele wyglądają tak, że użytkownik za pomocą specjalnej aplikacji zestawia szyfrowane połączenie, stanowiąc tunel. W momencie zestawienia tunelu otwierany jest nowy port na interfejsie pętli zwrotnej (127.0.0.1) komputera klienta. Aplikacja na komputerze użytkownika (np. program pocztowy) zamiast łaczyć się bezpośrednio z IP serwera łączy się ze swoim adresem 127.0.0.1, wysyłając dane, które program obsługujący tunel pobiera, następnie szyfruje i przesyła przez Internet na drugą stronę tunelu. Po drugiej stronie połączenia program tunelujący odbiera dane odszyfrowuje i przekazuje - po interfejsie pętli (127.0.0.1) - do właściwej aplikacji (np. serwera POP3).
Oczywiście tunele, nie są alternatywą dla obsługi przez daemony SSL czy TLS, główną różnicą jest tutaj ruch między aplikacją daemona, czy klienta a programem tunelującym. Nie stanowi to jak zagrożenia, do momentu zarażenia systemu złośliwym oprogramowaniem.
Wśród administratorów najpopularniejszymi programami do tworzenie tuneli są Stunnel oraz SSH, oba posiadają wersje na UNIX-y oraz na MS Windows.
Stunnel
Stunnel - rozprowadzany na licencji GNU/GPL program do tworzenia szyfrowanych połączeń TCP. Program do uwierzytelnienia wykorzystuje certyfikaty SSL/TLS X.509.
Dostępność programu w różnych systemach operacyjnych:
- Linux : REPOzytorium(Alpine, Arch, Cent OS, Debian, Fedora, Mageia, OpenMandriva, OpenSUSE(leap), Ubuntu, Slackware)
- *BSD : FreeBSD(REPO), NetBSD(REPO), OpenBSD(PORTS)
- macOS : brew install stunnel
- Windows : https://www.stunnel.org/downloads/stunnel-5.56-win64-installer.exe
Oczywiście program można skompilować samodzielnie potrzebne biblioteki:
libssl, libssl-dev, zlib. Podczas
./configure
podajemy
--prefix=/usr/local/stunnel
, z
docelowym miejscem instalacji. Jeśli
./configure
nie zgłosi błędu wykonujemy kolejno:
make
oraz
make install
.
Konfiguracja składa się z jednego pliku konfiguracyjnego oraz plików certyfikatów. Do jego działania potrzebujemy CA (urządu certyfikacji) oraz klucz i certyfikat dla serwera (najlepiej bez hasła).
Program Stunnel oczekuje klucza prywatnego oraz certyfikatu w jednym
pliku - podawanym w dyrektywie cert
pliku konfiguracyjnego. Musimy przygotować taki plik, uważając na jego
format. Na początku umieszczamy klucz serwera, następnie pustą linijkę
odstępu, a po niej certyfikat.
root@ca:/etc/ssl# cat private/serverkey_bezhasla.pem > private/server.pem root@ca:/etc/ssl# echo " " >> private/server.pem root@ca:/etc/ssl# cat servercert.pem >> private/server.pem
Bardzo ważna jest pusta linijka przerwy pomiędzy kluczem a certyfikatem.
Tak przygotowane pliki server.pem wraz z certyfikatem wystawcy CA (plik cacert.pem) musimy przegrać na właściwy serwer używając bezpiecznego połączenia, np. program SCP/SFTP lub fizycznego sprawdzonego nośnika np. pendrive'a. Pliki zapisujemy na serwerze w katalogu /etc/stunnel.
Należy pamiętać, aby na docelowej maszynie nadać odpowiednie uprawnienia do pliku server.pem tak, aby tylko root mógł go przeczytać. Do tego posłużą dwa poniższe polecenia:
root@srv:~# chown root:root /etc/stunnel/server.pem root@srv:~# chmod 600 /etc/stunnel/server.pem
Czy będą na potrzebne certyfikaty dla klientów? To zależy od aplikacji, czy posiada ona wewnętrzne metody uwierzytelniania użytkowników. Jeśli usługa jest ogólnodostępna tak jak np. IRC, warto rozważyć wdrożenie certyfikatów dla klientów, o ile chcemy utajnić nasz serwer IRC. Wystawianie dla tuneli certyfikatów klienta ma sens w jeszcze jednym przypadku, mianowicie chodzi o ograniczenie dostępu do konkretnych rzeczy - tylko konkretne osoby mogą korzystać z konkretnych zasobów. Jeśli już decydujemy się na uwierzytelnianie użytkowników, to należy pamiętać aby w Common Name podać nazwę jednoznacznie identyfikująca np. login korporacyjny. Decyzje o uwierzytelnieniu użytkowników, należy podjąć samodzielnie, warto pod jedno za lub przeciw wziąć liczbę użytkowników.
stunnel.conf
Plik konfiguracyjny składa się z sekcji globalnej oraz przynajmniej jednej dotyczącej danego tunelu (instancji/usługi). Puste linie są ignorowane, podobnie jak komentarze zaczynające się od średnika (;) lub krzyżyka (#).
Wykaz najważniejszych opcji globalnych
chroot = katalog
(tylko Unix) - określa katalog, w którym uwięziony zostanie proces programu po inicjalizacji. Ścieżki podane w opcjachCApath
,CRLpath
,pid
,exec
muszą być określone względem tego katalogu. Owo uwięzienie sprawia, że nawet w przypadku znalezienia poważnego błędu w aplikacji, umożliwiającego wywołanie powłoki systemu Unix, napastnik zostanie "uwięziony" wewnątrz katalogu /var/run/stunnel. Nie będzie mógł po za ten katalog wyjść, a więc nie będzie miał dostępu do żadnych innych plików serwera.chroot
jest typową metodą zabezpieczania programów w środowisku uniksowym,compression = zlib | rle
- wybór algorytmu kompresji przesyłanych danych. Domyślna opcja to brak kompresji. Możemy skorzystać z prostego algorytmu RLE lub z bardziej wydajnej biblioteki zlib. W tym drugim przypadku biblioteka OpenSSL musi być skompilowana z obsługą kompresjizlib
,debug = wartość
- określa poziom szczegółowości logowania w skali od 1 do 7, odpowiadający poziomom daemonasyslog
,output = plik
- użycie tej opcji spowoduje logowanie informacji do wskazanego pliku zamiast do daemonasyslog
,setuid = uid
(tylko Unix) - identyfikator użytkownika, na którego prawach będzie działał Stunnel. Program po uruchomieni zrzuca uprawnienia administratora i działa jako wskazany tutaj użytkownik,setgid = gid
(tylko Unix) - opcja jak powyżej tylko dotycząca grupy.
Opcje dotyczące sekcji usług
accept = [adres:]port
- nasłuchuje na podanym adresie i porcie. Jeśli nie zostanie jawnie podany adres IP, Stunnel będzie nasłuchiwał na wszystkich adresach IP dostępnych w systemie,connect = [adres:]port
- połacz się ze zdalnym serwerem na podany port. Domyślnie localhost,cert = server.pem
- plik z kluczem prywatnym i certyfikatem,ciphers = lista_algorytmów
- zawiera listę dozwolonych algorytmów SSL. Przydatna jeśli druga strona nie wspiera jakiegoś szyfru,client = yes | no
- ustala, czy sekcja jest klientem czy serwerem. Domyślna wartość:no
- tryb serwerowy,CRLfile = plik_CRL
- plik z listą odwołanych certyfikatów (CRL). Używana, gdy załączona jest opcjaverify
,ident = nazwa_użytkownika
- weryfikuj nazwę zdalnego użytkownika korzystając z protokołu IDENT,verify = poziom
- domyślnie0
- nie weryfikuj certyfikatu (klienta). Dyrektywa ta może przyjmować następujące wartości:- poziom
1
- weryfikuj, jeżeli został przedstawiony, - poziom
2
- weryfikuj certyfikat przez lokalne CA, - poziom
3
- weryfikuj z lokalnie zainstalowanym certyfikatem drugiej strony.
verify
po stronie serwera jest koniecznie jeśli dostęp do tunelu mają mieć wyłącznie uwierzytelnieni użytkownicy (z wystawionymi certyfikatami przez nasze CA).- poziom
retry = yes | no (tylko Unix)
- połącz ponownie sekcjęconnect+exec
po rozłączeniu.
Przykład 1
Przykład opisuje stworzenie tunelu TCP umożliwiającego bezpieczne ściąganie poczty przez protokół POP3.
Jak wiadomo protokół POP3 w swej pierwotnej postaci przesyła wszystkie dane, łącznie z hasłem, jawnym tekstem. Naszym celem będzie przepuszczenie sesji połączenia POP3 przez szyfrowany tunel SSL, tak aby nikt nie był w stanie odczytać ani treści poczty ani hasła.
Ze względu na to, że POP3 uwierzytelnia klientów, certyfikaty dla użytkowników tunelu nie będą potrzebne. Podstawowym celem tunelu jest zapewnienie szyfrowania transmisji. Uwierzytelnienie serwera będzie dobrym pomysłem, bo daje pewność, że łączą się z właściwym serwerem, a nie z podstawionym przez intruza w wyniku zmiany routingu. Przykład można wykonać wg. poniższych punktów.
- Instalujemy najwygodniejszym dla nas sposobem Stunnel w naszym systemie,
- Generujemy na komputerze przeznaczony do CA, klucz i certyfikat dla serwera, po czym łączymy ze sobą oba pliku w plik server.pem, pamiętając o pustej linijce przerwy.
- Przegrywamy na serwer docelowy przygotowany plik server.pem oraz cacert.pem - certyfikat CA. Pamiętając o zmianie uprawnień dla pliku server.pem.
- Tworzymy plik /etc/stunnel/stunnel.conf z zawartością
pokazaną w poniżej:
# stunnel.conf po stronie serwera # opcje globalne chroot = /var/run/stunnel ; ścieżka do chroota pid = /stunnel.pid setuid = stunnel ; zrzuć uprawnienia do użytkownika stunnel setgid = stunnel ; jw. dla grupy debug = 3 output = /var/log/stunnel.log # sekcja związana z sekcją pop3 [pop3s] ; początek sekcji pop3 accept = 995 ; oczekuj połączeń na porcie 995 connect = 110 ; przekazuj dane do portu 110 localhosta cert = /etc/stunnel/server.pem ; plik PEM z kluczem prywatnym i certyfikatem CAfile = /etc/stunnel/cacert.pem ; certyfikat CA verify = 0 ; nie sprawdzamy certyfikatów użytkowników
Czytając ten plik konfiguracyjny wraz z komentarzami można zrozumieć jak będzie działał program Stunnel. Najważniejszą rzeczą jak trzeba by tutaj zaznaczyć, jest że POP3 nasłuchuje na pętli zwrotnej (127.0.0.1) na portcie 110. Jeśli instalując jakąś usługę już wiemy że będziemy używać tunelu do realizowania połączenia między jej daemonem a klientem, to w konfiguracji należy ustawić jako adres nasłuchiwania 127.0.0.1. Klienci łączą się na standardowym porcie 995 (standardowy port pop3s) z tunelem, ten przekazuje dane wewnątrz serwera na port 110 pętli zwrotnej do daemona POP3. - Uruchamiamy tunel na serwerze:
# stunnel /etc/stunnel/stunnel.conf
- Instalujemy na komputerze klienta Stunnel.
- Przenosimy plik z certyfikatem CA - cacert.pem - na komputer klienta.
- Tworzy plik konfiguracyjny klienta pokazany poniżej:
debug = 3 output = stunnel.txt ; loguj do pliku [pop3s] ; początek sekcji połączenia POP3S accept = 127.0.0.1:110 ; słuchaj na porcie 110 interfejsu pętli zwrotnej connect = 85.198.209.251:995 ; połącz się ze zdalnym serwerem na port 995 client = yes ; jestem klientem CAfile = certs.pem ; certyfikat CA potrzebny do uwierzytelnienia serwera verify = 2 ; weryfikuj certyfikat serwera
Warto zaznaczyć że współczesne programy pocztowe obsługują SSL/TLS same w sobie, dlatego punkty 6-8 są zbędne. Jednak aby program nie zgłaszał błedu w połączeniu należy dodać certyfikat naszego CA do zaufanych wystawców, a po stronie serwera natomiast należy wyłączyć opcje weryfikacji klienta. (verify = 0
), ponieważ programy pocztowe nie przedstawiają swojego certyfikatu (a przynajmniej nie wszystkie da się do tego zmusić).
Przykład 2
Przykład przedstawia stworzenie tunelu TCP umożliwiającego bezpieczny dostęp do aplikacji bazodanowej wewnątrz sieci LAN.
Zadanie to możemy rozwiązać za pomocą programu Stunnel, przy czym w tym przypadku program będzie działał na routerze, a nie bezpośrednio na serwerze bazodanowym. Przyda nam się tutaj opcja uwierzytelniania klientów, a także załączenie kompresji.
Zadanie wykonujemy wg. poniższych punktów.
- Zainstalujemy program Stunnel na routerze.
- Generujemy na osobnym komputerze (CA) klucz i certyfikaty dla serwera i użytkowników. Pamiętajmy, aby nie ściągać haseł z kluczy dla użytkowników.
- Przenosimy przygotowany plik server.pem oraz certyfikat CA (plik cacert.pem) na router. Ustawiamy uprawnienia tak aby tylko root był właścicielem i tylko on miał prawo odczytu.
- Ustalamy, na jakim porcie i jakim adresie działa baza danych.
- Przygotowujemy plik konfiguracyjny po stronie routera
- Odblokowujemy na firewallu możliwość łączenia się z portem, na którym słucha program Stunnel.
- Przenosimy klucz i certyfikat (w formie client.pem) oraz certyfikat CA (cacert.pem) na komputer użytkownika. Pozostawiamy kopie certyfikatów użytkowników na komputerze CA.
- Przygotowujemy plik konfiguracyjny klienta i testujemy połączenie.
Jeśli jest to możliwe to dobrze by było, żeby Stunnel od strony Internetu nasłuchiwał na jakimś wysokim porcie, z którym nie jest skojarzona żadna usługa.
Poniżej przedstawiono plik konfiguracyjny routera:
# plik konfiguracyjny programu Stunnel po stronie routera # opcje globalne chroot = /var/run/stunnel ; ścieżka do chroota pid = /stunnel.pid setuid = stunnel ; zrzuć uprawnienia do użytkownika stunnel setgid = stunnel ; jw. dla grupy debug = 3 output = /var/log/stunnel.log # sekcja związana z dostępem do serwera SQL [sqls] ; początek sekcji SQL accept = 11298 ; oczekuj połączeń na tym porcie connect = 192.168.20.6: 3050 ; przekazuj do portu 3050 hosta 192.168.20.6 cert = /etc/stunnel/server.pem CAfile = /etc/stunnel/cacert.pem verify = 2
Jeśli na naszym routerze domyślną polityką jest blokuj, to w następnej kolejności należy odblokować port na którym słucha Stunnel.
Do uruchomienia tunelu pozostała jeszcze konfiguracja klienta. W tym celu należy zainstalować program Stunnel oraz przegrać przygotowane wcześniej certyfikaty client.pem oraz cacert.pem. Konfiguracja klienta jest przestawiona poniżej.
debug = 3 output = stunnel.txt ; loguj do pliku [sqls] accept = 127.0.0.1: 3050 ; słuchaj na porcie 110 interfejsu pętli zwrotnej connect = 85.198.209.251:11298 ; połącz się z serwerem na port 11298 client = yes ; jestem klientem CAfile = certs.pem ; plik z certyfikatem CA, ewentualnie certyfikatem serwera cert = client.pem ; plik z kluczem i certyfikatem użytkownika verify = 2 ; weryfikuj certyfikat serwera przez CA
Ostatnią rzeczą jaką należy zrobić jest zmiana adresu IP serwera bazy danych aplikacji, która ma korzystać z tej bazy na adres pętli zwrotnej. Do testowania działania tunelu przydaje się Telnet - po połączeniu się z portem lokalnego interfejsu, powinien odpowiedzieć serwer bazy danych.
SSH
SSH - protokół sieciowy umożliwiający bezpieczne (szyfrowane) połączenie z powłoką/terminalem (interfejsem tekstowym komputera).
Generalnie SSH, służy nie tylko do pracy za pomocą zdalnej powłoki na odległych serwerach, za pomocą poleceń możemy wygenerować klucze RSA, których później możemy użyć do logowania bez hasła, lub jednego odrębnego hasła dla wszystkich innych serwerów czy bezpiecznego transferu plików jak i również zestawić szyfrowany tunel. Jedyne czego potrzebujemy to konta na serwerze oraz takich możliwości (są ogólnodostępne serwery oferujące konta powłoki, jednak opcje tunelowania są tam niedostępne - przyp. red. 2021).
W niniejszym punkcie zostanie przedstawionych kilka praktycznych przykładów dla tunelowania SSH.
Przykład 1
Podstawowym przykładem będzie zestawienie tunelu SSH pomiędzy lokalnym
portem TCP/12345 a portem TCP/445 odległej maszyny. Przy użyciu unixowego
klienta ssh
składnia polecenia będzie
następująca:
jkowalski@srv10:~$ ssh admin@123.10.12.11 -L 12345:127.0.0.1:445
Liczba podana po -L
określa, który
lokalny port klienta ma zostać użyty dla potrzeb tunelu.
127.0.0.1:445
mówi nam, że zdalna strona
- serwer SSH, ma połączyć się z adresem
127.0.0.1
na port TCP/445
. Czyli w tym przypadku
koniec tunelu stanowić będzie lokalny interfejs zdalnego serwera i
działająca tam SAMBA.
Po podaniu hasła użytkownika zdalnego, tunel zostanie utworzony. W systemach unixowych uruchomienie usługi na porcie poniżej 1024 wymaga uprawnień administratora (root) o czym warto pamiętać. Nie ma to miejsca w systemach Windows.
Czasami może się zdarzyć, że chcemy zestawić tunel na określony czas, a także żeby proces przeszedł w tło. Dla przykładu możemy zestawić tunel trwający 10 minut.
$ ssh -f -n -L 12345:127.0.0.1:445 admin@123.10.12.11 sleep 600
Opcja -f
powoduje przeniesienie na tło
wykonania polecenia /bin/sleep, z kolei opcja
-n
jest często używana z opcją
-f
, powoduje ona przekierowanie pliku
/dev/null na standardowego wejścia dla procesu uruchomionego
w tle. Opcja -n
zostanie
zignorowana gdy ssh
będzie prosił o
hasło.
Utworzenie tunelu z portami 1:1
Przydatne wtedy, gdy aplikacja ma już zdefiniowane odgórnie porty.
xf0r3m@KAT2:~$ ssh xf0r3m@dl.morketsmerke.net -L 445:127.0.0.1:445
Przykład 2 - SSH jako Socks Proxy
Tunele SSH można wykorzystać do zestawiania końców tunelu z różnymi hostami, do tej port hosta na końcu tunelu był stały. Twórcy SSH zaimplementowali coś takiego jak tunele dynamiczne. Jeśli pakiet zostanie przekazany na przykład przez jakieś ustawienie proxy na port, na którym jest uruchomiony tunel dynamiczny, serwer zdalny zestawi koniec tunelu pomiędzy sobą a hostem docelowym na danym porcie zwartym w pakiecie. Można użyć tej techniki do omijania blokad portów.
xf0r3m@KAT2:~$ ssh xf0r3m@dl.morketsmerke.net -D 8080
Przykład 3 - tunele z przekazywaniem zdalnym
SSH pozwala na jeszcze jeden rodzaj tuneli. Mianowicie tunel z
przekazywaniem zdalnym. Polega on na tym że nasz serwer, który z jakiś
powodów nie może być normalnie wypuszczony do Internetu, tworzy
specjalny rodzaj tunelu, który otwiera port na serwerze. Otwarcie tego
portu pozwoli na połączenie się potencjalnego klienta z problematycznym
serwerem, warunkiem jest zestawienie kolejnego tunelu, tym razem takie
jak wcześniej (lokalnego), który przekieruje dane z aplikcji na port
otwarty na serwerze, a ten z kolei na nasz serwer. Jeśli jesteśmy
administratorem serwera SSH, możemy ustawić go tak aby zdalny port
nasłuchiwał na wszystkich adresach na serwerze, co analogicznie
uwidacznia go z poziomu internetu (nie koniecznie, może być jeszcze
wymagany port forwarding na routerze/bramie), służy do tego opcja
GatewayPorts
, która domyślnie ustawiona
jest na no
ze względów bezpieczeństwa,
niweluje nam potrzebę zestawiania lokalnego przekazywania (klasycznego
tunelu SSH). Warunek jest prosty. Czy otwarty przez zdalne przekazywanie
serwera ma być ogólnodostępny w internecie. Jeśli tak to (i oczywiście
mamy do tego odpowiednie uprawnienia) możemy przestawić tę opcję na
yes
. Jeśli nie to pozostaje nam
zestawić tylko tunel pomiędzy lokalnym portem a otwartym zdalnym portem.
#port zdalny xf0r3m@KAT2:~$ ssh xf0r3m@dl.morketsmerke.net -R 11111:127.0.0.1:3389
#port lokalny xf0r3m@KAT2:~$ ssh xf0r3m@dl.morketsmerke.net -L 13389:127.0.0.1:11111
Podobno jeśli używamy XP wersji Professional to nie powinniśmy przekierowywać lokalnego tunelu na 3389, ponieważ może na nim działać lokalny serwer usług terminalowych (sic!).
Po zestawieniu tych tuneli powinniśmy móc się połączyć, za pomocą klienta RDP, na lokalnie przekierowanym porcie czyli TCP/13389.
Tunel UDP po SSH
W przykładach na powyższych stronach, tunelowane były inne połączenia TCP. To tutaj zostanie przedstawiony pomysł na tunelowanie UDP przez połączenie SSH (TCP). Generalnie do tunelowanie UDP bardziej nadają się sieci VPN, jednak przestawiony sposób działa dobrze i może przydać do prostych zastosowań.
Załóżmy, że musimy połączyć się z usługa UDP na porcie 7777, jednak nasz komputer jest podłączony do sieci, która blokuje połączenia UDP na tym porcie.
W tym celu musimy zestawić połączenie TCP naszego komputera z serwerem pośredniczącym SSH na interesujących nas portach. W tym celu na naszym komputerze wpisujemy polecenie:
xf0r3m@srv01:~$ ssh -L 7777:localhost:7777 xf0r3m@srv02.morketsmerke.net
Teraz na serwerze SSH musimy utworzyć "przekaźnik" danych, który dane odczytane z TCP 7777 prześle do portu 7777 UDP do serwera. Wykorzystamy do tego kolejkę FIFO oraz program Netcat. Na serwerze pośredniczącym wpisujemy polecenie:
root@srv02:~# mkfifo /tmp/fifo
Kolejnym krokiem będzie uruchomienie programu Netcat, który będzie słuchał na porcie TCP 7777 serwera (pobierał dane z tunelu) a następnie już bezpośrednio będzie przekazywał je do serwera:
xf0r3m@srv02:~$ nc -l -p 7777 < /tmp/fifo | nc -u 123.10.12.11 7777 > /tmp/fifo
W pierwszej części nc
nasłuchuje na adresie pętli zwrotnej
na porcie 7777, pobierając dane z tunelu a następnie przekaże je do
potokiem to kolejnej instancji nc, która wyśle je do serwera,
natomiast odpowiedzi przekaże z powrotem do kolejki, a te trafią tunelem
do naszego komputera.
Teraz wracamy do naszego komputera i tam tworzymy nową kolejkę FIFO.:
xf0r3m@srv01:~# mkfifo /tmp/fifo
Następnie uruchamiamy program Netcat z odpowiedni parametrami:
xf0r3m@srv01:~#nc -l -u -p 7777 < /tmp/fifo | nc localhost 7777 > /tmp/fifo
NC uruchamia port 7777 UDP, to z nim będzie się łączyć nasza aplikacja, dane wyjściowe przekazywane są do tunelu gdzie przekazywane są do serwera odpowiedzi są przekazywane do kolejki, a następnie jako dane wejściowe (pobrane z kolejki FIFO) do aplikacji.
Powinniśmy teraz móc się połączyć. Jeśli jest z czymś problem to warto upewnić się czy do kolejki trafią dane, na wolnej konsoli możemy wyświetlić jej zawartość poleceniem (na obu maszynach):
$ tail -f /tmp/fifo
OpenVPN
OpenVPN - to działający w oparciu o protokół SSL/TLS program do zestawiania wirtualnych sieci prywatnych.
Do najważniejszych cech można zaliczyć m.in.:
- prosta instalacja i konfiguracja,
- działa w warstwie użytkownika,
- wykorzystuje dobrze znany i sprawdzony protokół SSL,
- dostępny jest na licencji GPL w wersji 2,
- działa z większością systemów operacyjnych nawet z Windows Mobile,
- działa bezproblemowo w sieciach za NAT-em.
Instalacja
Instalacja programu OpenVPN różni się w zależności od zainstalowanego systemu operacyjnego. W systemach Linux możemy zainstalować program, używając właściwego dla swojej dystrybucji narzędzia do zarządzania pakietami, lub też pobrać źródła programu OpenVPN i skompilować je samodzielnie. W przypadku systemu FreeBSD zaleca się użycie systemu portów. Dla systemów MS Windows (2000, XP, Vista) dostępny jest pakiet instalacyjny, który oprócz właściwego programu zainstaluje też sterownik wirtualnego interfejsu TAP.
Poniżej przedstawione zostanie instalacja w systemie GNU/Linux Debian
z wykorzystaniem apt-get
a także
kompilacje ze źródeł.
Instalacja w systemie GNU/Linux Debian
Będąc zalogowanym jako root wpisujemy polecenie:
root@srv01:~# apt-get install openvpn.
Program apt-get
ściągnie z sieci paczkę
z programem OpenVPN i zainstaluje plik w odpowiednich katalogach.
Skrypt instalacyjny zapyta także, czy utworzyć plik urządzenia
/dev/net/tun. Na te pytania należy odpowiedzieć twierdząco,
urządzenie jest potrzebne do działania VPN. Skrypt instalacyjny Debiana
zapyta także o to czy w przypadku aktualizacji programu OpenVPN
powinien wyłączyć usługę przed aktualizacją, czy też robić to po
aktualizacji. Odpowiedź na to pytanie jest istotna w przypadku gdy dostęp
do konsoli serwera mamy tylko przez nasz tunel VPN - wówczas należy
odpowiedzieć NIE (nie zatrzymuj usługi przed
aktualizacją). W przeciwnym razie stracilibyśmy łączność z serwerem.
W przypadku "paczek" Debianowych program zostanie
zainstalowany w katalogu /usr/sbin, a pliki konfiguracyjny
powinien znajdować się w /etc/openvpn.
Instalacja przez kompilację źródeł programu (Linux)
Opis instalacji ze źródeł jest uniwersalny dla większości systemów *niksowych. Przed kompilacją upewnij się, czy masz zainstalowane w systemie tzw. narzędzia deweloperskie ( np. dla dystrybucji opartych na Debianie jest to pakiet pod nazwą build-essentials) tj. kompilator języka C++ (pakiet g++) i program make. Jako że OpenVPN działa w oparciu o protokół SSL, potrzebna będzie także zainstalowana biblioteka openssl wraz z nagłówkami (pakiety libssl, libssl-dev). Dystrybucje, w których instalacja oprogramowania na ogół polega na kompilacji źródeł, powinny mieć wszystkie potrzebne biblioteki już zainstalowane.
Przed kompilacją programu OpenVPN upewnij się że masz zainstalowaną w systemie bibliotekę LZO (wraz z nagłówkami) - odpowiedzialną za kompresje danych. Wprawdzie można skompilować OpenVPN bez tej biblioteki, jednakże pozbawimy się możliwości używania kompresji w połączeniach VPN. Aby sprawdzić czy mamy zainstalowane pliki nagłówkowe biblioteki LZO wykonujemy poniższe polecenie.
srv:~# find /usr/ -type -f -name 'lzo1x.h'
Jeśli nie znaleziono pliku lzo1x.h, to musimy jeszcze skompilować i zainstalować bibliotekę LZO. W tym celu wykonujemy poniższe czynności.
- Pobieramy kod źródłowy biblioteki LZO ze strony http://www.oberhumer.com/opensource/lzo/#download. Musimy pobrać pełną wersję, nie wybierajmy wersji Mini-LZO, która nie zawiera potrzebnych plików nagłówkowych. Rozpakowujemy kod w jakiś katalog tymczasowy np. /usr/src/lzo-2.10.
- Wpisujemy polecenie:
# ./configure && make && make install
Jeśli mamy zainstalowane w systemie podstawowe narzędzia deweloperskie,
biblioteka powinna skompilować się bez problemów. W wyniku instalacji
(polecenia make install
) powinny
powstać pliki nagłówkowe biblioteki LZO - w katalogu
/usr/local/include/lzo. Teraz możemy przejść do kompilacji
programu OpenVPN.
- Pobieramy źródła stabilnej wersji programu OpenVPN ze strony głównej projektu https://openvpn.net/community-downloads/.
- Rozpakowujemy plik w katalogu /usr/src/. W tym celu
wpisujemy polecenie:
# unzip openvpn-<numer_wersji>.zip
- Przechodzimy do katalogu openvpn-<numer_wersji> i
wpisujemy polecenie:
# ./configure
- Możemy zapoznać się z listą dostępnych opcji wpisując polecenie
# ./configure --help | more
, jednakże w większości przypadków domyślne opcje konfiguracyjne są wystarczające. - Jeśli podczas działania skryptu
./configure
nie zostaną zgłoszone błędy, możemy uruchomić właściwą kompilacje programu w tym celu wpisujemy polecenie:# make
Kompilacja nie trwa długo, na szybkim komputerze po około minucie programmake
zakończy działanie. - Ostatnim krokiem jest instalacja skompilowanych plików we właściwych
katalogach. W tym celu wpisujemy polecenie:
# make install
Program powinien zainstalować się w katalogu /usr/local/bin
OpenVPN potrzebuje też do działania wirtualnego interfejsu sieciowego TUN/TAP, którego sterownik musi być wkompilowany w jądro systemu, bądź mieć postać modułów (Linux). Jeśli nie kompilowaliśmy jądra swojego systemu samodzielnie, to najprawdopodobniej odpowiedni sterownik mamy już w systemie (popularne dystrybucje dodają go w postaci modułów). Aby się o tym przekonać wpisujemy polecenie:
# modprobe tun
Jeśli program modprobe
nie zgłosi błędu,
możemy wpisać komendę dmesg
, aby
sprawdzić, czy moduł jądra został załadowany do pamięci. Szukajmy napisu
zawierającego "TUN/TAP". Gdy program
modprobe
zgłosi
następujący błąd:
Can't locate module tun
,
oznacza to, że albo sterownik interfejsu TUN/TAP został
wkompilowany w jądro, albo też sterownika nie ma ani w jądrze, ani w
postaci modułu. Aby sprawdzić to, wpisujemy polecenie:
dmesg | grep -i tun
. Powinniśmy
zobaczyć komunikat świadczący o obecności sterownika TUN/TAP, w
przeciwnym razie jądro nie obsługuje tego sterownika i będzie trzeba je
przekompilować.
(od Redaktora strony: Tutaj ze względu na to, że książka została wydana 10 lat temu. Ta część zostanie zakończona. Rekompilacja jądra przedstawiona w tym miejscu w książce była kompatybilna z jądrem 2.6, w momencie pisania jest 5.5.10, wiele rzeczy z tym związane mogło zostać zmienione, natomiast nie umiejętna rekompilacja jądrą może unieruchomić system, ta część zostanie pominięta)
Ostatnim etapem instalacji programu OpenVPN jest stworzenie pliku urządzenia interfejsu TUN oraz modyfikacja skryptów startowych. Wpisujemy polecenie:
# mknod /dev/net/tun c 10 200
Jeśli instalowaliśmy OpenVPN z paczki, jest wielce prawdopodobne, że plik już istnieje, więc wywołanie tego polecenia zwróci błąd o tym że, pliki istnieje. Nie należy się nim przejmować. W przypadku gdy sterownik TUN jest w postaci modułu, upewnijmy się czy jest on dopisany w pliku odpowiedzialnym za ładowanie modułów przy starcie systemu. Niestety nie ma tutaj spójności pomiędzy systemami. Poniżej znajdują się ścieżki dla najpopularniejszych dystrybucji:
- /etc/modules - dystrybucja Debian i wszystkie bazujące na niej,
- /etc/rc.modules - dystrybucja Slackware,
- /etc/modprobe.conf - dystrybucja RedHat, Fedora, Aurox, o inne bazujące na RHEL.
Jako, że do działania sieci VPN na pewno będzie potrzebne przekazywanie
pakietów (ang. forwarding) dopisujemy do pliku
/etc/sysctl.conf linijkę:
net.ivp4.ip_forward = 1
.
Ze względów bezpieczeństwa serwera na potrzeby działania programu OpenVPN powinieneś stworzyć osobne konto bez możliwości logowania się i bez możliwości uruchomienia powłoki. Program OpenVPN zaraz po uruchomieniu się zrzuci uprawnienia użytkownika root na to specjalne konto.
Zakładamy konto OpenVPN oraz grupę o takiej samej nazwie. W tym celu wykonujemy poniższe polecenia.
groupadd openvpn
usermod -g openvpn -d /usr/local/etc/openvpn -s /bin/false -f 1 openvpn
mkdir /user/local/etc/openvpn
chown openvpn:openvpn /usr/local/etc/openvpn
W powyższym przykładzie konfiguracje programu OpenVPN będziemy przechowywali w katalogu /usr/local/etc/openvpn. Możemy ją zmienić oczywiście dostosowując je do własnych potrzeb.
Konfiguracja OpenVPN
Konfiguracja programu OpenVPN polega na stworzeniu jednego pliku konfiguracyjnego oraz ewentualnym przygotowaniu klucz i certyfikatów SSL dla serwera i klientów. Liczba opcji konfiguracyjnych sukcesywnie rosła, osiągając już całkiem pokaźne rozmiary. Jednak w typowych konfiguracjach używać będziemy używać tylko podstawowych opcji. Nim przejdziemy do praktycznych przykładów, zostaną opisane najważniejsze właściwości programu OpenVPN.
OpenVPN może działać w jednym z dwóch podstawowych typów:
- Tryb routera - używany w przypadku konfiguracji typu brama + wielu klientów lub brama-brama. Dobrym przykładem jest tutaj zdalny dostęp do zasobów firmy przez mobilnych pracowników.
- Tryb bridge'a - używany najczęściej w przypadku łączenia dwóch lub większej liczby sieci. W tym przypadku między sieciami przekazywany jest cały ruch łącznie z broadcastami. Przykładem wykorzystania tego trybu jest stworzenie tuneli VPN pomiędzy oddziałem firmy a centralą, tak aby działał między nimi protokół IPX.
Trybu bridge'a powinniśmy używać tylko w gdy jest naprawdę konieczne. We wszystkich pozostałych lepszym rozwiązaniem jest tryb routera. Przede wszystkim dla tego że nie przesyła pakietów broadcast. Po drugie w przypadku routera każdy z klientów ma osobną podsieć IP, dzięki czemu możemy prosto i skutecznie definiować, który użytkownik do czego ma dostęp na firewallu (np. iptables).
Drugą istotną kwestią, którą musismy rozważyć, jest sposób uwierzytelniania klientów. Tutaj także mamy dwie możliwości:
- Uwierzytelnianie przez współdzielony stały klucz znany obu stronom. Rozwiązanie proste w konfiguracji, nie nadaje się dla wielu użytkowników. Znakomicie sprawdza się jednak w przypadku łączenia podsieci, np. oddziału firmy z centralą,
- Uwierzytelnianie przez certyfikaty SSL X.509, znane z poprzedniego rozdziału. To rozwiązanie znakomicie nadaje się do tworzenia zdalnego dostępu dla pracowników. Dzięki własnościom protokołu SSL/PKI możemy wystawiać użytkownikom certyfikat na określony czas, w razie potrzeby unieważnić je, nadawać dostęp na podstawie właściciela certyfikatu itp.
Jeśli mamy wybrać metodę to uwierzytelnianie po przez certyfikaty X.509 należy zastosować wszędzie tam, gdzie mamy do czynienia z czynnikiem ludzkim (odchodzący pracownicy, nieznani użytkownicy). Rozwiązanie z kluczem współdzielonym wystarcza w przypadku łączenia ze sobą routerów.
UDP czy TCP - który protokół transportowy wybrać dla potrzeb tunelu? OpenVPN może działać z wykorzystaniem zarówno protokół UDP, jak i TCP. Autorzy OpenVPN zalecają używanie protokołu UDP, co może na pierwszy rzut oka wydawać się dziwne, ponieważ UDP nie zapewnia mechanizmów kontroli przesyłu ani mechanizmów potwierdzeń. Powodem jest wydajność transmisji. Chodzi tutaj o znany problem, jak pojawia się w przypadku przesyłania transmisji TCP zawartej (tunelowanej, enkapsulowanej) w ramach innej sesji TCP - co miałoby miejsce w przypadku uruchomienia tunelu po TCP. Mechanizm retransmisji sprawdza się bardzo dobrze na zawodnych łączach internetowych, natomiast gdy ten sam zgubiony pakiet próbują retransmitować dwa protokoły TCP, prowadzi to do zapchania łącza. Wyobraźmy sobie sytuacje, w której pierwsza warstwa transportowa (ta, po której działa tunel) zaczyna gubić pakiety. W czasie, w którym warstwa niższa czeka na retransmisje, warstwa wyższa TCP (ta, która "przenosi" właściwie dane użytkownika wewnątrz tunelu) nie dostaje potwierdzeń od hosta docelowego i sama zaczyna retransmitować brakujące segmenty - zatykając tym samym i tak przytkaną już warstwę niższą. To zjawisko nazywa się efektem meltdown lub TCP meltdown.
W praktyce dużo zależy od tego, jakie dane będą przesyłane przez tunel VPN, oraz od jakości połączenia. W przypadku dobrego łącza i małego obciążenia różnica może być pomijalna. Jeśli zamierzamy uruchomić bramę dostępować dla pracowników mobilnych, musimy pod uwagę, że "nietypowe" porty UDP mogą być blokowane w takich miejscach jak hotel czy publiczny hotspot itp. Ostatecznie nic nie stoi na przeszkodzie aby uruchomić dwa osobne tunele, jeden działający na TCP, drugi na UDP.
Praktyczny przykład - zdalny dostęp do zasobów dla pracowników firmy
Możemy rozważyć następujący przypadek. Dostępu do zasobów sieci LAN, tj.
dysków udostępnionych na serwerze Windows 2003, bazy danych MySQL
oraz aplikacji intranetowej, potrzebuje grupa handlowców. Brama
internetowa w firmie działa na Linuksie, użytkownicy mają na laptopach
system MS Windows XP. Klasa adresowa wewnątrz sieci firmowej to
192.168.10.0/24
.
Jako, że mamy tu do czynienia z czynnikiem ludzkim na pewno zastosujemy uwierzytelnianie użytkowników przez certyfikaty SSL. Zanim jeszcze przejdziemy do konfiguracji programu OpenVPN, należy przygotować klucze i certyfikaty SSL dla serwera (bramy) i użytkowników.
Generowanie certyfikatów SSL
Aby móc skonfigurować niezbędne będzie utworzenie urzędu certyfikacji oraz certyfikatów zarówno dla serwera jak i dla poszczególnych użytkowników, zostało zobrazowane w sekcji poświęconej SSL: Generowanie certyfikatów SSL
Konfiguracja po stronie serwera
Konfiguracje serwera rozpoczynamy od przegrania na nasz serwer OpenVPN do katalogu z konfiguracją, certyfikatu; klucza prywatnego serwera oraz certyfikatu wystawcy CA. Następnie po stronie serwera musimy wygenerować plik pomocniczy z parametrami algorytmu kryptograficznego Diffiego-Hellmana. Algorytm ten umożliwia uzgodnienie stronom wspólnego klucza do szyfrowania symetrycznego, który będzie znany tylko im. Do tego celu potrzebne są wylosowane dwie liczby pierwsze zawarte w pliku DH. Obecnie za bezpieczne uznaje się aby klucz użyty w protokole DH był długości 1024 bitów. Do celu użyjemy biblioteki OpenSSL. Wpisujemy polecenie podane poniżej,
openssl dhparam -out dh1024.pem 1024
Operacja może potrwać nawet kilka minut - w zależności o szybkości procesora. Podczas generowania klucza (1024-bitowej liczby pierwszej) na ekranie zobaczymy kropki. Przygotowany plik dh1024.pem przegrywamy do katalogu konfiguracyjnego programu OpenVPN. Teraz możemy przejść do edycji po stronie serwera. Przykładowy plik został podany poniżej.
dev tun ; rodzaj interfejsu — dla routera zawsze TUN local 85.198.209.251 ; adres, na którym będzie działał VPN proto udp ; tunel będzie działał na porcie UDP port 17003 ; używany port user openvpn ; zrzuć uprawnienia na wskazanego użytkownika group openvpn ; jw. dla grupy ca cacert.pem ; plik certyfikatu CA cert servercert.pem ; certyfikat serwera key serverkey.pem_bezhasla ; plik z kluczem prywatnym serwera dh dh1024.pem ; plik z parametrami protokołu Diffiego-Hellmana server 10.8.0.0 255.255.255.0 ; klasa adresowa, z której przydzielane będą adresy IP klientom ifconfig-pool-persist ipp.txt ; zawiera informacje o przydzielonych adresach IP client-config-dir ccd ; katalog z plikami specyficznych ustawień użytkowników keepalive 10 120 ; comp-lzo ; algorytm kompresji
Spośród tego pliku konfiguracyjnego szerszego omówienia wymagają dwie
opcje.
ifconfig-pool-persist <nazwa pliku>
w pliku wskazanym w tej dyrektywie OpenVPN zapisuje nazwy
użytkowników oraz adresy IP, jakie zostały przydzielone klientom z puli
adresów określonej dyrektywą server
.
Nazwa użytkownika to zawartość pola Common Name z certyfikatu klienta.
Adres IP zapisane są w postaci podsieci o masce /30
(255.255.255.252). Dzięki plikowi
ifconfig-pool-persist
klient
może otrzymać to samo IP po ponownym podłączeniu.
Z plikiem ipp.txt związana jest pewna nieścisłość która zostanie
wyjaśniona przy okazji opisu bardziej złożonej konfiguracji. Kolejną
dyrektywą wartą omówienia jest
client-config-dir <nazwa katalogu>
,
opcja ta wskazuje katalog, w którym znajdują się konfiguracje
poszczególnych użytkowników. Twórcy OpenVPN przewidzieli
możliwość dostosowywania konfiguracji do konkretnych użytkowników. W
momencie zestawiania połączenia VPN program sprawdza, czy istnieje plik
konfiguracyjny użytkownika w katalogu ccd i jeśli tak,
przetwarza zapisane w nim opcje. Pliki w katalogu ccd muszą mieć
nazwy zgodne z polem Common Name
certyfikatu klienta.
Między innymi dlatego pole Common Name
certyfikatu SSL jest
dla programu OpenVPN takie ważne. Najczęściej poprzez CCD
przekazujemy użytkownikowi adres IP, adresy serwerów DNS, informacje o
routingu.
Uruchomienie usługi serwera
Mając przygotowany plik konfiguracyjny, możemy uruchomić proces serwera. W tym celu wpisujemy polecenie:
/usr/sbin/openvpn --config /usr/local/etc/openvpn/server.conf
Dostosowując oczywiście ścieżki dostęp do według własnej konfiguracji. Jeśli mamy skonfigurowaną zaporę sieciową na domyślne blokowanie musimy odblokować ją na porcie jaki podaliśmy dla usługi OpenVPN.
Konfiguracja klienta
Aby przetestować nasze pierwsze połączenia VPN, musimy jeszcze skonfigurować ustawienia po stronie użytkownika. Zakładając, że pliki z kluczem prywatnym oraz certyfikatem użytkownika mamy już przygotowane. Należy przegrać je na komputer użytkownika nazywając odpowiednio user.key i user.crt. Przegrać musimy też certyfikat urzędu CA - plik cacert.pem, aby było wygodnie pisać plik konfiguracyjny i darować sobie pisanie ścieżek do certyfikatów umieścimy je w tym samym katalogu co plik konfiguracyjny. Poniżej znajduje się przykładowy plik konfiguracyjny dla klienta.
dev tun ; interfejs typu TUN (router) client ; tryb klienta remote 85.198.209.251 ; adres zdalnego serwera proto udp ; użyty protokół transportowy port 17003 ; port, z którym się połączy nobind ; nie otwieraj portu po stronie klienta ca cacert.pem ; plik z certyfikatem CA cert user.crt ; plik z certyfikatem użytkownika key user.key ; plik z kluczem prywatnym użytkownika comp-lzo ; załączona kompresja verb 3 ; poziom komunikatów
Podczas zestawiania połączenia program kliencki czy na Windows czy to na Linux będzie wyświetlać komunikaty, z nich możemy wywnioskować czy połączenie zostało zestawione czy też nie. Jeśli wydaje nam się, że tak to dla pewności możemy spingować adres interfejsu TUN na serwerze. W razie problemów przydatnym staje się program tcpdump lub Wireshark. Jednak, że adres przydzielony przez serwer w sieci VPN nie daje nam jeszcze możliwości komunikacji z hostami w sieci LAN w siedzibie firmy. Aby móc wykorzystać zasoby z siedziby firmy, należy ustawić trasę w systemie aby ruch skierowany na adresy w sieci firmowej przechodził przez interfejs TUN (wirtualny interfejs sieci VPN).
Ustawienia trasy czy też statycznych adresów serwerów DNS, możemy ustawić
tak, aby były one przekazywane przy połączeniu. Polecenie
push
może zostać umieszczone w pliku
konfiguracyjnym wtedy mamy do czynienia z konfiguracją globalną, lub w
katalogu ccd w plikach konfiguracyjnych użytkowników. Składnia
polecenia push
dla
route
:
push "route 192.168.10.20 255.255.255.255"
Zwróćmy uwagę na to, że nie ma adresu bramy. Otóż OpenVPN sam dobierze sobie adres bramy odpowiedni dla tunelu klienta.
Bardziej złożona konfiguracja z wieloma użytkownikami
Załóżmy, że do sieci firmowej zdalny dostęp przez VPN powinna mieć spora liczba pracowników - np. trzydziestu. Jako że osoby te należą do różnych działów, uprawnienia do zasobów wewnętrznych muszą różnić się. Pomijając dalsze uwierzytelnienia w warstwie aplikacji (hasło do bazy danych itd.), powinniśmy tak skonfigurować zdalny dostęp, aby pracownik "widział" jedynie to, co powinien, a nie całą sieć wewnętrzną. Nie wątpliwie najprościej ten cel zrealizować przez blokadę na firewallu. Tutaj świetnie sprawdzi się iptables.
W pierwszej kolejności wygenerujemy klucze wraz certyfikatami dla wszystkich użytkowników, następnie powinniśmy gdzieś sobie rozpisać kto do czego powinien mieć dostęp. Należy pamiętać, aby użytkownik zdalny miał dostęp TYLKO! do niezbędnych zasobów. Jeśli nie ma konieczności to nie powinien on również mieć dostępu do Internetu przez sieć VPN. Są w sumie trzy takie zasady, dzięki którym będziemy realizować naszą konfiguracje. Otóż:
- Każdemu z użytkowników, OpenVPN powinien przydzielać zawsze to samo IP, na podstawie którego będziemy przyznawać dostęp tylko do określonych zasobów w sieci LAN (serwerów, usług).
- Poprzez mechanizm CCD (client-config dir) będziemy przekazywać użytkownikom ich konfiguracje (modyfikacja tabeli routingu, zmiana serwerów DNS itp.).
- Informacje o adresach IP oraz dostępnie do serwerów wewnętrznych będzie zapisywali w plikach konfiguracyjnych OpenVPN oraz w postaci reguł iptables.
Przypisywanie stałych adresów IP użytkownikom
Za przydzielanie użytkownikom stałych adresów IP odpowiada dyrektywa
ifconfig-push
, którą umieścimy w plikach
ustawień użytkowników - w katalogu ccd. Składnia instrukcji
ifconfig-push
jest następująca:
ifconfig-push <adres_klienta> <adres_serwera>
Na przykład:
ifconfig-push 10.8.0.10 10.8.0.9
Pliki ustawień użytkowników w katalogu ccd
Poprzez pliki konfiguracyjne w katalogu ccd możemy przekazać różne parametry, poniżej znajduje się klika przykładów.
push "route <adres> <maska>"
- dodaje wpis do tablicy routingu klienta.push "dhcp-option DNS <adres_IP_serwera_DNS>
- ustawia nowy DNS w konfiguracji klienta.push "dhcp-option DOMAIN <nazwa_domeny>
- ustawia sufiks domeny w konfiguracji DNS klienta.push "redirect-gateway"
- ustawienie tej opcji spowoduje przekierowanie całego ruchu klienta (domyślna trasa)
Skorzystanie z ostatniej opcji
(redirect-gateway
) będzie wymagało
utworzenia regułek NAT-u, aby
użytkownik mógł "wychodzić na świat" z adresu firmowego routera.
Korzystając z ww. opcji, utworzymy dla każdego z użytkowników odpowiedni plik w katalogu ccd. Będziemy przekazywali adres IP oraz wpisy dodające trasy w tabeli routingu.
Logowanie zdarzeń do pliku
Jeśli planujemy produkcyjnie wdrożyć program OpenVPN z większą
liczbą użytkowników, warto mieć możliwość szybkiego i łatwego sprawdzenia
informacji takich jak: kto, kiedy i skąd połączył się z VPN. Informacje
tego typu warto archiwizować jako ewentualny "dowód w sprawie". Może też
wrzucić je do bazy SQL dla łatwiejszej obróbki i generowania statystyk.
Do tego celu możemy wykorzystać opcję serwera OpenVPN
learn-address
. Opcja ta - jeśli jest
załączona - wywoła skrypt podany jako parametr podczas zdarzeń takich
jak podłączenie się klienta, zmiana adresu IP czy rozłączenie.
Składnia opcji jest następująca:
learn-address <skrypt>
OpenVPN przekaże do skryptu parametry takie, jak:
- parametr:
akcja
(add,delete,update
) - w zależności od tego co miało miejsce, - parametr: adres IP klienta (przydzielony w ramach tunelu),
- parametr: nazwa
Common Name
użytkownika.
Niestety żaden skrypt nie jest dołączony do OpenVPN. Musimy napisać go samodzielnie.
Unieważnianie certyfikatów
Przy większej liczbie użytkowników prędzej czy później zajdzie potrzeba zablokowania dostępu do VPN któremuś z nich. Powody mogą być różne, najczęstsze to odjeście z pracy lub kradzież laptopa.
Załóżmy, że chcemy unieważnić certyfikat użytkownika jkowalski. W pierwszej kolejności musimy korzystając z programu OpenSSL, unieważnić certyfikat. Logujemy się na komputer CA, i przechodzimy do katalogu /etc/ssl, a następnie wpisujemy polecenie:
root@ca:/etc/ssl# openssl ca -revoke jkowalskicert.pem
OpenSSL zapyta o hasło klucza CA i po podaniu prawidłowego unieważni certyfikat. Po unieważnieniu certyfikatu dostaniemy informacje zwrotną, że baza została zaktualizowana. Możemy teraz podejrzeć zawartość pliku index.txt - przy użytkowniku jkowalski zobaczymy znacznik R (ang. revoked).
Musimy jeszcze wygenerować listę CRL, w której zapisane są wszystkie unieważnione certyfikaty.
root@ca:/etc/ssl# openssl ca -gencrl -out crl.pem
Teraz należy wygenerowany plik crl.pem, przegrać na serwer do katalogu z konfiguracją OpenVPN. Następnie do pisać do pliku konfiguracyjnego:
crl-verify crl.pem
Restartujemy usługę (zatrzymujemy i uruchamiamy ponownie) OpenVPN. Teraz możemy przetestować czy jkowalski rzeczywiście nie ma już dostępu do VPN, zestawiając połączenie jako on. Nie dostaniemy żadnego komunikatu, po stronie klienta. Połączenie po prostu się nie zestawia.
Łączenie oddziałów firmy
Rozważmy przypadek, w którym musimy połączyć siedzibę firmy z nowo powstałym oddziałem w innym mieście.
Sposób pierwszy, podobny w działaniu do poprzedniego przypadku, tunel VPN działający w trybie routera. W tym przypadku komputery w siedzibie A i siedzibie B będą w innych klasach adresowych i do komunikacji między sobą będą używały bram. Rozwiązanie dobre bo separuje podsieć przepuszczając tylko wymagany ruch. Niestety nie zawsze się to sprawdza, gdyż, jak wiemy routery nie przekazują pakietów wysyłanych na adres rozgłoszeniowy sieci (ang. broadcast), a niektóre protokoły używają tego adresu do poprawnego działania.
W związku z powyższym omówimy też drugie rozwiązanie - oparte na mostach sieciowych. W tym przypadku tunel VPN będzie przezroczysty dla warstwy sieci, dzięki czemu komputery będą się widziały tak, jakby oddziały były połączone siecią Ethernet. Wówczas komputery w oddziałach A i B będą w tej samej klasie adresowej i do komunikacji nie będą używały bram.
Generalnie zalecam używanie trybu routera wszędzie tam gdzie to tylko możliwe. Rozwiązanie "mostkowe" przepuszcza przez tunel cały ruch warstwy sieci, w tym także zapytania ARP, co oczywiście wpływa na obciążenie łącza VPN.
Przykład rozwiązania z routerem
Rozważmy przypadek. Siedzibę firmy A musimy połączyć tunelem z oddziałem
B. Klasa używana w sieci wewnętrznej w siedzibie A to
192.168.20.0/24
. Komputery w oddziale B
powinny mieć dostęp do trzech serwerów z sieci w siedzibie A:
192.168.20.3, 192.168.20.4, 192.168.20.5
.
Dodatkowo komputery z oddziału B powinny mieć dostęp do Internetu przez
łącze z siedziby A. Routery po obu stronach działają na Linuksie.
Na interfejsach tunelu użyjemy klasy
10.3.0.0/30
. Dla potrzeb
sieci wewnętrznej w oddziale B wykorzystamy klasę
192.168.30.0/24
.
- Instalujmy program OpenVPN na obu routerach opisany w początkowych sekcjach tego artykułu.
- Generujemy współdzielony klucz na serwerze. W tym celu wpisujemy
polecenie:
openvpn --genkey --secret secret.key
W omawianym przypadku jako metodę uwierzytelnienia zastosujemy współdzielony klucz (ang. pre-shared key - PSK) - ponieważ jest tylko jeden klient, nie ma potrzeby generowania certyfikatów. - Przegrywamy plik secret.key na drugi router, używając
bezpiecznej transmisji danych - najlepiej połączenia SCP lub SFTP:
scp secret.key root@router.siedzibab.pl:/etc/openvpn
- Przygotowujemy plik konfiguracyjny dla serwera (brama w siedzibie A)
dev tun ; rodzaj interfejsu — dla routera zawsze TUN local 85.98.29.251 ; adres routera, na którym „słucha” OpenVPN proto udp ; tunel będzie działał na porcie UDP port 17003 ; używany port ifconfig 10.3.0.1 10.3.0.2 ; adres serwera, adres klienta secret /etc/openvpn/secret.key ; ścieżka do współdzielonego klucza (PSK) user openvpn ; zrzuć uprawnienia na wskazanego użytkownika group openvpn ; jw. dla grupy keepalive 10 120 comp-lzo ; algorytm kompresji verb 3 ; poziom szczegółowości logowania
- Przygotowujemy plik konfiguracyjny dla klienta (brama w siedzibie B)
dev tun ; rodzaj interfejsu — dla routera zawsze TUN remote 85.98.29.251 ; adres drugiej strony — routera w siedzibie A proto udp ; tunel będzie działał na porcie UDP port 17003 ; używany port ifconfig 10.3.0.2 10.3.0.1 ; adres klienta, adres serwera secret /etc/openvpn/secret.key ; ścieżka do współdzielonego klucza (PSK) user openvpn ; zrzuć uprawnienia na wskazanego użytkownika group openvpn ; jw. dla grupy keepalive 10 120 comp-lzo ; algorytm kompresji verb 3 ; poziom szczegółowości logowania
Zauważ brak słowa kluczowegoclient
w pliku konfiguracyjnym klienta. Nie jest to błąd. Opcjaclient
jest synonimem opcjitls-client
, a w tym przypadku nie używamy uwierzytelnienia TLS. - Upewniamy się, czy na obu routerach załączone jest przekazywania
pakietów.
cat /proc/sys/net/ipv4/ip_forward
Polecenie powinno na obu routerach zwrócić 1, jeśli zwraca 0. To należy wykonać polecenie:echo 1 > /proc/sys/net/ipv4/ip_forward
oraz dopisać do linijkę skryptów startowych systemu (sysctl.conf) - Jeżeli domyślną polityką bezpieczeństwa na serwerze (bramie w
siedzibie A) jest blokuj, to musimy otworzyć port 17003. W
tym celu wpisujemy polecenie:
iptables -I INPUT -i ethX -p udp -d IP_routera --dport 17003 -j ACCEPT
GdzieethX
jest nazwą interfejsu łączącego router z Internetem,IP_routera
adres IP, pod którym router jest dostępny w Internecie. Pamiętajmy aby zapisać nasze reguły firewalla. - Jeżeli komputery oddziale B mają mieć dostęp do Internetu przez tunel
VPN, to na routerze w siedzibie B musimy zmienić domyślną bramę.
Powinna wskazywać adres IP tunelu VPN routera w siedzibie A. Obecnej
bramy (przydzielonej przez ISP dla siedziby B użyjemy tylko do
komunikacji z routerem w siedzibie A. Na routerze w siedzibie B
wpisujemy polecenie:
Uwaga!Jeśli pracujemy zdalnie na routerze
ważna jest tutaj kolejność działania. Gdybyśmy zaczęli od usunięcia
domyślnej bramy na routerze w oddziale, skutkowało by to utratą
komunikacji z nim!
rtr-officeB:~# ip route add <IP_rtr_w_office_A>/32 via <Brama_ISP_w_office_B>
Jeśli w naszym systemie brakuje poleceniaip
, to należy użyć starszego polecenia:rtr-officeB:~# route add -host <IP_rtr_w_office_A> gw <Brama_ISP_w_office_B>
Następnie usuwamy istniejącą domyślną trasę:rtr-officeB:~# ip route delete default lub rtr-officeB:~# route delete default
- Pora na zestawienie tunelu i sprawdzenie czy strony widzą się na
wzajem po adresach ustawionych w plikach konfiguracyjnych w
dyrektywie
ifconfig
:# openvpn --config <ścieżka do pliku konfiguracyjny>
- Jeśli mamy wzajemną widoczność, musimy ustawić bramę domyślną na
routerze w biurze B:
rtr-officeB:~# ip route add default via <ip_tun_w_office_A> lub rtr-officeB:~# route add default gw <ip_tun_w_office_A>
Od tej chwili cały ruch z oddziału B będzie przechodził przez łącze VPN. - Pozostało jeszcze skonfigurować reguły firewalla na routerze w
siedzibie A. Musimy określić na co zezwalamy komputerom z sieci
"oddziałowej"
192.168.30.0/24
. Jako, że domyślną polityką może być blokuj, każdy dostep trzeba jawnie zadeklarować. Zgodnie z założeniami komputery z siedziby B powinny mieć dostęp do odpowiednich serwerów. Na routerze w siedzibie A wpisujemy poniższe polecenia:iptables -I FORWARD -i tun0 -p ip -s 192.168.30.0/24 -d 192.168.20.3 -j ACCEPT iptables -I FORWARD -i tun0 -p ip -s 192.168.30.0/24 -d 192.168.20.4 -j ACCEPT iptables -I FORWARD -i tun0 -p ip -s 192.168.30.0/24 -d 192.168.20.5 -j ACCEPT
Aby zapewnić komputerom z oddziału B połączenie z Internetem, musimy jeszcze stworzyć jakąś regułę NAT. Przykładowa może wyglądać następująco:iptables -t nat -A POSTROUTING -o ethX -s 192.168.30.0/24 -j SNAT --to <ADRES NAT>
ethX
oznacza interfejs, przez których łączymy się z Internetem.ADRES NAT
jest to adres na jaki zachodzić ma translacja adresów, przeważnie adres interfejsu, przez który łączymy się z Internetem.
Tunel VPN z mostkowaniem
W niniejszym przykładzie rozważymy przypadek połączenia oddziału firmy z
centralą "przezroczystym" tunelem VPN. Założenie jest takie aby przez
tunel przekazywane były pakiety rozgłoszeniowe. Klasa adresowa używana w
obu podsieciach to 192.168.20.0/24
. Most zbudujemy z dwóch
interfejsów: karty sieciowej eth1 łączącej router z siecią LAN oraz
wirtualnego interfejsu TAP. Oprócz programu OpenVPN będziemy
potrzebowali wkompilowanego w jądro systemu (bądź w postaci modułu)
sterownika mostów sieciowych oraz programu do administracji mostem.
Do zarządzania mostem służy pakiet bridge-utils, który na ogół
nie wchodzi w skład popularnych dystrybucji i będzie trzeba go
doinstalować. W przypadku dystrybucji opartych o GNU/Linux Debian:
# apt-get install bridge-utils
- Przygotowanie środowiska
- Instalujemy program OpenVPN na obu routerach opisany na początku sekcji sposób,
- Generujemy współdzielony klucz na serwerze. W tym celu
wpisujemy polecenie:
# openvpn --genkey --secret secret.key
W omawianym przypadku jako metodę uwierzytelnienia zastosujemy współdzielony klucz (ang. pre-shared key - PSK) - ponieważ jest tylko jeden klient, nie ma potrzeby generowania certyfikatów, - Przegrywamy plik secret.key na drugi router, używając
bezpiecznej transmisji danych - najlepiej połączeniem SCP/SFTP:
# scp secret.key root@router.siedzibab.pl:/etc/openvpn
- Przygotowujemy plik konfiguracyjny dla serwera (brama w
siedzibie A)
dev tap ; rodzaj interfejsu — dla bridge zawsze TAP local 85.98.29.251 ; adres routera, na którym „słucha” OpenVPN proto udp ; tunel będzie działał na porcie UDP port 17003 ; używany port ifconfig 192,168.20.0 255.255.255.0 ; adres serwera, adres klienta secret /etc/openvpn/secret.key ; ścieżka do współdzielonego klucza (PSK) user openvpn ; zrzuć uprawnienia na wskazanego użytkownika group openvpn ; jw. dla grupy keepalive 10 120 comp-lzo ; algorytm kompresji verb 3 ; poziom szczegółowości logowania
- Przygotowujemy plik konfiguracyjny dla klienta (brama w
siedzibie B)
dev tap ; rodzaj interfejsu — dla bridge zawsze TAP remote 85.98.29.251 ; adres drugiej strony — routera w siedzibie A proto udp ; tunel będzie działał na porcie UDP port 17003 ; używany port ifconfig 192,168.20.0 255.255.255.0 ; adres klienta, adres serwera secret /etc/openvpn/secret.key ; ścieżka do współdzielonego klucza (PSK) user openvpn ; zrzuć uprawnienia na wskazanego użytkownika group openvpn ; jw. dla grupy keepalive 10 120 comp-lzo ; algorytm kompresji verb 3 ; poziom szczegółowości logowania
Zwróćmy uwagę na brak słowa kluczowegoclient
w pliku konfiguracyjnym klienta. Nie jest to błąd. Opcjaclient
jest synonimem opcjitls-client
, a w tym przypadku nie używamy uwierzytelnienia TLS. - Jeżeli domyślną polityką bezpieczeństwa na serwerze (bramie w
siedzibie A) jest blokuj, to musimy otworzyć port
UDP/17003. W tym celu wpisujemy polecenie:
# iptables -I INPUT -i ethX -p udp -d IP_routera --dport 17003 -j ACCEPT
GdzieethX
jest nazwą interfejsu łączącego router z Internetem,IP_routera
adres IP, pod którym router jest dostępny w Internecie. Pamiętajmy aby zapisać nasze reguły firewala. - Uruchamiamy program OpenVPN i sprawdzamy czy istnieje
on liście procesów (w obu sidzibach).
# openvpn --config <plik konfiguracyjny>
- Tworzymy na obu routerach most używając programu
brctl
. W tym celu wpisujemy podane poniżej polecenia zachowując kolejność na obu komputerach.# brctl addbr br0 # tworzy interfejs dla bridge'a # brctl addif br0 eth1 # dodaje do bridge'a interfejs eth1 # brctl addif br0 tap0 # dodaje do bridge'a interfejs tap0 # ifconfig eth1 0.0.0.0 promisc up # przestawia karty eth1 i tap0 # ifconfig tap0 0.0.0.0 promisc up # w tryb nasłuchiwania (promiscuous mode)
Szczególną uwagę warto zwrócić na komendębrcrl addif br0 eth1
, a konkretnie na interfejs eth1 podany jako parametr. Powinien to być interfejs łączący router z siecią lokalną, a nie Internetem. Pomyłka w tym miejscu będzie skutkować utratą komunikacji z serwerem (jeśli pracujemy zdalnie). Następną rzeczą, na którą warto zwrócić uwagę jest to, że na interfejsieeth1
nie przydzielamy adresu IP! Interfejsy mostu są przezroczyste dla warstwy sieciowej i nie posiadają adresów IP. Aby nasz router miał przydzielony adres z klasy lokalnej, musimy skonfigurować go na interfejsiebr0
. Nadajmy więc routerom adresy z puli lokalnej. Przypisujemy IP192.168.20.1
routerowi po stronie siedziby A.# ifconfig br0 192.168.20.1 up
Routerowi w oddziale B przypiszemy adres IP 192.168.20.200.# ifconfig br0 192.168.20.200 up
Jeśli wszystko poszło pomyślnie to strony powinny się "pingować".
192.168.20.1
przydzielony na interfejsiebr0
routera w siedzibie A pełni też funkcje bramy domyślnej dla komputerów w swoim LAN-ie (komputerów w siedzibie A)! W związku z powyższym wszystkie reguły firewalla, które dotyczyłyby interfejsueth1
, teraz dotyczą interfejsubr0
. Most nie potrzebuje załączonego przekazywania pakietów, natomiast w związku z faktem że serwer w siedzibie A, pełni funkcje mostu i routera, przekazywanie musi być załączone. Upewnijmy się, czy plik /proc/sys/net/ipv4/ip_forward ma zawartość 1.# cat /proc/sys/net/ipv4/ip_forward
Jeśli nie to mu ją wpisujemy:# echo 1 > /proc/sys/net/ipv4/ip_forward
- Debugowanie
Nie wykluczone, że za pierwszym razem wszystko nie zadziała od razu. Zostanie tutaj przedstawione kilka kroków, które przydają się podczas debugowania.
- Sprawdzamy czy tunel w ogóle się zestawił - przeglądamy logi
programu OpenVPN. Sprawdzamy, czy program widnieje na
liście procesów - za pomocą polecenia
# ps aux | grep vpn
- Sprawdzamy, czy interfejs br0 powstał po obu stronach tunelu.
Wpisujemy polecenie:
# ifconfig | grep br0
- Używając polecenia
brctl show br0
, sprawdzamy, czy oba interfejsy (tap0
ieth1
) widnieją na liście interfejsów członkowskich na moście br0. Jeśli któregoś z nich brakuje - dodajemy go, za pomocą polecenia:# brctl addif <interfejs>
- Upewniamy się czy wszystkie interfejsy tworzące most działają w
trybie promiscuos (nasłuchiwania). Wpisujemy polecenia:
# ifconfig eth1 promisc # ifconfig tap0 promisc
- Możemy użyć programu tcpdump, do przeglądania pakietów pojawiających się na obu stronach mostu.
- Możemy podglądać na bierząco jak most uczy się adresów MAC.
Listę adresów sprawdzamy poleceniem:
brctl showmacs br0
- Jeśli w dalszym ciągu nic nie działa, czasem dobrym rozwiązaniem jest zresetowanie komputerów i rozpoczęcie wszystkiego od nowa
- Jeśli pracujemy zdalnie na odległym serwerze, dobrym rozwiązaniem będzie napisanie skryptu, który będzie pingował wybrany serwer co 20 min. W przypadku braku odpowiedzi, skrypt powinien zresetować serwer.
- Sprawdzamy czy tunel w ogóle się zestawił - przeglądamy logi
programu OpenVPN. Sprawdzamy, czy program widnieje na
liście procesów - za pomocą polecenia
IPSec
IPSec (ang. IP Security - bezpieczeństwo w IP) - to zestaw protokołów kryptograficznych opracowanych przez grupę IETF w odpowiedzi na zapotrzebowanie rynku IT na bezpieczną komunikację sieciową przez Internet.
Podstawowym założeniem przy projektowaniu IPSec było zapewnienie integralności i poufności przesyłanych danych niezależnie od używanych protokołów warstw wyższy modelu OSI (TCP/UDP itd.). Zapewnienie integralności przesyłanych danych, czyli możliwości wykrycia tego, czy pakiet nie został zmodyfikowany, osiągnięto poprzez stosowanie skrótów kryptograficznych zamiast zwykłych sum kontrolnych w protokole IP, (które można przeliczyć po modyfikacji pakietu). Poufność z kolei, zapewnia szyfrowanie danych kluczem symetrycznym (np. DES, 3DES, AES). Przy czym IPSec nie narzuca wyboru algorytmu szyfrowania, dzięki czemu protokół jest bardzo uniwersalny. W razie złamania w przyszłości, któregoś z obecnie używanych algorytmów wystarczy jego zamiana bez potrzeby przebudowy całego protokołu.
IPSec może być wykorzystywany w jednym z dwóch trybów. Pierwszy to tryb transportowy, w którym nagłówek IPSec wstawiany jest pomiędzy oryginalny nagłówek IP a nagłówek warstwy transportowej. Tryb transportowy używany jest pomiędzy dwoma hostami komunikującymi się przez IPSec. Drugim rodzajem połączeń IPSec jest tryb tunelowy, w którym cały pierwotny pakiet IP enkapsulowany jest wewnątrz nagłówka IPSec. Tryb tunelowy na ogół wykorzystywany jest do łączenia całych sieci korporacyjnych z wykorzystaniem bram VPN. W tym przypadku komputery w sieciach wewnętrznych "nie wiedzą" w ogóle o fakcie, że pakiety po opuszczeniu routera opakowane są w nagłówki IPSec i w zaszyfrowanej formie wędrują przez Internet. Brama VPN po drugiej stronie wyodrębnia pierwotne pakiety IP i przesyła do właściwego hosta wewnątrz sieci lokalnej. Warto zauważyć, że w trybie tunelowania w razie ewentualnego podsłuchu transmisji osoba podsłuchująca nie jest wstanie dowiedzieć się nawet, pomiędzy jakimi hostami wymieniane są dane. Adresy źródłowy i docelowy nagłówka IPSec zawierają adresy bram VPN, a nie rzeczywistych hostów.
Dwa podstawowe protokoły wchodzące w skład IPSec to AH i ESP. Protokół AH (ang. Authentication Header) zapewnia integralność danych, ale nie zapewnia poufności. Nie jest możliwy spoofing czy inna modyfikacja pakietu ponieważ suma kontrolna została zabezpieczona kryptograficznie (funkcją skrótu - metoda HMAC) przy użyciu tajnego klucza znanego tylko nadawcy i odbiorcy.
Przed właściwą komunikacją zabezpieczoną protokołem AH (lub ESP) strony nawiązują logiczne połączenie w warstwie sieci, tworząc tzw. skojarzenie bezpieczeństwa SA (ang. Security Association). SA charakteryzują następujące elementy:
- idetyfikator używanego protokołu bezpieczeństwa (AH lub ESP),
- źródłowy i docelowy adres IP połączenia,
- 32-bitowa liczba będąca identyfikacją połączenia, określana mianem SPI (ang. Security Parameter Index).
Skojarzenie bezpieczeństwa SA jest jednokierunkowe, dlatego do bezpiecznej komunikacji dwustronnej potrzebne są dwa niezależne kanały SA, po jednym w każdnym kierunku. Zauważmy jednak, że w pewnych okolicznościach wystarczy zabezpieczenie tylko jednej strony (np. odpowiedzi serwera DNS), stąd koncepcja "jednokierunkowości" połączeń jest uzasadniona.
Z protokołem AH związane jest także pojęcie SN - serial number, którego celem jest zabezpieczenie transmisji przez atakiem polegającym na wielokrotnym przesyłaniu tego samego pakietu do odbiorcy przez hosta, który podsłuchał pakiet (ang. reply attack). Na początku komunikacji strony ustawiają wartość SN na 0, a następnie inkrementują ją wraz z każdym wysłanym pakietem. Dzięki temu odbiorca może wykryć, że odebrany właśnie pakiet to kopia już wcześniej otrzymanego.
Protokół ESP (ang. Encapsulated Security Payload) pierwotnie zapewniał wyłącznie szyfrowanie transmisji przy użyciu któregoś z szyfrów blokowych (DES, 3DES, AES). Dlatego dla zapewnienia integralności i poufności danych wykorzystywano oba protokoły - AH i ESP - jednocześnie.
Obecnie jednak ESP zapewnia także sprawdzenia integralności danych (zasada działania bardzo podobna do AH - suma kontrolna zabezpieczona kryptograficznie), dlatego protokół AH wychodzi z użycia. W przypadku gdy szyfrowanie transmisji nie jest konieczne, w ESP istnieje możliwość zastosowania algorytmu NULL zamiast któregoś z algorytmów kryptograficznych. Istotną różnicą między protokołami ESP i AH jest fakt, że w przypadku ESP ochrona integralności nie obejmuje nagłówka IP (tego widzianego przez pośredniczące routery), dzięki czemu protokół IPSec/ESP może przechodzić przez połączenia za NAT-em.
Za automatyczną negocjację parametrów połączenia tj. uwierzytelnianie, ustalenie relacji SA oraz późniejsze uzgadniania kluczy kryptograficznych odpowiada osobny protokół wymiany kluczy - IKE (ang. Internet Key Exchange), także wchodzący w skład IPSec . Przy czym samo uwierzytelnienie może być przeprowadzone różnymi metodami - współdzielony klucz, podpisy RSA, certyfikaty X.509 lub Kerberos.
Protokół IKE działa w dwóch fazach. Pierwsza faza - ISAKMP (ang. Internet Security Association and Key Management Protocol), odpowiada za przeprowadzenie uwierzytelnienia, utworzenie kanału ISAKMP SA i zarządzanie nim. Druga faza - Oakley, odpowiada za uzgadnianie klucz (wg. algorytmu DH) i związków SA w trakcie połączenia.
ISAKMP może zostać przeprowadzona w trybie głównym (ang. main mode) lub w tzw. trybie agresywnym (ang. aggresive mode). W trybie głównym wymieniane są 3 dwukierunkowe komunikaty (komunikat-odpowiedź - razem 6). W trybie agresywnym natomiast przesyłane są jedynie 3 komunikaty. Tryb agresywny jest szybszy, natomiast ma pewną słabość, którą w pewnych okolicznościach można wykorzystać do odgadnięcia klucz PSK. Otóż w trybie agresywnym cześć informacji przesyłana jest przez ustanowieniem bezpiecznego kanału. W przypadku uwierzytelnienia przez PSK i użycia trybu agresywnego osoba podsłuchująca transmisję jest w stanie podejrzeć hash współdzielonego klucza, a następnie próbować odnaleźć klucz metodą słownikową/siłową. Znając PSK, atakujący może zestawić tunel VPN, podszywając się pod pracownika firmy, którego połączenie wcześniej podsłuchał. Oprócz rozkodowania PSK możliwy jest w tym przypadku atak typu man-in-the-middle.
Z powyższego wynika, że powinniśmy unikać trybu agresywnego w połączeniu z uwierzytelnianiem PSK. Ogólnie nie powinniśmy używać uwierzytelnienia przez PSK dla tuneli zdalnych pracowników, gdzie IP drugiej strony tunelu nie jest znane (możliwość siłowego odgadnięcia hasła).
Faza druga (Oakley) przebiega zawsze w trybie quick mode. Jako że jest to faza druga, nie przeprowadza ona własnych metod uwierzytelnienia i umożliwia szybkie (stąd nazwa) zestawienie relacji IPSec SA.
Z drugą fazą związane jest także opcjonalne pojęcie PFS (ang. Perfect Forward Secrecy) - poufność doskonała. Przez pojęcie to rozumie się sposób wymiany kluczy sesyjnych w trakcie połączenia IPSec. Załączenie PFS, zapewnia że materiał klucza głównego może być używany do wygenerowania tylko jednego klucza sesji. Przed utworzeniem nowego klucza sesji jest przeprowadzana wymiana kluczy (algorytm Diffiego-Hellmana) w celu wygenerowania nowego materiału klucza głównego. Dzięki zastosowaniu PFS uzyskanie przez atakującego pojedynczego klucza pozwala mu na odczytanie tylko wiadomości zaszyfrowanych tym kluczem. Niestety, załączenie PFS wiąże się ze spadkiem wydajności (i wzrostem obciążenia procesora). Dodatkowo nie wszystkie implementacje obsługują tę właściwość.
Każda ze stron przechowuje informacje o nawiązanych skojarzeniach SA w tzw. bazie SAD (ang. Security Association Database).
Do terminologi związanej z IPSec musimy jeszcze dołożyć pojęcia SPD - Security Policy Database. SPD to baza odpowiadająca przyjętej polityce bezpieczeństwa. Baza SPD jest używana dla pakietów wychodzących. System sprawdza przed wysłaniem, czy dla określonego hosta docelowego (sieci docelowej) istnieje jakiś wpis określający, czy protokół IPSec ma zostać użyty. Jeżeli tak, przeglądana jest baza SAD w poszukiwaniu skojarzenia SA odpowiedzialnego za komunikacje w określonym hostem docelowym.
IPSec a translacja adresów (maskarada)
NAT (ang. Network Address Transtalation) to translacja adresów popularnie zwana maskaradą. Najkrócej mówiąc polega ona ukrywaniu hosta wewnętrznego poprzez zamianę adresu źródłowego w nagłówku pakietu IP - na adres routera. W tym przypadku NAT (a w zasadzie PAT - Port Address Translation) stara się zachować port źródłowy, który został wybrany przez hosta źródłowego; dopiero gdy ten port jest zajęty przez inne połączenie NAT, zostanie zamieniony na inny. Router pełniący rolę NAT-u przechowuje wszystkie bieżące połączenia w specjalnej tabeli NAT, dzięki czemu wie, do którego hosta przekierować ma odpowiedzi przychodzące na dany port. Mechanizm ten doskonale sprawdza się w przypadku połączeń TCP/UDP, gdzie bezproblemowo możemy przekierować połączenie przychodzące na port 1234 do portu 5673 komputera wewnątrz sieci (za maskaradą).
W przypadku połączeń IPSec sprawa nie wygląda tak prosto z dwóch powodów. Po pierwsze w przypadku protokołu AH nie jest możliwa zmiana adresu źródłowego w nagłówku pakietu IP, gdyż cały nagłówek zabezpieczony jest przed zmianą - do nagłówka dodawany jest skrót kryptograficzny utworzony z sumy kontrolnej pakietu oraz tajnego hasła. Jakakolwiek modyfikacja nagłówka pakietu uznana będzie za naruszenie integralności danych (router, nie znając hasła nie będzie w stanie wygenerować odpowiedniego skrótu). Na to nic nie poradzimy. Dla protokołu AH nie jest możliwa translacja adresów.
W przypadku protokołu ESP sprawa wygląda lepiej, gdyż, ochronie integralności nie podlega "zewnętrzny" nagłówek IP, tak więc możliwa jest zamiana źródłowego adresu IP. Pojawia się jednak niestety problem z wieloma klientami znajdującymi się za tym samym routerem (maskaradą). Protokół ESP nie wykorzystuje portów, jak ma to miejsce w protokołach TCP i UDP, dlatego nie można w prosty sposób odróżnić połączeń IPSec inicjowanych z różnych hostów wewnątrz sieci.
Rozwiązanie powyższego problemu jest tzw. NAT-Traversal. Mechanizm ten polega na enkapsulacji protokołu ESP wewnątrz połączenia UDP (najczęściej port 4500)
Jak widać działanie protokołu IPSec (zespołu protokołów) jest dość złożone. Przedstawiono tutaj najistotniejsze elementy, tak aby poza posiadaniem wiedzy praktycznej, warto posiadać wiedzę teoretyczną, która to pomoże zrozumieć nam gdzie zrobiliśmy błąd, jeśli coś nie zadziała lub nagle przestanie. Na szczęście konfiguracja połączenia IPSec z automatyczną wymianą kluczy (IKE) nie jest wcale taka trudna, co zostanie zobrazowane.
Najważniejsze pojęcia związane z IPSec
- Protokół ESP (ang. Encapsulated Security Payload) - podstawowy składnik IPSec. Pierwotnie zapewniał wyłączenie poufność, tj. szyfrowanie transmisji przy użyciu któregoś z szyfrów blokowych (DES, 3DES, AES). Obecnie jednak ESP zapewnia także sprawdzenie integralności danych. ESP w przeciwieństwie do AH nie zabezpiecza nagłówka IP pierwotnego pakietu,
- Protokół AH (ang. Authentication Header) - jeden z protokołów wchodzących w skład IPSec. Jego zadaniem jest zapewnienie integralności przesyłanych danych (funkcja skrótu HMAC). Protokół AH nie zapewnia poufności. Wychodzi on obecnie z użycia, ponieważ ESP zapewnia tę samą funkcjonalność oraz szyfrowanie,
- Protokół ISAKMP (ang. Internet Security Association and Key Management Protocol) - odpowiada za negocjacje parametrów IPSec, przeprowadzenie uwierzytelnienia, tworzenia kanału SA i zarządzanie nim. Do działania wykorzystuje port 500 UDP,
- Związek SA (ang. Security Association) - inaczej relacja SA, jednokierunkowy, logiczny kanał komunikacyjny zestawiany w komunikacji IPSec. Do dwustronnej komunikacji IPSec potrzebne są dwa kanały SA. Skojarzenie SA identyfikowane jest przez 32-bitową liczbę zwaną SPI (ang. Security Parametr Index),
- SPI (ang. Security Parametr Index) - 32-bitowa liczba, będąca identyfikatorem skojarzenia SA w komunikacji IPSec,
- Baza SAD - każda ze stron tunelu IPSec przechowuje informacje o nawiązanych relacjach SA w tzw. bazie SAD,
- DH (Diffie-Hellman) - algorytm uzgadniania klucza, w którym dwie strony na podstawie wymienionych liczb uzgadniają liczbę wynikową - klucz. Osoba podsłuchująca transmisje nie jest w stanie na podstawie tego co usłyszała, wyliczyć klucza,
- Grupa DH - informacja mówiąca o wielkości liczb używanych w obliczeniach w algorytmie Diffiego-Hellmana. DH1:768bitów, DH2:1024bity, DH5:1536 bitów. Grupa pierwsza obecnie uważna jest za słabą,
- Hash - inaczej funkcja skrótu. Dla dowolnie długiego ciągu wejściowego wyliczany jest skrót o stałej długości. Do najczęściej używanych funkcji należą MD5 i SHA-1, SHA-2. Funkcje skrótu wykorzystywane są do tworzenia sygnatur (np. cyfrowe zabezpieczenie sumy kontrolnej pakietu lub pliku),
- HMAC (ang. keyed-Hash Message Authentication Code) - zabezpieczona hasłem funkcja skrótu. Dzięki temu oprócz ochrony integralności zapewniona jest też autentyczność pochodzenia. Osoba zabezpieczająca dokument podaje hasło i na podstawie hasła oraz dokumentu tworzony jest skrót. Osoba sprawdzająca znając hasło, jest w stanie potwierdzić autentyczność,
- SHA (SHA-1, SHA-2) - funkcje skrótu służące to tworzenia sygnatur,
- MD5 - funkcja skrótu, w wyniku której powstaje 128-bitowy hash,
- DES (ang. Data Encryption Standard) - algorytm szyfrowania symetrycznego. Ze względu na słabość klucza - 56 bitów - obecnie wyszedł z użycia. Jego następcy to 3DES oraz AES,
- AES (ang. Adavanced Encryption Standard) - silny szyfr blokowy, możliwe długości klucza to 128, 192, 256 bitów. Powstał w wyniku konkursu na następcę DES. Obecnie często wykorzystywany w kryptografii. m.in w IPSec,
- RSA - jeden z algorytmów kryptografii asymetrycznej, stosowany m.in. w podpisach cyfrowych,
- Transform-set - w terminologii Cisco zbiór parametrów związanych z połączeniem IPSec. Do parametrów metrów tych należą m.in.: rozdzaj protokołu IPSec (ESP, AH) używany protokół szyfrowania (3DES, AES), używana funkcja skrótu (SHA, MD5) itp,
- Crypto-map - w terminologii Cisco to ustawienie, które wiąże niejako wszystkie parametry tunelu w całość. Zawiera nazwę transform-seta (parametry IPSec), adres IP zdalnego routera oraz numer listy dostępu, kontrolującej jaki ruch zostanie przesłany tunelem VPN.
W niniejszym artykule zostanie omówione przygotowanie systemu do działania z protokołem IPSec.
IPSec - przygotowanie środowiska w systemie Linux
Z punktu wiedzenia systemu operacyjnego połączenia IPSec można podzielić na dwie części:
- Część odpowiedzialną za zarządzanie pakietami (protokół AH/ESP) - tj. enkapsulację pakietów IP w pakiety IPSec, zabezpieczenie sum kontrolnych itd. Z racji tego, że operacje te muszą być wydajne, ich obsługą zajmują się moduły jądra systemu.
- Część odpowiedzialną za zestawienie połączenia i późniejszą wymianę kluczy (protokół IKE). Obsługę tych funkcji zajmuje się program (daemon) działający w warstwie użytkownika - w systemie Linux to demon Pluto (wchodzący w skład OpenSWAN).
Obecnie każde współczesne jądro Linuxa ma już wbudowane moduły dla protokołu IPSec. Nie potrzeby przeprowadzania żadnych modyfikacji.
Instalacja programu OpenSWAN
OpenSWAN to implementacja protokołu IPSec w systemie Linux rozwijana przez grupę developerów, którzy wcześniej pracowali nad projektem FreeSWAN. W trakcie prac doszło do konfliktu i część deweloperów rozpoczęła pracę nad OpenSWAN.
Jeżeli używana przez nas dystrybucja wspiera automatyczną instalację pakietów, możesz zainstalować program OpenSWAN z gotowych paczek. W przypadku Debian możesz zastosować pakiet używając programu apt.
Opcjonalnym składnikiem, który należałoby zainstalować jest serwer L2TP - najlepiej xl2tpd. Dlaczego opcjonalnym? Gdyż nie wszystkie rozwiązania IPSec używają tunelowania L2TP. Niemniej implementacja IPSec firmy Microsoft wbudowana w każdy z systemów Windows wymaga do działania właśnie protokołu L2TP. Jeśli zamierzamy łączyć z bramą VPN, używając wbudowanych w Windows mechanizmów IPSec, musimy zainstalować demon L2TP.
Protokół L2TP umożliwia przesłanie ramek połączenia PPP przez przez protokół IP (Internet), które to połączenie normalnie realizowane jest tylko w bezpośrednim połączeniu punkt-punkt (modemy, linie szeregowe itd.). Samo połączenie PPP operuje w warstwie drugiej modelu OSI i służy do enkapsulacji protokołów warstwy wyższej (IP, IPX itd.), zapewniając jednocześnie uwierzytelnienie oraz kompresję. Połączenie protokołu L2TP z PPP umożliwia tunelowanie protokołu IP w ramach innego połączenia IP, dlatego często wykorzystywane jest w sieciach VPN. Wykorzystanie protokołu PPP daje także dodatkowe możliwości, jak np. przydzielanie adresów IP tunelowi, przekazywanie parametrów sieciowych, takich jak DNS, WINS itp.
Naturalnie aby tunelowanie połączenia PPP przez protokół L2TP mogło działać, potrzebny jest także demon PPP. Jako że nie jest już instalowany domyślnie w popularnych dystrybucjach możemy go zainstalować z repozytorium dystrybucji, dla Debiana możemy skorzystać z polecenia apt
Praktyczny przykład - brama IPSec/VPN dla użytkowników mobilnych
W tej sekcji stworzymy bramę VPN dla użytkowników mobilnych łączących się zdalnie z siedzibą firmy. Użytkownicy używają na laptopach systemu Microsoft Windows i wbudowanego weń "klienta" IPSec. Analogicznie jak dla przykładu z bramą OpenVPN, użytkownicy powinni mieć dostęp do kilku serwerów w sieci LAN. Adresy IP użytkowników mobilnych nie są znane i mogą oni się łączyć z różnych miejsc, także zza maskarady (połączenia GPRS, hotspot itd.). Po stronie bramy VPN wykorzystamy system Linux oraz oprogramowanie OpenSWAN.
Konfiguracja bramy IPSec (Linux)
Konfigurację zaczniemy od przygotowania demona L2TP. Tworzymy plik
konfiguracyjny /etc/l2tp/l2tpd.conf
. Zawartość pliku
l2tpd.conf powinna wyglądać następująco:
[global] listen-addr = 85.98.29.251 ;adres internetowy bramy port = 1701 ;port — zostawiamy domyślny [lns default] ip range = 192.168.10.198-192.168.10.250 ;pula IP dla klientów local ip = 85.98.29.251 ;IP lokalny połączenia PPP require chap = yes ;wymagamy uwierzytelniania CHAP ;refuse pap = yes require authentication = yes name = ipsec ppp debug = yes pppoptfile = /etc/ppp/options.l2tpd ;pozostały length bit = yes
Zwrócić należy uwagę na wymóg uwierzytelniania dotyczy tutaj połączenia PPP a nie L2TP. Demon L2TP nie możliwości przeprowadzenia swojego uwierzytelniania, ale nie jest to w tym przypadku potrzebne.
Teraz tworzymy plik z opcjami programu pppd - /etc/ppp/options.l2tpd. Przykładową konfigurację przedstawiono poniżej.
ipcp-accept-local ; pppd zaakceptuje lokalny adres połączenia ipcp-accept-remote ; jw. dla adresu drugiej strony require-mschap-v2 ; wymagamy uwierzytelniania MSCHAP wersji drugiej auth proxyarp idle 1800 mtu 500 mru 500 # eof
Następnie konfigurujemy plik z danymi uwierzytelniającymi dla PPP - /etc/ppp/chap-secrets
# Secrets for authentication using CHAP # client server secret IP addresses user * "test"
gdzie user
to nazwa użytkownika a
"test"
- hasło.
W sytuacji gdyby PPP było jedynym uwierzytelnieniem, moglibyśmy wpisać do pliku chap-secrets wszystkich użytkowników. Nie ma to jednak sensu, gdyż podstawowym uwierzytelnieniem będą certyfikaty X.509. Niemniej konfiguracje PPP można wykorzystać do przypisywania stałych adresów IP dla poszczególnych klientów, np.:
jacek * "test12" 192.168.10.220 michal * "test13" 192.168.10.221
Ostatni element przygotowania bramy IPSec to właściwa konfiguracja programu OpenSWAN, która sprowadza się w najprostszym przypadku do edycji dwóch plików - ipsec.conf oraz ipsec.secrets. Poniżej został przedstawiony plik ipsec.conf W tym przypadku metodą uwierzytelnienia jest klucz współdzielony a klientami mogą być użytkownicy Windowsa znajdujący się za NAT-em.
version 2.0 config setup interfaces=%defaultroute plutodebug=none forwardcontrol=yes nat_traversal=yes virtual_private=%v4:10.0.0.0/8,%v4:172.16.0.0/12,%v4:192.168.0.0/16,%v4:!192.168.10.0/24 conn roadwarrior-l2tp leftprotoport=17/1701 rightprotoport=17/1701 also=roadwarrior conn roadwarrior auth=esp authby=secret compress=yes keyexchange=ike keyingtries=3 pfs=no rekey=yes left=%defaultroute right=%any rightsubnet=vhost:%no,%priv auto=add #Disable Opportunistic Encryption include /etc/ipsec.d/examples/no_oe.conf
Twórcy programu OpenSWAN przyjęli konwencję, aby stron połączenia nie nazywać w klasyczny sposób: "serwer" i "klient" (lub też "źródło" i "cel"), tylko "strona lewa" (ang. left) i "strona prawa" (ang. right). Ma to swoje uzasadnieniem, ponieważ tak naprawdę i tak zestawiane są dwa nie zależne skojarzenia SA - dla każdego z kierunków transmisji. Poza tym nie zawsze jest jasne, która strona jest bardziej serwerem, a która bardziej klientem (przykład łączenia oddziałów firm). Przez "left" rozumie się lokalną konfigurację, a przez "right" odległą stronę. Zauważyć warto, że w przypadku połączenia typu użytkownik mobilny-brama IPSec, patrząc od strony bramy IPSec, strona "right" najczęściej nie jest znana (nie znamy adresu IP, z którego będzie łączyć się użytkownik). W przypadku łączenia dwóch bram IPSec (łączenie oddziałów firmy) strony "left" i "right" są na ogół ściśle określone. W anglojęzycznej terminologii pracowników mobilnych, który łączą się z rożnych miejsc kraju i świata, przyjęło nazwywać się roadwarrior.
Poniżej znajduje się analiza najważniejszych wpisów z pliku
konfiguracyjnego. Plik jest podzielony na kilka sekcji. Podstawowe opcje
- tzw. globalne - są zwarte w sekcji
config setup
.
version 2.0
- informuje program OpenSWAN, że składnia pliku będzie zgodna z OpenSWAN, a nie z przestarzałym FreeSWAN.interfaces=%defaultroute
- oznacza interfejs, na którym ma działać IPSec. Wartość domyślna to%defaultroute
, co oznacza, że zostanie użyty adres IP bramy domyślnej komputera. Na ogół%defaultroute
jest poprawną wartością.plutodebug=none
- definiuje poziom szczegółowości logów demona pluto. Inne możliwe wartości to: all, raw, krypt, parsing, emitting, control. Najbardziej optymalną jest opcja control, gdy logi nie będą nam już potrzebne, to przełączamy nanone
.forwardcontrol=yes|no
- sprawdza, czy załączone jest przekazywanie pakietów IP (ang. IP forwarding). Jeżeli nie, to je załącza. Po zakończeniu działania tunelu przywraca poprzednią wartość.nat_traversal=yes|no
- domyślnie:no
. Ważna opcja, jeżeli spodziewasz się połączeń zza NAT-a (maskarady). Złączenie jej sprawi, że OpenSWAN będzie oczekiwał także połączeń na porcie UDP 4500, po którym przenoszone są pakiety IPSec.virtual_private
- określa podsieci (z zakresu "prywatnych" klas IP), z których mogą łączyć się klienci. Na ogół podaje się tutaj wszystkie pule IP zdefiniowane do użytku prywatnego, z wyjątkiem puli używanej w sieci firmowej, do której użytkownicy chcą mieć dostęp przez VPN.
Sekcja conn roadwarrior-l2tp
-
odpowiedzialna za połączenia L2TP (port UDP/1701). Jest ona potrzebna,
jeśli oczekujemy połączeń od klientów wbudowanych w systemy Windows.
Ważne jest, aby sekcja L2TP umieszczona była w pliku przed właściwą
sekcją odpowiedzialną za połączenia klientów.
(conn roadwarrior
).
conn roadwarrior
- właściwa sekcja połączeń dla pracowników zdalnych.auth=esp
- określa protokół IPSec. Możliwe opcje to ah lubesp
. Zalecaną metodą jest ESP, ponieważ obsługuje uwierzytelnienie i szyfrowanie.authby=secret
- określa sposób uwierzytelnienia stron. Wartośćsecret
oznacza współdzielony klucz (PSK). W przypadku uwierzytelnienia z wykorzystaniem certyfikatów opcja powinna mieć wartość rsasigcompress=yes
- możliwa kompresja danych.keyexchange=ike
- wartośćike
oznacza, że do uzgodnienia kluczy zostanie użyty protokół IKE (Internet Key Exchange). Użycie IKE jest zalecane, także przez twórców OpenSWAN.keyingtries=3
- określa, ile prób negocjacji SA może nastąpić (maksymalnie).pfs=yes|no
- włącza (yes
) lub wyłącza (no
) PFS.rekey=yes
- określa, czy połączenie po wygaśnięciu powinno być renegocjowane. Możliwe wartości toyes
lub no. Domyślnieyes
.right=%any
- określa adres drugiej strony. Słowo kluczowe%any
oznacza, że adres IP nie jest znany (przypadek mobilnych pracowników).rightsubnet=vhost:%no,%priv
- opcjarightsubnet
określa podsieć drugiej strony. W przypadku połączeń typuroadwarriors
z możliwym NAT-em oraz "nie NAT-em" powinna mieć wartośćvhost:%no,%priv
Przez NAT oraz "nie NAT" należy rozumieć że użytkownicy mogą łączyć się zza NAT-u lub też mieć "zewnętrzny" adres IP i obie konfiguracje będą działać jednocześnie.auto=add
- opcja przyjmuje wartości: start, add, ignore(domyślna!) oraz manual. Znaczenie poszczególnych opcji jest następujące:- start - załaduj konfigurację i inicjuj połączenie z druga stroną. Wartość najczęściej używana w przypadku połączeń dwóch routerów lub jeśli strona jest klientem (ma inicjować połączenie z drugą stroną).
- add - załaduj konfiguracje i odpowiadaj na przychodzące połączenia (czekaj na połączenia od drugiej strony). Wartość używana dla konfiguracji typu roadwarriors - nie znamy ani czasu, ani adresu IP, z jakiego połączy się mobilny pracownik. Jedyne, co możemy zrobić odpowiedzieć na jego połączenia.
- ignore - ignoruje sekcję tego połączenia. Uwaga: jest to wartość domyślna, dlatego musisz przypisać jakąś wartość sekcjom, które mają działać.
- manual - opcja używana przy ręcznej konfiguracji wymiany kluczy (zamiast użycia IKE). Opcja niepolecana.
W ostatniej linijce pliku konfiguracyjnego widzimy dołączony plik:
#Disable Opportunistic Encryption include /etc/ipsec.d/examples/no_oe.conf
Dołączenie powyższego pliku wyłącza tzw. szyfrowanie oportunistyczne, które w tym przypadku nie jest potrzebne (strony uwierzytelniają się w inny sposób), a pozostawienie go załączonego skutkowałoby serią komunikatów w logach systemowych, mówiących o nie możliwości sprawdzenia informacji w DNS-ie. Idea szyfrowania oportunistycznego polega na możliwości uwierzytelnienia dowolnych hostów w internecie bez wcześniejszej wymiany tajnego klucza, (lub kluczy publicznych), Uwierzytelnienia hosta odbywa się tutaj na podstawie informacji pobranych z bezpiecznych serwerów DNS (ang. Secure DNS).
Ogólna uwaga odnośnie składni pliku ipsec.conf. Należy pamiętać aby pomiędzy sekcjami połączeń była jedna linijka przerwy. Nazwa sekcji nie powinna się zaczynać od spacji czy tabulacji. Opcje w ramach sekcji mogą zaczynać się od tabulacji.
Pozostał nam jeszcze do konfiguracji plik /etc/ipsec.secrets. W przypadku współdzielonego klucza oraz połączeń z nie znanych adresów IP składnia pliku jest następująca:
<adres_ip_odpowiednik_%defaultroute> %any: PSK "<klucz_współdzielony>"
Po zapisaniu pliku, należy zmienić uprawnienia, tak aby możliwość odczytu
pliku miał tylko użytkownik root (
chmod 600
).
Uruchomienie tunelu
Aby uruchomić tunel (proces nasłuchiwania), wpisujemy poniższe polecenie:
# ipsec setup start
Konfiguracja klienta Windows
W tej sekcji zajmiemy się konfiguracją połączenia IPSec w systemach Windows, tak aby ich użytkownicy mogli się połączyć z naszą bramą Linuksową. Metodą uwierzytelnienia będzie klucz współdzielony oraz dodatkowe uwierzytelnianie w połączeniu PPP (MS-CHAP v2). Do połączenia będziemy używać wbudowanego w Windows klienta IPSec. W nowszych systemach Windows konfiguracja sprowadza się dodania nowego połączenia przy użyciu kreatora. Aby dodać nowe połączenie, wykonujemy poniższe czynności:
- Wchodzimy do Panelu sterowania i wybieramy Połączenia sieciowe,
- Uruchom Kreatora nowego połączenia. Kreator zapyta o rodzaj połączenia - wybieramy opcje "Połącz z siecią w miejscu pracy". Następnie klikamy przycisk Dalej,
- W następnym kroku wybieramy opcje Połączenie wirtualnej sieci prywatnej, następnie klikamy przycisk Dalej,
- Wpisujemy nazwę połączenia np.
ipsec1
, - Podajemy adres IP lub nazwę DNS bramy VPN
- Kończymy pracę kreatora, klikając przycisk Zakończ. Przed uruchomieniem naszego połączenia trzeba zmodyfikować dwie opcje. Wchodzimy we właściwości nowego połączenia - klikamy prawym przyciskiem myszy ikonę nowego połączenia i wybieramy z menu opcje Właściwości. Postępujemy wg. poniższych punktów,
- Przechodzimy do zakładki Zabezpieczenia i wybieramy opcje Ustawienia protokołu IPSec,
- Zaznaczamy opcje Użyj klucza wstępnego do uwierzytelniania oraz wpisujemy w polu Klucz: hasło podane w pliku /etc/ipsec.secrets na Linuksie. Zatwierdzamy przyciskiem OK,
- Następnie przechodzimy do zakładki Sieć i zmieniamy wartość pola Typ wirtualnej sieci prywatnej (VPN) z Automatyczny na Sieć VPN a protokołem L2TP IPSec,
- Zapisujemy zmiany.
W tej chwili możemy połączyć się z bramą IPSec. Klikamy dwukrotnie myszką na ikonę połączenia VPN. W oknie dialogowym podajemy nazwę użytkownika i hasło, a następnie klikamy przycisk Połącz. Nazwa użytkownika i hasło to oczywiście dane uwierzytelniające połączenie PPP (patrz plik /etc/ppp/chap-secrets na Linuksie).
Debugowanie połączenia
Jeśli wykonaliśmy wszystkie kroki z poprzednich punktów połączenie powinno zadziałać od razu. W praktyce pewnie pojawią się jakieś komplikacje. W tej sekcji zostanie podanych kilka porad dotyczących tego, jak znaleźć błąd.
W przypadku połączeń Windows-Linux (OpenSWAN) opartych na PSK błąd wystąpi prawdopodobnie gdzieś po stronie Linuksa. Konfiguracja Windowsa jest bowiem tak prosta, że trudno byłoby w niej coś zrobić źle.
Zaczynamy od przekierowania wszystkich logów systemowych do jednego pliku, aby łatwiej było podglądać na bieżąco, co się dzieje. Dlaczego wszystkie do jednego pliku? Otóż dlatego że IPSec nie składa się z jednego demona, jest ich wiele, wiec wygodniej jest przeglądać jeden plik niż wiele. Aby przekierować wszystkie logi wpisujemy do pliku /etc/syslog.conf poniższą linijkę:
*.* /var/log/all
Następnie przeładowujemy konfiguracje demona Syslog. Wpisujemy polecenie:
killall -HUP syslogd
W środowisku produkcyjnym plik na serwerze może szybko przyrastać. Należy pamiętać, aby po zakończonych testach usunąć wpis z konfiguracji Sysloga. Łączymy sie z serwerem z innej konsoli, lub jeśli pracujemy lokalnie, przełączamy się na drugą konsolę). Wpisujemy polecenie:
tail -f /var/log/all
Na tej konsoli będziesz miał stały podgląd logów systemowych. Jeśli na serwerze działają inne usługi, które możemy wyłączyć (np. poczta, czy dhcp), zróbmy to - im mniej logów, tym łatwiej je przeglądać. Przełączamy się na pierwszą konsolę i sprawdzamy następujące rzeczy:
- Czy działa demon L2TP - wpisujemy polecenie:
# ps -aux | grep "l2tp"
Powinniśmy zobaczyć proces. Jeśli nie działa - uruchamiamy go wpisując polecenie:# xl2tpd
Sprawdzamy ponownie, czy widnieje na liście procesów. Jeżeli nie - sprawdzamy co mówią logi na drugiej konsoli. - Sprawdzamy poleceniem
netstat
, czy serwer nasłuchuje na portach 4500 (NAT Traversal), 500 (Pluto - IKE) oraz 1701 (L2TP). W tym celu wpisujemy polecenie:netstat -anp | grep udp
Powinniśmy zobaczyć nasłuchujące procesy powiązane z danymi portami. - Upewniamy się, czy firewall nie blokuje potrzebnych portów UDP oraz protokołu ESP. Najlepiej na czas testów w ogóle wyłączyć firewall, tzn. ustawiamy domyślną politykę zapory na ACCEPT.
- Sprawdzamy, czy w systemie na pewno jest zainstalowany program
pppd
- wpisujemy polecenie:which pppd
- Upewnijmy się, że w pliku ipsec.conf widnieje wpis
pfs=no
, który oznacza, że PFS nie jest konieczne (możliwe gdy druga strona to obsługuje). Implementacja Microsoftu nie obsługuje PFS, dlatego nie możemy go wymuszać.
Po stronie Windowsa debugowanie jest utrudnione z racji braku "sysloga". Można jedna zainstalować program Wireshark - bardzo dobry sniffer sieciowy - i analizować nim fazy połączenia. W przypadku Windows, należy upewnić się że żaden program typu firewall nie blokuje połączenia zwłaszcza takie kombajny jak różne pakiety "Internet Security".
Konfiguracja z uwierzytelnianiem przez certyfikat
W tej sekcji utworzymy bramę IPSec dla mobilnych użytkowników, z tą tylko różnicą, że do uwierzytelnienia użyjemy certyfikatów X.509, a nie klucza współdzielonego. Konfiguracja taka jest zdecydowanie bardziej zalecana przy zdalnym dostępie pracowników, gdyż umożliwia w razie potrzeby unieważnienie certyfikatu użytkownikowi.
Zakładamy tutaj że mamy już wygenerowane klucze i certyfikaty dla serwera i użytkownika (na razie jeden użytkownik wystarczy).
Konfiguracja po stronie Linuksa (bramy VPN) znacząco się nie różni - więcej pracy będzie w systemie Windows.
Konfiguracja OpenSWAN z wykorzystaniem certyfikatów.
Po stronie Linuksa - w stosunku do konfiguracji z użyciem PSK - zmianie ulegają tylko pliki ipsec.conf oraz ipsec.secrets, pozostałe konfiguracje pozostają identyczne (demon L2TP, konfiguracja pppd).
Konfiguracje wykonujemy wg. następujących punktów:
- Zapisujemy klucz prywatny serwera jako: /etc/ipsec.d/private/serverkey.pem
- Zapisujemy certyfikat serwera jako /etc/ipsec.d/certs/servercrt.pem
- Zapisujemy certyfikat CA jako /etc/ipsec.d/cacerts/cacert.pem
- Plik z listą unieważnionych certyfikatów (poźniejszy etap) powinien znajdować się w katalogu /etc/ipsec.d/crls/.
- Dokonujemy zmian w pliku /etc/ipsec.secrets, tak aby miał
następującą składnię:
: RSA serverkey.pem "<hasło_klucza_prywatnego>"
gdzie:serverkey.pem
- to nazwa pliku z kluczem prywatnym, którego program OpenSWAN oczekuje w katalogu /etc/ipsec.d/private/,hasło_klucz_prywatnego
- to hasło do klucza prywatnego serwera. W przypadku gdy klucz nie jest zabezpieczony hasłem, można je pominąć. Wstawienie wartości %prompt spowoduje, że program OpenSWAN przy starcie będzie pytał o hasło do klucza.
- Tworzymy plik konfiguracyjny /etc/ipsec.conf
version 2.0 config setup interfaces=%defaultroute plutodebug=none forwardcontrol=yes nat_traversal=yes virtual_private=%v4:10.0.0.0/8,%v4:172.16.0.0/12,%v4:192.168.0.0/16,%v4:!192.168.10.0/24 conn roadwarrior-l2tp leftprotoport=17/1701 rightprotoport=17/1701 also=roadwarrior conn roadwarrior auth=esp authby=rsasig compress=yes keyexchange=ike keyingtries=3 pfs=no left=%defaultroute leftcert=/etc/ipsec.d/certs/servercrt.pem right=%any rightrsasigkey=%cert rightsubnet=vhost:%no,%priv rightca=%same auto=add #Disable Opportunistic Encryption include /etc/ipsec.d/examples/no_oe.conf
Opcjarightrsasigkey=%cert
oznacza, że druga strona uwierzytelni się, przedstawiając swój certyfikat. Opcjarightca=%same
oznacza, że certyfikat drugiej strony (klienta) musi być wystawiony przez to samo CA co certyfikat serwera, czyli przez CA, którego certyfikat znajduje się na serwerze w pliku: /etc/ipsec.d/cacert/cacert.pem. - Uruchamiamy usługę IPSec, wpisując polecenie:
ipsec setup start
Import certyfikatów w systemie Windows
Zakładając, że wygenerowaliśmy już użytkownikom klucz oraz wystawiliśmy certyfikaty podpisane przez nasze CA. Powinniśmy mieć już pliki user.key i user.crt. Będziemy musieli przekonwertować nasze klucze i certyfikaty na format PKCS#12 używany w systemach Windows. Konwersje zostały przedstawione podkoniec sekcji poświęconej SSL.
Przy imporcie certyfikatów należy powstrzymać się od instalowania certyfikatów w systemie Windows przez kliknięcie na plik. Ta metoda nie działa prawidłowo. Zamiast tego będziemy używać przystawki MMC.
Utworzymy przystawkę MMC, dzięki której będziemy mogli importować nasze
klucze i certyfikaty. Naciskamy kombinację klawiszy (Win + r), w okienku
uruchom pisujemy polecenie: mmc
- uruchomi się konsola MMC.
Z menu Plik konsoli MMC wybieramy opcję Dodaj/Usuń przystawkę.... Pojawi się okno Dodaj/Usuń przystawkę - klikamy przycisk Dodaj.
Na liście dostępnych przystawek zaznaczamy Certyfikaty, a następnie klikamy Dodaj - uruchomi się kreator konfiguracji przystawki. Wybieramy Konto komputera, następnie klikamy Dalej. W następnym kroku wybieramy opcję Komputer lokalny oraz klikamy przycisk Zakończ.
Z menu Plik wybieramy opcję Zapisz, aby zapisać gotową przystawkę na dysku. Możemy ją nazwać dowolnie - np. ipsec.mmc.
Mając gotową przystawkę, możemy zaimportować certyfikat. W tym celu rozwiń przystawkę Certyfikaty, a następnie kliknij prawym przyciskiem myszy folder Osobisty. Z menu wybieramy Wszystkie zadania a następnie Importuj... - uruchomi się kreator importu certyfikatów.
W kreatorze dodawania certyfikatów wskazujemy przygotowany wcześniej plik certyfikatu użytkownika. Kreator zapyta o hasło klucza prywatnego - podajemy je. Klikamy przycisk Dalej, następnie wybieramy opcje Automatycznie wybierz magazyn certyfikatów na podstawie typu certyfikatu (WAŻNE!) oraz ponownie klikamy Dalej.
Musimy jeszcze zainstalować certyfikat swojego CA w katalogu zaufanych urzędów certyfikacji. W tym celu klikamy prawym przyciskiem myszy katalog Zaufane główne urzędy certyfikacji, a następnie z menu wybieramy opcję Wszystkie zadania/Importuj.
Po wybraniu opcji Importuj uruchomi się kolejny kreator importu certyfikatów. Musimy wskazać plik z certyfikatem CA (ca.crt). Kreator importu certyfikatów oczekuje pliku z rozszerzeniem *.crt, a nie *.pem, dlatego przed importem musimy się upewnić czy plik ma takie rozszerzenie.
Klikamy przycisk Dalej, a następnie wybierz opcję Umieść wszystkie certyfikaty w następującym magazynie - Zaufane główne urzędy certyfikacji. Wychodzimy z konsoli zapisując zmiany.
Konfiguracja połączenia
Konfiguracja połączenia przeprowadzamy dokładnie w taki sam sposób, jak w przykładzie z kluczem współdzielonym. Jedyna różnica polega na tym, aby w zakładce Zabezpieczenia nie zaznaczymy opcji Ustawienia protokołu IPSec/Użyj klucza wstępnego do uwierzytelniania. Zapisujemy zmiany i próbujemy się połączyć.
Jeśli pojawi się błąd odnośnie certyfikatu, to należy upewnić się że poprawnie zaimportowaliśmy certyfikat CA w magazynie Zaufane główne urzędy certyfikacji. Najlepiej zrobić to jeszcze raz.
Jeśli połączenie się zestawiło, spróbujmy spingować drugą stronę wtedy będzie mieli pewność.
Łączenie oddziałów firmy tunelem IPSec
W tej sekcji stworzymy tunel łączący siedzibę firmy A z oddziałem B. W obu lokalizacjach routery działają pod kontrolą Linuksa z instalowanym programem OpenSWAN. Celem tunelu jest zapewnienie bezpiecznej komunikacji w oddziałach.
Do uwierzytelnienia obu stron użyjemy tym razem kluczy RSA (klucz prywatny i publiczny). Jeżeli routery mają stałe IP, możesz użyć nawet klucza współdzielonego (hasła), ale pamiętajmy, aby zablokować na firewallu możliwość łączenia się z protokołem IPSec ze wszystkich hostów wyjątkiem adresu IP "drugiej strony" (w przeciwnym razie ktoś będzie mógł próbować odgadnąć hasło, np. przez atak typu brute force).
Ponieważ implementacja IPSec w Linuksie nie wymaga użycia protokołu PPP oraz L2TP, konfiguracja tutaj jest znacznie prostsza niż w przypadku połączenia z użytkownikami mobilnymi.
Tworzymy plik konfiguracyjny podany na listingu poniżej będzie to plik siedziby firmy A.
version 2.0 config setup interfaces=%defaultroute forwardcontrol=yes rp_filter=0 nat_traversal=noconn linux-to-linux auth=esp authby=rsasig pfs=yes left=91.192.0.186 leftsubnet=192.168.20.0/24 leftrsasigkey=0sAQPuvae6KEw/yHijDjqHomCyLo8oO3H8wl3UExuTArCXtzc1DO5X2E8QFIu0grLofzIzgoCy8AkoFthFPJIyDF3zKVH9ppMS8XQQL2naWp+YOm2cROstRlAfyvC/jF7GvWlRIjxzHzCLCIJXihZmFZGN1ku/DExLx5TjzqG/bXQ9DQ== right=91.192.0.185 rightsubnet=192.168.30.0/24 rightrsasigkey=0sAQODH/CRwexspJ6mu/bThfQzs84IpaHBYNs5MeDpxbiLdacZjM22PqOvbVIqeQlYg4zHMAnB2EyUIgYHskJqyRmtmg6S5ELxnNHqvTE92KI5Bdicn458CowdqR2Jtc4tvD7OWHv/RFzmt6W1kIHPiILAOkR2mSvATgI/QhZtNN4oaw== auto=start include /etc/ipsec.d/examples/no_oe.conf
Znaczenie ważniejszych opcji jest następujące:
authby=rsasig
- uwierzytelnianie przez klucze RSA,left=91.192.0.186
- adres IP routera w siedzibie firmy A ("lewa strona" - lokalna routera),leftsubnet=192.168.20.0/24
- sieć LAN za routerem w siedzibie firmy A,leftrsasigkey=0sAQPuvae6KE...
- klucz publiczny "lewej strony" (routera w siedzibie A),right=91.192.0.185
- adres IP bramy odległej lokalizacji (oddziału B),rightsubnet=192.168.30.0/24
- sieć LAN za routerem w oddziale B,rightrsasigkey=0sAQODH/CRw...
- klucz publiczny prawej strony.
Warto zauważyć że PFS zostało włączone, nie trzeba tego robić jawnie, jest to opcja domyślna dla połączeń linux-linux. Ponieważ jest ona obsługiwana nie należy jej wyłączać.
Ze względu na to iż powyższy listing jest gotowcem pobranym z plików
załączonych do pakietu OpenSWAN, aby użyć go w swoim przypadku
należy zmienić wyżej wymienione opcje, prócz
authby
. Aby zmienić klucze musimy je
wygenerować poleceniem pakietu OpenSWAN. Poniżej znajduje się
lista czynności do wykonania, aby uruchomić tunel IPSec łączący oddziały
firmy.
- Na obu routerach wydajemy poniższe polecenie:
# ipsec rsasigkey 1024 > /root/key.rsa
- Na obu routerach kopiujemy ciąg znaków zaczynający się
od
#pubkey=...
i umieszczamy go w pliku ipsec.conf przy parametrzeleftrsasigkey=
, po czym usuwamy skopiowany ciąg znaków z pliku klucza. - Kopiujemy ciąg umieszczony w
leftrsasigkey
do pliku konfiguracyjnego w oddziale B, umieszczając go przy parametrzerightrsasigkey=
- Klucz przy parametrze
leftrsasigkey=
umieszczamy w pliku konfiguracyjnym routera w siedzibie firmy A przy parametrzerightrsasigkey=
- Otwieramy do edycji plik /etc/ipsec.secrets i umieszczamy w
nim następujący wpis:
91.192.0.186 91.192.0.185: RSA { //część klucz prywatnego pobrana z pliku /root/key.rsa //począwszy od linii: Modulus do końca pliku }
gdzie 91.192.0.186 to w powyższym przykładzie adres IP "lewej strony" (IP lokalnego routera), a 91.192.0.185 to IP odległego routera. Na drugim routerze wpis wygląda odwrotnie. W sekcji pomiędzy nawiasami klamrowymi ({...}
) powinien znaleźć się klucz prywatny RSA. - Uruchamiamy tunel po obu stronach, wpisując poniższe polecenie:
# ipsec setup start
- Sprawdzamy czy połączenie IPsec zostało zestawione. Wpisujemy
polecenie:
# ip xfrm state