Migrado de OpenVPN al WireGuard por plifirmigi retojn en unu L2-reton

Migrado de OpenVPN al WireGuard por plifirmigi retojn en unu L2-reton

Mi ŝatus kunhavigi mian sperton pri kombinado de retoj en tri geografie malproksimaj apartamentoj, ĉiu el kiuj uzas enkursigilojn kun OpenWRT kiel enirejo, en unu komunan reton. Elektinte metodon por kombini retojn inter L3 kun subreta vojigo kaj L2 kun ponto, kiam ĉiuj retaj nodoj estos en la sama subreto, oni preferas la duan metodon, kiu estas pli malfacila agordi, sed provizas pli da ŝancoj, ĉar travidebla. uzo de teknologioj estis planita en la kreita reto Wake-on-Lan kaj DLNA.

Parto 1: Fono

OpenVPN estis komence elektita kiel la protokolo por efektivigi ĉi tiun taskon, ĉar, unue, ĝi povas krei frapetan aparaton, kiu povas esti aldonita al la ponto senprobleme, kaj due, OpenVPN subtenas operacion super la TCP-protokolo, kiu ankaŭ estis grava, ĉar neniu el la apartamentoj havis dediĉitan IP-adreson, kaj mi ne povis uzi STUN, ĉar ial mia ISP blokas envenantajn UDP-konektojn de iliaj retoj, dum la TCP-protokolo permesis al mi plusendi la VPN-servilan havenon sur luita VPS uzante SSH. Jes, ĉi tiu aliro donas grandan ŝarĝon, ĉar la datumoj estas ĉifritaj dufoje, sed mi ne volis enkonduki la VPS en mian privatan reton, ĉar ankoraŭ ekzistis risko, ke triaj partioj eku kontrolon super ĝi, do havante tian. aparato en la hejma reto estis ege nedezirinda kaj estis decidite pagi por sekureco kun granda superkosto.

Por plusendi la havenon sur la enkursigilo sur kiu estis planite deploji la servilon, la programo sshtunnel estis uzata. Mi ne priskribos la komplikaĵojn de ĝia agordo - ĉi tio estas farita sufiĉe facile, mi nur rimarkas, ke ĝia tasko estis plusendi TCP-havenon 1194 de la enkursigilo al la VPS. Poste, la OpenVPN-servilo estis agordita sur la tap0-aparato, kiu estis konektita al la br-lan-ponto. Post kontroli la konekton al la nove kreita servilo de la tekkomputilo, evidentiĝis, ke la ideo de haveno plusendado pravigis sin kaj mia tekkomputilo fariĝis membro de la reto de la enkursigilo, kvankam ĝi ne estis fizike en ĝi.

La afero restis malgranda: necesis distribui IP-adresojn en malsamaj apartamentoj, por ke ili ne konfliktu kaj agordi enkursigilojn kiel OpenVPN-klientojn.
La sekvaj enkursigiloj IP-adresoj kaj DHCP-servilaj intervaloj estis elektitaj:

  • 192.168.10.1 kun gamo 192.168.10.2 - 192.168.10.80 por la servilo
  • 192.168.10.100 kun gamo 192.168.10.101 - 192.168.10.149 por enkursigilo en apartamento n-ro 2
  • 192.168.10.150 kun gamo 192.168.10.151 - 192.168.10.199 por enkursigilo en apartamento n-ro 3

Ankaŭ necesis asigni ĝuste ĉi tiujn adresojn al la klientaj enkursigiloj de la OpenVPN-servilo aldonante la linion al ĝia agordo:

ifconfig-pool-persist /etc/openvpn/ipp.txt 0

kaj aldonante la sekvajn liniojn al la /etc/openvpn/ipp.txt dosiero:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

kie flat1_id kaj flat2_id estas la aparatnomoj specifitaj dum generado de atestiloj por konektiĝi al OpenVPN

