Bypass neufbox 6 avec NetBSD

Tags: , , , , ,
Add comments

Comme je l’expliquais dans le post précédent, je suis passé chez SFR/neuf avec un forfait fibre. La box de l’opérateur, la neufbox donc, ne supportant pas de mode bridgé, quelques opérations sont nécessaires à une intégration cohérente dans votre réseau domestique.

Je me suis grandement inspiré de cette excellente documentation pour réaliser le bypass de la neufbox, cependant plusieurs éléments du tutoriel ne sont plus d’actualité. Je ne rentrerai donc pas dans le détail théorique puisque l’article de neufbox4.org est parfaitement explicite, mais focaliserai sur les méthodes à mettre en œuvre pour faire rentrer votre neufbox dans votre réseau local.

Première chose, donner du lien à la nb6. Ceci est très simplement réalisé par un serveur DHCP, ISC DHCP dans mon cas, présent dans pkgsrc/net/isc-dhcpd. J’ai isolé la neufbox dans un VLAN dedié, untagged coté équipement, tagged sur mon switch. Cette opération n’est absolument pas nécessaire, mais j’aimais assez l’idée d’isoler l’équipement de l’opérateur. Après avoir ajouté le vlan dans la liste des interfaces gêrées par le serveur DHCP dans /etc/rc.conf:

isc_dhcpd_flags="vlan2 vlan3 vlan9"
isc_dhcpd=YES

On ajoute un subnet dédié :

subnet 192.168.9.0 netmask 255.255.255.0 {
        default-lease-time 3600;
        max-lease-time 3600;

        range 192.168.9.1 192.168.9.10;
        option routers 192.168.9.254;
        option domain-name-servers 192.168.9.254;
        # needed for sfr neufbox
        option nis-domain "ftth_axione_omniswitch";
        allow unknown-clients;
}

Et dans la foulée, on s’assure que la box aura toujours la même IP dans ce range :

host neufbox {
        hardware ethernet 34:85:14:85:52:27; # cette MAC est évidemment fausse
        fixed-address 192.168.9.1;
}

Une fois le port “fibre” (gris) de la box branché à votre switch, un redémarrage plus loin, les 3 leds vertes en façade devraient être allumées.

Si vous souhaitez accéder à l’interface de la neufbox, sachez qu’elle est accessible depuis le switch intégré (ports bleus) sur l’adresse IP 192.168.1.1. Ceci est modifiable via le lien http://192.168.1.1/network/lan (ce lien n’est pas présent dans le menu).

L’aspect moins simple de l’opération concerne la VoIP. Je vous renvoie à la section “réseau local” de l’article précedemment cité pour comprendre le pourquoi de ce qui suit, mais pour faire court, la box ne disposant pas de son IP publique SFR, il faut intercepter son traffic sortant vers l’infrastructure de l’opérateur, et modifier le contenu des requêtes envoyées afin d’y inclure notre IP publique.

J’ai réalisé ce tour de passe-passe sous NetBSD, à l’aide de pf et nginx. On redirige tout d’abord le traffic HTTP en provenance de la neufbox sur un port spécifique de l’interface loopback :

neufbox_if="vlan9"
# [...]
rdr pass on $neufbox_if proto tcp from 192.168.9.1 to any port 80 -> \
        127.0.0.1 port 89

Puis dans le fichier de configuration nginx, on ajoute un nouveau serveur muni d’une location / :

    server {
        listen 127.0.0.1:89;
        server_name foo *.neufbox.neuf.fr;

        access_log  /var/log/nginx/neufbox.access.log;
        error_log  /var/log/nginx/neufbox.error.log;

        resolver 127.0.0.1;

        location / {
                if ($args ~ "^ip_data=[^&]*&ip_voip=[^&]*&ip_tv=[^&]*&(.*)$") {
                        set $others $1;
                        set $nip "ip.publique.neuf"; # a modifier avec votre IP
                        rewrite /(.*) /$1?ip_data=$nip&ip_voip=$nip&ip_tv=$nip&$others? break;
                }
                proxy_redirect off;
                proxy_pass http://$host;
        }
    }

Merci à Adrien ze pour le coup de main sur la réécriture. En effet, alors que je bataillais sur le mécanisme de rewrite, ze a découvert que cette méthode de nginx ignore purement et simplement les arguments d’une URI, d’où la nécessité de passer par un ifqui match l’URL à modifier.

Un reboot de la neufbox et un tcpdump -A -ni bien placé devraient vous démontrer que la box est désormais capable de télécharger une foule d’informations la concernant, de mettre à jour son firmware et surtout, de s’informer sur les mécanismes SIP en place chez l’opérateur.

La box étant derrière un routeur et accédant à l’Internet à travers du NAT, il est utopique d’imaginer que la voix passera sans sourciller. Car si en effet la signalisation (SIP, donc) passe sans broncher (voyant allumé), si vous tentez de passer un coup de fil, vous ne recevrez ni tonalité, ni son, pas plus que vous n’en emmétrez, simplement parce que le RTP ne parvient pas jusqu’à la box.

Pour résoudre ce casse tête, plusieurs actions sont nécessaires. En premier lieu, l’installation de l’excellent serveur proxy SIP/RTP siproxd, disponible dans la plupart des systèmes de paquets. Sous NetBSD, il est présent dans pkgsrc-wip. Bon en fait il était pété, je l’ai réparé, je suis sur le point de le commit.
La configuration du logiciel est assez simple :

if_inbound  = vlan9 # interface neufbox
if_outbound = vlan8 # interface publique
sip_listen_port = 5060
daemonize = 1
user = nobody
rtp_port_low  = 7070
rtp_port_high = 7089
outbound_proxy_host = fixed.p-cscf.sfr.net
outbound_proxy_port = 5060

