====== 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 / dev
ip -6 addr del / dev
Per aggiungere e togliere una rotta IPv6:
ip -6 route add / via [dev ]
ip -6 route del / via [dev ]
ip -6 route add default via [dev ]
ip -6 route del default via [dev ]
===== 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 **[[wp>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 **[[wp>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 **[[http://www.shorewall.net/IPv6Support.html|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: **[[http://strugglers.net/~andy/blog/2011/09/04/linux-ipv6-router-advertisements-and-forwarding/|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.//