Sieci VPN

  1. Wstęp
  2. Słabość protokołów sieciowych i związane z tym problemy
  3. SSL jako standard bezpiecznego przesyłania danych
  4. Tunelowanie portów
  5. OpenVPN - praktyczne implementacja tuneli VPN
  6. IPSec
  7. IPSec w systemie Linux
 _                      _             _ _
| |_ ___ _ __ _ __ ___ (_)_ __   __ _| | | ___   __ _
| __/ _ \ '__| '_ ` _ \| | '_ \ / _` | | |/ _ \ / _` |
| ||  __/ |  | | | | | | | | | | (_| | | | (_) | (_| |
 \__\___|_|  |_| |_| |_|_|_| |_|\__,_|_|_|\___/ \__, |
			                        |___/

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.:

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:

  1. 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).
  2. Serwer w odpowiedzi wysyła klientowi numer obsługiwanej wersji SSL, obsługiwane algorytmy szyfrujące, a także swój certyfikat (klucz publiczny).
  3. 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.
  4. 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.
  5. 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
  6. Jeśli jest wymagane uwierzytelnienie klienta, jest to robione w tej chwili. Wówczas klient musi przesłać certyfikat.
  7. 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).
  8. 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.
  9. 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.
  10. 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:

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ć.

  1. Pobieramy ze strony http://www.openssl.org/source/ źródła najnowszej wersji pakietu i zapisz w katalogu /usr/src/,
  2. Porównujemy wartość MD5 pliku pobranego z sieci (polecenie md5sum) z wartością udostępnioną na stronie openssl.org,
  3. Rozpakowujemy zawartość archiwum poleceniem
    $ tar zxf openssl-nr_wersji.tar.gz
    
  4. Przechodzimy do katalogu openssl-nr_wersji.
  5. 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
    
  6. Jeśli skrypt ./config nie zgłosi błędu, możemy przejść do właściwej kompilacji programu. W tym celu wpisujemy polecenie
    # make
    
  7. 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.

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:

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

Opcje dotyczące sekcji usług

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.

  1. Instalujemy najwygodniejszym dla nas sposobem Stunnel w naszym systemie,
  2. 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.
  3. Przegrywamy na serwer docelowy przygotowany plik server.pem oraz cacert.pem - certyfikat CA. Pamiętając o zmianie uprawnień dla pliku server.pem.
  4. 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.
  5. Uruchamiamy tunel na serwerze:
    # stunnel /etc/stunnel/stunnel.conf
    
  6. Instalujemy na komputerze klienta Stunnel.
  7. Przenosimy plik z certyfikatem CA - cacert.pem - na komputer klienta.
  8. 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.

  1. Zainstalujemy program Stunnel na routerze.
  2. 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.
  3. 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.
  4. Ustalamy, na jakim porcie i jakim adresie działa baza danych.
  5. Przygotowujemy plik konfiguracyjny po stronie routera
  6. Odblokowujemy na firewallu możliwość łączenia się z portem, na którym słucha program Stunnel.
  7. 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.
  8. 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.:

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.

  1. 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.
  2. 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.

  1. Pobieramy źródła stabilnej wersji programu OpenVPN ze strony głównej projektu https://openvpn.net/community-downloads/.
  2. Rozpakowujemy plik w katalogu /usr/src/. W tym celu wpisujemy polecenie:
    # unzip openvpn-<numer_wersji>.zip
    
  3. Przechodzimy do katalogu openvpn-<numer_wersji> i wpisujemy polecenie:
    # ./configure
    
  4. 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.
  5. 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 program make zakończy działanie.
  6. 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:

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.

  1. groupadd openvpn
  2. usermod -g openvpn -d /usr/local/etc/openvpn -s /bin/false -f 1 openvpn
  3. mkdir /user/local/etc/openvpn
  4. 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:

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:

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óż:

  1. 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).
  2. Poprzez mechanizm CCD (client-config dir) będziemy przekazywać użytkownikom ich konfiguracje (modyfikacja tabeli routingu, zmiana serwerów DNS itp.).
  3. 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.

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:

  1. parametr: akcja (add,delete,update) - w zależności od tego co miało miejsce,
  2. parametr: adres IP klienta (przydzielony w ramach tunelu),
  3. 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.

  1. Instalujmy program OpenVPN na obu routerach opisany w początkowych sekcjach tego artykułu.
  2. 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.
  3. 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
    
  4. 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
    
  5. 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 kluczowego client w pliku konfiguracyjnym klienta. Nie jest to błąd. Opcja client jest synonimem opcji tls-client, a w tym przypadku nie używamy uwierzytelnienia TLS.
  6. 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)
  7. 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
    
    Gdzie ethX 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.
  8. 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 polecenia ip, 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
    
  9. 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>
    
  10. 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.
  11. 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
  1. Przygotowanie środowiska
    1. Instalujemy program OpenVPN na obu routerach opisany na początku sekcji sposób,
    2. 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,
    3. 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
      
    4. 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
      
    5. 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 kluczowego client w pliku konfiguracyjnym klienta. Nie jest to błąd. Opcja client jest synonimem opcji tls-client, a w tym przypadku nie używamy uwierzytelnienia TLS.
    6. 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
      
      Gdzie ethX 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.
    7. Uruchamiamy program OpenVPN i sprawdzamy czy istnieje on liście procesów (w obu sidzibach).
      # openvpn --config <plik konfiguracyjny>
      
    8. 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 interfejsie eth1 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 interfejsie br0. Nadajmy więc routerom adresy z puli lokalnej. Przypisujemy IP 192.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ć".
    Zauważmy że adres 192.168.20.1 przydzielony na interfejsie br0 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 interfejsu eth1, teraz dotyczą interfejsu br0. 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
    
  2. 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.

    1. 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
      
    2. Sprawdzamy, czy interfejs br0 powstał po obu stronach tunelu. Wpisujemy polecenie:
      # ifconfig | grep br0
      
    3. Używając polecenia brctl show br0, sprawdzamy, czy oba interfejsy (tap0 i eth1) 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>
      
    4. Upewniamy się czy wszystkie interfejsy tworzące most działają w trybie promiscuos (nasłuchiwania). Wpisujemy polecenia:
      # ifconfig eth1 promisc
      # ifconfig tap0 promisc
      
    5. Możemy użyć programu tcpdump, do przeglądania pakietów pojawiających się na obu stronach mostu.
    6. Możemy podglądać na bierząco jak most uczy się adresów MAC. Listę adresów sprawdzamy poleceniem:
      brctl showmacs br0
      
    7. Jeśli w dalszym ciągu nic nie działa, czasem dobrym rozwiązaniem jest zresetowanie komputerów i rozpoczęcie wszystkiego od nowa
    8. 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.

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:

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

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:

  1. 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.
  2. 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.

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).

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:

  1. Wchodzimy do Panelu sterowania i wybieramy Połączenia sieciowe,
  2. 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,
  3. W następnym kroku wybieramy opcje Połączenie wirtualnej sieci prywatnej, następnie klikamy przycisk Dalej,
  4. Wpisujemy nazwę połączenia np. ipsec1,
  5. Podajemy adres IP lub nazwę DNS bramy VPN
  6. 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,
  7. Przechodzimy do zakładki Zabezpieczenia i wybieramy opcje Ustawienia protokołu IPSec,
  8. 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,
  9. 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,
  10. 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:

  1. 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.
  2. 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.
  3. 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.
  4. Sprawdzamy, czy w systemie na pewno jest zainstalowany program pppd - wpisujemy polecenie:
    which pppd
    
  5. 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:

  1. Zapisujemy klucz prywatny serwera jako: /etc/ipsec.d/private/serverkey.pem
  2. Zapisujemy certyfikat serwera jako /etc/ipsec.d/certs/servercrt.pem
  3. Zapisujemy certyfikat CA jako /etc/ipsec.d/cacerts/cacert.pem
  4. Plik z listą unieważnionych certyfikatów (poźniejszy etap) powinien znajdować się w katalogu /etc/ipsec.d/crls/.
  5. 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.
  6. 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
    
    Opcja rightrsasigkey=%cert oznacza, że druga strona uwierzytelni się, przedstawiając swój certyfikat. Opcja rightca=%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.
  7. 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:

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.

  1. Na obu routerach wydajemy poniższe polecenie:
    # ipsec rsasigkey 1024 > /root/key.rsa
    
  2. Na obu routerach kopiujemy ciąg znaków zaczynający się od #pubkey=... i umieszczamy go w pliku ipsec.conf przy parametrze leftrsasigkey=, po czym usuwamy skopiowany ciąg znaków z pliku klucza.
  3. Kopiujemy ciąg umieszczony w leftrsasigkey do pliku konfiguracyjnego w oddziale B, umieszczając go przy parametrze rightrsasigkey=
  4. Klucz przy parametrze leftrsasigkey= umieszczamy w pliku konfiguracyjnym routera w siedzibie firmy A przy parametrze rightrsasigkey=
  5. 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.
  6. Uruchamiamy tunel po obu stronach, wpisując poniższe polecenie:
    # ipsec setup start
    
  7. Sprawdzamy czy połączenie IPsec zostało zestawione. Wpisujemy polecenie:
    # ip xfrm state