DHCPv6-PD na Linuxu - automatické vytváření rout

DHCPv6-PD na Linuxu - automatické vytváření rout
« kdy: 23. 09. 2016, 23:57:08 »
Zdravím všechny a prosím o radu.

Rozjíždím v jedné menší komunitní síti (cca. 800 domácností, něco po drátě většinou ale vzduchem) IPv6 a narazil jsem na problém. Používáme v síti ISC-DHCP-server jak pro IPv4 tak pro IPv6, vše funguje až na DHCPv6-PD. Server sice přiřadí prefix pro koncovou síť a zanese ho do leases, ale už nevytvoří záznam v routovací tabulce. Tím pádem nastane ta nejhorší možná situace co s IPv6 může nastat. Koncová síť dostane adresy a distribuluje je koncovým stanicím, ale odpovědi na dotazy z těchto sítí nemají kam dorazit, ztratí se ještě před CE (customer edge) routerem.

- Zastřešující routa /48 (přiděluji /56) na interface nefunguje, protože chybí adresa pro next-hop (router který prefix získal)
- Řešení na CE routrech pomocí OSPFv3, RIPng apod. zakazuje RFC 6204 a na koncových zařízeních není k dispozici (UBNT)
- Existuje upravený kód ISC-DHCP který ale není v mainline [ https://github.com/mpalmer/isc-dhcp ] ale u nás nejsou lidské zdoje na jeho udržování/portování
- Ruční vytváření rout by byla ta opravdu krajní možnost
- Ideálně aby úpravu tabulek řešil samotný DHCP server a neupravovali se na základě odposlechu jeho komunikace (ale přivítám i tyto návrhy)

Nemáte někdo zkušenosti s nějakou implementací DHCPv6-PD která by upravovala i routy v routovací tabulce kernelu? Nemusí se jednat jen o řešení pomocí ISC DHCP. Koukal jsem do dokumentací ISC Kea a Dibbleru, ale nenašel jsem o tom žádnou zmínku.

Děkuji za všechny rady a podněty.


erotel

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #1 kdy: 24. 09. 2016, 10:19:13 »
Jo tak s tím jsem taky bojoval.Navíc se mi nepodařilo v linuxu vnutit DHCP6-PD statické záznamy.Dal jsem tam mikrotik ten je s ipv6 trošku dál.V DHCP6-PD jdou definovat statické prefixy,automaticky vytvoří routu a propaguje ji přes OSPF3.Bohužel ani jeden(linux i mikrotik) zatím neumí agregace prefixů(nepřišel jsem zatím jak to obejít),takže je v routovací tabulce spoustu /56 prefixů.Z toho důvodu to dáváme lidem co si řeknou.

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #2 kdy: 24. 09. 2016, 13:32:00 »
erotel:
Agregované routy jsem na Linuxu vyřešil. Mám na každém AP /44 a pro každý interface mám /48. Tudíž mi stačilo dát na interface adresu například 2001:db8:abcd::1/48 a Bird ji přes protokol direct pošle do OSPFv3. DHCPv6-PD mám nastavený tak, že začíná až od 2001:db8:abcd:100::/56 a pokračuje do :ff00::/56. Propagaci /56 rout pak jde zakázat buďto export filtrem nebo zákazem importu z protokolu kernel. Není to zrovna nejčistší řešení, ale funguje to.

Na jednom APčku budeme zkoušet UBNT EdgeRouter Pro, tak uvidím, jak to bude fungovat. Bohužel vyměnit všechny routery v síti není moc schůdné řešení (z historických důvodů routujeme na x86). I v případě toho největšího low-endu by výměna přišla nejmíň na čtvrt mega jen na materiálu.

mrak

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #3 kdy: 24. 09. 2016, 20:20:16 »
 Tohle jsem u nas v siti taky resil, nakonec to obsluhuje bash script spousteny jako udalost v dhcp. Vyhoda je v tom, ze propagace te routy nijak nezavisi na CPE (to ostatne ma byt jen dhcpv6 clinet).

Pokud mas zajem muzu poskytnout config i script, staci napasat ;)

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #4 kdy: 24. 09. 2016, 21:12:28 »
mrak:
Pokud by si byl ochotnej se o to podělit bylo by to bezvadný. Buďto sem do fóra nebo mailem na adresu z mého profilu.

