[Tuto] Résoudre le problème de hairpinning Orange avec le DHCP/DNS de YunoHost

https://forum.yunohost.org/t/tuto-resoudre-le-probleme-de-hairpinning-orange-avec-le-dhcp-dns-de-yunohost/4125/37

Avertissement



Dans un premier je voudrais préciser que cette méthode fonctionne avant tout pour moi ! Je n’ai aucune idée du respect des “bonnes pratiques” avec ces propositions là.

Cependant, je serais ravi d’échanger avec vous tous (utilisateurs de YunoHost ou bien dev YunoHost) par rapport à cette méthode là ; est-ce une bonne pratique ? ; est-ce que je me prends la tete ? ; est ce qu’il y a moyen de faire ça plus facilement ? Enfin bref j’attend avec impatience vos retours wink

Introduction



Étant client Orange fibre j’ai comme beaucoup le problème de hairpinning avec ma Livebox.

En épluchant un peu le forum ici et d’autres sur internet voici la solution que je propose pour contourner ce problème.

Pour résumer je n’utilise la Livebox que comme bridge internet, c’est mon serveur YunoHost qui fait office de serveur DHCP et résolveur DNS. Tout ça grace à DNSmasq qui est normalement installé est activé par défaut sur votre serveur YunoHost.

Pour résumé voici les avantages de cette méthode :



La TV par internet



Personnellement je n’utilise pas le décodeur TV d’orange (en plus j’ai le décodeur blanc qui est complètement buggé …;). Cependant, je le précise plus tard, mais il est important que le décodeur reçoive son IP du serveur DHCP de la box et non pas par YunoHost. Je crois que c’est dû au fait que la TV d’Orange a besoin d’utiliser les DNS hardcodés dans la LiveBox.

Finalement : Si vous voulez garder la TV d’Orange il faut laisser activer le DHCP de la LiveBox, pour les autres aucun problème à le désactiver.

Je précise les deux cas dans le tuto.

Vérification de la config actuelle



Avant de commencer je propose de faire un petit tour d’horizon afin d’être sûr que la base soit bonne. De mon coté, voici le contenu des différents fichiers de configuration qui nous intéresse dans leurs états juste après une installation fraiche de YunoHost.



