07.03.2022
Konfiguracja OpenVPN na systemie VyOS 1.1.3
BezpieczeństwoKonfiguracjaLinux | UnixZapora sieciowa
openvpnnavyos113

Ostatnia aktualizacja: 03.02.2023r.

Kilka lat temu przez ponad dwa tygodnie męczyłem się z ustawieniem serwera OpenVPN na systemie Windows Server 2008 R2. Sprawdziłem mnóstwo poradników w Internecie, wykonałem niezliczone ilości prób, testów konfiguracji, jednak efekt miałem ten sam - ówczesna nowa wersja oprogramowania zwyczajnie nie działała, przynajmniej na moim systemie. Po takim czasie bezskutecznej pracy (dla doprecyzowania - dwa tygodnie po osiem godzin pracy) stwierdziłem, że być może prościej będzie to postawić na Linuxie. Wtedy ten system był dla mnie czarną magią, szczególnie jeśli cała konfiguracja miałaby przebiegać przez wiersz poleceń. Stwierdziłem, że spróbuję wdrożyć system, z którego korzystał (lub nadal korzysta, jednak tego nie wiem) portal dobreprogramy.pl czyli Vyatta. Niestety w 2012 roku projek został przejęty przez firmę Brocade Communications Systems. Nowy właściciel zmienił nazwę projektu i skomercjalizował projekt. Jednak w przyrodzie nic nie ginie i społeczność skupiona wokół projektu zaczęła rozwijać ostatnią wersję Vyatta Core pod nazwą VyOS i to jego postanowiłem wykorzystać. Po paru latach uświadomiłem sobie jak bardzo dobra była to decyzja. 😎 W ciągu 7 lat pracy system działał elegancko i sprawił mi w zasadzie tylko dwa problemy i obydwa były związane z zawieszonym interfejsem sieciowym - restart rozwiązywał problem. Strzelam, że miało to związek z tym, że system był zainstalowany jako maszyna wirtualna na Microsoft Hyper-V 2012 R2 i być może podczas długiej nieprzerwanej pracy natrafiałem na takie anomalie.

