Kahden oletusreitin käyttö

Linux.fista
Versio hetkellä 23. maaliskuuta 2009 kello 17.58 – tehnyt 80.83.8.47 (keskustelu)
Siirry navigaatioon Siirry hakuun

Oletetaan, että halutaan saada yhdelle Linux-koneelle useampi IP-osoite siten, että nämä osoitteet ovat erillisistä aliverkoista ja niiden liikenne kulkee eri yhdyskäytävien kautta ja molempien aliverkkojen kautta on myös pääsy ulkomaailmaan.

Itse IP-osoitteen antamisessa ei ole ongelmaa, kun koneellehan saa helposti useamman IP-osoitteen käyttämällä useampaa fyysistä verkkoliityntää tai käyttämällä fyysisen verkkoliitynnän lisänä virtuaalisia verkkolaitteita eth0:1, eth0:2 jne.

Verkkokorteille voi antaa IP-osoitteita komennolla ifconfig. Esimeriksi laitetaan fyysisille verkkokorteille eth1 ja eth2 IP-osoitteet ja aliverkon peitteet:

 ifconfig eth0 192.168.1.2 netmask 255.255.255.0 up
 ifconfig eth1 172.16.1.2 netmask 255.255.255.0 up

Uudet Linux-asennukset laittavat oletuksena reititystietoihinsa reitin kummallekin aliverkolle, mutta jos se pitäisi tehdä itse, niin perinteisesti se tapahtuisi komennolla route:

 route add -net 192.168.1.0 eth0
 route add -net 172.16.1.0 eth1

Tässä vaiheessa koneella voi kommunikoida kummassakin aliverkossa olevien muiden koneiden kanssa, mutta mikäli laitteella halutaan päästä myös muualle, niin koneelle pitää kertoa myös oletusreitti. Oletetaan, että verkkoylläpito (tai operaattori) on antanut aliverkkonsa oletusyhdyskäytävän osoitteeksi xxx.xxx.xxx.1 -osoitteen. Perinteiset verkkoasetukset joskus aiemmin tehnyt tekisi luultavasti seuraavat komennot:

 route add default gw 192.168.1.1
 route add default gw 172.16.1.1

Jotta ymmärrettäisiin, miksi yllä oleva konfiguraatio ei toimi pitää ymmärtää, kuinka Linuxin reititys toimii.

Ensinnä pitää ymmärtää, kuinka verkkopeite (eng. netmask) toimii. Verkkopeitteen ymmärtää helpommin, mikäli kirjoittaa sen binaarilukuna eli 255.255.255.0 => 11111111.11111111.11111111.00000000. Tuosta näemme helposti, että maskissa on 24 ykköstä, joten verkkomaskin tarkkuus on 24, ja joissain yhteyksissä tuollainen verkkomaski ilmoitetaankin IP-osoitteen yhteydessä muodossa A.B.C.D/24.

Mikäli kohdeosoitteena olisi esimerkiksi IP-osoite 10.11.12.13, niin se binaariluvuksi kirjoitettuna on 00001010.00001011.00001100.00001101. Mikäli sitä tarkastellaan verkkomaskin /24 kanssa, niin tutkitaan ainoastaan 24 ensimmäistä bittiä, joten IP-osoitteessa oleva 13 voi olla ihan mitä tahansa ja se silti on samassa aliverkossa.

Sitten tarkastellaan kuinka IP-paketin reitti määräytyy. Ensinnä käyttöjärjestelmä järjestää reititystaulussa olevat tiedot siten, että tarkimmat reittimääreet ovat ensimmäisenä. Eli tässä tapauksessa ensimmäisenä ovat nuo aliverkkojen reitit ja niiden jälkeen reitit oletusyhdyskäytävän kautta. Reititykset näkee komennolla route:

 Kernel IP routing table
 Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
 192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
 172.16.1.0      0.0.0.0         255.255.255.0   U         0 0          0 eth1
 0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 eth0
 0.0.0.0         172.16.1.1      0.0.0.0         UG        0 0          0 eth1

Yrittäessään reitittää pakettia kohdeosoitteeseen 10.11.12.13 käyttöjärjestelmä käy tuota listaa läpi järjestyksessä. Kun löytyy ensimmäisen tieto, johon tuo IP-osoite sopii, käytetään siinä olevaa reititystietoa. Eli reitityspäätös tapahtuu seuraavasti:

  1. Ensimmäisellä rivillä maski on 255.255.255.0, joten reititettävän paketin osoite maskattuna on 10.11.12.X ja reititystiedon kohteen osoite on 192.168.1.X => Eivät ole samat.
  2. Toisella rivillä on sama maski, eikä osoite 10.11.12.X täsmää myöskään tällä rivillä olevan kohteen 172.16.1.X kanssa.
  3. Kolmannella rivillä on maskina 0.0.0.0, eli ei yhtään merkitsevää bittiä, siispä reititettävän paketin osoite on maskattuna X ja reititystiedossa olevan kohteen osoite on maskattuna myöskin X => osoitteet ovat samat, ja siis käytetään tällä rivillä määriteltyä reititystietoa eli yhdyskäytävänä käytetään laitetta 192.168.1.1, joka löytyy laitteen eth0 takaa.