Code BASH :
source /etc/network/interfaces.d/*
 
# The loopback network interface
auto lo
iface lo inet loopback
 
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp




Code CSS :
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.0.1




Code NGINX :
nameserver 84.200.69.80
nameserver 141.255.128.100
nameserver 80.67.169.12
nameserver 80.67.188.188
nameserver 80.67.169.40
nameserver 89.234.186.18
nameserver 213.73.91.35
nameserver 89.234.141.66
nameserver 89.233.43.71
nameserver 91.239.100.100
nameserver 85.214.20.141
nameserver 141.255.128.101
nameserver 84.200.70.40




Code JAVASCRIPT :
domain-needed
expand-hosts
 
listen-address=127.0.0.1
resolv-file=/etc/resolv.dnsmasq.conf
cache-size=256


1. Attribution d’une IP fixe au serveur YunoHost



Si ce n’est pas déjà fait, je pense que c’est une bonne chose de fixer l’adresse IP du serveur YunoHost étant donné que nous allons désactiver le serveur DHCP de la LiveBox.

Pour ça, il suffit d’éditer le fichier 
/etc/network/interfaces
 et de modifier la ligne correspondant à l’interface réseau utilisée. Mais avant, on fait une petite sauvegarde du fichier avec 
sudo cp /etc/network/interfaces /etc/network/interfaces.bak
 et enfin on édite le fichier avec 
sudo nano /etc/network/interfaces
 et on le modifie comme ceci :

Code NGINX :
source /etc/network/interfaces.d/*
 
# The loopback network interface
auto lo
iface lo inet loopback
 
# The primary network interface
allow-hotplug eth0
iface eth0 inet static # On passe en static
address 192.168.1.2 # Adresse IP locale que l'on souhaite pour YunoHost
netmask 255.255.255.0 # Le masque du sous-réseau
gateway 192.168.1.1 # L'adresse de notre passerelle, ici c'est notre box qui a normalement cette IP


Un petit redémarrage et normalement vous pouvez vous connecter à votre serveur avec sa nouvelle IP.

2. Activer le serveur DHCP de DNSmasq



Maintenant on va activer le serveur DHCP de YunoHost. Le rôle du serveur DHCP est de fournir une adresse IP valide aux machines qui se connectent à votre réseau local ainsi que les différentes informations utiles comme la passerelle ou encore le resolveur DNS.

Jusqu’à présent c’était votre LiveBox qui était chargée de faire ça. Maintenant c’est votre serveur YunoHost qui va s’en charger. L’avantage en utilisant celui-ci, c’est qu’il va communiquer comme résolveur DNS sa propre IP et faire travailler DNSmasq, contrairement à LiveBox qui fourni les DNS d’Orange.

Pour activer le serveur DHCP de YunoHost il faut éditer le fichier 
/etc/dnsmasq.conf
 mais avant on fait une sauvegarde avec 
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak
 et enfin 
sudo nano /etc/dnsmasq.conf
 afin de modifier le fichier comme ceci :

Code RUBY :
domain-needed
expand-hosts
 
# listen-address=127.0.0.1 # On veut écouter aussi les machines de notre LAN
resolv-file=/etc/resolv.dnsmasq.conf
 
cache-size=2048 # Nombre d'entrées DNS max à garder en cache
bogus-priv
dhcp-range=192.168.1.10,192.168.1.50,255.255.255.0,24h # Active le serveur DHCP,
# celui-ci fournira des adresses IP entre 192.168.1.10 et 192.168.1.50 aux machines du réseau
dhcp-option=option:router,192.168.1.1 # Indique la passerelle de notre réseau
 
# Seulement si vous gardez la TV d'Orange, il faut récupérer l'adresse MAC du décodeur et la renseigner ici
# Cette ligne dit à DNSmasq de ne pas s'occuper du décodeur TV et de ne pas lui donner d'IP
# C'est la LiveBox qui le fera (voir plus bas)
dhcp-host=8c:10:d4:d7:a7:ad,ignore


Il ne faut pas oublier d’ouvrir le port 67 UDP sur votre serveur pour que le serveur DHCP soit visible sur votre réseau. Nous faisons ça avec la commande 
sudo yunohost firewall allow UDP 67
.

Enfin, on relance DNSmasq pour prendre en compte la configuration avec 
sudo service dnsmasq restart
 et on regarde que tout se passe bien avec 
sudo service dnsmasq status
.

À partir de maintenant votre serveur DHCP doit être fonctionnel, vous pouvez peut être essayer sur une autre machine dans vos paramètres réseau en demandant de renouveler le bail DHCP et en spécifiant l’adresse IP de votre serveur afin de ne pas utiliser le DHCP de la LiveBox.

Si vous récupérez bien une adresse IP dans la tranche que vous avez spécifié et que votre connexion internet fonctionne alors on peut passer à la suite et désactiver le serveur DHCP de la LiveBox

3. Désactiver le serveur DHCP de la LiveBox



Rien de bien compliquer, connectez vous sur l’interface admin de votre Box depuis un navigateur en entrant l’URL 192.168.1.1. Connectez vous en tant qu’admin et rendez vous dans l’onglet “Configuration avancée” et l’onglet “DHCP”.



4. Vérification du fonctionnement de DNSmasq



Maintenant votre serveur DHCP et resolveur DNS perso de YunoHost devrait fonctionner correctement. Pour tester tout ça il vous suffit sur une de vos machines de la déconnecter du réseau et de la reconnecter pour qu’elle interroge le serveur DHCP de YunoHost. Si tout va bien elle devrait récupérer une adresse IP de l’intervalle que vous avez défini dans 
/etc/dnsmasq.conf
 et votre connexion internet devrait fonctionner.

Pour vous assurer que le résolveur DNS utilisé est bien celui de YunoHost faites un petit 
dig www.google.fr
 dans votre shell ; le serveur indiqué devrait être l’adresse IP de votre serveur YunoHost.

Mais pour l’instant, si dans votre navigateur vous essayez d’accéder à votre interface YunoHost via votre domaine principal cela ne fonctionne pas. Tout simplement parce que DNSmasq retourne à votre machine votre adresse IP publique. Il va falloir modifier la config de DNSmasq pour qu’il vous retourne l’adresse IP locale de votre serveur et non pas l’adresse IP publique.

5. Ajouter vos domaines à la config de DNSmasq



Pour chacun de vos domaines il va falloir modifier le fichier qui correspond dans le dossier 
/etc/dnsmasq.d
 comme par exemple le fichier 
/etc/dnsmasq.d/toto.fr
 indiqué ici :

Code INI :
# address=/toto.fr/80.80.80.80 # On remplace la ligne avec notre IP publique
address=/toto.fr/192.168.1.2 # par l'IP locale de notre serveur YunoHost
txt-record=toto.fr,"v=spf1 mx a -all"
mx-host=toto.fr,toto.fr,5
srv-host=_xmpp-client._tcp.toto.fr,toto.fr,5222,0,5
srv-host=_xmpp-server._tcp.toto.fr,toto.fr,5269,0,5


Après un 
sudo service dnsmasq restart
 vous devriez pouvoir accéder sur chacune de vos machines à votre interface Yunohost en utilisant votre nom de domaine comme URL.

6. Mise en place et renouvellement des certificats Let’s Encrypt



Cependant il reste encore un problème. Lorsque vous mettez en place un certificat pour vos noms de domaine vous obtenez le message suivant :

Code BASH :
Attention : Expiration du délai lors de la tentative du serveur de se contacter
via HTTP en utilisant son adresse IP publique (domaine toto.fr avec l’IP
xx.xxx.xxx.xxx). Vous rencontrez peut-être un problème d’hairpinning ou
alors le pare-feu/routeur en amont de votre serveur est mal configuré.


En effet, le NAT loopback de la Livebox ne fonctionne pas, donc quand YunoHost interroge votre IP publique sur le port 80 celle-ci n’est pas capable de renvoyer l’IP locale de votre serveur.

Le seul moyen que j’ai trouvé pour le moment est d’utiliser iptables afin de transférer tout le trafic de votre IP publique vers l’IP locale de votre serveur YunoHost.

Dans un premier temps il faut activer l’ip forwarding en éditant le fichier 
/etc/sysctl.conf
 avec un 
sudo nano /etc/sysctl.conf
 et dé-commenter la ligne 
net.ipv4.ip_forward
 afin d’avoir 
net.ipv4.ip_forward=1
.

Maintenant il faut ajouter une règle Iptables afin de maintenir la redirection d’IP même si l’IP publique change.
Pour cela j’utilise Cron afin de vérifier toutes les 15 minutes si mon IP a changé et modifier la redirection si besoin.

Dans un premier temps je créé un dossier dans mon home afin d’accueillir mon script : 
mkdir ~/ynh_hairpinning_fix
.
Enfin je créé mon script avec 
nano ~/ynh_hairpinning_fix/ynh_hairpinning_fix.sh
 et voici son contenu :

Code BASH :
#!/usr/bin/env bash
 
local_ip="192.168.1.2"
last_ip_file="/home/admin/ynh_hairpinning_fix/last_ip.txt"
 
function delete_previous_iptables_rule {
rule_number=$(/sbin/iptables -L --line-numbers -t nat | grep 'ynh_hairpinning_fix' | awk '{print $1}')
cmd="/sbin/iptables -t nat -D OUTPUT $rule_number"
echo "$cmd"
eval $cmd
}
 
function add_iptables_rule {
cmd="/sbin/iptables -t nat -A OUTPUT -d $public_ip -j DNAT --to-destination $local_ip -m comment --comment \"ynh_hairpinning_fix\""
echo "$cmd"
eval $cmd
}
 
# Get current public IP
public_ip=`dig +short myip.opendns.com @resolver1.opendns.com`
echo "Current public IP: $public_ip"
 
# Check if the iptables rule exists, if not,
# just add the rule and save the current public IP
iptables_save=$(/sbin/iptables-save)
if [[ $iptables_save != *"ynh_hairpinning_fix"* ]];
then
echo "Iptables rule does not exist, let's add it"
 
# Add iptables rule
add_iptables_rule
 
# Save current public ip
echo "$public_ip" > $last_ip_file
 
exit 0
fi
 
# If the iptables rule exists,
# check if the public IP has changed
if [ -f "$last_ip_file" ]
then
previous_ip=$(head -n 1 $last_ip_file)
 
if [ "$previous_ip" = "$public_ip" ];
then
echo "Public IP unchanged, nothing to do"
 
else
echo "Public IP changed, let's modify iptables rule"
echo "Previous public IP: $previous_ip"
delete_previous_iptables_rule
add_iptables_rule
echo "$public_ip" > $last_ip_file
fi;
 
else
echo "Previous public IP unkown, let's modify iptables rule"
delete_previous_iptables_rule
add_iptables_rule
echo "$public_ip" > $last_ip_file
fi
 
exit 0


N’oubliez pas d’adapter la variable 
local_ip
 en mettant l’IP locale de votre YunoHost. Et enfin, rendez votre script exécutable avec 
chmod +x ~/ynh_hairpinning_fix/ynh_hairpinning_fix.sh
.
Vous pouvez maintenant le lancer une première fois avec la commande 
sudo ~/ynh_hairpinning_fix/ynh_hairpinning_fix.sh
 (important de se placer root car on utilise ici Iptables).
Maintenant vous pouvez vérifier que la règle a bien été ajouté dans Iptables avec 
sudo iptables -L --line-numbers -t nat
.

Il ne reste plus qu’à ajouter ce script à Cron pour vérifier régulièrement que si votre IP publique change.
Faite un 
sudo crontab -e
 afin d’éditer vos entrée Cron root et ajoutez la ligne suivante :
*/15 * * * * /home/admin/ynh_hairpinning_fix/ynh_hairpinning_fix.sh
.

