Na prawie każdej małej bramie OpenVPN pojawiają się dwa problemy z nazwami. Do podłączonego laptopa nie dotrzesz po nazwie z jego certyfikatu, a usługi za tunelem nie mają żadnych nazw. Wyglądają jak jeden problem i wymagają przeciwnego leczenia, bo jeden adres przesuwa się z każdą sesją, a drugi nie. Zdecyduj, jakiego rodzaju nazwę dodajesz, zanim cokolwiek zmienisz.

Decyduj dla każdej nazwy, nie dla całej bramy

Test jest prosty: czy ten adres zmienia się, gdy klient łączy się ponownie? Jeśli tak, nazwę trzeba generować z sesji VPN. Jeśli nie, należy ona do statycznego wpisu, który możesz przeczytać i przejrzeć.

Name kindSource of truthWhere it lives
Connected clientThe address OpenVPN just assignedGenerated hosts file, rewritten per session
Service behind the tunnelA fixed address you choseStatic address= drop-in
Anything with a certificate nameThe certificate, not the poolEither, but the name must match the certificate

Mieszanie ich to typowa porażka. Usługa przypięta w generowanym pliku znika przy pierwszym przepisaniu go przez skrypt, a klient wpisany w statyczny wpis wskazuje tego, kto miał ten adres ostatnio. Oba błędy pozostają niewidoczne, dopóki nazwa nie zostanie rozwiązana na złą maszynę. Wtedy osoba debugująca zakłada, że zepsuł się DNS, a nie plik.

Ścieżka dynamiczna: learn-address i pula

OpenVPN zna przydział, więc pozwól mu go podać. Te opcje serwera czynią przydział trwałym i skryptowalnym:

client-config-dir /etc/openvpn/ccd
ifconfig-pool-persist /etc/openvpn/ip-pool 60
script-security 2
learn-address /etc/openvpn/learn-address.sh

learn-address uruchamia twój skrypt za każdym razem, gdy adres jest dodawany, aktualizowany lub usuwany, i przekazuje operację, adres oraz nazwę wspólną. Minimalny skrypt dopisuje jedną linię na klienta i usuwa ją przy usuwaniu:

#!/bin/sh
HOSTS=/etc/openvpn/hosts.lan
case "$1" in
  add|update) echo "$2 $3" >> "$HOSTS" ;;
  delete)     sed -i "/^$2 /d" "$HOSTS" ;;
esac
kill -HUP $(cat /var/run/dnsmasq.pid)

Na urządzeniu tun drugi argument to adres tunelowy klienta, więc linii można użyć bezpośrednio. Na urządzeniu tap OpenVPN przekazuje zamiast tego adres MAC klienta, bo segment tap może przenosić także inne protokoły niż IPv4, i wtedy trzeba odszukać adres w pliku puli po nazwie wspólnej, zanim cokolwiek napiszesz.

Bądź jasny co do tego, czym jest generowany plik: migawką tego, kto jest teraz połączony. Nazwy znikają przy rozłączeniu, co jest dokładnie tym, czego chcesz dla laptopów przenoszących się między sieciami, i dokładnie tym, czego nie chcesz dla serwera działającego całą noc.

Ścieżka statyczna: address= i rozwijanie domeny

Skieruj dnsmasq na generowany plik zamiast na systemowy plik hosts i daj mu domenę, aby krótkie nazwy rozwijały się do w pełni kwalifikowanych:

domain=corp.example
no-hosts
addn-hosts=/etc/openvpn/hosts.lan
listen-address=127.0.0.1,10.8.0.1
bind-interfaces

Gdy domain jest ustawione, linia taka jak 10.8.0.6 alice odpowiada zarówno dla alice, jak i alice.corp.example. Trzymaj listen-address tylko na bramie tunelu i loopbacku, bo resolver przypadkowo opublikowany na interfejsie LAN to usługa, której nie zamierzałeś oferować.

Usługi, które nigdy nie pochodzą z puli, mają własne wpisy. Umieść je w osobnym pliku drop-in w katalogu konfiguracji dystrybucji, aby aktualizacja pakietu nie mogła ich nadpisać:

address=/files.corp.example/10.8.0.20
address=/db.corp.example/10.9.0.5

Przekaż resolver albo nic się nie stanie

Resolver, o który nikt nie pyta, niczego nie zmienia. Serwer musi go ogłosić:

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"

Klienci Windows sami stosują obie opcje. Większość klientów Linux nie: potrzebują wspieranej integracji resolvera, takiej jak hook update-resolv-conf dystrybucji albo obsługa DNS w NetworkManagerze, lub ręcznie ustawionej domeny wyszukiwania i serwera nazw. Sprawdź rzeczywisty resolver klienta, zamiast zakładać, że push został dochowany, bo zignorowany push wygląda dokładnie jak serwer, który nie odpowiada.

Sprawdź na trzech warstwach

Najpierw zapytaj bezpośrednio serwer, potem klienta, a potem aplikację:

dig +short @10.8.0.1 alice.corp.example
getent hosts files.corp.example

Jeśli bezpośrednie zapytania odpowiadają, a aplikacja nie, wina leży w przekazaniu klientowi, a nie w strefie. Jeśli nazwa się rozwiązuje, a połączenie nadal zawodzi, nazwa jest w porządku i następna do sprawdzenia jest trasa lub zapora.

Zapisz obie kategorie obok konfiguracji: które nazwy są generowane, które przypięte i z którym certyfikatem każda musi się zgadzać. Następna osoba dodająca serwer skopiuje pierwszy znaleziony wzorzec.

Powiązane artykuły