Díky :)


erotel

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #5 kdy: 25. 09. 2016, 08:15:35 »
erotel:
Agregované routy jsem na Linuxu vyřešil. Mám na každém AP /44 a pro každý interface mám /48. Tudíž mi stačilo dát na interface adresu například 2001:db8:abcd::1/48 a Bird ji přes protokol direct pošle do OSPFv3. DHCPv6-PD mám nastavený tak, že začíná až od 2001:db8:abcd:100::/56 a pokračuje do :ff00::/56. Propagaci /56 rout pak jde zakázat buďto export filtrem nebo zákazem importu z protokolu kernel. Není to zrovna nejčistší řešení, ale funguje to.

Na jednom APčku budeme zkoušet UBNT EdgeRouter Pro, tak uvidím, jak to bude fungovat. Bohužel vyměnit všechny routery v síti není moc schůdné řešení (z historických důvodů routujeme na x86). I v případě toho největšího low-endu by výměna přišla nejmíň na čtvrt mega jen na materiálu.

No my s síti máme mikrotiky,jen hlavní routery jedou na linuxu.

M.

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #6 kdy: 25. 09. 2016, 10:40:54 »
Mikrotiky (RouterOS) neumí pro IPv6 agregaci rout v OSPFv3, respektive neumí ani multiarea, to nemají doděláno.
Jinak jako DHCPv6-PD server pro koncové stanice celkem OK (pokud to nchci řídit přes Radius), včetně toho, že udělá routu na koncový router. Tady snad jen chybí, aby bylo možno vysílat IPv6 RA do interfejsu i bez přidělení spojovacího segmentu, protože některé home routery nektivují IPv6 na WAN (a nepokusí se  o získání prefixu přes DHCPv6-PD), dokud neuslyší na WANu ohlášení routeru (dělají to např Huawei krabičky na GPONu).

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #7 kdy: 25. 09. 2016, 13:53:58 »
M.:
Ono není čemu se divit. RA by se do sítě mělo vyslat v každým případě, pokud to Mikrotiky nedělají, tak je to chyba. DHCPv6-PD se má inicializovat až po RA (nezávisle na hodnotách M a O bitů).

Přidělování rozsahů přes RADIUS (framed-IPv6-prefix) mám taky v plánu, hned potom co vyřeším ten problém s routováním. Pokud by si měl nějaké vyzkoušené rady, tak je přivítám.

M.

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #8 kdy: 25. 09. 2016, 15:00:21 »
M.H.: ROS vysílá RA do sítě jen v případě, že má k propagaci piřdělen na daném interfejsu globální prefix (protože existencí globálního prefixu s příznakem advertise simuluje přímé nastavení AdvSendAdvertisements=true, které by mělo být u každého inerfejsu). Bez prefixu není ochoten vysílat RA.
A Huawei do doby, dokud neuslyší RA, tak hlásí, že IPv6 není dostupné (přitom má natvrdo nastaveno, že na WAN straně nemá nic zkoumat, natvrdo přes DHCPv6-PD má vzít prefix pro LAN a default routa míří do PPPoE tunelu). Nad GPONem to jede v PPPoE režimu, takže takto musím zbytečně obětovat jeden spojovací prefix /64 do každé PPPoE linky, aby to šlo (zcela zbytečně, home routeru stačí mít jen globální prefix na LAN straně dodaný přes DHCPv6-PD a vše funguje jak má).
Dále. Pokud provozuješ spojení ke koncákům přímo nad Ethernetem (IPoE), tak DHCPv6-PD server aktuálně v ROSu vůbec neumí s Radiuem spolupacovat. Omezená spolupráce je jen v případě PPP like spojení (PPPoE/L2TP/SSTP/PPTP/PPP). Takže pokud se používá PPPoE tak pomocí framed-IPv6-prefix jde poslat prefix, který se použije jako spojovací uvnitř PPPoE mezi mým routerem a routerme koncáka (na základě tohoto spustí ROS RA do aného spojneí), tím se nepřiděluje prefix, který má použít DHCPv6-PD server. Ten reaguje na privátní Mikrotik_Delegated_IPv6_Pool, což je jméno dopředu vytvořeného poolu na ROS straně, z kterého se vezme prefix, kerý se má posílat klientovi přes DHCPv6-PD (ideální by bla pro toto podpora normalizovného Delegated-IPv6-Prefix, který má sloužit k nastavení DHCPv6-PD serveru).
Jinak drobným podvodem by mělo jít udělat i agregace IPv6 prefixů v ROSu: použitím sumární globální routy mířící nikam, její propagce do OSPFv3 a odfiltrování pak specifických subrout od DHCPv6-PD serveru.

