La Fibre

Datacenter et équipements réseaux => Routeurs => SFR Remplacer la box SFR par un routeur => Discussion démarrée par: luke_2016 le 04 juin 2019 à 14:14:18

Titre: FFTH - bypass complet de la NB6 avec pfSense (Netgate SG3100) Part 1
Posté par: luke_2016 le 04 juin 2019 à 14:14:18
Bonjour,

Après avoir glaner des informations un peu partout sur le net et beaucoup dans ce forum, voici ma méthode avec pfSense.

1. Objectif et cible:

Pour cela j’ai mis en œuvre la solution suivante :

Voici le schéma de mon réseau : Reseau.png
(http://Réseau.png)

2.Préambule
Avant de commencer le bypass de votre neufbox, je vous conseille de faire une capture réseau du démarrage de votre neufbox. Cela vous permettra de récupérer les informations suivantes :

on y va....

3.Configuration des interfaces de pfSense
    3.1.Interface WAN

Il va falloir leurrer SFR en utilisant le DUID- Link Layer de la neufbox sur notre pfSense. Pour cela :

Aller dans le menu « System » -> « Advanced », et sur l’onglet « Networking » ajouter:

Pour l'adresse IPv4 :
Il faut configurer l’interface WAN en Dhcp client ipv4 avec les informations suivantes :

Pour l'adresse IPv6 :
Tout d'abord il faut changer le binaire Dhcp client standard de pfSense avec une recompilation pour arm64, prenant en compte le raw-option. En effet la version de mon dhcp6c ne gère pas le raw-option.

Cette opération peut paraitre compliquée, mais il suffit de récupérer les sources du dhcp6c de OpnSense et de recompiler le source pour votre architecture. En ce qui me concerne c'est du ARM64.

Il existe des compilations de ce source pour x86 sur le net.

Une fois compilé, il faut le placer sur le pfsense (faites une sauvegarde de l'original avant) dans le répertoire : /usr/local/sbin.

Ceci fait, configurez l’interface WAN en Dhcpv6 avec les informations suivantes:

Le contenu du fichier de configuration :
Mes interfaces physiques ont les noms suivants :
WAN:  mvneta2
LAN:   mvneta1
OPT1: mvneta0

fichier: dhcp6c_wan_new.conf
#config for SFR
interface mvneta2 {
send raw-option 16 00:00:a0:0c:00:34:<code hexa de la chaine du Vendor class Identifier>;
send ia-pd 1;
request domain-name-servers;
script "/var/etc/dhcp6c_wan_script.sh";
};
id-assoc pd 1{
prefix ::/00 0 0;
prefix-interface mvneta1{
sla-id 1;
sla-len 8;
};
prefix-interface mvneta0{
sla-id 2;
sla-len 8;
};
};

Ceci petit fichier permet d'envoyer l'option 16 (Vendor class identifier) via le send raw-option.
De définir les Prefix à obtenir.

La partie prefix-interface permet de définir plusieurs préfix, qui seront utilisés par les interfaces LAN et OPT1.
Pour LAN on positionne l'ID à 1 et on prend un prefix de 56 (64-56 = 8 )
Pour OPT1 on positionne l'ID à 2 et onprend un prefix de 56 (64-56 = 8 )

Voilà terminé pour l'interface WAN.

3.2.Interface LAN
IPv4 :
Configurez l'interface avec une adresse IPv4 statique : 192.168.5.1 (pour moi)

IPv6:
Configurez l'interface avec le protocole : Track Interface. (Cela permettra de récupérer le Prefix sur cette interface.)
IPv6 Interface : WAN
IPv6 Prefix ID : 1

3.3.Interface OPT1
IPv4 :
Configurez l'interface avec une adresse IPv4 statique : 192.168.50.1 (pour moi)

IPv6:
Configurez l'interface avec le protocole : Track Interface. (Cela permettra de récupérer le Prefix sur cette interface.)
IPv6 Interface : WAN
IPv6 Prefix ID : 2

4.Configuration des serveurs Dhcp et Dhcpv6 de pfSense

4.1.Pour l'interface LAN

Si vous en avez besoin sur cette interface (ce qui est mon cas), la configuration est simple:

DHCP IPv4: Allez dans "Services"->"DHCP server", sélectionner l'interface "LAN" et entrez les paramètres suivants (changer à votre convenance):

DHCP IPv6: Allez dans "Services"->"DHCPv6 Server & RA", sélectionner l'interface "LAN" et entrez les paramètres suivants (changer à votre convenance):

4.2.Pour l'interface OPT1

DHCP IPv4: Allez dans "Services"->"DHCP server", sélectionner l'interface "OPT1" et entrez les paramètres suivants (changer à votre convenance):
Créer un mapping statique pour la neufbox: Pour moi ce sera 192.168.50.203

DHCP IPv6: Allez dans "Services"->"DHCPv6 Server & RA", sélectionner l'interface "OPT1" et entrez les paramètres suivants (changer à votre convenance):
Ici mon prefix est un fake, mais le concept est le suivant: je reçois un /56: 1234:1234:1234:56/56, je crée un range pour un seul préfix en /60: 1234:1234:1234:5620/60

Sélectionnez l'onglet "Router Advertisements", et entrez les paramètres suivants:

5.Faire croire à la neufbox qu'elle est connectée à internet.
Pour faire croire à la neufbox qu’elle est connectée à internet, il suffit de :
Pour utiliser le Téléphone:
Dans mon cas je n’ai pas besoin du téléphone, je n’ai pas tester la téléphonie avec cette configuration, mais avec cette configuration la neufbox voit bien une configuration téléphone correcte. Vous trouverez ma configuration dans la section suivante "Configuration Téléphonie pour la neufbox".

Pour utiliser la télévision avec le STB évolution:
La télévision fonctionne avec l’IGMP. La configuration est récupérée via un fichier xml. Il faudra mettre en œuvre l’igmp proxy sur le pfSense et quelques règles de firewall. Ceci est assez simple. Voir la section suivante "Configuration Télévision pour la neufbox".

Pour utiliser la VOD:
Tout d’abord, il est à noter que j’ai encore quelques petits soucis. Les détails dans le section "Configuration VOD pour la neufbox".

Ici c’est un petit plus compliqué. En fait la neufbox récupère aussi la configuration de la VOD via un fichier xml. Le STB évolution, lui se configure en faisant appel à l’API neufbox sur l’adresse IP 192.168.1.1.

Le STB utilise le protocole RTSP (Real Time Streaming Protocol) pour récupérer les informations de la VOD, via les messages DESCRIBE et SETUP. Le serveur de VOD répond alors avec la configuration du flux vidéo : en général UDP unicast.

Le problème est que le flux vidéo UDP est initié par le serveur indépendamment du protocole RTSP. Donc il va donc falloir rediriger ce flux vers la Neufbox. Cette dernière se débrouillera pour le fournir au STB. Voir le section suivante "Configuration VOD pour la neufbox".

5.1.Configuration Internet pour la neufbox
Il faut Intercepter les requêtes HTTP GET qu'èmet la neufbox vers les serveurs neufbox:

Tout d’abord dans votre capture réseau vous devriez voir les requêtes http GET. Voici la liste des fichiers avec les hostname appelés et les paramètre qu'il va falloir changer :

fichier general.xml:
fichier firmware2.xml:
fichier voip2.xml:
fichier cfgnbXchilli_201709081500.xml:
fichier cfgnb4tvservices_201702141200.xml:
fichier cfgnbXca_201506231500.xml:
fichier wanservices2.xml:
Ma solution pour intercepter les requêtes :

Suite au prochain post....
Titre: FFTH - bypass complet de la NB6 avec pfSense (Netgate SG3100) Part 2
Posté par: luke_2016 le 04 juin 2019 à 14:36:33
Voici la partie 2:

J'ai créé un Alias pour la Neufbox: NB6_box_50

La règle de NAT Port Forward:
interface: OPT1Redirect target IP127.0.0.1
protocol: TCP/UDPRedirect target Port89
Source: NB6_box_50DescriptionRedirect to local nginx changing ip_dhcp
Source Port Range: AnyNAT ReflexionDisabled
Destination: invert Match, OPT1 AddressFilter Rule associationRule NAT Redirect to local nginx changing ip_dhcp
Destination Port RangeHTTP
[



Le serveur Nginx:
Nginx est déjà présent sur pfSense 2.4.4, il suffit de créé une nouvelle instance qui sera démarrée par un petit script (point suivant) au démarrage du pfSense.

Configuration du serveur Nginx:
Fichier de configuration: /usr/local/etc/nginx/my_nginx.conf
fichier my_nginx.conf
#user  nobody;
worker_processes  1;

pid /var/run/my_nginx.pid;

load_module /usr/local/libexec/nginx/ndk_http_module.so;
load_module /usr/local/libexec/nginx/ngx_http_lua_module.so;

# This default error log path is compiled-in to make sure configuration parsing
# errors are logged somewhere, especially during unattended boot when stderr
# isn't normally logged anywhere. This path will be touched on every nginx
# start regardless of error log location configured here. See
# https://trac.nginx.org/nginx/ticket/147 for more info.
#
error_log  /usr/local/my_nginx/logs/system_error.log;
#

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /usr/local/my_nginx/logs/global_access.log  main;
    error_log   /usr/local/my_nginx/logs/global_error.log;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
include /usr/local/my_nginx/mvneta2_ip;

        listen       89;
        server_name  localhost;

        #charset koi8-r;

        access_log  /usr/local/my_nginx/logs/other_access.log  main;
   error_log   /usr/local/my_nginx/logs/other_error.log;

rewrite_log on;

root /usr/local/my_nginx/www;

        location / {
    resolver <your DNS>;
    add_header X-debug-message "other-site" always;
    proxy_pass http://$http_host$uri$is_args$args;
}
    }


    server {
include /usr/local/my_nginx/mvneta2_ip;

listen 89;
server_name *.neufbox.sfr.net;

access_log /usr/local/my_nginx/logs/neufbox_access.log main;
error_log  /usr/local/my_nginx/logs/neufbox_error.log;

root /usr/local/my_nginx/www;

location / {
    set $xdebug_ip_dhcp "no";
    set $xdebug_new_uri_ip "";
    set $xdebug_old_uri_ip "";
   
    if ($arg_ip_dhcp != "") {
access_by_lua_block {
    local args, err = ngx.req.get_uri_args()
    local wan_ip = ngx.var.xdebug_wan_ip
    ngx.var.xdebug_old_uri_ip = args.ip_dhcp
    args.ip_dhcp = wan_ip
    ngx.var.xdebug_new_uri_ip = wan_ip
            ngx.req.set_uri_args(args)
}
set $xdebug_ip_dhcp "yes";
    }
    add_header X-debug-message "ip_dhcp present: $xdebug_ip_dhcp, old ip_dhcp: $xdebug_old_uri_ip, new ip_dhcp: $xdebug_new_uri_ip" always;
    proxy_set_header Accept-Encoding "";
    resolver <your DNS> ipv6=off;
    proxy_pass http://$http_host$uri$is_args$args;
    sub_filter_types application/xml;
    sub_filter_once off;
    sub_filter residential.p-cscf.sfr.net</proxy> sip.parisdmz.lan</proxy>;
}
    }

Petites explications :
Le serveur écoute sur le port 89 (conforme à notre règle de NAT).
Il y a deux serveurs virtuels : un pour les hostnames *.neufbox.sfr.net et un pour le reste.

Le serveur normal
Il va tout simplement faire un proxy_pass (forward proxy) sans rien changer.
J'ai ajouté une variable de header à des fins de debug uniquement (le add_header), vous pouvez le supprimer…

Le serveur *.neufbox.sfr.net:
J'utilise le module http_lua pour faire la réécriture. C'est plus simple à lire (de mon point de vue)
J'inclus un fichier contenant l'IP Publique WAN du pfSense (voir plus loin):
include /usr/local/my_nginx/mvneta2_ip;

Je créé quelques variables:
$xdebug_ip_dhcp "no"; (à des fins de debug)
$xdebug_new_uri_ip ""; (va contenir l'IP publique WAN du pfsense)
set $xdebug_old_uri_ip ""; (à des fins de debug)

Si j'ai un paramètre ip_dhcp dans l'uri alors je réécrit l'uri:
En remplaçant la valeur avec cette prise dans le fichier mvneta2_ip.
Une fois terminer, je proxy_pass la requête.
J'ai ajouté une modification de la réponse pour la téléphonie (voir la section Téléphonie).

Le script de démarrage nginx et de récupération de l'IP Publique WAN:
Fichier start_my_nginx.sh:
#!/bin/sh

#Sleep a little
sleep 5

# get the wan ip address in a file
ifconfig mvneta2 | grep "inet " | awk -F'[: ]' '{print "set $xdebug_wan_ip "$2";"}' > /usr/local/my_nginx/mvneta2_ip

#sleep a little
sleep 5

#check if my_nginx is already running if so kill it and restart
if [ -e /var/run/my_nginx.pid ]
then
echo "my_nginx is running so kill it..."
pkill -F /var/run/my_nginx.pid
fi
echo "(re)start my_nginx..."
/usr/local/sbin/nginx -c /usr/local/etc/nginx/my_nginx.conf

Explications:
Je récupère l'adresse IPv4 de l'interface mvneta2 via un ifconfig.
Je stocke dans un fichier nommé mvneta2_ip, la commande :
Set $xdebug_wan_ip "<IP récupérée>";
Ce fichier est inclus dans la configuration de mon nginx (voir ci-avant).
Puis je regarde si par hasard mon nginx tourne déjà.
Si c'est le cas je le kill et je le relance.
Sinon je le lance tout seul.

NOTE IMPORTANTE: Pour pouvoir executé des script de démarrage sous pfSense en automatique il faut ajouté le package ShellCmd. Puis le configurer:
"Services"->"ShellCmd":
A ce stade, la neufbox doit être opérationnelle pour l'internet IPv4 et IPv6.

5.2.Configuration Téléphonie pour la neufbox
Il faut installer le package siproxd, ave la configuration suivante:
Enable siporxyd: Flagged
Inbound Interface: OPT1
Outbound Interface: WAN
Listening port: 5060

Maintenant il faut savoir que la neufbox va s'enregistrer directement sur le serveur SIP de SFR. Cette configuration lui est fournie par le fichier voip2.xml. Dans mon cas le serveur SIP est: residential.p-cscf.sfr.net.

Pour utiliser notre proxy, il faut modifier la réponse à la requête http du fichier voip2.xml, en modifiant la ligne qui contient le tag xml proxy. C'est la raison de la présence des lignes sub_filter du my-nginx.conf.

Je remplace tout simplement ce hostname par le mien.

Et c'est tout.
Attention je n'ai pas l'utilité de la téléphonie, donc je ne suis pas aller plus loin dans la configuration. En tout état de cause, la box récupère bien une téléphonie OK avec cette configuration.

5.3.Configuration Télévision pour la neufbox
Pour la télévision il va falloir utiliser le serveur proxy IGMP du pfsense.

La neufbox récupère les informations pour la télévision dans le fichier : cfgnb4tvservices_201702141200.xml.

Ce fichier contient tous les networks et hostnames nécessaire à la configuration du proxy igmp.

En premier, j'ai créé un alias : TV_SFR qui contient la liste des réseaux de la partie <igmp-src-list> du fichier.

J'ai activer le proxy IGMP avec la configuration suivante:
Interface : WAN
Type: UpStream
Threshold : 1
Networks : mettre toutes les entrées de la section <igmp-src-list> (malheureusement ici on ne peut pas utiliser l'alias).

Interface : OPT1
Type: DownStream
Threshold: 1
Networks: 192.168.50.0/24

Règles de Firewall pour l'igmp:
Action: Pass
Interface: WAN
Address Family: IPv4
Protocol: IGMP
Source: Any
Destination: Network, 224.0.0.0/4
Advanced Options: Allow IP options flagged

Action: Pass
Interface: WAN
Address Family: IPv4
Protocol: UDP
Source: Single Host or Alias, TV_SFR
Destination: Network, 224.0.0.0/4
Advanced Options: Allow IP options flagged

Action: Pass
Interface: OPT1
Address Family: IPv4
Protocol: IGMP
Source: OPT1 net
Destination: Any
Advanced Options: Allow IP options flagged

A ce stade la télévision doit être opérationnelle sur le STB branché derrière la neufbox.

5.4 Configuration VOD pour la neufbox:
Comme je l'ai indiqué précédemment, le problème ici c'est que le protocole de flux vidéo est UDP et que la connexion est initiée par le serveur (qui dépend tu replay ou de la vod choisie).

Le protocole de demande de vidéo est standard : RTSP.

Les informations sur les serveurs de VOD sont incluses dans le fichier: cfgnb4tvservices_201702141200.xml.

Dans un premier temps, je créé un alias pour les serveurs de VOD: REPLAY_SFR

Je créé une règle de NAT Port Forward:
interface: WANRedirect target IP192.168.50.203
protocol: UDPRedirect target Port8000
Source: AnyDescriptionVOD SFR
Source Port Range: AnyNAT ReflexionUse System Default
Destination: Wan AddressFilter Rule associationRule NAT VOD SFR
Destination Port RangeFrom:8000 To 8999
Attention: ici l'adresse de redirect est l'adresse fixe (static mapping) de la neufbox.

Ici je pense que j'ai encore un petit souci, de temps en temps mon STB me donne un code d'erreur AG2 ou AG3, mais en faisant plusieurs tentatives cela passe quand même. Il faut que j'étudie cela. Je pense que cela vient du range UDP… à voir.

Et voilà….

Je suis passé rapidement sur plusieurs points qui feront surement l'objet d'un update de ce post. Entre autre il s'agit essentiellement de problématiques de DNS

Bon AM.
Titre: FFTH - bypass complet de la NB6 avec pfSense (Netgate SG3100) Part 1
Posté par: shewy80 le 02 août 2019 à 16:47:47
Hello

Une petite question : pourquoi faire si compliqué ? je suis en train de chercher à mettre en place pfsense sur un PC recyclé pour l'occasion avec 2 ports réseaux.

Je comptais assez simplement connecter l'ONT à la box sfr  comme c'est actuellement et tout désactiver. Réseau en 192.168.0.X
Le PC avec pfsense y sera relié sur l'un des 4 eth configuré en IP Fixe.
DMZ vers cette IP.

L'autre port de pfsense en 192.168.1.X servant de dhcp/dns/firewall etc ...

Le téléphone reste branché à la SFR Box. Pas de box TV (Android Box à la place comme bcp)

ça marcherait non ?
Ton post me mets le doute .... Pourquoi vouloir supprimer complètement la box opérateur, si elle ne fait plus que du transit de paquets ?


Titre: FFTH - bypass complet de la NB6 avec pfSense (Netgate SG3100) Part 1
Posté par: john_matrix le 08 août 2019 à 15:11:59
Merci pour le tuto !
Je l'utiliserais lorsque j'aurais mis en place un pfSense virtuel.
Par contre, ça serait intéressant de faire un bypass complet en supprimant complètement la Neufbox du réseau (même en tant que client)
Titre: FFTH - bypass complet de la NB6 avec pfSense (Netgate SG3100) Part 1
Posté par: Florian le 16 août 2019 à 05:18:24
Hello

Une petite question : pourquoi faire si compliqué ? je suis en train de chercher à mettre en place pfsense sur un PC recyclé pour l'occasion avec 2 ports réseaux.

Je comptais assez simplement connecter l'ONT à la box sfr  comme c'est actuellement et tout désactiver. Réseau en 192.168.0.X
Le PC avec pfsense y sera relié sur l'un des 4 eth configuré en IP Fixe.
DMZ vers cette IP.

L'autre port de pfsense en 192.168.1.X servant de dhcp/dns/firewall etc ...

Le téléphone reste branché à la SFR Box. Pas de box TV (Android Box à la place comme bcp)

ça marcherait non ?
Ton post me mets le doute .... Pourquoi vouloir supprimer complètement la box opérateur, si elle ne fait plus que du transit de paquets ?

Faire une sorte de double nat, même en "dmz" n'est pas le but je suppose. Et la.nb6 ne propose pas de mode bridge...