Franck Rousseau
2022-12-09T17:45:03+01:00
http://membres-liglab.imag.fr/rousseau
Franck Rousseau
Franck.Rousseau@imag.fr
Remplacer une Livebox 4 fibre Orange par un routeur Ubiquiti ER-X
2021-02-28T00:00:00+01:00
http://membres-liglab.imag.fr/rousseau/tech/2021/02/28/fibre-orange-avec-routeur-er-x
<h1 id="configurer-laccès-fibre-orange-pour-edge-router">Configurer l’accès fibre Orange pour Edge Router</h1>
<p>Ce tutoriel concerne la configuration d’un <strong>EdgeRouter X</strong> en remplacement d’une <strong>LiveBox 4</strong> pour un abonnement <strong>Sosh</strong> pour obtenir une connectivité <strong>IPv4 et IPv6</strong>.
Il se base sur de nombreux autres trouvés en ligne cités en référence en fin d’article, donc rien de bien nouveau.
Pas toujours très clairs, pas toujours adaptés, et nécessitant d’exécuter un binaire inconnu sur mon routeur, j’ai décidé de faire une compil.</p>
<h2 id="matériel">Matériel</h2>
<ul>
<li><a href="https://www.ui.com/edgemax/edgerouter-x/">EdgeRouter X</a> Ubiquiti ;</li>
<li><a href="https://www.tp-link.com/fr/business-networking/accessory/mc220l/">MC220L</a> TP-Link ;</li>
<li>module adaptateur fibre SFP fourni par Sosh, indispensable car il est reconnu côté opérateur, on ne peut donc pas le remplacer par un autre.</li>
</ul>
<p>Il semblerait que ce SFP ne soit pas compatible avec certains équipements, notamment les routeurs Ubiquiti avec slot SFP, pour les plus aventureux, il existerait une <a href="https://forum.openwrt.org/t/support-for-gpon-sfp-fgs202/42641/47?u=minhng99">modification hardware</a>.</p>
<h2 id="quelques-explications-rapides">Quelques explications rapides</h2>
<p>La configuration par DHCP Orange nécessite trois choses :</p>
<ul>
<li>de communiquer sur le <code class="language-plaintext highlighter-rouge">VLAN 832</code>, dans les exemples donnés plus loin, la connexion à Internet se fait sur <code class="language-plaintext highlighter-rouge">eth0</code>, c’est là qu’est branché le <code class="language-plaintext highlighter-rouge">MC220L</code> ;</li>
<li>une authentification <a href="https://datatracker.ietf.org/doc/html/rfc3118">RFC 3118</a> ;</li>
<li>le marquage des paquets DHCP dans la bonne classe de service (QoS) : c’est pour cela qu’on patch <code class="language-plaintext highlighter-rouge">dhclient</code>, il y a d’autres solutions comme intercaler un switch ou utiliser <code class="language-plaintext highlighter-rouge">tc</code>, mais c’est plutôt lourd ou non disponible dans EdgeOS.</li>
</ul>
<p>EdgeOS utilise <code class="language-plaintext highlighter-rouge">dhcp6c</code> comme client DHCPv6 pour configurer le préfixe délégué. Comme il nous faut le <code class="language-plaintext highlighter-rouge">dhclient</code> patché, pas possible d’utiliser la configuration standard du routeur.</p>
<p>Il faut aussi empêcher la post config par défaut de casser la config DNS quand une adresse v6 est récupérée, cela se fait en inhibant le hook dans ce cas précis en surchargeant <code class="language-plaintext highlighter-rouge">make_resolv_conf</code>, cf. <code class="language-plaintext highlighter-rouge">dhclient-ipv6-nodns-hook</code>.</p>
<h2 id="compiler-pour-le-er-x">Compiler pour le ER-X</h2>
<p>Il faut modifier le binaire <code class="language-plaintext highlighter-rouge">dhclient3</code> pour qu’il applique une priorité au trafic DHCP.
En utilisant le support fourni par WireGuard, il est assez facile de le faire soi-même.</p>
<ul>
<li>récupérer les <a href="https://www.ui.com/download/edgemax/">sources</a> <code class="language-plaintext highlighter-rouge">EdgeOS [GPL.ER-e50.v2.0.9.5346345.tar.bz2](https://dl.ui.com/firmwares/edgemax/v2.0.9/gpl/GPL.ER-e50.v2.0.9.5346345.tar.bz2)</code></li>
<li>puis <code class="language-plaintext highlighter-rouge">vyatta-dhcp3_4.1-ESV-R15-ubnt1+t5350120.dev.stretch.24c30f9.tar.gz</code></li>
<li>générer l’environnement de compilation
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>git clone git@github.com:WireGuard/wireguard-vyatta-ubnt.git
<span class="gp">$</span><span class="w"> </span>docker build <span class="nt">--pull</span> <span class="nt">-t</span> edgeos50-mipsel:latest <span class="nt">-f</span> ci/DOCKERFILE-mipsel <span class="nb">.</span>
</code></pre></div> </div>
</li>
<li>voici le <a href="/rousseau/files/code/0001-Orange-EdgeOS-dhcpd-patch.patch">patch</a> que j’ai appliqué, adapté de <a href="https://github.com/shisva/USG_Orange/blob/master/patch_dhclient3/iscdhcp_priority.patch">celui-ci</a></li>
<li>compiler le client DHCP
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>docker run <span class="nt">-it</span> <span class="nt">--rm</span> <span class="nt">--entrypoint</span> /bin/bash <span class="nt">--volume</span> /<path>/GPL.ER-e50.v2.0.9.5346345/edgeos-vyatta-dhcp:/var/src edgeos50-mipsel
<span class="gp">$</span><span class="w"> </span><span class="nb">cd</span> /var/src/
<span class="gp">$</span><span class="w"> </span>apt-get update
<span class="gp">$</span><span class="w"> </span>apt-get <span class="nb">install </span>debhelper
<span class="gp">$</span><span class="w"> </span>dpkg-buildpackage <span class="nt">-us</span> <span class="nt">-uc</span> <span class="nt">-amipsel</span>
<span class="go">** fail
</span><span class="gp">$</span><span class="w"> </span><span class="nb">cd </span>client
<span class="gp">$</span><span class="w"> </span>mipsel-linux-gnu-strip dhclient
</code></pre></div> </div>
</li>
</ul>
<h2 id="générer-les-configurations">Générer les configurations</h2>
<ul>
<li>générer la chaine d’authentification <code class="language-plaintext highlighter-rouge">rfc3118-auth</code> à partir de son identifiant Orange, exemple avec <code class="language-plaintext highlighter-rouge">fti/wwwwwww</code> :
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">echo</span> <span class="nt">-n</span> fti/wwwwwww | <span class="nb">od</span> <span class="nt">-A</span> n <span class="nt">-t</span> x1 | <span class="nb">sed</span> <span class="s1">'s/^ *//g'</span> | <span class="nb">sed</span> <span class="s1">'s/ *$//g'</span> | <span class="nb">sed</span> <span class="s1">'s/ */:/g'</span>
<span class="go">66:74:69:2f:77:77:77:77:77:77:77
</span></code></pre></div> </div>
<p>y ajouter le préfixe <code class="language-plaintext highlighter-rouge">00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d:</code></p>
</li>
<li>créer la configuration dans le routeur, par exemple via l’onglet <strong>Config Tree</strong>, sinon en ligne de commande, ne pas oublier d’activer le firewall pour IPv6, je ne mets pas les règles ici, il suffit de dupliquer celles configurées par défaut pour v4 en gros
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>interfaces {
ethernet eth0 {
description Internet
duplex auto
speed auto
vif 832 {
address dhcp
description "Orange Data fti/wwwwwww"
dhcp-options {
client-option "send vendor-class-identifier &quot;sagem&quot;;"
client-option "send user-class &quot;\053FSVDSL_livebox.Internet.softathome.Livebox4&quot;;"
client-option "send rfc3118-auth 00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d:66:74:69:2f:77:77:77:77:77:77:77;"
client-option "send dhcp-client-identifier <address MAC SFP>;" # ne semble pas utile
client-option "request subnet-mask, routers, domain-name-servers, domain-name, broadcast-address, dhcp-lease-time, dhcp-renewal-time, dhcp-rebinding-time, rfc3118-authentication, domain-search, SIP-servers, Vendor-Specific-Information;"
default-route update
default-route-distance 210
global-option "option rfc3118-auth code 90 = string;"
global-option "option SIP-servers code 120 = string;"
global-option "option Vendor-Specific-Information code 125 = string;"
name-server update
}
egress-qos "0:0 1:0 2:0 3:0 4:0 5:0 6:6 7:0"
firewall {
in {
ipv6-name WAN_IN_6
name WAN_IN
}
local {
ipv6-name WAN_LOCAL_6
name WAN_LOCAL
}
}
ipv6 {
address {
autoconf
}
dup-addr-detect-transmits 1
}
}
}
</code></pre></div> </div>
</li>
<li>copier les fichiers nécessaires sur le routeur, cf. en fin d’article
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">user@host:~$</span><span class="w"> </span>scp <span class="se">\</span>
<span class="go"> edgeos-vyatta-dhcp/client/dhclient \
dhclient-ipv6-nodns-hook \
dhclient-ipv6-pd-hook \
gandi-update-hook \
dhclient6_eth0_832.conf \
dhclient6.service \
router:/tmp
</span></code></pre></div> </div>
</li>
<li>déplacer les fichiers aux bons endroits sur le routeur
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">user@router:~$</span><span class="w"> </span><span class="nb">sudo cp</span> /tmp/dhclient /sbin/dhclient3
<span class="gp">user@router:~$</span><span class="w"> </span><span class="nb">sudo cp</span> /tmp/dhclient-ipv6-nodns-hook /etc/dhcp3/dhclient-enter-hooks.d/
<span class="gp">user@router:~$</span><span class="w"> </span><span class="nb">sudo cp</span> /tmp/dhclient-ipv6-pd-hook /etc/dhcp3/dhclient-exit-hooks.d/
<span class="gp">user@router:~$</span><span class="w"> </span><span class="nb">sudo cp</span> /tmp/gandi-update-hook /etc/dhcp3/dhclient-exit-hooks.d/
<span class="gp">user@router:~$</span><span class="w"> </span><span class="nb">sudo cp</span> /tmp/dhclient6_eth0_832.conf /etc/dhcp3
<span class="gp">user@router:~$</span><span class="w"> </span><span class="nb">sudo cp</span> /tmp/dhclient6.service /etc/systemd/system
<span class="gp">user@router:~$</span><span class="w"> </span>systemctl daemon-reload
<span class="gp">user@router:~$</span><span class="w"> </span>systemctl start dhclient6
<span class="gp">user@router:~$</span><span class="w"> </span>systemctl <span class="nb">enable </span>dhclient6
</code></pre></div> </div>
</li>
</ul>
<h2 id="références">Références</h2>
<ul>
<li><a href="https://vincent.bernat.ch/fr/blog/2019-orange-livebox-linux">https://vincent.bernat.ch/fr/blog/2019-orange-livebox-linux</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/en-cours-remplacer-sa-livebox-par-un-routeur-ubiquiti-edgemax/">https://lafibre.info/remplacer-livebox/en-cours-remplacer-sa-livebox-par-un-routeur-ubiquiti-edgemax/</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/ubiquiti-er-ipv6-dhcp6-en-2-x/">https://lafibre.info/remplacer-livebox/ubiquiti-er-ipv6-dhcp6-en-2-x/</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/tuto-edgerouter-erpro-8-pour-internet-livebox-dhcp-pour-tv-et-telephone/">https://lafibre.info/remplacer-livebox/tuto-edgerouter-erpro-8-pour-internet-livebox-dhcp-pour-tv-et-telephone/</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/clarification-remplacement-livebox-par-edgerouter/">https://lafibre.info/remplacer-livebox/clarification-remplacement-livebox-par-edgerouter/</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/ubiquiti-er-ipv6-dhcp6-en-2-x/">https://lafibre.info/remplacer-livebox/ubiquiti-er-ipv6-dhcp6-en-2-x/</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/tutot-er4-v2-0-8-ipv6-tv-et-tel-derriere-livebox/msg778389/#msg778389">https://lafibre.info/remplacer-livebox/tutot-er4-v2-0-8-ipv6-tv-et-tel-derriere-livebox/msg778389/#msg778389</a></li>
<li><a href="https://lafibre.info/remplacer-livebox/attribuer-un-prefix-ipv6-a-la-lb-derriere-un-edgerouter-x/">https://lafibre.info/remplacer-livebox/attribuer-un-prefix-ipv6-a-la-lb-derriere-un-edgerouter-x/</a></li>
</ul>
<h2 id="fichiers">Fichiers</h2>
<ul>
<li><code class="language-plaintext highlighter-rouge">dhclient-ipv6-nodns-hook</code></li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># prevent messing with DNS configs when receiving V6 PD from Orange</span>
<span class="c"># since they don't provide any v6 DNS information in their DHCPv6 reply</span>
<span class="nv">LOG_FILE</span><span class="o">=</span>/tmp/dhclient6.log
<span class="nb">echo</span> <span class="sb">`</span><span class="nb">date</span><span class="sb">`</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="nb">echo</span> <span class="s2">"entering dhclient-ipv6-nodns-hook"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">case</span> <span class="s2">"</span><span class="nv">$reason</span><span class="s2">"</span> <span class="k">in
</span>PREINIT6|BOUND6|RENEW6|REBIND6|DEPREF6|EXPIRE6|RELEASE6|STOP6<span class="p">)</span>
make_resolv_conf<span class="o">()</span> <span class="o">{</span>
<span class="nb">echo</span> <span class="s2">"*** skipping make_resolv_conf"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="o">}</span>
<span class="p">;;</span>
<span class="k">esac</span>
<span class="nb">echo</span> <span class="s2">"---"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
</code></pre></div></div>
<ul>
<li><code class="language-plaintext highlighter-rouge">dhclient-ipv6-pd-hook</code></li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># this script gets</span>
<span class="c"># $reason $interface $old_ip6_prefix $new_ip6_prefix</span>
<span class="c"># https://vincent.bernat.ch/fr/blog/2019-orange-livebox-linux</span>
<span class="nv">LOG_FILE</span><span class="o">=</span>/tmp/dhclient6.log
<span class="nv">IA_PD_IFACES</span><span class="o">=</span><span class="s2">"switch0"</span>
<span class="nb">echo</span> <span class="sb">`</span><span class="nb">date</span><span class="sb">`</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="nb">echo</span> <span class="s2">"entering dhclient-ipv6-pd-hook"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">for </span>i <span class="k">in </span>reason interface old_ip6_prefix new_ip6_prefix<span class="p">;</span> <span class="k">do
</span><span class="nb">echo</span> <span class="nv">$i</span><span class="o">=</span><span class="se">\'</span><span class="k">${</span><span class="p">!i</span><span class="k">}</span><span class="se">\'</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">done
</span>ipv6_prefix_setup<span class="o">()</span> <span class="o">{</span>
<span class="c"># If old prefix differs from new one, flush it.</span>
<span class="o">[</span> <span class="nt">-n</span> <span class="s2">"</span><span class="nv">$old_ip6_prefix</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$old_ip6_prefix</span><span class="s2">"</span> <span class="o">!=</span> <span class="s2">"</span><span class="nv">$new_ip6_prefix</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">{</span>
<span class="k">for </span>iface <span class="k">in</span> <span class="nv">$IA_PD_IFACES</span><span class="p">;</span> <span class="k">do
</span>ip <span class="nt">-6</span> addr flush dev <span class="s2">"</span><span class="nv">$iface</span><span class="s2">"</span> scope global <span class="o">||</span> <span class="se">\</span>
<span class="nb">echo</span> <span class="s2">"failed to flush global IPv6 addresses from interface </span><span class="nv">$iface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">done</span>
<span class="o">}</span>
<span class="c"># If new prefix, assign it.</span>
<span class="o">[</span> <span class="nt">-n</span> <span class="s2">"</span><span class="nv">$new_ip6_prefix</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="o">{</span>
<span class="nv">offset</span><span class="o">=</span>0
<span class="k">for </span>iface <span class="k">in</span> <span class="nv">$IA_PD_IFACES</span><span class="p">;</span> <span class="k">do
</span><span class="nv">offset</span><span class="o">=</span><span class="k">$((</span>offset <span class="o">+</span> <span class="m">1</span><span class="k">))</span> <span class="c"># should be < 10 otherwise broken IPv6 address below</span>
<span class="nv">new_ip6</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$new_ip6_prefix</span> | <span class="nb">sed</span> <span class="nt">-e</span> <span class="s2">"s@00::/56@0</span><span class="nv">$offset</span><span class="s2">::1/64@g"</span><span class="si">)</span>
<span class="nb">echo</span> <span class="s2">"setting </span><span class="nv">$new_ip6</span><span class="s2"> on </span><span class="nv">$iface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">if</span> <span class="o">!</span> ip <span class="nt">-6</span> addr show dev <span class="s2">"</span><span class="nv">$iface</span><span class="s2">"</span> | <span class="nb">grep</span> <span class="nt">-qwF</span> <span class="s2">"</span><span class="nv">$new_ip6</span><span class="s2">"</span><span class="p">;</span> <span class="k">then
</span>ip <span class="nt">-6</span> addr add <span class="s2">"</span><span class="nv">$new_ip6</span><span class="s2">"</span> dev <span class="s2">"</span><span class="nv">$iface</span><span class="s2">"</span> <span class="o">||</span> <span class="se">\</span>
<span class="nb">echo</span> <span class="s2">"failed to add new address </span><span class="nv">$new_ip6</span><span class="s2"> to interface </span><span class="nv">$iface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">else
</span><span class="nb">echo</span> <span class="s2">"address </span><span class="nv">$new_ip6</span><span class="s2"> already assigned to interface </span><span class="nv">$iface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="k">fi
done</span>
<span class="o">}</span>
ip <span class="nt">-brief</span> <span class="nt">-6</span> a show scope global <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="o">}</span>
<span class="k">case</span> <span class="s2">"</span><span class="nv">$reason</span><span class="s2">"</span> <span class="k">in
</span>BOUND6|EXPIRE6|REBIND6|REBOOT6|RENEW6<span class="p">)</span>
<span class="k">if</span> <span class="o">[</span> <span class="nt">-n</span> <span class="s2">"</span><span class="nv">$old_ip6_prefix</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="o">[</span> <span class="nt">-n</span> <span class="s2">"</span><span class="nv">$new_ip6_prefix</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
</span>ipv6_prefix_setup
<span class="k">fi</span>
<span class="c"># Handle default route</span>
<span class="k">case</span> <span class="nv">$old_ip6_prefix</span>,<span class="nv">$new_ip6_prefix</span> <span class="k">in</span>
,<span class="p">)</span> : <span class="p">;;</span>
<span class="k">*</span>,<span class="p">)</span>
<span class="nb">echo</span> <span class="s2">"remove default route for </span><span class="nv">$interface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
sysctl <span class="nt">-qw</span> net/ipv6/conf/<span class="nv">$interface</span>/accept_ra<span class="o">=</span>0
ip <span class="nt">-6</span> route del default proto ra <span class="o">||</span> <span class="nb">true
echo</span> <span class="s2">"stop RA daemon"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="p">;;</span>
<span class="k">*</span><span class="p">)</span>
<span class="nb">echo</span> <span class="s2">"request default route for </span><span class="nv">$interface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
sysctl <span class="nt">-qw</span> net/ipv6/conf/<span class="nv">$interface</span>/accept_ra<span class="o">=</span>2
rdisc6 <span class="nv">$interface</span> <span class="o">||</span> <span class="se">\</span>
<span class="nb">echo</span> <span class="s2">"cannot request default route for </span><span class="nv">$interface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
ip <span class="nt">-6</span> route list default <span class="o">>></span> <span class="nv">$LOG_FILE</span>
systemctl restart radvd.service
<span class="p">;;</span>
<span class="k">esac</span>
<span class="p">;;</span>
<span class="k">*</span><span class="p">)</span>
<span class="nb">echo</span> <span class="s2">"</span><span class="nv">$reason</span><span class="s2"> ignored for </span><span class="nv">$interface</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="p">;;</span>
<span class="k">esac</span>
<span class="nb">echo</span> <span class="s2">"---"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
</code></pre></div></div>
<ul>
<li><code class="language-plaintext highlighter-rouge">gandi-update-hook</code> : dépend évidemment du prestataire, c’est juste un exemple de mise à jour des entrées DNS sur changement d’adresse</li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># update Gandi DNS entries</span>
<span class="nv">API_KEY</span><span class="o">=</span>thisIsTheKey
<span class="nv">DOMAIN</span><span class="o">=</span>theDomain.here
<span class="nv">NAME</span><span class="o">=</span>theName
<span class="nv">LOG_FILE</span><span class="o">=</span>/tmp/dhclient6.log
<span class="nb">echo</span> <span class="sb">`</span><span class="nb">date</span><span class="sb">`</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="nb">echo</span> <span class="s2">"entering gandi-update-hook"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="nv">IPADDR</span><span class="o">=</span><span class="s2">""</span>
update<span class="o">()</span> <span class="o">{</span>
curl <span class="nt">-X</span> PUT <span class="nt">-H</span> <span class="s2">"Authorization: Apikey </span><span class="nv">$API_KEY</span><span class="s2">"</span> <span class="nt">-H</span> <span class="s2">"Content-Type: application/json"</span> <span class="nt">-d</span> <span class="s1">'{"rrset_type":"'</span><span class="nv">$FAMILY</span><span class="s1">'","rrset_ttl":1800,"rrset_name":"'</span><span class="nv">$NAME</span><span class="s1">'","rrset_href":"https://api.gandi.net/v5/livedns/domains/'</span><span class="nv">$DOMAIN</span><span class="s1">'/records/'</span><span class="nv">$NAME</span><span class="s1">'/'</span><span class="nv">$FAMILY</span><span class="s1">'","rrset_values":["'</span><span class="nv">$IPADDR</span><span class="s1">'"]}'</span> https://api.gandi.net/v5/livedns/domains/<span class="nv">$DOMAIN</span>/records/<span class="nv">$NAME</span>/<span class="nv">$FAMILY</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="nb">echo</span> <span class="nt">-e</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">updated </span><span class="nv">$IPADDR</span><span class="s2">"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
<span class="o">}</span>
<span class="k">case</span> <span class="s2">"</span><span class="nv">$reason</span><span class="s2">"</span> <span class="k">in
</span>BOUND|RENEW|REBIND|REBOOT<span class="p">)</span>
<span class="nv">FAMILY</span><span class="o">=</span>A
<span class="nv">IPADDR</span><span class="o">=</span><span class="sb">`</span>ip <span class="nt">-4</span> addr show dev eth0.832 | <span class="nb">grep</span> <span class="nt">-Po</span> <span class="s1">'inet \K[\d.]+'</span><span class="sb">`</span>
<span class="p">;;</span>
BOUND6|RENEW6|REBIND6<span class="p">)</span>
<span class="nv">FAMILY</span><span class="o">=</span>AAAA
<span class="nv">IPADDR</span><span class="o">=</span><span class="sb">`</span>ip <span class="nt">-6</span> addr show dev switch0 scope global | <span class="nb">grep</span> <span class="nt">-Po</span> <span class="nt">-m</span> 1 <span class="s1">'inet6 \K[0-9a-f:]+'</span><span class="sb">`</span>
<span class="p">;;</span>
<span class="k">esac</span>
<span class="o">[</span> x<span class="k">${</span><span class="nv">IPADDR</span><span class="k">}</span> <span class="o">=</span> x <span class="o">]</span> <span class="o">||</span> update
<span class="nb">echo</span> <span class="s2">"---"</span> <span class="o">>></span> <span class="nv">$LOG_FILE</span>
</code></pre></div></div>
<ul>
<li><code class="language-plaintext highlighter-rouge">dhclient6_eth0_832.conf</code></li>
</ul>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>option dhcp6.auth code 11 <span class="o">=</span> string<span class="p">;</span>
option dhcp6.vendorclass code 16 <span class="o">=</span> string<span class="p">;</span>
option dhcp6.userclass code 15 <span class="o">=</span> string<span class="p">;</span>
interface <span class="s2">"eth0.832"</span> <span class="o">{</span>
<span class="c"># Orange France specific options</span>
send dhcp6.vendorclass 00:00:04:0e:00:05:73:61:67:65:6d<span class="p">;</span>
send dhcp6.userclass 00:2b:46:53:56:44:53:4c:5f:6c:69:76:65:62:6f:78:2e:49:6e:74:65:72:6e:65:74:2e:73:6f:66:74:61:74:68:6f:6d:65:2e:6c:69:76:65:62:6f:78:34<span class="p">;</span>
send dhcp6.vendor-opts 00:00:05:58:00:06:00:0e:49:50:56:36:5f:52:45:51:55:45:53:54:45:44<span class="p">;</span>
<span class="c"># Authentication to Orange France DHCP server (same as ipv4)</span>
send dhcp6.auth 00:00:00:00:00:00:00:00:00:00:00:1a:09:00:00:05:58:01:03:41:01:0d:66:74:69:2f:77:77:77:77:77:77:77<span class="p">;</span>
<span class="c"># Replace xx:xx:xx:xx:xx:xx with the MAC address of your external interface</span>
send dhcp6.client-id 00:03:00:01:xx:xx:xx:xx:xx:xx<span class="p">;</span>
request dhcp6.auth, dhcp6.vendor-opts, dhcp6.name-servers, dhcp6.domain-search<span class="p">;</span>
<span class="o">}</span>
</code></pre></div></div>
<ul>
<li><code class="language-plaintext highlighter-rouge">dhclient6.service</code></li>
</ul>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[Unit]</span>
<span class="py">Description</span><span class="p">=</span><span class="s">DHCPv6 Prefix Delegation</span>
<span class="py">Wants</span><span class="p">=</span><span class="s">network.target</span>
<span class="py">Before</span><span class="p">=</span><span class="s">network.target</span>
<span class="nn">[Service]</span>
<span class="py">Type</span><span class="p">=</span><span class="s">forking</span>
<span class="py">ExecStart</span><span class="p">=</span><span class="s">/sbin/dhclient -6 -P -nw -cf /etc/dhcp3/dhclient6_eth0_832.conf -pf /var/run/dhclient6_eth0_832.pid -lf /var/run/dhclient6_eth0_832.leases eth0.832</span>
<span class="nn">[Install]</span>
<span class="py">WantedBy</span><span class="p">=</span><span class="s">multi-user.target</span>
</code></pre></div></div>
Debian Wheezy on upgraded MacMini 1,1
2014-11-13T00:00:00+01:00
http://membres-liglab.imag.fr/rousseau/tech/2014/11/13/debian-mini
<p>This post is a compilation of things that I have found to configure properly an old Intel CoreDuo <strong>MacMini 1,1</strong> that was upgraded to a <strong>MacMini 2,1</strong> with an Intel <a href="http://ark.intel.com/fr/products/27255/Intel-Core2-Duo-Processor-T7200-4M-Cache-2_00-GHz-667-MHz-FSB">Core2Duo T7200</a> processor following the <a href="http://www.xlr8yourmac.com/systems/mac_mini_core_2_duo_swaps.html">known</a> <a href="https://www.ifixit.com/Guide/Mac+mini+Model+A1176+Core+2+Duo+Processor+Replacement/1178?revisionid=HEAD">procedure</a> and a brand new <a href="http://forum.netkas.org/index.php?topic=874.0">2,1 EFI firmware</a> (which is bizarrely missing at <a href="http://support.apple.com/en-us/HT1237">Apple</a>).</p>
<p>Problem booting on USB flashdrive, I had to use a DVD. This ended up with a grub-pc BIOS install of Debian.</p>
<h2 id="references">References</h2>
<ol>
<li><a id="refind"></a><a href="http://www.rodsbooks.com/ubuntu-efi/">EFI-Booting Ubuntu on a Mac</a></li>
<li><a id="efimac"></a><a href="http://glandium.org/blog/?p=2830">Debian EFI mode boot on a Macbook Pro, without rEFIt</a></li>
<li><a id="efiboot"></a><a href="http://blogs.gnome.org/diegoe/2012/11/16/efi-mode-boot-on-macbook31-with-debian/">EFI mode boot on Macbook3,1 with Debian</a></li>
<li><a id="grubmac"></a><a href="http://mennucc1.debian.net/macbook_linux_efi.html">Booting Linux inside a MacBook using grub and EFI</a></li>
<li><a id="grub"></a><a href="https://wiki.archlinux.org/index.php/GRUB#.22No_suitable_mode_found.22_error">GRUB “No suitable mode found” error</a></li>
<li><a id="keymac"></a><a href="http://lokan.fr/2013/12/11/configurer-correctement-son-clavier-mac-sous-debian/">Configurer correctement son clavier MAC sous Debian</a></li>
</ol>
AlgoTel 2013
2013-01-02T00:00:00+01:00
http://membres-liglab.imag.fr/rousseau/announcement/2013/01/02/algotel_2013
<p>15èmes Rencontres Francophones pour les Aspects Algorithmiques des Télécommunications</p>
<p><em>28 au 31 mai, Pornic, Loire-Atlantique</em></p>
<p><a href="https://algotel2013.sciencesconf.org">AlgoTel 2013</a></p>
<p>Les <a href="https://algotel2013.sciencesconf.org/resource/page/id/2.html">dates importantes</a></p>
New site
2012-04-20T00:00:00+02:00
http://membres-liglab.imag.fr/rousseau/announcement/2012/04/20/new_site
<p>Updating my web site and moving to a <a href="https://jamstack.org/generators/">static generator</a>.</p>
<p>Might be moving to <a href="http://jekyllrb.com/">Jekyll</a>, with <a href="http://jekyllbootstrap.com/">Jekyll Bootstrap</a>
and <a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a>.
Testing the whole shebang right now, seems promising.</p>
<!--more-->
<p>Nice references that might help:</p>
<ul>
<li><a href="http://www.terminally-incoherent.com/blog/2012/01/25/building-your-first-jekyll-site-in-5-minutes/">Building your first Jekyll site in 5 minutes</a></li>
<li><a href="http://www.jacquesf.com/2011/03/creating-excerpts-in-jekyll-with-wordpress-style-more-html-comments/">Creating Excerpts in Jekyll</a></li>
</ul>
Fixing nss-mdns for IPv6 linklocal scoped addresses
2011-10-24T00:00:00+02:00
http://membres-liglab.imag.fr/rousseau/tech/2011/10/24/fixing-nss-mdns-for-ipv6-linklocal-scoped-addresses
<h2 id="the-configuration">The configuration</h2>
<p>Running <code class="language-plaintext highlighter-rouge">FreeBSD 8.2-RELEASE</code> with <code class="language-plaintext highlighter-rouge">GENERIC</code> kernel.</p>
<p>Update: still works on <code class="language-plaintext highlighter-rouge">9</code> and <code class="language-plaintext highlighter-rouge">9.1</code></p>
<p><a href="http://www.freshports.org/dns/nss_mdns/">nss_mdns</a> is a port of <a href="http://0pointer.de/lennart/projects/nss-mdns/">nss-mdns</a> for FreeBSD. It adds support for mDNS address resolution system-wide through the use of a name service switch plugin. Here is the simplest configuration:</p>
<ul>
<li>install <a href="http://avahi.org/">avahi</a> (mDNS implementation) and <a href="http://0pointer.de/lennart/projects/nss-mdns/">nss-mdns</a> using ports
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">#</span><span class="w"> </span><span class="nb">cd</span> /usr/ports/net/avahi
<span class="gp">#</span><span class="w"> </span>make <span class="nb">install</span>
<span class="gp">#</span><span class="w"> </span><span class="nb">cd</span> /usr/ports/dns/nss_mdns
<span class="gp">#</span><span class="w"> </span>make <span class="nb">install</span>
</code></pre></div> </div>
<p>and make appropriate configuration changes</p>
</li>
<li>in <code class="language-plaintext highlighter-rouge">/usr/local/etc/avahi/avahi-daemon.conf</code>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="py">use-ipv6</span><span class="p">=</span><span class="s">yes</span>
</code></pre></div> </div>
</li>
<li>in <code class="language-plaintext highlighter-rouge">/etc/rc.conf</code>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="py">dbus_enable</span><span class="p">=</span><span class="s">"YES"</span>
<span class="py">avahi_daemon_enable</span><span class="p">=</span><span class="s">"YES"</span>
</code></pre></div> </div>
</li>
<li>in <code class="language-plaintext highlighter-rouge">/etc/nsswitch.conf</code>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="err">hosts:</span> <span class="err">files</span> <span class="err">mdns</span> <span class="err">dns</span>
</code></pre></div> </div>
</li>
</ul>
<h2 id="the-problem">The problem</h2>
<p>IPv6 is configured on all interfaces and no global prefix is defined. We only have linklocal addresses.
mDNS resolution works fine, but <code class="language-plaintext highlighter-rouge">ping6</code> fails miserably, even when specifying the outgoing interface.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">bsd1#</span><span class="w"> </span><span class="nv">RES_OPTIONS</span><span class="o">=</span>inet6 getent hosts bsd2.local
<span class="go">fe80::a00:27ff:fef4:c55d bsd2.local
</span><span class="gp">bsd1#</span><span class="w"> </span>ping6 bsd2.local
<span class="go">ping6: UDP connect: Device not configured
</span><span class="gp">bsd1#</span><span class="w"> </span>ping6 <span class="nt">-I</span> em0 bsd2.local
<span class="go">ping6: UDP connect: Device not configured
</span></code></pre></div></div>
<p>This is not a routing problem, we would have <code class="language-plaintext highlighter-rouge">Network is unreachable</code> in this case, but an interface / scope id problem.</p>
<h2 id="the-bug">The bug</h2>
<p>Even option <code class="language-plaintext highlighter-rouge">-I</code> in <code class="language-plaintext highlighter-rouge">ping6</code> would not change anything. And when tracing down the scope id used, it turned out to be 673273636! Obviously, there is no such device configured. (cf. <a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/ping6/ping6.c?annotate=1.37.2.2.4.1">ping6.c:966</a> <code class="language-plaintext highlighter-rouge">src.sin6_scope_id</code> and <code class="language-plaintext highlighter-rouge">dst.sin6_scope_id</code>1)</p>
<p>The problem is in <code class="language-plaintext highlighter-rouge">bsdnss.c</code> where the address is copied in <code class="language-plaintext highlighter-rouge">sin6_addr</code> with a way to long length, <code class="language-plaintext highlighter-rouge">ai->ai_addrlen</code>, where it should be <code class="language-plaintext highlighter-rouge">sizeof(struct in6_addr)</code>.</p>
<h2 id="the-quick-fix-and-dirty-enhancement">The quick fix and dirty enhancement</h2>
<p>With this fixed, no more device not configured, but still a network unreachable. Although, using <code class="language-plaintext highlighter-rouge">ping6 -I</code> works nicely now.
But it would be great to have the scope id filled in the data structure, which is possible at low cost, since avahi returns this information, the second field in the reply below.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">bsd1#</span><span class="w"> </span>nc <span class="nt">-U</span> /var/run/avahi-daemon/socket
<span class="go">RESOLVE-HOSTNAME-IPV6 bsd2.local
+ 2 1 bsd2.local fe80::a00:27ff:fef4:c55d
</span></code></pre></div></div>
<p>A simple and dirty patch in <code class="language-plaintext highlighter-rouge">query.h</code> to add the <code class="language-plaintext highlighter-rouge">scope_id</code> to the data structure (we can do that safely, even if it is very ugly, because the buffer mallocated at <code class="language-plaintext highlighter-rouge">nss.c:307</code> is huge), <code class="language-plaintext highlighter-rouge">avahi.c</code> to fill this info, and <code class="language-plaintext highlighter-rouge">bsdnss.c</code> to fill the <code class="language-plaintext highlighter-rouge">struct sockaddr_in6</code> when we have a linklocal address, and that’s it.
Things work nicely now:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">#</span><span class="w"> </span>ping6 bsd2.local
<span class="gp">PING6(56=40+8+8 bytes) fe80::a00:27ff:fe9d:5a8f%em1 --></span><span class="w"> </span>fe80::a00:27ff:fef4:c55d%em1
<span class="go">16 bytes from fe80::a00:27ff:fef4:c55d%em1, icmp_seq=0 hlim=64 time=0.329 ms
16 bytes from fe80::a00:27ff:fef4:c55d%em1, icmp_seq=1 hlim=64 time=0.657 ms
^C
--- bsd2.local ping6 statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.329/0.493/0.657/0.164 ms
</span></code></pre></div></div>
<h2 id="the-patch">The patch</h2>
<p>This fix and enhancement were made only for the FreeBSD port, based on <code class="language-plaintext highlighter-rouge">release-0.10</code>.</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">git diff</code> on branch <a href="http://git.0pointer.net/nss-mdns.git/log/?h=tags/release-0.10"><code class="language-plaintext highlighter-rouge">release-0.10</code></a> (not needed if you use the port)</li>
<li><a href="/code/patch-src_AAA-nss-mdns-linklocal.diff">patch-src_AAA-nss-mdns-linklocal.diff</a> patch file for the FreeBSD port: this patch was made so that it can be applied before the port patches without problems (hence the stupid name)
<ul>
<li>copy this file in <code class="language-plaintext highlighter-rouge">/usr/ports/dns/nss_mdns/files</code></li>
<li><code class="language-plaintext highlighter-rouge">make install</code> (<code class="language-plaintext highlighter-rouge">deinstall</code> before if needed)</li>
</ul>
</li>
</ul>
<h2 id="references">References</h2>
<ul>
<li><a href="http://www.freebsd.org/releases/8.2R/announce.html">FreeBSD 8.2</a></li>
<li><a href="http://www.freebsd.org/doc/handbook/network-ipv6.html">IPv6</a> on FreeBSD</li>
<li><a href="http://avahi.org/">avahi</a></li>
<li><a href="http://0pointer.de/lennart/projects/nss-mdns/">nss-mdns</a></li>
<li><a href="http://www.freshports.org/dns/nss_mdns/">nss_mdns</a> port</li>
<li><a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/ping6/">ping6</a> source code</li>
<li><a href="http://www.endeavoursofanengineer.com/blog/2010/05/08/installing-avahi-on-freebsd-2/">Installing avahi on FreeBSD</a></li>
<li><a href="http://myfreebsd.homeunix.net/hints_n_kinks/local-ports.html#LOCAL-PATCHES">Local Patches and Ports</a></li>
</ul>