erotel

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #9 kdy: 26. 09. 2016, 08:54:15 »
Tak včera mi to nedalo a testnul jsem nastavení mikrotika:

Vytvořím bridge a na něj dám ipv6 xxxx:xxxx:xxxx::1/40 a přes ospfv3 ten prefix začnu propagovat.
Vytvořím pool /48 pro dhcp6-pd na daný interface.
Nakonfiguruju dhcp6-pd,ten přidělí prefix /56 a propaguje ji,ale jen v rámci routeru.

V routovací tabulce jsou prefixy /56 jen v rámci routeru,jinak jsou viditelné jen /40.


mrak

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #10 kdy: 07. 10. 2016, 13:49:30 »
mrak:
Pokud by si byl ochotnej se o to podělit bylo by to bezvadný. Buďto sem do fóra nebo mailem na adresu z mého profilu.

Díky :)

provozuju to s isc-dhcpd-4.1.1-P1 (centos6)
Ten konfig jsem az na drobne upravy nasel nekde na netu:

Kód: [Vybrat]
default-lease-time 16000;
preferred-lifetime 14400;
option dhcp-renewal-time 3600;
option dhcp-rebinding-time 7200;
allow leasequery;
option dhcp6.name-servers 2a00:ca8:0:1::20, 2a00:ca8::100;
option dhcp6.preference 255;
option dhcp6.info-refresh-time 21600;
server-duid LL;
# "\000\003\000\001\122\124\000\000\000\001";


# kod zajistujici pridani routy pri PD
option dhcp6.macaddr code 193 = string;
option dhcp6.leased-address code 194 = string;
option dhcp6.pkt code 9998 = string;
option dhcp6.leased-prefix code 9999 = string;
option dhcp6.leased-prefix-len code 9997 = string;
option dhcp6.ll-addr code 9996 = string;
option dhcp6.leased-prefix-cidr code 9995 = string;

option dhcp6.uli code 6011 = integer 32;
option dhcp6.ulo code 6010 = integer 32;

option dhcp6.macaddr = binary-to-ascii(16, 8, ":", suffix(option dhcp6.client-id, 6));

# extract the byte with U/L bit
option dhcp6.uli = substring(suffix(option dhcp6.client-id, 6), 0, 1);

# invert the U/L bit by checking the symbol in the binary string
# representation and adjusting the result accordingly
if substring(suffix(binary-to-ascii(2, 8, "", config-option dhcp6.uli), 2), 0, 1) = "1" {
  # Seems there's no minus so we gotta do subtraction by addition overflow
  option dhcp6.ulo = encode-int( extract-int(config-option dhcp6.uli, 8) + 254, 8);
} else {
  option dhcp6.ulo = encode-int( extract-int(config-option dhcp6.uli, 8) + 2, 8);
}