Afin d’autoriser le traffic RTP vers notre proxy sur les ports allant de 7070 à 7089, nous ajoutons à notre pf.conf :

# RTP / siproxd
pass in quick on $ext_if proto udp from any to any port 7069 <> 7090

L’adresse du proxy SIP fixed.p-cscf.sfr.net est fournie par la réponse à l’une des requêtes HTTP effectuées par la neufbox à son démarrage. Et justement, c’est cette adresse qu’il va nous falloir modifier pour que la neufbox interroge notre serveur siproxd plutot que ceux de SFR directement.

Dans de précédentes versions des neufbox, il suffisait de remplacer l’adresse du proxy SIP par celle désirée, mais la normalisation et plusieurs protocoles sont passés par là. Ainsi la box ne se contente-t-elle pas uniquement d’interroger un simple serveur SIP passé en argument mais réalise plutôt une requête DNS de type SRV à la recherche d’une entrée _sip._udp dans le sous domaine passé en paramètre. Cela se traduit par les lignes suivantes dans la zone DNS qui régit le réseau domestique :

$ORIGIN sip.mon.domaine.local.
@                       A       192.168.9.254
_sip._udp               SRV     10 1 5060       sip.mon.domaine.local.

192.168.9.254 est l’IP sur laquelle écoute le service siproxd.

On y est presque.

Il nous reste à modifier le contenu des informations renvoyées par l’infrastructure SFR afin de remplacer les entrées relatives au proxy sip par notre propre proxy. Ceci est à nouveau réalisé par le biais de nginx et en particulier du module sub_filter. Notez qu’il est possible que votre installation de nginx ne possède pas ce module par défaut, auquel cas il faudra recompiler ce dernier avec le flag --with-http_sub_module (oui je vais l’ajouter dans pkgsrc/www/nginx :). On modifie la configuration précédemment enregistrée :

        location / {
                if ($args ~ "^ip_data=[^&]*&ip_voip=[^&]*&ip_tv=[^&]*&(.*)$") {
                        set $others $1;
                        set $nip "ip.publique.sfr";
                        rewrite /(.*) /$1?ip_data=$nip&ip_voip=$nip&ip_tv=$nip&$others? break;
                }
                proxy_redirect off;
                proxy_pass http://$host;
                sub_filter fixed.p-cscf.sfr.net</proxy> sip.mon.domaine.local</proxy>;
                sub_filter_once off;
                sub_filter_types application/xml;
        }

Une fois de plus, on redémarre notre pauvre neufbox dont elle doit se demander ce qu’elle a bien pu faire dans une vie antérieure pour mériter ça… and voila !

Notez que les logs de siproxd affichaient un “can’t resolve ims.mnc010.mcc208.3gppnetwork.org “ qui est le realm utilisé pour l’authentification SIP, et que j’ai donc ajouté à mon /etc/hosts l’entrée suivante :

172.26.235.91   ims.mnc010.mcc208.3gppnetwork.org

car c’est l’adresse qui semblait être appelée par la neufbox en mode “direct”, mais je n’ai aucune certitude quand à l’exactitude de ce mapping. Le realm ne devrait de toutes façons être d’aucune utilité au proxy local, l’ajout statique de cette entrée n’a donc probablement d’intérêt que de m’éviter des Gigaoctets de logs.

Update Nicolas Sapa m’informe sur Twitter qu’il est parfaitement normal que l’adresse 3gpp ne soit pas resolue hors du GPRS roaming exchange, aussi serait-il probablement plus judicieux de la faire résoudre sur une adresse locale quelconque.

4 Responses to “Bypass neufbox 6 avec NetBSD”

  1. FRLinux Says:

    Encore une fois du bien poilu :-)

  2. Marin Says:

    Salut,

    Si ça peut t’aider pour bypasser la téléphonie sans avoir à dépendre de la Neufbox, j’ai effectué diverses captures réseau du démarrage et du fonctionnement de la Neufbox 6, et j’ai fait un article où je décris le contenu de ces captures, ainsi que la méthode utilisée : https://lafibre.info/sfr-espace-technique/captures-reseau-du-demarrage-et-fonctionnement-de-la-neufbox-6/#msg113345

  3. iMil Says:

    @Marin excellent ! C’est une sacrée analyse que tu as mené là, chapeau :)

  4. BR Says:

    La syntaxe à base de if me titille un chouilla.

    Que veut dire “[rewrite] ignore purement et simplement les arguments d’une URI” ? Par défaut, justement, rewrite ajoute à la fin de l’URI de redirection les arguments de celle d’origine, à moins qu’un “?” final soit ajouté à la redirection, comme ce que tu as fais.

    Quel est le problème d’utiliser :
    rewrite /([^?])?ip_data=[^&]&ip_voip=[^&]&ip_tv=[^&](&.)? /$1?ip_data=$nip&ip_voip=$nip&ip_tv=$nip$2? break;

    ou même (si nginx évite de répéter les arguments de l’URI d’origine dans celle de destination si ils y ont déjà été spécifiés) :

    rewrite /([^?])?ip_data=[^&]&ip_voip=[^&]&ip_tv=[^&](&.)? /$1?ip_data=$nip&ip_voip=$nip&ip_tv=$nip break;

    Merci de m’éclairer sur la nécessité d’utiliser if :o)

Leave a Reply

WP Theme & Icons based on GlossyBlue by N.Design Studio
Banner from www.trynthlas.com
Entries RSS Comments RSS Log in
Performance Optimization WordPress Plugins by W3 EDGE