Nedávno som potreboval spojiť 2 zariadenia cez internet, ale ani jedno zo zariadení nedisponovalo verejnou IPv4 adresou. Aj keď v nadpise uvádzam „bez verejnej IPv4 adresy“ je to myslené tak, že zariadenia, ktoré budeme spájať, nebudú mať verejné IPv4 adresy. V skutočnosti musíme medzi zariadenia postaviť nejaký prostredník a teda bez verejnej IPv4 adresy sa nepohneme. Riešením je použitie nejakej formy VPN. Či už sa rozhodneme pre platenú VPN, prenajatie VPS, alebo zakúpenie verejnej IPv4, tak nikdy to vo svete IPv4 nebude zadarmo.
Obsah
- Cieľ projektu
- Riešenie pre BFU
- Postavíme si VPN tunel
- Konfigurácia servera
- Konfigurácia klienta (MT)
- Instalácia a konfigurácia klienta (OpenWRT)
- Záver
Cieľ projektu
Na jednej strane internetu je mobilne zariadenie a na druhej strane je IP kamera. Mobilné zariadenie dostáva IPv4 adresu od mobilného ISP z rozsahu CGN 100.64.0.0/10 (neverejná IPv4 adresa) a IP kamera je za NAT nejakého ISP (neverejná IPv4 adresa). Spojenie a komunikácia týchto zariadení bez prostredníka s verejnou IPv4 adresou nie je možná. Môj ISP našťastie ponúka verejnú IPv4 adresu zdarma, takže si nemusím objednávať služby tretích strán. Tretia strana je z bezpečnostného hľadiska vždy problém, pretože predstavuje MITM.