option dhcp6.ll-addr = concat("fe80::", binary-to-ascii(16,16, ":",
                                concat(config-option dhcp6.ulo,
                                       substring(suffix(option dhcp6.client-id, 6), 1, 2),
                                       encode-int(255, 8),
                                       encode-int(254, 8),
                                       substring(suffix(option dhcp6.client-id, 6), 3, 3))) );


#option dhcp6.leased-address = binary-to-ascii(16,16, ":", suffix(substring(option dhcp6.ia-pd, 12, 100), 16));
option dhcp6.leased-prefix = binary-to-ascii(16,16, ":", suffix(substring(option dhcp6.ia-pd, 12, 100), 16));
option dhcp6.leased-prefix-len = binary-to-ascii(10,8, ".", substring(suffix(substring(option dhcp6.ia-pd, 12, 100), 17), 0, 1));
option dhcp6.leased-prefix-cidr = concat (config-option dhcp6.leased-prefix, "/", config-option dhcp6.leased-prefix-len);

if substring(config-option dhcp6.leased-prefix, 0, 1) = "2" {
        log (info, concat ("Prefix ",config-option dhcp6.leased-prefix-cidr,
                                " leased to ", config-option dhcp6.macaddr,
                                " via ", config-option dhcp6.ll-addr ));
        execute("/bin/cmd", "dhcp6_route_add", config-option dhcp6.leased-prefix-cidr, config-option dhcp6.ll-addr);
} else {
        log (info, "No prefix leased in this packet or not REBIND");
}

subnet6 xx00:cax:a10:53a0::/64 {
        range6 xx00:cax:a10:53a0::2 2a00:ca8:a10:53a0::100;
        range6 xx00:cax:a10:53a0:: temporary;
        prefix6 xx00:cax:a10:53a1:: 2a00:ca8:a10:53a3:: /64;
}

/bin/cmd je bash script. ztezeni funkce z nej :
ziskani adresy pro nexthop a pridani do kernelu, zaroven se do souboru zapise timestamp ktery se s kazdym dhcp-pd periodickem requesu prodlouzi. Pokud neni prodlouzen, je casem smazan (cron a wipe funkce).

