quic study

Multipath Quic

A QUIC szabvány bevezeti a Connection ID fogalmat, ami az IP cím és a port mellett, a végpontok azonosítani tudjdák egymást, hogy az adott streamhez milyen csomagok tartoznak. Ezért ha változik az IP címe egy végpontnak (mozgó végpontok esetén gyakori), továbbá is ismerni fogja a két végpont egymást, és melyik csomagok tartoztak melyik stream-hez.

Elökészítés

Első sorban, tényleges hálózat konfigurációja elég nagy igényekkel jár, különbötő számítógépek kell rendelkezésre áljanak. Egy ennél sokkal egyszerübb megolás egy emulált virtuális hálózat létrehozása, amelyik közel ugyanúgy viselkedik mint egy fizikai hálózat. Erre ad lehetőséget a Mininet alkalmazás, aminek segítségével hálózati kommunikációt emulál.

Opcionális: A Mininet Python utasításokat használ ezért Python3 segítségével könnyeben tudunk Mininet parancsokat kiadni, illetve host-okat konfigurálni (Linux környezetben már le van töltve).

Továbbá szükség lessz egy alkalmazásra ami lehetőve teszi a hálozati forgalom és a kommunikáció csomagjainak viszgálatát. Erre alkalmas a Wireshark, ráadásul a Mininet interface-ei láthatóak lesznek számára. Ha mégsem müködne, akkor a Mininet Walkthrough segítséget nyújt arra, hogy a Wireshark felismerje az általa definiált interface-eket.

Ellenörizzük, hogy ha helyessen jártunk el. Az első a Wiresharkot indítja el a háttérben, a második a Mininetet. A Minineten indítsunk el az alapértelmezett topológiát. Ekkor meg kell jelenjen Wiresharkban a virtuális hálózat interface-ei.

sudo wireshark &
sudo mn

Indítsuk el a csomagelkapásokat mind a két inteface-én az alapértelmezett topológiában (lást WSH dokumentáció). Adjuk ki a pingall parancsot mininet termináljában. Ekkor látnunk kell echo ping üzeneteket a Wireshark-ban.

A multipath teszteléséhez nem lessz elég az alapértelmezett topológia, sajátot kell létrehozni. A mininet/custom könyvtárban hozzunk létre egy úgy Python program file-t, ez lessz az új topológia (az útmutatóban ennek a neve picoquic_2sw_2host_test.py). Ebbe a következő kódot másodljuk be.

import os
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
from mininet.log import setLogLevel, info
from mininet.cli import CLI
from mininet.link import Intf
from mininet.node import Controller

class PicoquicNetworkTopo( Topo ):
    #Builds from network topology
    def build(self):
        #Adding switches
        s1 = self.addSwitch('s1')
        s2 = self.addSwitch('s2')

        #Adding hosts
        h1 = self.addHost('h1', ip='192.168.0.1/24')
        h2 = self.addHost('h2', ip='192.168.0.2/24')

        #Connecting hosts and switches
        self.addLink(s1, h1)
        self.addLink(s1, h2)
        self.addLink(s2, h1)
        self.addLink(s2, h2)

def run():
    #Bootstrap a Mininet network using the topology
    mytopo = PicoquicNetworkTopo()
    net = Mininet(topo=mytopo)

    #Run a configuration in this topology
    net.start()

    #Run multipath configuration
    net['h1'].cmd('ip addr add 192.168.1.1/24 dev h1-eth1')
    net['h1'].cmd('ip link set h1-eth1 up')
    net['h2'].cmd('ip addr add 192.168.1.2/24 dev h2-eth1')
    net['h2'].cmd('ip link set h2-eth1 up')

    CLI(net)
    net.stop()

if __name__ == '__main__':
    #This is the main
    setLogLevel('info')
    run()

topos = {'mytopo': PicoquicNetworkTopo }

A kódban láthatóan hivatkozunk egy bash file-ra. Ebben van definiálva a hostoknak a másodlagos interface-ük. Az egyik ilyen bash file tartalma a következő (config_h1.sh):

#Save connection keys to file for decryption
ip addr add 192.168.1.1/24 dev eth1
ip link set eth1 up

Hasonlóan configuráljuk a config_h2.sh file-t is.

Picoquic

A Picoquic implementációt a következő linken lehet elérni: GitHub - private-octopus/picoquic: Minimal implementation of the QUIC protocol
Itt található egy útmutató is, hogy hogy kell letölteni, illetve lefordítani a programot, illetve milyen további komponensekre van szükség.