Poste, OpenVPN-klientoj estis agorditaj sur la enkursigiloj, la tap0-aparatoj sur ambaŭ estis aldonitaj al la br-lan-ponto. En ĉi tiu etapo, ĉio ŝajnis esti en ordo, ĉar ĉiuj tri retoj vidas unu la alian kaj funkcias kiel tuto. Tamen, ne tre agrabla detalo rezultis: foje aparatoj povis ricevi IP-adreson ne de sia enkursigilo, kun ĉiuj sekvaj sekvoj. Ial, la enkursigilo en unu el la apartamentoj ne havis tempon respondi al DHCPDISCOVER ĝustatempe kaj la aparato ricevis la malĝustan adreson. Mi rimarkis, ke mi bezonas filtri tiajn petojn en tap0 sur ĉiu el la enkursigiloj, sed kiel evidentiĝis, iptables ne povas funkcii kun aparato se ĝi estas parto de ponto kaj ebtables devus veni al mi savo. Je mia bedaŭro, ĝi ne estis en mia firmvaro kaj mi devis rekonstrui la bildojn por ĉiu aparato. Farante tion kaj aldonante ĉi tiujn liniojn al /etc/rc.local de ĉiu enkursigilo, la problemo estis solvita:

ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP

Ĉi tiu agordo daŭris tri jarojn.

Parto 2: Enkonduko de WireGuard

Lastatempe, Interreto ĉiam pli parolis pri WireGuard, admirante la simplecon de ĝia agordo, altan transigan rapidon, malaltan ping kun komparebla sekureco. Serĉi pliajn informojn pri ĝi evidentigis, ke nek laboro kiel ponta membro nek laboro super la TCP-protokolo estas subtenataj de ĝi, kio pensigis min, ke ankoraŭ ne ekzistas alternativoj al OpenVPN por mi. Do mi prokrastis koni WireGuard.

Antaŭ kelkaj tagoj, la novaĵo disvastiĝis per rimedoj unumaniere rilate al IT, ke WireGuard finfine estos inkluzivita en la Linukso-kerno, ekde la versio 5.6. Novaĵartikoloj, kiel ĉiam, laŭdis WireGuard. Mi denove plonĝis en la serĉon de manieroj anstataŭigi la bonan malnovan OpenVPN. Ĉi-foje mi renkontis ĉi tiu artikolo. Ĝi parolis pri kreado de Ethernet tunelo super L3 uzante GRE. Ĉi tiu artikolo donis al mi esperon. Restis neklare kion fari kun la UDP-protokolo. Serĉado kondukis min al artikoloj pri uzado de socat kune kun SSH-tunelo por plusendi UDP-havenon, tamen ili rimarkis, ke ĉi tiu aliro nur funkcias en ununura koneksa reĝimo, kio signifas, ke pluraj VPN-klientoj estus neeblaj. Mi elpensis la ideon agordi VPN-servilon sur VPS, kaj agordi GRE por klientoj, sed kiel montriĝis, GRE ne subtenas ĉifradon, kio kondukos al tio, ke se triaj akiros aliron al la servilo, la tuta trafiko inter miaj retoj estas en iliaj manoj, kio tute ne konvenis al mi.

Denove, la decido estis farita en favoro de redunda ĉifrado, uzante VPN super VPN laŭ la sekva skemo:

Tavolo XNUMX VPN:
VPS Estas servilo kun interna adreso 192.168.30.1
MS Estas kliento VPS kun interna adreso 192.168.30.2
MK2 Estas kliento VPS kun interna adreso 192.168.30.3
MK3 Estas kliento VPS kun interna adreso 192.168.30.4

Tavolo XNUMX VPN:
MS Estas servilo kun ekstera adreso 192.168.30.2 kaj interna 192.168.31.1
MK2 Estas kliento MS kun la adreso 192.168.30.2 kaj havas internan IP de 192.168.31.2
MK3 Estas kliento MS kun la adreso 192.168.30.2 kaj havas internan IP de 192.168.31.3

* MS - enkursigilo-servilo en apartamento 1, MK2 - router en apartamento 2, MK3 - router en apartamento 3
* Aparataj agordoj estas publikigitaj en la spoiler ĉe la fino de la artikolo.

Kaj do, pings inter la nodoj de la reto 192.168.31.0/24 iru, estas tempo pluiri al agordo de la GRE-tunelo. Antaŭ tio, por ne perdi aliron al enkursigiloj, indas agordi SSH-tunelojn por plusendi la havenon 22 al la VPS, tiel ke, ekzemple, enkursigilo de la apartamento 10022 estos disponebla ĉe la haveno 2 de la VPS, kaj router de apartamento 11122 estos disponebla sur haveno 3 de la VPS. router de apartamento XNUMX. Plej bone estas agordi la plusendon per la sama sshtunnel, ĉar ĝi restarigos la tunelon se ĝi falos.