Riešenie pre BFU
Bežný užívatelia to riešia tým jednoduchším, ale menej bezpečným spôsobom. Zakúpia si IP kameru (obyčajne z Ázijskej krajiny). Ďalej si stiahnu do mobilného zariadenia aplikáciu a z IP kamery naskenujú QR kód. V QR kóde je uložená konfigurácia aplikácie, kde sa v skrytosti vyplnia dôležité parametre aby sa IP kamera mohla spojiť s aplikáciou. Komunikácia potom prebieha cez prostredník (nazvime to cloud) a zákazník sa aj bez verejnej IPv4 adresy dokáže spojiť s IP kamerou. Pre bežného užívateľa je to jednoduchý a funkčný spôsob a bez akéhokoľvek ďalšieho zásahu to funguje. Ak Ázijsky výrobca skrachuje, alebo ukončí svoje pôsobenie, tak zvyčajne vypne aj svoje servery a užívateľovi ostanú oči pre plač. Ak sa nechce užívateľ viazať na tretiu stranu, tak ideálnou možnosťou je vlastnenie verejnej IPv4 adresy a využitie VPN tunela. Týmto spôsobom budeme mať nad prostredníkom kontrolu sami.
Postavíme si VPN tunel
Rozhodol som sa, že ako VPN použijem WireGuard o ktorom som písal pred nedávnom. Podľa predchádzajúceho obrázka je z ľavej strany mobilný telefón (Android, alebo IOS), ktorý má IPv4 adresu z rozsahu CGN. Ako prostredník bude slúžiť LXC (kde bude verejná IPv4 adresa). Z druhej strany je wifi router s podporou OpenWRT na ktorý je pripojená IP kamera (úplne na pravo). Vzľhadom k tomu, že IP kamera nemá podporu WireGuard, musel som pred ňu postaviť zariadenie (OpenWRT), ktoré podporu WireGuard má. Nemusí to byť striktne OpenWRT, môže tam byť akýkoľvek iný OS s podporou pre Wireguard (napr. Mikrotik).
Inštalácia Wireguard nie je nič zložité a je to popísane v tomto článku. Tak isto je triviálne vygenerovať pár kľúčov pre server a klientov. Klienti a server si medzi sebou vymenia verejne kľúče a spojenie funguje. To znamená, že WireGuard nainštalujeme na
- server (v mojom prípade LXC)
- mobilné zariadenie (Android, alebo IOS)
- (wifi)router, ktorý je postavený na OpenWRT (nexx)
Konfigurácia servera
Za predpokladu, že už sme vygenerovali privátne a verejné kľúče, tak serverovú časť nakonfigurujeme týmto spôsobom a wg0.conf bude vyzerať asi takto
[Interface]
PrivateKey = eNbtK0AOXsTsW+f**************s9+RNgP1MGJq34=
Address = 10.30.0.1/32
ListenPort = 51830
PreUp = sysctl -w net.ipv4.ip_forward=1
PostDown = sysctl -w net.ipv4.ip_forward=0
#Nexx router
[Peer]
PublicKey = 7mcbsTwkPL+C6C**************Vum5rAVZ32fTKS8=
AllowedIPs = 192.168.80.0/24,10.30.0.2/32
#mobile client
[Peer]
PublicKey = 2puYaBPY5xEB64**************y/iXJeg1P2ketQM=
AllowedIPs = 10.30.0.3/32
Dôležité je zapnúť forwardovanie packetov v jadre (riadok 6) a u klienta (Nexx router) nastavíme okrem rozsahu WG siete aj LAN sieť aby sme sa mohli dostať na zariadenia v LAN sieti wifi routera (riadok 12). WireGuard automaticky vygeneruje pre túto konfiguráciu aj routy a routovacia tabuľka vyzerá následovne. Tu je dôležitý riadok 6, ktorý smeruje pakety do siete 192.168.80.0/24 cez wg0.
default via 192.168.30.1 dev eth0 onlink
10.30.0.2 dev wg0 scope link
10.30.0.3 dev wg0 scope link
10.30.0.4 dev wg0 scope link
192.168.30.0/24 dev eth0 proto kernel scope link src 192.168.30.10
192.168.80.0/24 dev wg0 scope link
Konfigurácia klienta (MT)
Inštalácia aplikácie WireGuard do mobilného telefónu (MT) je triviálna úloha. Pre OS Android stiahneme aplikáciu z Google Play a pre iphone použijeme úložisko App Store. Takto bude vyzerať konfigurácia wg0 pre (MT). Samozrejme, jednoduchšie je z konfiguráku vygenerovať QR kód a z mobilom cez aplikáciu WireGuard kód naskenovať ako zadávať všetky parametre ručne.
[Interface]
Address = 10.30.0.3/32
PrivateKey = mK6wKvd9ZR4LMCNu**************UU5bNVfyYiaH8=
[Peer]
PublicKey = CXOePGlyO27X3qxI**************7+bBZXJ22p2DA=
AllowedIPs = 192.168.80.0/24
Endpoint = example.com:51830
PersistentKeepalive = 25
Inštalácia a konfigurácia klienta (OpenWRT)
Najprv do OpenWRT nainštalujeme aplikáciu WireGuard. V rámci webového rozhrania prejdeme na
System --> Software
kde klikneme na Update list...
Do kolónky filter zadáme kľúčové slovo wireguard a počkáme pokiaľ sa nezobrazia výsledky hľadania. Systém nájde asi 41 balíkov s kľúčovým slovom wireguard. Z toho je asi 33 jazykových mutácii. My budeme inštalovať balík luci-app-wireguard s ktorým sa nainštalujú aj všetky závislosti potrebné na chod aplikácie.
Následne sa pustime do konfigurácie. Konfigurovať môžeme cez webové rozhranie, čo je jednoduchšie na pochopenie, alebo cez terminál, úpravou konfiguračných súborov. Najprv ukážem konfiguráciu cez web a potom cez terminál.
Konfigurujeme cez webové rozhranie
Predpokladajme, že OpenWRT je defaultne nastavený a funguje na ňom internet. Na WAN rozhraní je neverejná IPv4 adresa. Na LAN strane si môžeme nastaviť (ľubovoľný rozsah z RFC 1918 aby nekolidoval z druhou stranou) napr. 192.168.80.0/24. Ďalej budeme vytvárať rozhranie (interface) pre VPN sieť wg0. V rámci OpenWRT web administrácie prejdeme na
network --> Interfaces --> Add new interface
a nastavíme podľa obrázka. Meno si môžeme zvoliť ako chceme (ja som zvolil tradične wg0).