Mutta entäs, jos paketin lähettäjäosoitteena olikin tuo 172.16.1.2 ja kohteena edelleenkin tuo 10.11.12.13? Sillekin reitityspäätös tehdään samalla tavalla, joten paketti päätyy eth0-laitteen takana olevalle reitittimelle 192.168.1.1, mikä on väärin, ja monissa tapauksissa tuo reititin ei edes suostu välittämään IP-osoitteen 172.16.1.2 lähettämää liikennettä. Tuo lähettäjäosoite voi vaihdella siksi, että verkkoon kommunikoiva ohjelma saattaa nimenomaan haluta käyttää sitä, tai paketti voi olla vaikkapa paluuliikennettä siihen kun joku muu kone on halunnut keskustella nimenomaan osoitteen 172.16.1.2 kanssa.

Ratkaisu

Ratkaisu ongelmaan on se, että Linuxille voi tehdä useamman reititystaulun, ja sitten liikenteen lähettäjäosoitteen perusteella valitaan, mitä taulua käytetään.

Tuo aiemmin käytetty route-käsky ei enää kelpaa, koska se käyttää aina oletustaulua eikä sille voi kertoa, että reititystieto halutaankin johonkin toiseen. Pitää käyttää uudempaa työkalua ip, johon on rakennettu myös ifconfigin ja oikeastaan lähes kaikkien muidenkin verkon konfigurointiin tarvittavien komentojen toiminnallisuus.

Ensimmäisenä voisi katsoa, että mitä reitityssääntöjä koneessa on komennolla ip rule show:

 0:      from all lookup local
 32766:  from all lookup main
 32767:  from all lookup default

Eli koneessa on siis kolme reitityssääntöä, ja aiemmin kerrottua reitityspäätösprosessia pitääkin laajentaa. Reitityspäätöstä tehdessään käyttöjärjestelmä käy ensimmäisenä läpi nuo säännöt prioriteettijärjestyksessä (rivin ensimmäinen numero).

Ensimmäisessä säännössä sanotaan, että sitä käytetään, mikäli lähettäjäosoitteena on mikä tahansa (from all), ja käytetään reititystaulua, joka on nimetty nimelle local. Mikäli siellä mikään reititystieto ei täsmännyt kokeillaan seuraavaa sääntöä.

Myös toinen sääntö pätee kaikille paketeille (from all), ja tällä kertaa katsotaan reititystaulusta, jonka nimi on main. Tämä main on se taulu, jota vanhan tyylinen route-komento muokkaa.

Kolmanteen sääntöön ei yleensä ikinä päästä, ja useimmissa tapauksissa tuossa default-reititystaulussa, ei edes ole yhtään mitään.

Voimme siis ratkaista ongelmamme tekemällä molemmille oletusreiteille oman reititystaulun. Uusia reititystauluja luodessa niille voi käyttää nimiä ainoastaan, mikäli nimet ja id-numerot on mainittuna tiedostossa /etc/iproute2/rt_tables muodossa "numero nimi", jokainen omalla rivillään. Tässä tapauksessa ei välttämättä nimi selvennä, joten käytämme id-numeroita 192 ja 172 jolloin muistanemme pelkästä numerostan minkä reitityksestä on kyse:

 ip route add 192.168.1.0/24 dev eth0 table 192
 ip route add default via 192.168.1.1 dev eth0 table 192
 ip route add 172.16.1.0/24 dev eth1 table 172
 ip route add default via 172.16.1.1 dev eth1 table 172

Reititystaulun sisällön voi katsoa komennolla

ip route show table <taulun numero>

Ja kun molemmat reititystaulut on lisätty, lisätään kummallekin reitityssääntö, jossa kerrotaan milloin tauluja pitää käyttää. Säännöt ovat yksinkertaiset, jos lähettäjänä on osoite aliverkosta 192.168.1.0/24 (from 192.168.1.0/24), niin käytetään taulua, jonka id on 192 (table 192). Ja vastaavalla tavalla toiselle aliverkolle:

 ip rule add from 192.168.1.0/24 table 192
 ip rule add from 172.16.1.0/24 table 172

Mikäli "ip rule add" -komentoon ei kerrota prioriteettia, niin sääntö menee tuolla aiemmin olevien eteen ja nyt jos katsotaan reitityssäännöt uudestaan, niin se näyttänee tältä:

 0:      from all lookup local
 32764:  from 172.16.1.0/24 lookup 172
 32765:  from 192.168.1.0/24 lookup 192
 32766:  from all lookup main
 32767:  from all lookup default

ip-komento ei laita asetuksia suoraan käyttöön, vaan asetukset pitää vielä erikseen ottaa käyttöön ennen kuin ne ihan oikeasti vaikuttavat verkkoliikenteeseen. Tämä tapahtuu komennolla ip route flush cache.

Nyt homman pitäisi toimia. Vaikka main-taulua käyttävään sääntöön ei pitäisi normaalitilanteessa joutua, kannattaa silti sinnekin jotain järkevää laittaa.

Kannattaa huomioida, että vaikka reititystiedot häviävätkin automaattisesti kun verkkoliityntä sammutetaan, jäävät reitityssäännöt kuitenkin edelleen olemaan, joten ne pitää poistaa erikseen.