_                      _             _ _
| |_ ___ _ __ _ __ ___ (_)_ __   __ _| | | ___   __ _
| __/ _ \ '__| '_ ` _ \| | '_ \ / _` | | |/ _ \ / _` |
| ||  __/ |  | | | | | | | | | | (_| | | | (_) | (_| |
 \__\___|_|  |_| |_| |_|_|_| |_|\__,_|_|_|\___/ \__, |
			                        |___/

Laboratorium sieci VPN

Laboratorium sieci prywatnych, powstało w celu sprawdzenia wartości merytorycznej, materiału Sieci VPN w kategorii terminallog.

Z tego co udało mi się zaobserwować to że mamy cztery główne metody realizacji, takich sieci czy też połączeń.

W zależności od naszych potrzeb możemy użyć, któregoś z powyższych narzędzi. Jeśli musimy zabezpieczyć połączenie punkt-punkt dla jednej usługi, to możemy kłaniać się ku dwóm pierwszym rozwiązaniom. Oczywiście wszystko ma swoje wady. Dla programu Stunnel, potrzebować będziemy certyfikatów, oczywiście wystawionych przez wiarygodne źródło certyfikacji, nic nie stoi na przeszkodzie, abyśmy sami stworzyli nasze własne CA.

Stunnel wymagania:

Wadą protokołu SSH jest to, że potrzebujemy serwera SSH gdzieś w Internecie.

SSH wymagania:

Zaletami tych dwóch rozwiązań są kolejno:

Zalety Stunnel:

Zalety SSH:

Co można rozumieć przez "samowystarczalne wymagania", otóż są to wymogi które możemy zrealizować samodzielnie, bez angażowania osób trzecich lub dodatkowych środków pieniężnych. Jeśli jesteśmy spłukani i możemy sobie pozwolić na konto shell, z możliwością tunelowania (większość darmowych zabrania tunelowania). Pozostaje na jedyne wyjście Stunnel.

Stunnel

Naszą przygodę rozpoczynamy od czystej maszyny wirtualnej, najlepiej z jakiś bezpiecznym Linuksem. Ja wybrałem do tego celu, i nie tylko jak się przekonamy później, dystrybucje Alpine Linux. Instaluje się ją jakieś 5 min. Opis instalacji znajdziemy pod tym adresem. Po zainstalowaniu już systemu, tworzymy nasze nowe CA (urząd certyfikacji).

Edytujemy plik /etc/ssl/openssl.cnf. Odnajdujemy sekcję [ CA_default ] ustawiamy tylko opcje dir, tak aby wskazywała na /etc/ssl. Zapisujemy plik. Tworzymy pusty plik index.txt, inicjujemy plik serial za pomocą ciągu '00' (dwa zera), tworzymy katalogi crl i newcerts oraz tak jak plik serial inicjujemy plik crlnumber za pomocą dwóch zer.

Teraz generujemy klucz prywatny oraz certyfikat dla CA, dzięki niemu będziemy mogli, podpisywać certyfikaty. Polecenie odnośnie generowania klucza znajdują się pod tym linkiem. Pamiętając zarazem aby nazwy plików były takie jak w pliku konfiguracyjnym openssl. W Common Name wpisujemy FQDN hosta CA.

W na końcach poleceń na wiki znajduje się przy niektórych liczba 1024, jest długość klucza. Ponieważ, obecnie klucze poniżej 2048 bitów są uznawane za niebezpieczne, warto pominąć tę wartość. W pliku /etc/ssl/openssl.cnf wartość wskazująca na domyślną długość klucza ustawiona jest 2048 bity.

Korzystając z poleceń na wiki, generujemy certyfikat CA oraz klucz prywatny serwera, po wygenerowaniu klucza, przechodzimy do wygenerowania wniosku dla serwera. W polu Common Name wpisujemy FQDN serwera. Teraz dopiero ustawienia CA w pliku konfiguracyjnym OpenSSL zostaną zweryfikowane. Wszystkie błędy zwracane są dość zrozumiałe. Więc nie powinno być problemów z ich identyfikacją i naprawą. Po wygenerowaniu certyfikatu warto zdjąć hasło, z klucza prywatnego serwera, będzie to konieczne, gdy nasz tunel będzie zestawiany wraz ze startem systemu, ponieważ oczekiwanie na hasło klucza będzie wstrzymywać start systemu i może go unieruchomić, jeśli pracujemy gdzieś zdalnie. Jednak nie należy tego robić na CA, ale na hoście docelowym gdzie Stunnel będzie pracować.

Akurat to nie Stunnel zwrócił mi uwagę na ten problem, nie mniej jednak warto wyrobić w sobie pewne nawyki.

Teraz przechodzimy do dość trudnego zdania, generalnie na wiki jest napisane, aby stworzyć CA na jakimś bezpiecznym komputerze, najlepiej nie podłączonym do sieci. Ja mam dwie wariacje na ten temat. Otóż możemy wykorzystać do tego celu Raspberry Pi 0, które hardwarowo jest offline, i komunikować się tylko z naszym komputerem za pomocą protokołu RNDIS, lub skorzystać z maszyny wirtualnej, tak jak w tym przypadku. Gdzie tworzymy maszynę z natywnym dostępem do internetu. Sprawdzamy czy mamy pakiet OpenSSL, jeśli nie to go instalujemy. Po zainstalowaniu lub upewnieniu się że pakiet jest obecny w systemie, wyłączamy maszynę. Ustawiamy interfejsy na nie podłączone, lub je usuwamy. Teraz do sedna, zanim włączymy maszynę ustawiamy jej katalog współdzielony na jeden z katalogów na naszym komputerze. Uruchamiamy maszynę, po jej uruchomieniu montujemy, katalog współdzielony, metoda na zamontowanie katalogu współdzielonego hipernadzorcy VirtualBox w Alpine Linux, znajduje się tutaj. Tam możemy przekopiować wygenerowane przez nas certyfikaty. Następnie przenieść je na inną maszynę.

Obecnie w większości dystrybucji Linux, stunnel występuje pod nazwą stunnel4 (gdzie 4 oznacza wersję protokołu IP z jaką pracuje). Stunnel, możemy zainstalować z paczki systemowej, lub skompilować samodzielnie. Po zainstalowaniu programu w przypadku systemu Alpine Linux w katalogu /var/run pojawia się katalog stunnel oraz jeden dodatkowy użytkownik, jednak konfiguracje rozpoczynamy od przygotowania pliku certyfikatu. Tworzymy nowy plik w /etc/stunnel przekierowując zawartość pliku klucza prywatnego. Następnie do owego pliku dodajemy linję ze samą spacją, przekierowując wyjście polecenia echo oraz dopisując do wszystkiego zawartość pliku z certyfikatem z serwera. Dla danego pliku ustawiamy odpowiednie uprawnienia 600 oraz właściciela i grupę na root. Teraz tworzymy w katalogu /var/run/stunnel, katalog wraz z podkatalogiem mianowicie var/log, tam będą umieszczane nasze logi z połączenia. Wracamy do katalogu /etc/stunnel tworzymy plik konfiguracyjny wg. wzorca. Teraz możemy uruchomić nasz tunel, wzór pliku konfiguracyjnego oraz uruchomienie tunelu znajdują się tutaj. Pamiętajmy dwie rzeczy, że bezpiecznie byłoby zmusić demona naszej zabezpieczanej usługi do nasłuchu tylko i wyłącznie na pętli zwrotnej o ile stunnel uruchamianym bezpośrednio na serwerze. Można go również uruchomić na routerze, opis znajduje się tutaj, oraz żeby zmienić porty i adresy na te które mamy tunelować, a nie kopiuj-wklej konfiguracje, a potem płacz że coś nie działa.

SSH

Tunele SSH są o tyle proste, że ich konfiguracja sprowadza się do wydania jednego polecenia. Oczywiście musimy mieć gdzieś w sieci serwer z SSH. Za pomocą tych tuneli możemy rozwiązać trzy konkretne problemy:

OpenVPN

OpenVPN jest chyba najpopularniejszą metodą zdalnego dostępu, i o dziwo korzystając z przykładów z książki, opisanych po tym adresem: https://morketsmerke.net/site/articles/terminallog/sieci_VPN#openvpn. Gdzie przetestowano zdalny dostęp do zasobów dla pracowników firmy oraz łączenie odziałów firmy to działa to bez zarzutu. Rzeczami, na które warto zwrócić uwagę jest to że musiałem co restart systemu tworzyć urządzenie TUN, (jedno polecenie, również znajduje się na wiki), może być to wina mojego systemu operacyjnego (Alpine Linux), na Lubuntu tego problemu nie było. I jeśli mamy ściągnąć hasło z klucza dla serwera, to zróbmy to już na docelowym hoście, ponieważ kiedy ja ściągałem hasło na CA, potem przeniosłem ten plik okazało się że jest on niezdatny do użycia. Więc to kolejna rzecz. Przy łączeniu oddziałów firmy, zmodyfikowałem scenariusz pod siebie, nie przepuszczałem całego ruchu, z oddziału przez siedzibę tylko za pomocą tras udostępniłem połączanie pomiędzy komputerami siedziby oraz oddziału. Trasy są bardzo proste.

Router w oddziale:

ip route add 192.168.20.0/24 via 10.3.0.2
Router w siedzibie:
ip route add 192.168.30.0/24 via 10.3.0.1
Gdzie klasy należą do poszczególnych podsieci X.Y.20.0/24 należy do klasy w siedzibie firmy, natomiast X.Y.30.0/24 należy do klasy w oddziale. Adres 10.3.0.2 adres TUN w oddziale, a 10.3.0.1 to adres TUN w siedzibie.

Myślę że w ta wariacja, jest bardziej aktualna do dzisiejszych czasów, gdzie dysponuje się naprawdę szybkimi łączami i nie potrzeba przepuszczać przez VPN, ruchu Pani Moniki, która lubi czytać pudelka do śniadania. Ponieważ opisy konfiguracj i na wiki działają tu je pominę.

IPSec

Sporym nadużyciem było by napisanie że IPSec jest bardziej przezroczystym OpenVPN. OpenVPN to pakiet oprogramowania realizujący połaczenia punkt-punkt. IPSec to zbiór protokołów. Przez zawiłą historię twórców implementacji OpenSWAN, (pakiet który jest opisywany na wiki), opis na wiki jest nieaktualny. Powszechnie jeśli mówimy o IPSec w Linux mamy na myśli pakiet LibreSWAN, który na swojej stronie zawiera gotowe HOW-TO's połączeń host-host oraz podsieć-podsieć. Problem w tym że to nie działa. Znalazłem tutorial na howtoforge.com. Na którym działają obie metody uwierzytelnienia.

Konfiguracja LibreSWAN opiera się na dwóch plikach: /etc/ipsec.conf oraz /etc/ipsec.secrets. W pierwszym znich znajduje się właściwa konfiguracja natomiast w drugim znajduje się PSK. Typowe dla IPSec jest to że nie mamy klienta oraz serwera, oczywiście w ramach własnych oznaczeń, możemy nazwać którąś ze stron klientem a którąś serwerem. W IPSec mamy stronę lewą (left) oraz stronę prawą (right). Strona lewa jest tak jakby stroną naszą, czy też lokalną natomiast prawa - stroną obcą, odległa. Po obu stronach musi widnieć ta sama konfiguracja tunelu, jednak z odniesieniem stron, tj. dla strony lewej, to jest tak jak konfigurujemy, natomiast w konfiguracji strony prawej, to ona jest stroną lewą, a lewa prawą. To tak samo jak z ludźmi, kiedy stoją do siebie na przeciwko. Mamy do dyspozycji w IPSec dwa modele połączeń. Jest połączenie punkt-punkt, czy jak to woli host-host lub sieć-sieć.

Przed przystąpieniem do konfiguracji, nie twórzmy nowych plików, wykorzystajmy te które są dostarczone wraz pakietem LibreSWAN, tylko zakomentujmy ostatnia dyrektywę include (include /etc/ipsec.d/*.conf), w pliku /etc/ipsec.conf oraz jedyną dyrektywę include (include /etc/ipsec.d/*.secrets) w pliku /etc/ipsec.secrets. Konfiguracje przy użyciu uwierzytelnienia PSK wygląda następująco:

Strona lewa:
Plik: ipsec.conf

config setup
protostack=netkey

conn mytunnel

	ike=aes256-sha256;modp4096
	phase2alg=aes256-sha256;modp4096
	left=172.16.2.144
	leftsubnet=192.168.20.0/24
	right=172.16.2.154
	rightsubnet=172.16.2.154/32
	authby=secret
	type=tunnel
  auto=start

Plik: ipsec.secrets

172.16.2.144 172.16.2.154: PSK "1234vpn_test1234"

Strona prawa: Plik: ipsec.conf

config setup
protostack=netkey

conn mytunnel

    ike=aes256-sha256;modp4096
    phase2alg=aes256-sha256;modp4096
    left=172.16.2.154
    leftsubnet=172.16.2.154/32
    right=172.16.2.144
    rightsubnet=192.168.20.0/24
    authby=secret
    type=tunnel
    auto=start

Plik: ipsec.secrets

172.16.2.154 172.16.2.144: PSK "1234vpn_test1234"

Powyższa konfiguracja przedstawia moją wariację na temat możliwych modeli połączeń. Na pierwszy rzut oka wygląda jak połączenie sieć-sieć, jednak w prawej podsieci znajduje się tylko jeden komputer. A więc można uznać że jest to połączenie sieć-host patrząc od lewej. Nie wiem czy ma sens, opis tych opcji, jeśli ktoś byłby zainteresowany, to use GOOGLE. Ważna rzecz, jeśli chodzi o IPSec. Jeśli korzystamy z pakietów LibreSWAN wbudowanych w system, to należy upewnić się czy mają identyczne wersje, w przeciwnym razie tunel inicjuje strona, która ma nowszą wersję oprogramowania. W przypadku tych samych wersji nie ma znaczenia, która inicjuje tunel. Aby uruchomić tunel, najpierw musimy uruchomić sługę IPSec poleceniem (na obu stronach):

# ipsec setup start

Po uruchomieniu usługi możemy dodać nasze połączenie (na obu stronach) poleceniem (podajemy nazwę połączenia, nazwa połączenia znajduje sie po słowie conn):

# ipsec auto --add mytunnel

Po dodaniu przez obie strony połączenia, jedna z nich (ta z wyższą wersją oprogramowania, jeśli po obu stronach są równe to bez znaczenia która) inicjuje tunel:

# ipsec auto --up mytunnel

Tunel zatrzymujemy poleceniem:

# ipsec auto --down mytunnel

Warto pamiętać o tym, że w pliku konfiguracyjnym mamy opcje auto ustawioną na start oznacza to że po dodaniu połączenia, będzie ono automatycznie zestawiane przy każdym starcie usługi ipsec. Poniżej przedstawię konfigurację z wykorzystaniem kluczy RSA do uwierzytelnienia. Poniższe kroki wykonujemy na obu komputerach. Te konfigurację zaczynamy od usunięcia obecnych plików /etc/ipsec.secrets. Następnie generujemy klucze właśnie do pliku poleceniem:

# ipsec newhostkey --output /etc/ipsec.secrets
Zawartość pliku powinna wyglądać mniej więcej tak:
: RSA   {
        # RSA 3216 bits   a   Thu May 21 19:34:25 2020
        # for signatures only, UNSAFE FOR ENCRYPTION
        #ckaid=69f3a4f8d322f423033de7ef0acc3a600a351f43
        #pubkey=0sAwEAAa235arqmgpHM21of9l7KagM4kOTZQ7VKjOwhPKdW/t+Lgo1Qp5RXcga9ENcIRUDMP3U2iqG8wOFeM0YmwsbMw58zcuTPodjjisuh4HZDf6LBvOfnG47P3mes1AJNdsDHJl96EFlrXpb3QHqK3caH9uX5qPsaiydc6ThjpYtOUyFqBkqBilg6XhO
        Modulus: 0xadb7e5aaea9a0a47336d687fd97b29a80ce24393650ed52a33b084f29d5bfb7e2e0a35429e515dc81af4435c21150330fdd4da2a86f3038578cd189b0b1b330e7ccdcb933e87638e2b2e8781d90dfe8b06f39f9c6e3b3f799eb3500935d
        PublicExponent: 0x010001
        }
# do not change the indenting of that "}"

Musimy pobrać do notatnika wartość #pubkey, z jednego i drugiego hosta. Następnie musimy je umieścić na pliku /etc/ipsec.conf jako wartości dla poszczególnych opcji. Więc leftrsasigkey, dla lewej strony oraz rightrsasigkey dla strony prawej na lewym hoście na prawym zaś odwrotnie. Konfiguracja wygląda zatem tak:

Strona lewa

config setup
    protostack=netkey

conn vpn_rsa

    ike=aes256-sha256;modp4096
    phase2alg=aes256-sha256;modp4096
    left=172.16.2.156
    right=127.16.2.157
    authby=rsasig
    leftrsasigkey=0sAwEAAa235arqmgpHM21of9l7KagM4kOTZQ7VKjOwhPKdW/t+Lgo1Qp5RXcga9ENcIRUDMP3U2iqG8wOFeM0YmwsbMw58zcuTPodjjisuh4HZDf6LBvOfnG47P3mes1AJNdsDHJl96EFlrXpb3QHqK3caH9uX5qPsaiydc6ThjpYtOUyFqBkqBi
    rightrsasigkey=0sAwEAAfVs/GW0tllOWsFf9SrXh8w/Nt99a8+HaY7mw0BvtnYRZol+8DOwEpgwkeAMD0A2L02EpFGj8fv3DgVOvrFK3/bI67XeR7K3/m55jhloYT97RrinQGXFoqWxpAQP6TQFADHjjNypn/vHWgncuH8yfBKlsxNSUgmd1ii+ohGK15J8OS9s6
    type=tunnel
    auto=start

Strona prawa

config setup
    protostack=netkey

conn vpn_rsa

    ike=aes256-sha256;modp4096
    phase2alg=aes256-sha256;modp4096
    left=172.16.2.157
    right=127.16.2.156
    authby=rsasig
    leftrsasigkey=0sAwEAAfVs/GW0tllOWsFf9SrXh8w/Nt99a8+HaY7mw0BvtnYRZol+8DOwEpgwkeAMD0A2L02EpFGj8fv3DgVOvrFK3/bI67XeR7K3/m55jhloYT97RrinQGXFoqWxpAQP6TQFADHjjNypn/vHWgncuH8yfBKlsxNSUgmd1ii+ohGK15J8OS9s6
    rightrsasigkey=0sAwEAAa235arqmgpHM21of9l7KagM4kOTZQ7VKjOwhPKdW/t+Lgo1Qp5RXcga9ENcIRUDMP3U2iqG8wOFeM0YmwsbMw58zcuTPodjjisuh4HZDf6LBvOfnG47P3mes1AJNdsDHJl96EFlrXpb3QHqK3caH9uX5qPsaiydc6ThjpYtOUyFqBkqBi
    type=tunnel
    auto=start

Tunel uruchamiamy wg. powyższych poleceń.

Podsumowanie

Przedstawione zostały tu cztery sposoby, na zabezpieczenie transmisji danych, dzięki którym możemy bez obaw korzystać z usług, które takich mechanizmów nie oferują. Jeśli jeszcze nie zdecydowaliśmy czego powinniśmy użyć. Osobiście polecił bym SSH do zabezpieczania pojedynczych połączeń oraz OpenVPN dla całych sieci. Głównymi wadami, które rzutowały na ten wybór pośród pozostałych to dla Stunnela - dodatkowo potrzebne certyfikaty, a dla IPSec - potrzeba jawnych adresów IP, dokumentacja (żeby na stronie projektu przykłady konfiguracji nie działały, no to coś jest nie halo), gdyby nie te adresy, to dało by się to jakoś znieść, tunel IPSec jest przezroczysty i to jest mega. Nie trzeba ustawiać nawet routingu. Dla mnie prostota i szybkość konfiguracji to ważne rzeczy, nikt nie lubi się bawić całych dzień z daną rzeczą. Istotna jest multiplatformowość dla OpenVPN, który występuje np. na OpenBSD. Oczywiście jest to moje w pełni subiektywne zdanie.