Mała uwaga, acz ważna - wydajność rozwiązania. Każde szyfrowanie ma określony rozmiar narzutu, który zależy od siły szyfrowania więc nigdy nie osiągniemy tej samej przepustowości łącza szyfrowanego co nieszyfrowanego. Krótka historia z życia wzięta na podstawie tych kilka lat pracy systemu. Jak wdrażałem to rozwiązanie, to w firmie miałem łącze światłowodowe o parametrach 20/20 Mbit czyli ok. 2,5 MB/s w piku. Kiedy system działał na serwerze IBM x3550 M4, gdzie hostem wirtualizacyjnym był Microsoft Hyper-V Server 2012 R2 to maksymalnie osiągałem prędkość 200 - 250 KB/s. Gdy prędkość łącza wzrosła mi do 40/40 Mbit to prędkość po VPN pozostała niezmienna. Kiedy zmigrowałem wirtualne maszyny z serwera IBM na serwer Thomas Krenn SC825 (niemiecka firma, która jest tak naprawdę rebrandingiem sprzętu Supermicro) to mimo, że stos oprogramowania pozostał ten sam to wydajność VPN wzrosła dwukrotnie do 400 - 500 KB/s. Następna migracja na tym samym serwerze z Microsoft Hyper-V 2012 R2 na Proxmox 7 wraz ze zmianą trybu działania kontrolera z RAID na IT oraz reorganizacją 8 dysków twardych (4 pary MIRROR w STRIPE`ie) spowodowała co prawda kolejny wzrost prędkości do 750 - 1000 KB/s, ale przyspieszenie łącza do 400/400 Mbit nie przyniosło dalszych wzrostów prędkości i w tym momencie osiągnąłem sufit. Na dzisiejsze czasy taka prędkość wypada kiepsko, choć podejrzewam, że znalazłoby się zastosowanie dla tego rozwiązania gdzie taka prędkość nie byłaby problemem. Ścianę przebiłem dopiero jak wdrożyłem serwer Supermicro SuperServer SYS-5019D-FN8TP z zainstalowanym systemem pfsense, gdzie jestem wstanie osiągnąć prędkość 500/500 Mbit (taką prędkość wykręciłem podczas testu lokalnego iperf). Także obecne rozwiązanie posłuży mi parę lat zanim ponownie natrafię na ścianę. A nawet jeśli to się stanie to w pierwszej kolejności spróbuję zmienić system na najnowszą wersję VyOS lub OPNsense i jeśli inny stos oprogramowania nie da mi zauważalnego przyspieszenia to wtedy będę się bawił innym urządzeniem. 😀

VyOS 1.1.3 oparty jest na systemie Debian 6. Obecnie lepiej korzystać z nowszych wersji systemu. Poniższą instrukcję zostawiam ku pamięci.

Parametry VM

  • 1 rdzeń CPU
  • 512 MB RAM
  • 2 GB HDD

OpenVPN

Z poniższych wersji korzystałem bezproblemowo na mojej konfiguracji przez ponad 7 lat. 😅

Instalacja systemu

  1. Pobieram instalator VyOS 1.1.3. Po uruchomieniu instalatora czekam na załadowanie systemu, a następnie loguję się go niego - login i hasło to vyos.

  2. Aby zainstalować system wprowadam komendę install image, a następnie wykonuję polecenia pojawiające się na ekranie. Mogę klikać klawisz Enter w celu akceptacji domyślnych wartości, oczywiście do czasu aż instalator zapyta się mnie czy jestem pewny, że chcę usunąć całą zawartość dysku twardego. 😉

  3. Zatrzymuję system poleceniem poweroff now w celu odmontowania obrazu ISO, a następnie uruchamiam maszynę wirtualną i zaraz po zalogowaniu poleceniem sudo passwd ustawiam nowe hasło.

Konfiguracja interfejsu sieciowego eth0

  1. Po zalogowaniu się do systemu wydaję polecenie configure w celu wejścia w tryb konfiguracji.
  2. Ustawiam interfejs sieciowy eth0 na pobieranie adresu IP z serwera DHCP.
    set interfaces ethernet eth0 address dhcp
  3. Zatwierdzam zmiany, zapisuję je do pliku konfiguracyjnego i wychodzę z trybu konfiguracji.
    commit
    save
    exit
  4. Sprawdzam czy system pobrał adres IP.
    show interfaces

SSH

  1. W trybie konfiguracji włączam na domyślnych ustawieniach usługę SSH na porcie 22.
    configure
    set service ssh port 22
  2. Zatwierdzam zmiany, zapisuję je do pliku konfiguracyjnego i wychodzę z trybu konfiguracji.
    commit
    save
    exit
  3. Generuję z hasłem klucze (prywatny i publiczny).
    ssh-keygen -q -f ~/id_rsa -N 'Przykl@d0w3_Ha$Lo' -b 4096 -t rsa
  4. Za pośrednictwem programu WinSCP loguję się do systemu na konto vyos, a następnie pobieram plik id_rsa. Ładuję plik klucza prywatnego do programu PuTTYgen i wpisuję hasło. Po załadowaniu pliku usuwam zawartość pola Key comment, a następnie klikam w przycisk Save private key w celu zapisania danych w formacie *.ppk, który później będę wykorzystywać np. w programie PuTTY. Usuwam plik id_rsa.

  5. Przelogowuję się na konto root i modyfikuję plik konfiguracyjny i restartuję usługę SSH.
    sudo nano -w /etc/ssh/sshd_config
    [...]
    Port 22122
    [...]
    LoginGraceTime 30
    PermitRootLogin no
    [...]
    RSAAuthentication yes
    PubkeyAuthentication yes
    AuthorizedKeysFile      %h/.ssh/authorized_keys
    [...]
    PasswordAuthentication no
    [...]
    #HostKey /etc/ssh/ssh_host_key
    
    sudo /etc/init.d/ssh restart
  6. Umieszczam wygenerowany wcześniej klucz publiczny w pliku autoryzowanych kluczy na koncie vyos.
    cat /home/vyos/id_rsa.pub >> /home/vyos/.ssh/authorized_keys
  7. Ustawiam odpowiednie uprawnienia dla ścieżki z kluczami SSH (wyłączny dostęp dla właściciela (/.ssh) oraz prawo odczytu i zapisu dla właściciela (/.ssh/authorized_keys)).
    chmod 700 /home/vyos/.ssh
    chmod 600 /home/vyos/.ssh/authorized_keys
  8. Wylogowuję się z konta root i wchodzę w tryb konfiguracji.
    configure
  9. Ładuję plik klucza publicznego dla konta vyos.
    loadkey vyos /home/vyos/id_rsa.pub
  10. Jeśli klucze zostały wygenerowane poza systemem, to wystarczy, że prześlesz je do systemu i wykonasz powyższe polecenie. Innym sposobem jest wejście w tryb edycji autoryzacji użytkownika systemu, a następnie ustawienie typu klucza oraz jego samego. Wykonując powyższe polecenie nie trzeba tego robić.
    edit system login user vyos authentication
    set public-keys vyos@vyos type ssh-rsa
    set public-keys vyos@vyos key klucz
  11. Ustawiam usługę SSH, aby nasłuchiwała na port ustawiony w pliku konfiguracyjnym oraz wyłączam autoryzację hasłem.
    set service ssh port numer
    set service ssh disable-password-authentication
  12. Zatwierdzam zmiany, zapisuję je do pliku konfiguracyjnego i wychodzę z trybu konfiguracji.
    commit
    save
    exit
  13. Na koniec usuwam pliki kluczy z systemu.
    rm -rf ~/id_rsa*

OpenVPN na tun

  1. Na początku z poziomu Windows przechodzę do katalogu C:\Program Files\OpenVPN\easy-rsa w celu przygotowania odpowiednich plików dla serwera OpenVPN. Na samym początku uruchamiam skrypt init-config i później uzupełniam skrypt vars - chodzi o wartości SET z końca pliku, które będą umieszczane w generowanych certyfikatach. Poniżej zawartość mojego pliku:
    @echo off
    rem Edit this variable to point to
    rem the openssl.cnf file included
    rem with easy-rsa.
    
    set HOME=%ProgramFiles%\OpenVPN\easy-rsa
    set KEY_CONFIG=openssl-1.0.0.cnf
    
    rem Edit this variable to point to
    rem your soon-to-be-created key
    rem directory.
    rem
    rem WARNING: clean-all will do
    rem a rm -rf on this directory
    rem so make sure you define
    rem it correctly!
    set KEY_DIR=keys
    
    rem Increase this to 2048 if you
    rem are paranoid.  This will slow
    rem down TLS negotiation performance
    rem as well as the one-time DH parms
    rem generation process.
    set KEY_SIZE=2048
    
    rem These are the default values for fields
    rem which will be placed in the certificate.
    rem Change these to reflect your site.
    rem Don't leave any of these parms blank.
    
    set KEY_COUNTRY=PL
    set KEY_PROVINCE=WLKP
    set KEY_CITY=Wolsztyn
    set KEY_ORG=GrzegorzWitaIT
    set KEY_EMAIL=admin@grzegorzwita.it
    set KEY_CN=GrzegorzWitaIT
    set KEY_NAME=GrzegorzWitaIT
    set KEY_OU=GrzegorzWitaIT
    set PKCS11_MODULE_PATH=changeme
    set PKCS11_PIN=1234
    

    Po uzupełnieniu pliku uruchamiam skrypty w poniższej kolejności:

    1. Generuję pusty plik index oraz serial (wykonuję to tylko raz, później przy generowaniu nowych certyfikatów nie muszę już tego robić).
      vars
      clean-all
    2. Generuję klucz CA (podobnie jak wyżej - wykonuję tylko raz).
      build-ca
    3. Generuję dla serwera klucz Diffie-Hellman (znowu, jak wyżej - wykonuję tylko raz).
      build-dh
    4. Generuję klucz TLS dla serwera oraz klientów.
      openvpn --genkey --secret ta.key
    5. Generuję klucz prywatny oraz certyfikat dla serwera.
      build-key-server server
    6. Generuję klucz prywatny oraz certyfikat dla klientów - w moim przypadku pliki nosiły nazwę clientnumer z numerowaniem +1 dla każdego kolejnego wywołania skryptu. Przeklikuję klawiszem Enter kreator do pojawienia się prośby o podanie Common Name, które w moim przypadku miało postać Imie_Nazwisko (bez polskich znaków). Tą wartość będę wykorzystywał podczas konfiguracji profili OpenVPN w VyOS.
      build-key client0

    Po przygotowaniu odpowiedniej ilości pakietów klucz prywatny - certyfikat przygotowuję paczki z plikami dla końcówek:

    1. Wygenerowane pliki klienckie (tj. client0.crt oraz client0.key) oraz serwerowe (tj. ca.crt, ca.key oraz ta.key) dla każdego klienta umieszczam w osobnych katalogach dla zachowania porządku.
    2. Przygotowuję plik konfiguracji client.ovpn - ważne, aby plik miał kodowanie ANSI / 8859-1, gdyż w przyciwnym wypadku program OpenVPN będzie wyświetlał błędy. Poniżej mój plik konfiguracyjny - ważne miejsca (pozycje bez znaku ";") musisz dostosować pod swoje ustawienia i wymagania. Pamiętaj, aby ustawiać odpowiednie nazwy kluczy prywatnych i certyfikatów, gdyż są one unikatowe dla każdej końcówki.
      
      ##############################################
      # Sample client-side OpenVPN 2.0 config file #
      # for connecting to multi-client server.     #
      #                                            #
      # This configuration can be used by multiple #
      # clients, however each client should have   #
      # its own cert and key files.                #
      #                                            #
      # On Windows, you might want to rename this  #
      # file so it has a .ovpn extension           #
      ##############################################
      
      # Specify that we are a client and that we
      # will be pulling certain config file directives
      # from the server.
      client
      
      # Use the same setting as you are using on
      # the server.
      # On most systems, the VPN will not function
      # unless you partially or fully disable
      # the firewall for the TUN/TAP interface.
      ##############################################
      # dev tun tworzy interfejs routowania (tzw. routed IP tunnel)
      # Używany w przypadku konfiguracji typu brama + wielu klientów lub brama-brama.
      # Przykład wykorzystania - łączenie się z firmą pracowników zdalnych.
      # dev tap tworzy interfejs mostkowy (tzw. ethernet tunnel)
      # używany w przypadku łączenia kilku sieci.
      # W tym przypadku między sieciami przekazywany jest cały ruch, łącznie z broadcastem (pakietami rozgłoszeniowymi), co
      # może prowadzić do nadmiernego obciążenia tunelu VPN niepotrzebnym ruchem.
      # Przykład wykorzystania - połączenie pomiędzy oddziałem firmy a centralą
      ;dev tap
      dev tun
      
      # Windows needs the TAP-Win32 adapter name
      # from the Network Connections panel
      # if you have more than one.  On XP SP2,
      # you may need to disable the firewall
      # for the TAP adapter.
      ;dev-node MyTap
      
      # Are we connecting to a TCP or
      # UDP server?  Use the same setting as
      # on the server.
      ##############################################
      # TCP jest protokołem umożliwiającym wykrywanie błędów transmisji (mniejsza wydajność)
      # UDP jest protokołem niezapewniającym mechanizmu kontroli pakietów i potwierdzeń (większa wydajność)
      ;proto tcp
      proto udp
      
      # The hostname/IP and port of the server.
      # You can have multiple remote entries
      # to load balance between the servers.
      remote vpn.grzegorzwita.it 1190
      
      # Choose a random host from the remote
      # list for load-balancing.  Otherwise
      # try hosts in the order specified.
      ;remote-random
      
      # wpis w tablicy routingu umożliwiający komunikację z inną siecią
      push "route 192.168.202.0 255.255.255.0"
      
      # Keep trying indefinitely to resolve the
      # host name of the OpenVPN server.  Very useful
      # on machines which are not permanently connected
      # to the internet such as laptops.
      resolv-retry infinite
      
      # Most clients don't need to bind to
      # a specific local port number.
      ##############################################
      # nie otwiera portu po stronie klienta
      nobind
      
      # Downgrade privileges after initialization (non-Windows only)
      ;user nobody
      ;group nobody
      
      # restart w przypadku braku połączenia
      # ping co 10s z limitem czasu 120s
      keepalive 10 120
      
      # Try to preserve some state across restarts.
      ##############################################
      # podczas restartu utrzymuje podniesiony wirtuany interfejs
      # podczas restartu nie będzie ponownie wczytany klucz
      persist-key
      persist-tun
      
      # If you are connecting through an
      # HTTP proxy to reach the actual OpenVPN
      # server, put the proxy server/IP and
      # port number here.  See the man page
      # if your proxy server requires
      # authentication.
      ;http-proxy-retry # retry on connection failures
      ;http-proxy [proxy server] [proxy port #]
      
      # Wireless networks often produce a lot
      # of duplicate packets.  Set this flag
      # to silence duplicate packet warnings.
      ;mute-replay-warnings
      
      # SSL/TLS parms.
      # See the server config file for more
      # description.  It's best to use
      # a separate .crt/.key file pair
      # for each client.  A single ca
      # file can be used for all clients.
      ca ca.crt			# certyfikat CA
      cert client0.crt		# certyfikat klientów
      key client0.key			# klucz prywatny klienta
      
      # Verify server certificate by checking
      # that the certicate has the nsCertType
      # field set to "server".  This is an
      # important precaution to protect against
      # a potential attack discussed here:
      #  http://openvpn.net/howto.html#mitm
      #
      # To use this feature, you will need to generate
      # your server certificates with the nsCertType
      # field set to "server".  The build-key-server
      # script in the easy-rsa folder will do this.
      ##############################################
      # sprawdzenie czy pole nsCertType w certyfikacie serwera = „server”
      # dodatkowa ochrona przed atakami typu Man-in-the-Middle
      remote-cert-tls server	# TLS Web Server Authentication
      ;ns-cert-type server	# Netscape Cert Type: SSL Server
      
      # If a tls-auth key is used on the server
      # then every client must also have the key.
      tls-auth ta.key 1		# klucz statyczny
      
      # Select a cryptographic cipher.
      # If the cipher option is used on the server
      # then you must also specify it here.
      ##############################################
      # algorytm szyfrowania
      # ustawienie wykorzystywane przez serwer i klientów
      # openvpn --show-ciphers
      cipher AES-192-CBC
      
      # Algorytmy hashujące
      # sprawdzające integralność przesyłanych informacji
      ;auth SHA512
      
      # Enable compression on the VPN link.
      # Don't enable this unless it is also
      # enabled in the server config file.
      ##############################################
      # algorytm kompresji zmniejszający zużycie transferu
      # parametr może zmiejszyć szybkość połączenia
      ;comp-lzo
      
      # log ze statusem działania
      status openvpn-status.log
      
      # log
      log openvpn.log
      
      # Set log file verbosity.
      ##############################################
      # poziom szczegółowości logowania zdarzeń
      # verb 0 - "tryb cichy" z wyjątkiem błędów krytycznych
      # verb 3-4 - ustawienie standardowe
      # verb 5-6 - przydatne w debuggowaniu problemów połączeniowych
      # verb 9 - "tryb ekstremalny" informujący o wszystkim
      verb 4
      
      # Silence repeating messages
      ;mute 20
      
      
    3. Tak przygotowane paczki (6 plików - ca,crt, ca.key, client.ovpn, client0.crt, client0.key oraz ta.key (u Ciebie część nazw może być inna)) instalowałem u każdego użytkownika, który miał mieć dostęp VPN.
  2. Konfiguruję serwer OpenVPN.
    1. W pierwszej kolejności przesyłam przez SCP do katalogu /config/auth pliki ca.crt, server.crt, server.key, dh2048.pem oraz ta.key.
    2. Wchodzę w tryb konfiguracji.
      configure
    3. Ustawiam tryb pracy.
      set interfaces openvpn vtun0 mode server
    4. Ustawiam protokoł.
      set interfaces openvpn vtun0 protocol udp
    5. Ustawiam lokalny port.
      set interfaces openvpn vtun0 local-port 1190
    6. Ustawiam podsieć.
      set interfaces openvpn vtun0 server subnet 10.23.1.0/24
    7. Ustawiam topologię podsieci.
      set interfaces openvpn vtun0 server topology subnet
    8. Ustawiam routing do sieci lokalnej LAN.
      set interfaces openvpn vtun0 server push-route 192.168.202.0/24
    9. Ustawiam dodatkowe parametry OpenVPN.
      set interfaces openvpn vtun0 openvpn-option „--tls-server --tls-auth /config/auth/ta.key 0 --crl-verify /config/auth/crl.pem‟
    10. Ustawiam certyfikat CA.
      set interfaces openvpn vtun0 tls ca-cert-file /config/auth/ca.crt
    11. Ustawiam certyfikat serwera.
      set interfaces openvpn vtun0 tls cert-file /config/auth/server.crt
    12. Ustawiam protokół Diffiego-Hellmana.
      set interfaces openvpn vtun0 tls dh-file /config/auth/dh2048.pem
    13. Ustawiam klucz publiczny.
      set interfaces openvpn vtun0 tls key-file /config/auth/server.key
    14. Ustawiam szyfrowanie.
      set interfaces openvpn vtun0 encryption aes192
    15. Ustawiam przekierowywanie zapytań DNS.
      set service dns forwarding listen-on vtun0
  3. Konfiguruję klientów poprzez ustawienie im statycznych adresów IP po VPN.
    set interfaces openvpn vtun0 server client Common_Name ip 10.23.1.2
  4. Konfiguruję NAT.
    1. Ustawiam numer reguły.
      set nat source rule 10
    2. Ustawiam podsieć źródłową.
      set nat source rule 10 source address 10.23.1.0/24
    3. Ustawienie interfejsu wychodzącego.
      set nat source rule 10 outbound-interface eth0
    4. Ustawienie translacji.
      set nat source rule 10 translation address masquerade
  5. Konfiguruję zaporę sieciową.
    1. Przygotowuję grupę ROOT.
      set firewall group address-group ROOT
    2. Przypisuję adresy OpenVPN do grupy ROOT.
      set firewall group address-group ROOT address 10.23.1.2
    3. Ustawiam grupę adresów, do których ma być dostęp.
      set firewall group address-group ROOT_ACCESS
    4. Przypisuję do grupy adresy, do których ma być dostęp.
      set firewall group address-group ROOT_ACCESS address 192.168.202.2
    5. Ustawiam regułę zezwalające na dostęp.
      set firewall name DOSTEP rule 10 action accept
    6. Ustawiam adresy, które mają być dostępne po VPN`ie. Mogę dodać wcześniej przygotowaną grupę lub całą podsieć. Do wyboru. 😉
      set firewall name DOSTEP rule 10 destination group address-group ROOT_ACCESS
      set firewall name DOSTEP rule 10 destination address 192.168.202.0/24
    7. Ustawiam grupę źródłową.
      set firewall name DOSTEP rule 10 source group address-group ROOT
    8. Jeśli potrzeba przygotowuję dodatkowe reguły i grupy adresów.
  6. Przypisanie grupy reguł do interfejsu sieciowego.
    set interfaces ethernet eth0 firewall out name DOSTEP

Dodatkowe informacje

sudo service rsyslog restart - ręczne usunięcie auth.log = wymagany restart usługi

0 komentarzy

Szybki kontakt

Masz pytania? Napisz