Redémarrez votre YunoHost et essayez de renouveler votre certificat ; normalement le warning a disparu !

Conclusion



Voilà tout !

J’espère que les explications sont assez claires et aussi que ce tuto peut servir à d’autre personnes (je ne sais pas pour les autres box comme Bbox ou encore SFR, peut être que ça peut servir, ou même chez nos amis Belges avec Proximus?).

Si d’autres clients Orange sont dans le même cas que je moi je veux bien vos trucs et astuces pour résoudre ce problème là, peut être qu’il y a plus simple et plus efficace ?

Et surtout merci à la communauté YunoHost heart_eyes

1)

voilà, j’ai fais comme suggéré un script qui récupère l’ip publique, et la stock dans une varible. J’ai donc:



Code BASH :
    #!/bin/bash
MYIPPUB=$(curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//');
/sbin/iptables -t nat -A OUTPUT -d $MYIPPUB -j DNAT --to-destination 192.168.1.2
exit 0


(fait à l’aide de ce post : https://askubuntu.com/questions/95910/command-for-determining-my-public-ip 3
et ce post https://www.commentcamarche.net/forum/affich-4755454-shell-stocker-le-resultat-d-une-commande 1 )



Merci beaucoup pour cette solution en tout cas, j’aurais été bien embêté sans ce tuto wink

2)

De mon coté je viens (enfin) d’intégrer ta méthode à mon YunoHost, voici mon script 
fake_loopback.sh
 au cas ou :

Code BASH :
#!/usr/bin/env bash
 
public_ip=`dig +short myip.opendns.com @resolver1.opendns.com`
/sbin/iptables -t nat -A OUTPUT -d "$public_ip" -j DNAT --to-destination 192.168.1.2


et mon entrée crontab (bien faire 
sudo crontab -e
 et pas 
crontab -e
 pour être sûr d’étirer le crontab de root et pas de l’user)

Code BASH :
@reboot /home/admin/fake_loopback.sh


3)