Ďalej nastavíme na karte General Settings ako je na obrázku. Private Key použijeme ten, ktorý sme vygenerovali na servery pre klienta (OpenWRT). IP adresses bude IP adresa, ktorú prideľujeme rozhraniu wg0

Ďalej na karte Firewall Settings vytvorime pre wg0 novú zónu.

Na karte Peers nastavíme všetko podľa obrázka. Public Key bude verejný kľúč servera. Allowed IPs, môžeme povoliť celý subnet. Endpoint Host nastavíme na verejnú IPv4 adresu servera (alebo doménové meno, ktoré bude preložené na IP adresu servera). Samozrejme nesmieme zabudnúť na Endpoint port (ak nevieš čo je Endpoint port, prečítaj si tento článok) a nepovinný údaj je aj Persistent Keep Alive. Následne klikneme na Save a Save & Apply.

Už by sme mali byť schopný pingať z mobilného zariadenia WiFi router (OpenWRT) 192.168.80.1. Teraz sa potrebujeme dostať z wg0 siete do LAN siete, kde je IP kamera s IP adresou 192.168.80.111. To znamená, že musíme spraviť forwarding z wg0 siete do LAN siete. V rámci web administrácie OpenWRT prejdeme do
Network --> Firewall --> General Settings --> Add
Nastavíme podľa obrázka

Ak to máme hotové, tak klikneme na Save a následne Save & Apply. Teraz by sme mali vedieť z mobilného zariadenia pingať aj IP adresy v LAN sieti a teda aj našu IP kameru 192.168.80.111.
Konfigurujeme cez terminál
Ak sme WireGuard nenainštalovali cez web rozhranie, tak to môžeme spraviť cez terminal.. Prihlásime sa do OpenWRT cez SSH a WireGuard nainštalujeme
ssh root@192.168.1.1
opkg update
opkg install wireguard-tools
opkg install luci-app-wireguard
Teraz budeme editovať 2 konfiguračné súbory. Na editáciu použijeme textový editor vi. Najprv nakonfigurujeme sieťové rozhranie
vi /etc/config/network
Vyhľadáme sekciu, kde posledný riadok zmeníme z 192.168.1.1 na 192.168.80.1.
config interface 'lan'
option device 'br-lan'
option proto 'static'
option netmask '255.255.255.0'
option ip6assign '60'
option ipaddr '192.168.80.1'
Ďalej na koniec konfiguračného súboru doplníme tieto riadky
config interface 'wg0'
option proto 'wireguard'
option private_key 'qAfZrE6ZWdBUCuk**************m2rvq2jBwy1nXY='
list addresses '10.30.0.2/32'
config wireguard_wg0
option public_key 'CXOePGlyO27X3qx**************m7+bBZXJ22p2DA='
list allowed_ips '10.30.0.0/24'
option endpoint_host 'example.com'
option endpoint_port '51830'
option persistent_keepalive '25'
option description 'server'
option route_allowed_ips '1'
Konfigurácia firewallu
vi /etc/config/firewall
Nakoniec súboru pridáme tieto nastavenia
config zone
option name 'wg0'
list network 'wg0'
option input 'ACCEPT'
option output 'ACCEPT'
option forward 'ACCEPT'
config forwarding
option src 'wg0'
option dest 'lan'
reboot -f
Po reboote sa prihlasujeme už na IP adrese 192.168.80.1. Teoreticky by malo všetko fungovať. Priznám sa, že ručným editovaním konfiguračných súborov som to netestoval, ale som presvedčený, že to je v poriadku.
Záver
V dnešnom blogu som popísal ako vytvoríme spojenie typu point-to-point resp. point-to-multipoint, kde ani jedno zo zariadení nevlastní verejnú IPv4 adresu. Klient sa teda môže pripojiť na konkrétne zariadenie, alebo na celú LAN sieť za wifi routerom. Vôbec som neriešil firewall, ale v prípade zakázania, nejakých portov, služieb, IP adries sa to dá nastaviť na wg0.conf. Ak by sme potrebovali takýchto virtuálnych tunelov vytvoriť viac, tak nevidím problém použiť ten istý LXC a VPN server môžeme nazvať VPN koncentrátorom.