Kód: [Vybrat]
dhcp6_route_add() {
        local DEV VALID PREFIX NEXTHOP
        # pridani/prepsani staticke routy pro delegovane prefixy
        #logger -s "INFO: dhcp6_route_add: args: 1:$1 2:$2"
        ! [[ "$1" =~ ^[a-f0-9:/]+$ ]] && logger -s "ERR: dhcp6_route_add argument1 neni ipv6 route" && return 2
        ! [[ "$2" =~ ^[a-f0-9:]+$ ]] && logger -s "ERR: dhcp6_route_add argument2 neni ipv6 adresa" && return 4
        # TODO: persistetni uloziste?
        [ -e ${Ddhcp6pd_dir} ] || mkdir -p ${Ddhcp6pd_dir}

        # Ziskame device kde je prefix routovan pokud jsme prilis rychli, nebude host v neighbor tabulce, chvili s tim pockame
        DEV=''
        i=0
        while true ;do
                DEV=$(ip -6 nei show $2|cut -d" " -f 3)
                [ -n "$DEV" ] && break
                [ -z "$DEV" ] && [ $i -gt 10 ] && logger -s "ERR: dhcp6_route_add nebyl nalezen DEV pro $2" && exit 16
                i=$(( i + 1))
                sleep 1
        done

        # time stamp do kdy je zaznam validni
        VALID=$(( $(date +%s) + $DHCP6_PD_VALID ))
        # zalozime/doplnime soubor
        echo "$VALID $1 $2 $DEV" >${Ddhcp6pd_dir}/$DEV-${1%%/*}
        # NOTE: soubor procistujeme v dhcp6_route_check() a v pripade odebirani IPcek z rozhrani
        # pridame/zmenime zaznam
        ip -6 route replace $1 via $2 dev $DEV
        logger -s "INFO: dhcp6_route_add: pridavam route $1 via $2 dev $DEV"
}

# vycisti routy, ktere jiz expirovaly (tohle se obcas vola z cron)
dhcp6_route_wipe() {
        local F RR NOW
        NOW=$(date +%s)
        for F in $(ls -1 ${Ddhcp6pd_dir} 2>/dev/null)  ;do
                RR=( $(head -n1 ${Ddhcp6pd_dir}/$F) )
                ! [ ${#RR[*]} = 4 ] && logger -s "ERR: dhcp6_route_clean() chybny obsah souhoru: $F" && continue
                if [ ${RR[0]} -lt $NOW ] ;then
                        ip -6 route delete ${RR[1]} via ${RR[2]}
                        logger "INFO: dhcp6_route_wipe: odebiram route ${RR[1]} via ${RR[2]}"
                        /bin/rm ${Ddhcp6pd_dir}/$F
                fi
        done
}

# refreshne platne routy, pouzivame po startu systemu k obnoveni PD rout
dhcp6_route_refresh() {
        local F RR NOW
        NOW=$(date +%s)
        for F in $(ls -1 ${Ddhcp6pd_dir})  ;do
                RR=( $(head -n1 ${Ddhcp6pd_dir}/$F) )
                ! [ ${#RR[*]} = 4 ] && logger -s "ERR: dhcp6_route_refresh() chybny obsah souhoru: $F" && continue
                if [ ${RR[0]} -gt $NOW ] ;then
                        # pridame/zmenime zaznam
                        ip -6 route replace ${RR[1]} via ${RR[2]} dev ${RR[3]}
                        logger -s "INFO: dhcp6_route_refresh: route ${RR[1]} via ${RR[2]} dev ${RR[3]}"
                fi
        done
}

Uznavam ze tohle neni zrovna na prvni pohled nejjednodussi reseni, ale funguje to docela spolehlive.

mrak

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #11 kdy: 19. 10. 2016, 19:00:52 »
Kód: [Vybrat]
option dhcp6.ll-addr = concat("fe80::", binary-to-ascii(16,16, ":",
                                concat(config-option dhcp6.ulo,
                                       substring(suffix(option dhcp6.client-id, 6), 1, 2),
                                       encode-int(255, 8),
                                       encode-int(254, 8),
                                       substring(suffix(option dhcp6.client-id, 6), 3, 3))) );

Dnes jsem narazil na prvni nedostatek tohoto reseni, addresa pro nexthop se odvozuje od konce DUID. viz substring(suffix(option dhcp6.client-id, 6), 3, 3)))  a to je problem protoze nektere implementace dhcp clienta (napr na mikrotiku) muzou pouzit k tvorbe DUID jinou MAC nez je rozhrani na kterem se pak dotazuje. Jestli je to chyba nevim, kazdopadne rozbiji to tento koncept  >:(

Pro ty kterym by nevadilo ze nemaji dhcp z repozitare je resenim pouzit patch https://github.com/mpalmer/isc-dhcp/commit/4c8ae763bcf83c9068d57a5d9f570690a581b6d6 ktery pridava option obsahujici client-address vytazenou z prichoziho paketu, kde je link-local addressa vzdy ta spravna...

Hodne stesti ;-)

M.

Re:DHCPv6-PD na Linuxu - automatické vytváření rout
« Odpověď #12 kdy: 19. 10. 2016, 21:50:10 »
a to je problem protoze nektere implementace dhcp clienta (napr na mikrotiku) muzou pouzit k tvorbe DUID jinou MAC nez je rozhrani na kterem se pak dotazuje. Jestli je to chyba nevim, kazdopadne rozbiji to tento koncept  >:(

Mikrotik při tvorbě DUID vždy použije MAC adresu prvního Ethernet portu (ether1) a doplni jej IAD, což je pak index interface na kterém je DHCPv6-PD klient puštěn. Plně vyhovuje RFC specifikaci.