Bonjour,
D’abord merci pour ce tuto qui fonctionne encore aujourd’hui .
Moi aussi j’avais ce problème d’accès au serveur depuis mon réseau local.
Mon modem-routeur est un D-link DSL-2640B, car je suis chez FDN qui ne fourni pas de box.

Information sur la version de YNH :

Code YAML :
# yunohost -v
yunohost:
repo: stable
version: 4.3.6.2
yunohost-admin:
repo: testing
version: 4.3.4.1
moulinette:
repo: stable
version: 4.3.3.1
ssowat:
repo: stable
version: 4.3.3.1


Ce que j’ai fait pour résoudre :

1. Attribution d’une IP fixe au serveur YunoHost
J’avais déjà assigné une IPv4 fixe à mon YNH.

2. Activer le serveur DHCP de DNSmasq



Code BASH :
domain-needed
expand-hosts
 
# listen-address=127.0.0.1 # On veut écouter aussi les machines de notre LAN
resolv-file=/etc/resolv.dnsmasq.conf
 
cache-size=2048 # Nombre d'entrées DNS max à garder en cache
bogus-priv
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,24h # Active le serveur DHCP,
# celui-ci fournira des adresses IP entre 192.168.1.100 et 192.168.1.200 aux machines du réseau
dhcp-option=option:router,192.168.1.1 # Indique la passerelle de notre réseau




3. Désactiver le serveur DHCP du D-link DSL-2640B
A partir de l’interface web en 192.168.1.1.



4. Vérification du fonctionnement de DNSmasq
En effet, une machine faisant appel au service DHCP reçoit bien une IP dans la plage spécifier dans 
/etc/dnsmasq.conf
 et comme Primary DNS l’IP statique du YNH.
Par contre, pour les machines configurées en IP fixe j’ai du renseigner le serveur DNS avec l’IP du YNH.
J’ai maintenant accès au YNH depuis toutes les machines du réseau local par son domain.tld.

5. Ajouter vos domaines à la config de DNSmasq
Un fichier 
domain.tld
 était déjà présent dans 
/etc/dnsmasq.d
, la ligne 
address=
 n’y figure pas mais par contre 4 lignes 
interface-name=
.
Ça fonctionne ainsi je n’ai donc rien modifié.

6. Mise en place et renouvellement des certificats Let’s Encrypt
J’ai d’abord tenté un “renouveler manuellement maintenant” et la validité du certificat est bien passée à 89 jours.
Ça fonctionne ainsi je n’ai donc rien modifié.

Conclusion



Merci à toute l’équipe. ok_hand