A lemásolt repository-ban navigáljunk a picoquic könyvtárba. Ebben található egy picoquicdemo, amit lefordítva, ennek parancsait alkalmazni tudjuk ebből a könyvtárból.

Egyszerű kliens-szerver kommunikáció

Egy egyszerü kliens-szerver kapcsolatot akarunk létrehozni, majd átküldei egy csomagot a hálózaton. Látható lessz a handshake protokolra példa, illetve szemlélteti a Connection ID (CID) használatát is.

Ehhez egyenlőre elég lessz a mininet alapértelmezett topológiája, ahhol két host egy switch-en keresztül össze van kötve. Viszont, annak érdekében hogy felismerhetőek maradjanak a végpontok érdemes a mac címet rögziteni, hogy minden futtatáskor ugyanaz maradjon. Elöször indítsunk egy Wireshark-ot a csomagok elkapásához a háttérben, majd a következő parancsal indítsuk el a mininetet is.

$ sudo wireshark &
$ sudo mn --mac

Rögtön látható a létrehozott csomópontok, illetve a kapcsolatok létrehozása. Legyen a h1 a szerver csomópont, a h2 pedig a klines. Késöbb szükségünk lesz a szerver IP címére ezért érdemes a mininet segítségével lekérdezni.

mininet> h1 ifconfig
h1-eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.1  netmask 255.0.0.0  broadcast 10.255.255.255
        inet6 fe80::200:ff:fe00:1  prefixlen 64  scopeid 0x20<link>
        ether 00:00:00:00:00:01  txqueuelen 1000  (Ethernet)
        RX packets 21  bytes 2527 (2.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 7  bytes 646 (646.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

A mininet csak hálózatot emulál, a hostok nem virtuális gépen futnak, hanem egy namespace-be vannak körülkerítve, ami a gazda gépre le van vetítve (pl. ezért látható ugyanaz a command log mind a két host-on). Nyissuk meg a két host xterm-jét:

> xterm h1 h2

A h1 xterm-jén navigáljunk a picoquic állomány gyökerébe. Az első részben lévő utasítások helyes fordítása esetén a következő parancsnak müködnie kell (ha ez nincs így akkor el kell végezni újra a fordítás lépéseit).

# ./picoquicdemo -h

A szert a következő utasítással lehet elindítani.

# ./picoquicdemo -1 -w ./htmlroot -n server -p 443
  • ./picoquicdemo: A picoquic szolgáltatásait szeretnénk igénybe venni. C kód futtatását idézi elő.
  • -1: ha a szerver küldött csomagot akkor kapcsoljon ki.
  • -w ./htmlroot: itt kell keresni a szolgáltatott file-okat. Ebbe egy index.html file-t érdemes létrehozni.
  • -n server: a picoquic szemantikájában fontos nevet adni a szervernek.
  • -p 443: innen tudja a picoquic hogy szerver, illetve milyen porton kell hallgason. A QUIC szabványa szerint 443 porton a standard port QUIC forgalomra.

A klinst következő utasítással lehet elindítani:

# ./picoquicdemo -o ./received -n server 192.168.0.1 443 index.htlm
  • -o ./recieved: ide irja a kapott file-t. Mivel mind a két host le van vetítve a gazda gépre, ha nem adnánk meg -w és -o parancsokat akkor ugyaoda irja mint ahhonna olvassa a file-t, ezért nem lehetne leellenőrizni hogy eredeményes volt-e a kapcsolat.
  • 192.168.0.1 443: ennek a szervernek szeretne olvasási kérést küldeni, az adott porton (az IP cím a h1 IP címe).
  • index.html: A letöltendő file-nak a neve

Ha megnézzük a wiresharkban a kapcsolat létrejottét, illetve a csomagok elkapását, észre lehet venni, hogy títkosítva vannak ezek az adatok, nem látható a Communication ID szerinti stream forgalom. Ez abból adódik, hogy a QUIC szabvány szerint, a titkosítás nem a szállítási reteg felett van, hanem bele van ágyazva az alkalmazás retegbe. Ezért a wireshark nem tudja elkapni a titkosítás kulcsait. Ennek következtébe le kell tárolni a generált kulcsokat, és kézzel meg kell adni ezeket (segítség ehhez a folyamathoz: TLS - Wireshark Wiki). Ezért a szerver parancsát módosítani kell a következőképpen:

# SSLKEYLOGFILE=\"sslkeys.log\" ./picoquicdemo -1 -w ./htmlroot -n server -p 443

Ha a kliens oldalon a kilépés 0 arument értékkel lép ki akkor a kapcsolat sikeres volt. Ez ellenörizhető azzal is, hogy rendelkezésre áll a html file a received mappában.

Kliens-szerver kommunikácio multipath segítségével

A mininet alapértelmezett topologiája már nem lessz alkalmas a multipath mechanizmusainak tesztelésére, ezért sajátot kell defininiálni. Egy példa topológia megtalálhato a ~/mininet/custom/picoquic_test könyvtáron belül. Az itteni topológia két host-ból és két switch-ből áll ahol minden switch minden hostal össze van kötve. Továbbá megtekinthető az is, hogy a topológia definiálásán belül, a host-ok IP cimet kaptak.

A QUIC multipath lehetővé teszi hogy több úton vegyen részt a kommunikáció a két végpont között. Ez csak akkor lehetséges ha a végpontok több interface-el rendelkeznek. Ekkor a a routerek egy másik útvonalon továbbitják a forgalmat (mivel az interface-ek különböző IP címmel rendelkeznek). Ennek müködése szerint a főkapcsolat kialakulása után, a handshake során a két fél egyezteti milyen multipath képeségekkel rendelkeznek, majd ezek útan a cliens fél átad egy alternativ IP címet, amivel a szerver kezdeményezhet kapcsolatot. (további információ elérhető a QUIC Multipath Draftban)

Ennek következtében a topológia definiálása során shell parancsok segítségével bővitettük a két host-ot új interfacekkel, így a két host-hoz tartozó IP címek:

  • h1: 192.168.0.1/0 és 192.168.1.1/1 ahol a /x jelenti az interface indexét
  • h1: 192.168.0.2/0 és 192.168.1.2/1 ahol a /x jelenti az interface indexét

Az előre definiált topológia használatát az alábbi parancs mutatja be:

$ sudo mn --custom ~/mininet/custom/picoquic_test/picoquic_2sw_2host_test.py --topo=mytopo

A topológia Python segítségével van definiálva ahogy a Mininet Python API segítségével, ezért Pythonnal közvetlen futtatni lehet a mininet kódot. Akár a Minineten belül lehet futtatni python kódot a host-okon (Python 2-esben a http.server neve SimpleHTTPServer)

$ sudo python3 /home/cloud/mininet/custom/picoquic_test/picoquic_2sw_2host_test.py

A szerver oldalt a következő képpen kell felparaméterezni. A -M a multipath típusát adja meg ami lehet none(0) full(1), simple(2) vagy both(3).

# SSLKEYLOGFILE=\"sslkeys.log\" ./picoquicdemo -1 -M 2 -w ./htmlroot -n server -p 443

A kliensnél figyelni kell, hogy adjunk meg alternativ elérhetőséget is. Ezt az -A paraméterrel lehet megtenni.

./picoquicdemo -M 2 -A 192.168.0.2/1,192.168.1.2/2 -o ./received -n server 192.168.0.1 443 index.html

Habár a parancs valóban a multipath implementációt használja fel, ennek nyomát mégsem lehet látni a futtatás során. Ennek oka az, hogy az index.html file túl egyszerű, nincsennek benne több objectumok amik beolvasásához több stream-et kellene nyitni. Helyette a -B paraméterrel meg lehet adni hogy mennyi byte csomag menjen át a hálózaton. A fenti kliens parancs helyett futtasuk le a következő parancsot:

./picoquicdemo -M 2 -A 192.168.0.2/1,192.168.1.2/2 -o ./received -B 100000 -n server 192.168.0.1 443

Most már a Wireshark segítségével látható, hogy a cél és a forrás IP címek bejegyzésben megjelentek az alternatív IP címek, illetve hogy az ezen csatornák CID-jével megegyező NEW_CONNECTION csomag tartalmában, szintém megtalálhatóak.

Quiche

A Quiche a Google Implementácioja a QUIC protokollnak. A legnagyobb külömbség a picoquic-el szemben, hogy a szerver parancsok és a kliens parancsok más szemantikával rendelkeznek: a klines ./quiche-klient, a szervernek pedig ./quiche-server. Így nehezebb összekeverni a két parancs használatát.

Elökészítés

Quiche implementációrol szoló útmutató alérhető itt: GitHub - qdeconinck/quiche: 🥧 Savoury implementation of the QUIC transport protocol and HTTP/3
Mivel a Quiche Rust-ban íródott, szükség lessz Rust 1.54 (vagy későbbi) fordítora. A Github repository-t klónozzuk le, az alább megadott parancsal:

git clone --recursive https://github.com/qdeconinck/quiche.git -b multipath

A fordításhoz szüksége lessz Cargo alkalmazásra, mivel a Quiche títkosítást BoringSSL segítségével valósul meg, amit autómatikusan hozzácsatol a fórdító. A fordítás így néz ki:

cd quiche
cargo build
cargo test

Az utolsó parancs futtatja az examples könyvtárban található összes tesztet. Ha ezek sikeresen lefutnak, akkor a megoldás helyes volt.

Egyszerű kliens-szerver kapcsolat

Elöszőr probáljuk ki azt hogy hogyan néz ki a kapcsolódás a Quiche esetén. Ehhez csak minimálisan szeretnénk felparaméterezni a parancsokat hogy a kapcsolat létrejöjjön. Navigáljunk a quiche/target/debug állományba. Innen tudjuk kiadni a quiche parancsokat. Nézzük meg milyen paramétereket lehet megadni a Quiche-nek

./quiche-server --help
./quiche-kliens --help

Ezek közül az alábbi opciókat paraméterezzük fel:

ParaméterÉrtékTargetMagyarázat
--listen0.0.0.0:4433serverA szerver ezen interface-en figylje a bejövő QUIC kéréseket. Az értékkel megadjuk hogy minden interface-en figylje az adott portszám forgalmát.
--cert/home/cloud/src/bin/cert.pemserverA TLS hitelesitő file-nak az elérésí útvonala
--key/home/cloud/src/bin/key.pemserverA TLS hitelesítés során a encryption key-nek az elérési útvonala
--trust-origin-ca-pem/home/cloud/src/bin/cert.pemclientA TLS hitelesítő file-t a kliensel is egyeztetni kell. Mindig használni kell, amikor server oldalon az implicitnél külömböző hitelesítő file-t akarunk megdani.
--indexindex.htmlserverAz index file-t határozza meg. Ezt kell továbítani ennek a szervernek, ha QUIC kérésé érkezik felé.
--root.serverAz index file elérésí útvonalát lehet megadni. Az érték jelentése, hogy az index file-t a programkönyvtár gyökerébe keresse.
--multipathserver/clientA multipath szolgáltatás bekapcsolása. Implicit esetben nincs bekapcsolva.
-Amásodlagos IP címclientAz elternatív IP címet lehet megadni. Itt ténylegesen csak az alternatív kell. Nem kell index-et is hozzárendeleni.

Sajnos a letöltött repository-ban a --cert és --key default mappájában hiányoznak a hitelesítéshez szükséges file-ok. Ennek köszönhetően generálni kell ezeket a file-okat és beletenni az alapértelmezett mappába. Egy másik müködőképes lehetőség, hogy felhasználjuk a picoquic TLS hitelesítő adatait. Ha így járunk el, akkor a következőképpen lehet felparaméterezni a parancsot:

./quiche-server --listen 0.0.0.0:443 --cert /home/cloud/picoquic/certs/cert.pem --key /home/cloud/picoquic/certs/key.pem --index index.html --root .

És a kliensnek megfelelő parancsa:

./quiche-client --trust-origin-ca-pem /home/cloud/picoquic/certs/cert.pem https://192.168.0.1:443/index.html

Ha wiresharkban elemezni kívájuk a forgalmat el kell végezni úgyanazokat a lépéseket amiket a picoquic során is elvégeztünk. A szerver oldalon a parancs elé az SSLKEYLOGFILE="sslkey.log"

Ha minden helyes volt, akkor látnunk kell a clines terminálban az index.html file kiiársát. A Wireshark segítségével megnézhetjuk a forgalmat, és hogy milyen csomagok érkeztem meg az interface-en.

Kliens-szerver kapcsolat multipath használatával

A multipath funkció használatához meg kell adni, úgy a kliens mint a szerver oldalon a multipath engedélyezését. Ezt a --multipath szintaktikával tehetjük meg. Bővítsük ezzel ki a kliens és a szerver elínditásához szükséges parancsokat.

SSLKEYLOGFILE="sslkey.log" ./quiche-server --listen 0.0.0.0:443 --cert /home/cloud/picoquic/certs/cert.pem --key /home/cloud/picoquic/certs/key.pem --index index.html --root . --multipath
./quiche-client --trust-origin-ca-pem /home/cloud/picoquic/certs/cert.pem https://192.168.0.1:443/index.html --multipath -A 192.168.1.1

Hogy a mulitpath funkciót kikényszerítsük szükség lessz egy nagyobb index.html file-ra. Egy ilyen file-t lehet letölteni erről a linkről, vagy használni lehet a quiche/target/debug/examples könyvtárban levő index.html file-t. Ezt viszont már nem szeretnénk hogy kiirja a konzolra ezért a következőképpen kell megváltoztatni a parancsot.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值