La tunelo estas agordita, vi povas konekti al SSH per la plusendita haveno:

ssh root@МОЙ_VPS -p 10022

Poste, malŝaltu OpenVPN:

/etc/init.d/openvpn stop

Nun ni agordu GRE-tunelon sur la enkursigilo de apartamento 2:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set grelan0 up

Kaj aldonu la kreitan interfacon al la ponto:

brctl addif br-lan grelan0

Ni faru similan proceduron sur la servila enkursigilo:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set grelan0 up

Kaj ankaŭ aldonu la kreitan interfacon al la ponto:

brctl addif br-lan grelan0

ekde ĉi tiu momento, pingoj komencas sukcese iri al la nova reto kaj mi, kontente, iras trinki kafon. Poste, por vidi kiel funkcias la reto ĉe la alia fino de la drato, mi provas SSH en unu el la komputiloj en la apartamento 2, sed la ssh-kliento frostas sen peti min pri pasvorto. Mi provas konektiĝi al ĉi tiu komputilo per telnet ĉe la haveno 22 kaj vidas linion, el kiu vi povas kompreni, ke la konekto estas establita, la SSH-servilo respondas, sed ial ĝi ne proponas al mi eniri.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Mi provas konekti al ĝi per VNC kaj mi vidas nigran ekranon. Mi konvinkas min, ke la afero estas en la fora komputilo, ĉar mi povas facile konektiĝi al la enkursigilo de ĉi tiu apartamento per la interna adreso. Tamen, mi decidas SSH en ĉi tiun komputilon per la enkursigilo kaj mi surprizas konstati, ke la konekto sukcesas kaj la fora komputilo funkcias bone, sed ankaŭ ne sukcesas konekti al mia komputilo.

Mi elprenas la grelan0-aparaton el la ponto kaj lanĉas OpenVPN sur la enkursigilo en la apartamento 2 kaj certigas, ke la reto funkcias ĝuste denove kaj ke konektoj ne falas. Serĉante mi trovas forumojn, kie homoj plendas pri la samaj problemoj, kie oni konsilas al ili altigi la MTU. Ne pli frue dirite ol farite. Tamen, ĝis la MTU estis fiksita al sufiĉe granda valoro de 7000 por gretap-aparatoj, aŭ faligitaj TCP-ligoj aŭ malrapidaj dissendoj estis observitaj. Pro la alta MTU por gretap, la MTU por WireGuard-ligoj de la unua kaj dua niveloj estis fiksitaj al 8000 kaj 7500, respektive.

Mi faris similan aranĝon ĉe la enkursigilo de apartamento 3, kun la nura diferenco, ke dua gretap-interfaco nomita grelan1 estis aldonita al la servila enkursigilo, kiu ankaŭ estis aldonita al la br-lan-ponto.

Ĉio funkcias. Nun vi povas meti la gretap-asembleon en aŭtomatan ŝarĝon. Por ĉi tio:

Metu ĉi tiujn liniojn en /etc/rc.local sur la enkursigilon en apartamento 2:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

Aldonis ĉi tion al /etc/rc.local sur la enkursigilo en apartamento 3:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

Kaj sur la servila enkursigilo:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

ip link add grelan1 type gretap remote 192.168.31.3 local 192.168.31.1
ip link set dev grelan1 mtu 7000
ip link set grelan1 up
brctl addif br-lan grelan1

Post restartigi la klientajn enkursigilojn, mi trovis, ke ial ili ne konektiĝis al la servilo. Konektante al ilia SSH (feliĉe, mi antaŭe agordis sshtunnel por ĉi tio), oni malkovris, ke WireGuard ial kreas itineron por la finpunkto, estante malĝusta. Do, por 192.168.30.2, la itinertabelo estis specifita en la itinertabelo tra la pppoe-wan interfaco, tio estas, tra la Interreto, kvankam la itinero al ĝi devus esti direktita tra la wg0 interfaco. Post forigo de ĉi tiu itinero, la konekto estis restarigita. Mi ne povis trovi instrukciojn ie ajn pri kiel devigi WireGuard ne krei ĉi tiujn itinerojn. Cetere, mi eĉ ne komprenis ĉu ĉi tio estas trajto de OpenWRT, aŭ de WireGuard mem. Sen devi trakti ĉi tiun problemon dum longa tempo, mi simple aldonis al ambaŭ enkursigiloj en skripto ripetita de tempigilo, linion kiu forigis ĉi tiun itineron:

route del 192.168.30.2

Supre

Mi ankoraŭ ne atingis kompletan malakcepton de OpenVPN, ĉar mi foje bezonas konektiĝi al nova reto de tekkomputilo aŭ telefono, kaj instali gretap-aparaton sur ili ĝenerale estas neeble, sed malgraŭ tio, mi ricevis avantaĝon en transdono de datumoj. rapideco inter apartamentoj kaj, ekzemple, uzi VNC ne plu estas maloportuna. Ping malpliiĝis iomete, sed iĝis pli stabila:

Kiam vi uzas OpenVPN:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=133 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=125 ms

--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19006ms
rtt min/avg/max/mdev = 124.722/126.152/136.907/3.065 ms

Kiam vi uzas WireGuard:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=124 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=124 ms
--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19003ms
rtt min/avg/max/mdev = 123.954/124.423/126.708/0.675 ms

Ĝi estas plejparte tuŝita de alta ping al VPS kiu estas proksimume 61.5ms

Tamen, la rapideco pliiĝis signife. Do, en apartamento kun enkursigilo-servilo, mi havas interretan konekton rapidon de 30 Mbps, kaj en aliaj apartamentoj, 5 Mbps. Samtempe, dum uzado de OpenVPN, mi ne povis atingi transdonon de datumoj inter retoj de pli ol 3,8 Mbps laŭ iperf, dum WireGuard "pumpis" ĝin ĝis la samaj 5 Mbps.

WireGuard-agordo sur VPS[Interface] Address = 192.168.30.1/24
ListenPort = 51820
PrivateKey = <ЗАКРЫТЫЙ_КЛЮЧ_ДЛЯ_VPS>

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_1_МС>
AllowedIPs = 192.168.30.2/32

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2>
AllowedIPs = 192.168.30.3/32

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3>
AllowedIPs = 192.168.30.4/32

WireGuard-agordo sur MS (aldonita al /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.2/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МС'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - сервер
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option listen_port '51821'
        list addresses '192.168.31.1/24'
        option auto '1'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list allowed_ips '192.168.31.2'

config wireguard_wg1ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3

        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list allowed_ips '192.168.31.3'

WireGuard-agordo sur MK2 (aldonita al /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.3/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК2'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list addresses '192.168.31.2/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

WireGuard-agordo sur MK3 (aldonita al /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.4/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК3'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list addresses '192.168.31.3/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

En la priskribitaj agordoj por la duanivela VPN, mi specifas la havenon 51821 al WireGuard-klientoj.En teorio, tio ne estas necesa, ĉar la kliento establos konekton de iu senpaga ne-privilegia haveno, sed mi faris ĝin tiel, ke ĉiuj envenantaj konektoj. povas esti rifuzita sur la wg0-interfacoj de ĉiuj enkursigiloj, krom alvenantaj UDP-konektoj sur haveno 51821.

Mi esperas, ke la artikolo estos utila al iu.

PS Ankaŭ mi volas kunhavigi mian skripton, kiu sendas al mi PUSH-sciigon al mia telefono en la aplikaĵo WirePusher kiam nova aparato aperas en mia reto. Jen ligo al la skripto: github.com/r0ck3r/device_discover.

UPDATE: OpenVPN-servilo kaj agordo de klientoj

OpenVPN-servilo

client-to-client

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/vpn-server.crt
dh /etc/openvpn/server/dh.pem
key /etc/openvpn/server/vpn-server.key

dev tap
ifconfig-pool-persist /etc/openvpn/ipp.txt 0
keepalive 10 60
proto tcp4
server-bridge 192.168.10.1 255.255.255.0 192.168.10.80 192.168.10.254
status /var/log/openvpn-status.log
verb 3
comp-lzo

OpenVPN-kliento

client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Change to your router's External IP
resolv-retry infinite
nobind

ca client/ca.crt
cert client/client.crt
key client/client.key
dh client/dh.pem

comp-lzo
persist-tun
persist-key
verb 3

Mi uzis easy-rsa por generi atestojn.

fonto: www.habr.com

Aldoni komenton