Table of Contents
IPv6
Struttura di un indirizzo IPv6
L'indirizzo è lungo 128 bit, la prima metà è la parte network (di cui i primi bit indicano il tipo), la seconda metà è la parte interface. Per generare automaticamente la parte interface può essere usato una parte del MAC address, generando il cosiddetto Extended Unique Identifier (EUI-64).
Tipi di indirizzo IPv6
- global utilizzati per la connessione internet (prefisso 3)
- link-local usato da apparati connessi fisicamente ad una LAN (prefisso FE80)
- site-local per reti private (prefisso FEC0)
Per abbreviare un indirizzo IPv6 è possibile sostituire la sequenza :0:
con ::
e collassare una sequenza di due punti con solo il primo e l'ultimo.
Disabilitare IPv6
Da Debian Squeeze:
echo net.ipv6.conf.all.disable_ipv6=1 > /etc/sysctl.d/disableipv6.conf
Aggiungere e togliere un indirizzo IPv6
Per aggiungere e togliere un indirizzo IPv6 da riga di comando (non persiste al reboot):
ip -6 addr add <ipv6address>/<prefixlength> dev <interface> ip -6 addr del <ipv6address>/<prefixlength> dev <interface>
Per aggiungere e togliere una rotta IPv6:
ip -6 route add <ipv6network>/<prefixlength> via <ipv6address> [dev <device>] ip -6 route del <ipv6network>/<prefixlength> via <ipv6address> [dev <device>] ip -6 route add default via <ipv6address> [dev <device>] ip -6 route del default via <ipv6address> [dev <device>]
Configurazione automatica
La configurazione è integrata nel protocollo IPv6. La configurazione automatica viene detta stateless, cioè avviene senza il ricorso a risorse esterne.
Il kernel fornisce le seguenti interfacce per controllare la configurazione automatica, normalmente i meccanismi sono tutti attivi:
/proc/sys/net/ipv6/conf/eth0/accept_ra | Decide se usare l'autoconfigurazione, compreso il rilevamento di un router. |
---|---|
/proc/sys/net/ipv6/conf/eth0/autoconf | Se viene individuato un router, genera un indirizzo IPv6 utilizzando il MAC address. |
/proc/sys/net/ipv6/conf/eth0/use_tempaddr | Se viene individuato un router, genera un indirizzo IPv6 casuale temporaneo. |
Quindi se esiste un host che annuncia la configurazione IPv6 (ad esempio un host GNU/Linux che esegue radvd, Router Advertisement Daemon), gli host nella stessa LAN si assegnano automaticamente un indirizzo IPv6 valido (ma non il default gateway).
Per modificare uno di quei parametri creare un file /etc/sysctl.d/90-local-ipv6.conf con ad esempio:
net.ipv6.conf.eth1.accept_ra=0
Per rendere immediatamente attive le modifiche:
cat /proc/sys/net/ipv6/conf/eth1/accept_ra 1 sysctl --system cat /proc/sys/net/ipv6/conf/eth1/accept_ra 0
Configurazione manuale
Anzitutto si deve disabilitare la configurazione automatica. Con Debian è necessario forzare il caricamento del modulo kernel IPv6 aggiungendo in /etc/modules
:
# Force IPv6 preload, so that /etc/sysctl.d/local.conf will be # parsed when the protocol is already available. ipv6
e aggiungere una riga in /etc/sysctl.d/local.conf
oppure in /etc/sysctl.conf
:
net.ipv6.conf.default.autoconf=0 net.ipv6.conf.default.accept_ra=0
Il modulo ipv6 va caricato manualmente perché lo script /etc/init.d/procps.sh
(che interpreta /etc/sysctl.conf
) viene eseguito troppo presto nella fase di boot, quando ipv6 ancora non è disponibile e quindi l'impostazione non avrebbe effetto. Inoltre si deve agire su default
piuttosto che su eth0
, perché lo script viene eseguito prima che l'interfaccia sia disponibile.
Per configurare staticamente l'indirizzo IP e il default gateway si aggiunge una sezione in /etc/network/interfaces
:
auto eth0 iface eth0 inet static address 62.48.51.14 netmask 255.255.255.0 broadcast 62.48.51.255 gateway 62.48.51.1 iface eth0 inet6 static #pre-up modprobe ipv6 address 2a01:6a0:ff:59::14 netmask 64 gateway 2a01:6a0:ff:59::1
Il comando pre-up
non è necessario in questo caso, perché abbiamo fatto il preload in /etc/modules
.
Al reboot si avranno due indirizzi su eth0, uno IPv4 e uno IPv6:
eth0 Link encap:Ethernet HWaddr 00:50:FC:FF:1D:3E inet addr:62.48.51.14 Bcast:62.48.51.255 Mask:255.255.255.0 inet6 addr: fe80::250:fcff:feff:1d3e/64 Scope:Link inet6 addr: 2a01:6a0:ff:59::14/64 Scope:Global ...
Anche rotte predefinite ce ne saranno due:
ip -6 route show 2a01:6a0:ff:59::/64 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295 fe80::/64 dev eth0 proto kernel metric 256 mtu 1500 advmss 1440 hoplimit 4294967295 ff00::/8 dev eth0 metric 256 mtu 1500 advmss 1440 hoplimit 4294967295 default via 2a01:6a0:ff:59::1 dev eth0 metric 1 mtu 1500 advmss 1440 hoplimit 4294967295
route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 62.48.51.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 0.0.0.0 62.48.51.1 0.0.0.0 UG 0 0 0 eth0
Neighbors table
Con IPv6 non si ha la tabella di ARP con associazione IPv4 - MAC. Qualcosa di equivalente sono i vicini di IPv6:
ip -6 neigh show fe80::223:5ff:fe1d:3ee8 dev eth0 lladdr 00:23:05:1d:3e:e8 router DELAY 2a01:6a0:ff:59::1 dev eth0 lladdr 00:23:05:1d:3e:e8 router REACHABLE
Per dimenticare l'associazione tra indirizzo IPv6 e il MAC address (link layer address):
ip -6 neigh del fe80::223:5ff:fe1d:3ee8 lladdr 00:23:05:1d:3e:e8 dev eth0 ip -6 neigh del 2a01:6a0:ff:59::1 lladdr 00:23:05:1d:3e:e8 dev eth0
Vediamo come funziona la scoperta di un vicino di rete:
ping6 2a01:6a0:ff:59::1
tcpdump -i eth0 -t -e -n 'icmp6' 00:50:fc:ff:1d:3e > 33:33:ff:00:00:01, ethertype IPv6 (0x86dd), length 86: 2a01:6a0:ff:59::14 > ff02::1:ff00:1: ICMP6, neighbor solicitation, who has 2a01:6a0:ff:59::1, length 32 00:23:05:1d:3e:e8 > 00:50:fc:ff:1d:3e, ethertype IPv6 (0x86dd), length 86: 2a01:6a0:ff:59::1 > 2a01:6a0:ff:59::14: ICMP6, neighbor advertisement, tgt is 2a01:6a0:ff:59::1, length 32 00:50:fc:ff:1d:3e > 00:23:05:1d:3e:e8, ethertype IPv6 (0x86dd), length 118: 2a01:6a0:ff:59::14 > 2a01:6a0:ff:59::1: ICMP6, echo request, seq 1, length 64 00:23:05:1d:3e:e8 > 00:50:fc:ff:1d:3e, ethertype IPv6 (0x86dd), length 118: 2a01:6a0:ff:59::1 > 2a01:6a0:ff:59::14: ICMP6, echo reply, seq 1, length 64
Cioè:
- Viene mandato una neighbor solicitation all Solicited-node multicast address (link-local scope) con prefisso di 104 bit
ff02::1:ff00
e suffisso di 24 bit preso dall'indirizzo destinazione. - Il MAC address del destinatario è un multicast 33:33:ff:00:00:01, che dovrebbe essere registrato sull'host destinazione.
- L'host risponde con il proprio MAC address annunciando il target IPv6.
Per vedere gli indirizzi multicast registrati su un host:
ip maddr show 1: lo inet 224.0.0.1 inet6 ff02::1 2: eth0 link 33:33:ff:00:00:06 link 33:33:ff:ba:bb:ec link 01:00:5e:00:00:01 link 33:33:00:00:00:01 inet 224.0.0.1 inet6 ff02::1:ff00:6 inet6 ff02::1:ffba:bbec inet6 ff02::1
Ping per tutti gli host nel link-local scope:
ping6 ff02::1%eth0
Ping per tutti i router nel link-local scope:
ping6 ff02::2%eth0
Filtro multicast su switch
Alcuni switch hanno un filtro sui pacchetti multicast abilitato. Questo impedisce il funzionamento del protocollo Neighbor Discovery Protocol, per cui il ping6
funziona sugli host remoti, ma non su quelli locali.
Ad esempio sullo switch 3Com 4228G bisogna disabilitare il multicastFilter/igmp
.
Shorewall6: iptables con IPv6
Vedere Shorewall IPv6 Support.
Un firewall basato su iptables, come Shorewall, non ha alcun effetto sul traffico IPv6. Considerato che con IPv6 l'indirizzo assegnato ad un host ha scope global (cioè è raggiungibile da tutta internet) è chiaro che sul router/firewall è opportuno mettere alcune regole, come minimo bisogna bloccare tutto il traffico dall'esterno verso l'interno.
Con Debian è sufficiente installare il pacchetto shorewall6 che affianca il pacchetto shorewall e gestisce IPv6 in modo del tutto separato da IPv4.
L'unica verifica da fare sullo Shorewall IPv4 è che in /etc/shorewall/shorewall.conf
sia impostato:
DISABLE_IPV6=No
Copiare dagli esempi (contenuti in /usr/share/doc/shorewall6/default-config/
oppure in /usr/share/shorewall6/configfiles/
) alcuni file di configurazione, in generale servono
questi:
/etc/shorewall6/zones
fw firewall net ipv6
/etc/shorewall6/interfaces
net eth0
/etc/shorewall6/policy
fw all ACCEPT all all REJECT info
/etc/shorewall6/rules
Ping(ACCEPT) all all AllowICMPs all all ACCEPT net fw tcp ssh,smtp,domain,www,pop3,imap2,imaps,https ACCEPT net fw udp domain,openvpn ACCEPT net:<2a01:4f8:d13:c03::2> fw tcp 5432
Quindi impostare in /etc/default/shorewall6
:
startup=1
IPv6 su PPP
Alcuni provider forniscono indirizzi IPv6 sulla normale connessione ADSL. In generale funziona l'autoconfigurazione durante la negoziazione del PPPoE (PPP over Ethernet). Qui di seguito le note per la configurazione della connessione di un host basato su Debian 9 Stretch.
Configurazione manuale
Se lo stack PPP non è opportunamente configurato, è possibile procedere alla configurazione manuale dell'indirizzo IPv6 e del relativo default gateway dopo che la connessione è stabilita. È ovviamente necessario conoscere i parametri che dovrebbero essere forniti dal provider. Ecco un esempio dei comandi da eseguire:
ip -6 addr add 2a02:1970:af32:421::1/64 dev ppp0 ip -6 route add default via fe80::a64c:32fe:ac3b:9480 dev ppp0
Configurazione automatica
La configurazione standard di una connessione PPPoE con Debian prevede la creazione di una istanza in /etc/network/interfaces:
auto adsl iface adsl inet ppp provider dsl-provider
Nel file /etc/ppp/peers/dsl-provider (oltre ai normali parametri user e remotename) si aggiungere il parametro:
+ipv6
Per ottenere la configurazione automatica si sfrutta il protocollo Stateless Address Autoconfiguration SLAAC, l'interfaccia ppp deve accettare il Router Advertisements.
Il kernel di Linux espone il parametro accept_ra delle varie interfacce di rete tramite lo pseudo filesystem /proc/sys/net/ipv6/conf/. Questi sono i valori possibili:
0 | Do not accept Router Advertisements. |
---|---|
1 | Accept Router Advertisements if forwarding is disabled (default). |
2 | Overrule forwarding behaviour. Accept Router Advertisements even if forwarding is enabled. |
Il valore predefinito 1 ovviamente non va bene per un firewall che effettua il forward dei pacchetti da una LAN verso internet.
Si potrebbe impostare a 2 il valore di default con questo comando:
echo 2 > /proc/sys/net/ipv6/conf/default/accept_ra
In questo modo - quando viene attivata l'interfaccia ppp0 - si otterrebbe l'autoconfigurazione IPv6. Ma non vogliamo cambiare il valore predefinito per tutte le interfacce attivate; vogliamo una soluzione più mirata. Neanche intervenire su /etc/network/interfaces (tramite le clausole pre-up e/o up) è consigliabile, perché la tempistica con cui i comandi vengono eseguiti va in conflitto con i tempi che il kernel richiede a fare il setup dell'interfaccia.
Sembra che la soluzione migliore sia quella di creare un file /etc/ppp/ipv6-up.d/accept_ra (deve essere eseguibile) con questo contenuto:
#!/bin/sh # Accept Router Advertisements; autoconfigure using them. echo 2 > "/proc/sys/net/ipv6/conf/${PPP_IFACE}/accept_ra"
NOTA: invece di utilizzare il comando echo è possibile, in alternativa, usare il comando sysctl come in questo esempio:
sysctl -w net.ipv6.conf.ppp0.accept_ra=2
Riferimenti web
Vedere questo post: Linux, IPv6, router advertisements and forwarding, nel quale si legge:
By default, a Linux host on an IPv6 network will listen for and solicit router advertisements in order to choose an IPv6 address for itself and to set up its default route. This is referred to as stateless address autoconfiguration (SLAAC).
In this context, what makes the difference between router or not are the settings of the /proc/sys/net/ipv6/conf/*/forwarding files (or the net.ipv6.conf.*.forwarding sysctl). If you turn your host into a router by setting one of those to “1”, you may find that your host removes any IPv6 address and default route it learnt via SLAAC.