samedi 10 avril 2010

Partager la connexion internet sous Ubuntu

Cette méthode est très simple mais néanmoins complète et efficace, ce qu'il nous faut c'est:
  • Un serveur: c'est le PC qui va se connecter à internet et partager cette connexion avec l'autre (les autres) PC (PCs), il doit être équipé de deux cartes réseaux (ou plus).
  • Le client: c'est le PC qui va recevoir la connexion internet depuis le serveur (on peut aussi avoir plusieurs clients)
Donc supposons qu'on ait un serveur équipé de deux cartes réseaux et ayant une connexion à internet activée + un client ayant une carte réseau, tout d'abord, on doit établir un réseau entres les deux machines, pour ce, je vais vous diriger vers un précédant billet mais avant, il faudra savoir détecter quelle carte réseau reçoit internet pour en déduire laquelle servira au partage (sera reliée à l'autre PC), on tape:
ubugnu@ubugnu-laptop:~$ ifconfig
dans un terminal, vous aurez un ensemble d'interfaces qui peuvent avoir les noms: lo, eth0, eth1, ...., ppp0, ppp1, ... etc, repérez celle qui porte une adresse IP, par exemple dans mon cas c'est:
eth0    Link encap:Ethernet  HWaddr 99:0e:JK:i9:65:17  
inet adr:192.168.1.2 Bcast:192.168.1.255 Masque:255.255.255.0
adr inet6: fe80::20e:7bff:fef6:6513/64 Scope:Lien
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
Packets reçus:8759 erreurs:0 :0 overruns:0 frame:0
TX packets:8802 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 lg file transmission:1000
Octets reçus:5836792 (5.8 MB) Octets transmis:2145823 (2.1 MB)
J'en conclut donc que c'est l'autre carte réseau eth1 qui servira pour le partage de connexion.
Remarque: Dans mon cas j'utilise mon modem comme routeur/serveur DHCP qui a attribué l'adresse IP (locale) 192.168.1.2 à ma carte réseau eth0, si vous utilisez votre modem comme Bridge et avez configuré votre connexion internet vie l'utilitaire pppoeconf vous aurez surement une interface ppp0 comme seule interface ayant une adresse IP (public dans ce cas) au lieu de eth0, vous aurez donc deux autres interfaces eth0 et eth1 (les deux cartes réseau) toutes deux sans adresse IP! alors comment distinguer laquelle est utilisée pour la connexion? Voici une méthode:
Détecter celle qui est reliée à internet: Débranchez celle qui est reliée à l'autre PC et ne laissez que celle qui reçoit l'internet, puis tapez la commande:
ubugnu@ubugnu-laptop:~$ watch ifconfig
Et surveillez quelle interface a le paramètre "Packets reçus" qui change, ce sera elle par laquelle transitent les paquets internet, supposons que c'est eth0, donc ça sera eth1 qui sera reliée à l'autre PC. Bien sûr, rien n'interdit d'échanger les deux...

Une petite récapitulation:
  1. On cherche quelle est l'interface qui reçoit internet ça peut être: (interface de connexion)
    • ppp0: si vous avez configuré votre connexion en utilisant pppoeconf
    • eth0 ou eth1 sinon
  2. On cherche quelle est l'interface qui servira à partager internet vers l'autre PC (interface de partage), ça sera soit eth1 ou eth0 selon qu'on ait trouvé eth0 ou eth1 comme interface de connexion
Donc, je vais supposer le cas que je juge le plus répandu parmi mes lecteurs, à savoir:
  • Interface d'entrée de l'internet: ppp0 (interface de connexion)
  • Interface de sortie: eth1 (interface de partage)
Bien sûr, dans tout ce qui suit, vous changerez ppp0 et eth1 par ce que vous avez trouvé en suivant ma précédente présentation. Notez tout ça sur un bout de papier.

Je vous dirige donc comme promis vers mon billet qui parle de comment créer un réseau entre deux PCs, une remarque importante, vu que dans mon cas c'est eth1 qui sera utilisée pour relier les deux PC je devrais donc remplacer la ligne:
ubugnu@ubugnu-laptop:~$ sudo ifconfig eth0 192.168.0.1
(pour le pc principal par exemple) par
ubugnu@ubugnu-laptop:~$ sudo ifconfig eth1 192.168.0.1
(pour le pc principal par exemple) dans le billet vers lequel je vous ai dirigé.
Ici le PC principal c'est notre serveur.
À la fin, faites un ping de part et d'autre pour vérifier que la liaison est bien établie, si c'est le cas, on peut continuer.

Coté Serveur:


Maintenant que les deux PC sont bien reliés, on doit rediriger les paquets (dans le serveur) de l'interface de connexion (ppp0) vers l'interface de partage (eth1), pour ce, on commence par indiquer quelle interface servira d'interface de partage.
Allez au Moniteur de connexion réseau, il doit être dans le tableau de bord, si ce n'est pas le cas; faites Alt+F2 et tapez nm-applet pour le faire apparaitre.Clique droit dessus, puis allez à "Modification de connexions", clique droit sur l'interface de partage (dans mon cas eth1) et choisissez "Partager avec d'autres ordinateurs". L'interface devrait disparaitre de la liste après cette opération.
Maintenant, on doit autoriser la redirection des paquets internet de l'interface de connexion (ppp0) vers l'interface de partage (eth1) en ajoutant des règles dans l'iptables, tapez dans la console:
ubugnu@ubugnu-laptop:~$ sudo iptables -A FORWARD -i ppp0 -o eth1 -s 192.168.0.0/24 -m conntrack --ctstate NEW -j ACCEPT 
ubugnu@ubugnu-laptop:~$ sudo iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ubugnu@ubugnu-laptop:~$ sudo iptables -A POSTROUTING -t nat -j MASQUERADE
La première règle sert à autoriser les paquets initialement transmis entre les deux interfaces, la deuxième sert à autoriser les connexions ainsi établies, la troisième établit le NAT (Network Adress Translation)
Il faut maintenant modifier deux fichiers, on utilisera nano:
ubugnu@ubugnu-laptop:~$ nano /proc/sys/net/ipv4/ip_forward
mettez 1 (le chiffre 1) et enregistrez avec Ctrl+o puis quittez avec Ctrl+x, puis:
ubugnu@ubugnu-laptop:~$ nano /etc/sysctl.conf
et ajoutez à la fin les lignes:
net.ipv4.conf.default.forwarding=1
net.ipv4.conf.all.forwarding=1
enregistrez et quittez.
(cette dernière opération n'est plus nécessaire dans les versions 9+)

Coté client:


Pour le client, il suffit de lui indiquer d'utiliser comme passerelle par défaut le serveur, dans notre cas le serveur à comme IP 192.168.0.1 (et le client 192.168.0.100 selon le précédent billet), donc, chez le client taper la commande:
ubugnu@ubugnu-laptop:~$ sudo route add default gw 192.168.0.1
À ce point la connéxion devrait être activée chez le client, pour s'en assurer on va pinger l'adresse IP de google.com:
ubugnu@ubugnu-laptop:~$ ping 209.85.227.99
Vous remarquerez qu'il y'a des temps de réponse, donc c'est bon. Seulement voila, si vous essayez de pinger google.com en utilisant son nom de domaine:
ubugnu@ubugnu-laptop:~$ ping google.com
vous n'aurez aucune réponse, c'est parce que le client n'a encore aucun serveur DNS à interroger pour traduire les noms de domaine en adresses IP, la même chose arrivera dans votre navigateur préféré si vous essayez.
Ce qui arrive, c'est que le client essais d'interroger la passerelle par défaut (en l'occurrence notre serveur) pour le DNS, or, on n'a pas configurer le serveur pour router les requêtes DNS, il y'a deux solutions:

Retour au serveur:


  1. Soit
    Installer dnsmasq:
    ubugnu@ubugnu-laptop:~$ sudo aptitude install dnsmasq
    qui va justement router les requêtes DNS (rediriger), il lui faut quelques modifications, on l'arrête d'abord:
    ubugnu@ubugnu-laptop:~$ sudo /etc/init.d/dnsmasq stop
    puis on édite don fichier de configuration avec nano:
    ubugnu@ubugnu-laptop:~$ sudo nano /etc/dnsmasq.conf
    en y mettant:
    interface=eth1
    dhcp-range=192.168.0.100,192.168.0.250,72h
    Puis on le redémarre avec:
    ubugnu@ubugnu-laptop:~$ sudo /etc/init.d/dnsmasq start
  2. Soit (de préférence)
    Transformer le serveur en une serveur DNS en installant bind9:
    ubugnu@ubugnu-laptop:~$ sudo apt-get install bind9
    Configurons le:
    ubugnu@ubugnu-laptop:~$ sudo nano /etc/bind/named.conf.options
    Recopiez ce qui suit
    options {
    directory "/var/cache/bind";
    // If there is a firewall between you and nameservers you want
    // to talk to, you may need to fix the firewall to allow multiple
    // ports to talk. See http://www.kb.cert.org/vuls/id/800113
    // Écouter les requêtes venant que de la boucle interne. Si vous voulez que BIND
    // écoute en IPv6, dé-commentez la ligne listen-on-v6 { ::1; } ou mettez listen-on-v6 { any; }
    listen-on { 127.0.0.1; };
    // listen-on-v6 { ::1; };
    auth-nxdomain no; # conform to RFC1035
    recursion yes;
    // Votre serveur BIND DNS permet la récursion et servira de cache que pour les
    // requêtes locales
    allow-recursion { 127.0.0.1; };
    allow-query-cache { 127.0.0.1; };
    // Pour cacher la version du serveur Bind DNS aux éventuels scans extérieurs
    version "Version non disponible!";
    // Rediriger toutes les réquêtes DNS vers les serveurs DNS
    // publiques de Google : les fameux 8.8.8.8 et 8.8.4.4
    //forwarders { 8.8.8.8; 8.8.4.4; };
    //forward only;
    };
    et redémarrez le serveur DNS
    ubugnu@ubugnu-laptop:~$ sudo /etc/init.d/bind9 restart
    Et le tour est joué.
Remarque: vous pouvez même utiliser ce serveur DNS pour le serveur lui même, pourquoi donc? Quand vous tapez un adresse internet, votre navigateur interroge les serveurs DNS de votre FAI (fournisseur d'accès internet), ça peut prendre plusieurs secondes, alors qu'en utilisant votre propre machine comme serveur DNS, les interrogations passées seront stockées en mémoire cache, et dès la deuxième requête DNS, le temps de réponse passera de plusieurs secondes à une milliseconde!!! C'est sûr qu'on ne s'en en passerait pas...
Pour rendre aussi votre serveur s'interroger lui-même quand il s'agit de DNS, pour ce, changer le fichier:
ubugnu@ubugnu-laptop:~$ sudo nano /etc/resolv.conf
Vous y trouverez les IPs des serveurs DNS de votre FAI, remplacez les par l'adresse IP locale nameserver 127.0.0.1
Maintenant, même le serveur utilisera son serveur DNS embarqué pour les résolutions des noms de domaines.

EDIT: (automatiser l'opération)
Que faire quand on redémarre? On ne vas pas à chaque fois refaire les mêmes opérations comme même! On va créer des commandes de connexion, il n'y aura qu'a taper ces deux simples commandes sur les deux machines à chaque fois qu'on veut partager la connexion.
  • Sur le serveur:

    ubugnu@ubugnu-laptop:~$ sudo nano /usr/bin/share-connection
    et on met dedans:
    ifconfig eth1 192.168.0.1
    iptables -A FORWARD -i ppp0 -o eth1 -s 192.168.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
    iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    iptables -A POSTROUTING -t nat -j MASQUERADE
    Après on rend le script exécutable:
    ubugnu@ubugnu-laptop:~$ sudo chmod +x /usr/bin/share-connection
  • Sur le client:

    ubugnu@ubugnu-laptop:~$ sudo nano /usr/bin/share-connection
    et on met dedans:
    ifconfig eth0 192.168.0.100
    route add default gw 192.168.0.1
    Après on rend le script exécutable:
    ubugnu@ubugnu-laptop:~$ sudo chmod +x /usr/bin/share-connection
Maintenant à chaque fois qu'on voudra partager la connexion, on tapera sur les deux machines la commande: # sudo share-connection