moja sieć domowa #2

mój ostatni wpis o konstrukcji domowej sieci spowodował, że otrzymałem parę ciekawych maili. mniejsza o większość - doceniam głosy pochwały i chylę czoła przed głosami krytyki :)

krótki opis (odsyłam do powyższego linku) jak co jest połączone zakończony, zajmijmy się zatem usługami.

podstawową jest oczywiście rozwiązywanie nazw, czyli DNS. “bo to zawsze jest DNS” jak mówi jedna z mądrości sieciowych.

ponieważ korzystam z UPSów (dziękujemy Ci, PGE…) mam to szczęście, że większość infrastruktury nawet w przypadku utraty zasilania, będzie działać. czasem jednak trzeba coś uaktualnić, zatrzymać, przenieść - i dobrze byłoby, gdyby usługi nadal działały. w szczególności, gdy Twoje własne dzieci wymuszają SLA sieci powyżej sześciu dziewiątek… ;)

enter anycast

przyznam, że na początku trochę kombinowałem z paroma DNSami ustawionymi na VMkach pod różnymi adresami IP. w szczególności dlatego, że wszedłem w posiadanie w ramach nieco szalonych zakupów paru(-nastu) Rasbperry Pi 3 i 4 ;)

z czasem jednak (ach, to utrzymanie sieci…) budowanie od zera całego FreeBSD na ARMa, nagrywanie go na kartę i podnoszenie wersji co parę tygodni stało się męczące i dałem sobie spokój. co więcej, postanowiłem też zamiast wielu adresów serwerów DNS rozgłaszać… jeden.

jeśli pamiętacie moją prezentację o IP anycaście (jeśli nie - przeczytajcie, poczekam), jedną z fajnych cech routingu jest możliwość rozgłaszania tego samego IP z wielu miejsc. dzięki czemu, resolvery DNS (które, nawiasem mówiąc, w większości desktopowych OSów są nieco ogłupiałe) nie muszą próbować wykazać się inteligencją i wykrywaniem “padniętych” adresów IP ponieważ ten sam IP może prowadzić do wielu instancji tej samej usługi.

w swojej sieci wydzieliłem zatem dwie podsieci - 192.168.66.0/24 dla wszystkich usług, z których domownicy mogą korzystać, oraz 192.168.168.0/24 dla konkretnie usług anycast. oba obecne serwery DNS pracujące jako VMki na dwóch różnych hostach - Intelowych NUCach:

  • ns1.wesola.local - 192.168.66.22/24
  • ns2.wesola.local - 192.168.66.33/24
  • ns.wesola.local - 192.168.168.168/32

obie VMki rozgłaszają ze swojego loopbacka0 prefiks 192.168.168.168/32 na którym pracuje rekursywny serwer DNS (a konkretnie - unbound). unbound dodatkowo odpytuje serwer nsd przypięty do 127.0.0.1/::1 o adresy z domeny wesola.local aby dać mi możliwość używania krótkich nazw hostów bez potrzeby pamiętania adresów lokalnych (umówmy się, domownicy raczej z tego nie korzystają).

konfiguracja sieci obu FreeBSD wygląda zatem tak:

[ns1 ~]$ more /etc/rc.conf
hostname="ns1"
ifconfig_vmx0="inet 192.168.66.22 netmask 0xffffff00"
ifconfig_lo0_alias1="inet 192.168.168.168 netmask 255.255.255.255"
defaultrouter="192.168.66.1"

oraz:

[ns2 ~]$ more /etc/rc.conf
hostname="ns2"
ifconfig_vmx0="inet 192.168.66.33 netmask 0xffffff00"
ifconfig_lo0_alias1="inet 192.168.168.168 netmask 255.255.255.255"
defaultrouter="192.168.66.1"

natomiast konfiguracja (częściowa) demonów DNS na obu hostach (zwróć uwagę na adresy IP):

[ns1 ~]$ more /usr/local/etc/unbound/unbound.conf
server:
        interface: 192.168.168.168
        outgoing-interface: 192.168.66.22
        port: 53
[...]
forward-zone:
        name: wesola.local
        forward-addr: 127.0.0.1
       
forward-zone: 
        name: "."
        forward-addr: 208.67.222.222
        forward-addr: 2620:119:35::35
        forward-addr: 208.67.220.220
        forward-addr: 2620:119:53::53

oraz:

[ns1 ~]$ more /usr/local/etc/nsd/nsd.conf
server:
        ip-address: 127.0.0.1
        ip-address: 192.168.66.22
        ip-address: 192.168.66.22@5053
[...]
zone:
        name: wesola.local
        zonefile: wesola.local

zone:
        name: 168.192.in-addr.arpa
        zonefile: wesola.local.rev
[...]

routing BGP dla automatyzacji usług

no dobrze, a jak to fizycznie działa ze sobą? host otrzymuje przez DHCP swój adres oraz wskazanie, że serwerem DNS jest 192.168.168.168. jak do niego dociera?

za routing między segmentami (VLANami) odpowiada mój przełącznik szkieletowy. ponieważ na obu VMkach z serwerami DNS mam odpalony OpenFRR który przez BGP rozgłasza prefiks 192.168.168.168/32 (żeby zapewnić sobie automatyczne powiadamianie o awariach ale i rozgłoszenie po wstaniu hosta), tablica routingu na Nexusie pokazuje:

sw-core# sh ip route 192.168.168.168
IP Route Table for VRF "default"
[...]

192.168.168.168/32, ubest/mbest: 2/0
    *via 192.168.66.22, [200/0], 3d00h, bgp-65055, internal, tag 65055
    *via 192.168.66.33, [200/0], 3d00h, bgp-65055, internal, tag 65055

po stronie przełącznika konfiguracja BGP wygląda tak:

router bgp 65055
  maxas-limit 64
  address-family ipv4 unicast
    maximum-paths 32         ! tak... czasem jest więcej niż 2 ścieżki ;)
    maximum-paths ibgp 32
  address-family ipv6 unicast
    maximum-paths 32         ! mam również IPv6 - ale go nie pokazuje ;)
    maximum-paths ibgp 32
  neighbor 192.168.66.22
    remote-as 65055
    timers 1 3
    address-family ipv4 unicast
      route-reflector-client
      filter-list 1 out      ! do NSów nie chcemy nic rozgłaszać
  neighbor 192.168.66.33
    remote-as 65055
    timers 1 3
    address-family ipv4 unicast
      route-reflector-client
      filter-list 1 out      ! do NSów nie chcemy nic rozgłaszać
!
ip as-path access-list 1 seq 10 deny "^$"

natomiast po stronie VMek z FreeBSD, konfiguracja procesu bgpd z paczki OpenFRR tak:

[ns1 /usr/local/etc/frr]$ more bgpd.conf
hostname ns1
password cisco               ! h4x0rs beware!
enable password cisco
!
router bgp 65055
 bgp router-id 192.168.66.22
 network 192.168.168.168/32
 neighbor 192.168.66.1 remote-as 65055
 address-family ipv4 unicast
 exit-address-family
log stdout

…i odpowiednio dla ns2:

[ns2 /usr/local/etc/frr]$ more bgpd.conf
hostname ns2
password cisco               ! h4x0rs beware as well!
enable password cisco
!
router bgp 65055
 bgp router-id 192.168.66.33
 network 192.168.168.168/32
 neighbor 192.168.66.1 remote-as 65055
 address-family ipv4 unicast
 exit-address-family
log stdout

co to oznacza? że klient otrzymuje jeden adres DNS przez DHCP, a protokół BGP zadba o rozłożenie ruchu pomiędzy dostępnymi serwerami DNS. w trakcie upgrade’u jednej z VMek prefiks automatycznie znika, Nexus routuje wszystkie zapytania do ocalałej instancji… a potem gdy druga wstanie, wznawia rozkładanie zapytań.

co się stanie, gdy dodam trzeci, czwarty, szesnasty serwer DNS? zapytania nadal będą rozkładane pomiędzy nimi, ale posiadanie aż tak wielu nie ma sensu. czasami, dla testów dokładam trzeci serwer właśnie na RbPi tylko po to, żeby potestować nowe ustawienia - ale taka konfiguracja zapewnia mi łatwość wprowadzania zmian w sposób niezauważalny dla użytkowników.

a ten DHCP?

DHCP też serwowane jest przez obie VMki (redundancja!) ale ponieważ specyfika ruchu jest nieco inna, nie trzeba wykorzystywać anycastu. zamiast tego, w każdym VLANie gdzie powinien być aktywny serwis DHCP, na Nexusie skonfigurowane są helpery DHCP IP:

sw-core# sh running-config interface vlan 33
[...]
interface Vlan33
[...]
  ip address 192.168.33.1/24
  ip verify unicast source reachable-via rx
  ip dhcp relay address 192.168.66.22  ! pierwsza VMka
  ip dhcp relay address 192.168.66.33  ! druga VMka
[...]

do serwowania DHCP wykorzystuje pakiet isc-dhcp z paczek FreeBSD - serwery skonfigurowane są jako redundantna para i zapewniają ciągłość działania nawet gdy któregoś zabraknie dzięki poniższej konfiguracji:

[ns1 /usr/local/etc]$ more dhcpd.conf
[...]
option domain-name-servers 192.168.168.168;
option domain-name "wesola.local";

omapi-port 7911;
omapi-key omapi_key;

key omapi_key {
     algorithm hmac-md5;
     secret Ofakekeyfakekeyfakekey==;
}

# konfiguracja redundantnej pary - adresy IP, porty i podział pul:

failover peer "wesola-fo" {        
 primary;
 address 192.168.66.22;
 port 519;
 peer address 192.168.66.33;
 peer port 520;
 max-response-delay 60;
 max-unacked-updates 10;
 mclt 3600;
 split 128;
 load balance max seconds 3;
}

# przykładowa pula dla VLANu 33 z przykładu powyżej:

# VLAN33
subnet 192.168.33.0 netmask 255.255.255.0 {
  option routers 192.168.33.1;
  option ntp-servers 192.168.33.1;
  pool {
   failover peer "wesola-fo";
   range 192.168.33.10 192.168.33.99;
  }
}

dzięki temu nie tylko usługa DNS jest redundantna i ‘samo optymalizująca się’, ale redundantny jest również serwis DHCP.

mam nadzieję, że zachęciłem do samodzielnych eksperymentów :)