Aller à la recherche

Des Logiciels Libres

Pour parler de Logiciels Libres en milieu professionnel... ou pas!

samedi, octobre 5 2013 19:50

Réseaux GRE avec routage OSPF

Objectifs

Etablir un réseau maillé (mesh) avec des liaisons GRE. Les tables de routage seront découvertes automatiquement via le protocole OSPF (Open Shortest Path First).

Donc dans un premier temps, configurer les liaisons GRE. Dans un second temps, configurer les démons ospfd pour la partie routage.

Topologie de la maquette

Il s'agit d'une version étendue de celle utilisée pour l'article sur la configuration d'un tunnel GRE simple. Au lieu d'avoir 2 réseaux distincts, nous en avons cette fois 4.

Les 4 réseaux A, B, C, D possède un identifiant qui leur a été attribué de manière arbitraire, pour simplifier les plans d'adressage:

  • Le réseau A => 16
  • Le réseau B => 22
  • Le réseau C => 227
  • Le réseau D => 13

Pour faire simple là aussi, ces différents réseaux sont reliés entre eux par un accès WAN sur une plage d'adresse unique en 192.168.122.X. X est remplacé par l'identifiant du réseau.

Chaque réseau possède des clients utilisant une plage d'adresse privée du style 192.168.X.0/24 où X est là aussi remplacé par l'idéntifiant du réseau.

Ce qui nous donne au final:

  • Réseau A Adresse WAN 192.168.122.16 avec réseau clients 192.168.16.0/24
  • Réseau B Adresse WAN 192.168.122.22 avec réseau clients 192.168.22.0/24
  • Réseau C Adresse WAN 192.168.122.227 avec réseau clients 192.168.227.0/24
  • Réseau D Adresse WAN 192.168.122.13 avec réseau clients 192.168.13.0/24

Toujours pour simplifier, l'adresse IP du serveur OpenBSD gérant le tunnel, et faisant office de passerelle, est sous la forme 192.168.X.254.

Bref voir le schéma suivant:

Gre 4 reseaux

En fonction de la fiabilité des liens entre les différents réseaux, il est possible de ne faire que seulement 2 liens entre chaque site, pour assurer la tolérance de panne. Pour que ce soit un vrai réseau maillé, pour N noeuds, chaque N doit avoir N-1 connexions. Donc dans notre cas, 3 connexions. Celles-ci seront numérotées arbitrairement pour faciliter encore une fois la configuration, voir le schéma suivant:

Gre 4 MESH

Il n'y a pas non plus de logique dans l'attribution des adresses IP des extrémités des tunnels, j'aurais pu opter pour un adressage du style 172.16.numero_tunnel.identifiant_réseau... Peut être la prochaine fois ;)

Ce numéro de tunnel est aussi repris dans la numérotation des interfaces GRE.

Pré-requis

Il s'agit des mêmes pré-requis que pour la configuration d'un tunnel GRE simple.

Pare-feu

Dans un premier temps, pour faciliter la mise en oeuvre, n'appliquons aucun filtrage sur les interfaces GRE.

Sur tun.a

Ajouter les lignes suivantes dans le début du fichier /etc/pf.conf:

set skip on gre0
set skip on gre1
set skip on gre2

OSPF

Sur tun.b

Ajouter les lignes suivantes dans le début du fichier /etc/pf.conf:

set skip on gre0
set skip on gre3
set skip on gre4
Sur tun.c

Ajouter les lignes suivantes dans le début du fichier /etc/pf.conf:

set skip on gre1
set skip on gre3
set skip on gre5
Sur tun.d

Ajouter les lignes suivantes dans le début du fichier /etc/pf.conf:

set skip on gre2
set skip on gre4
set skip on gre5

Autorisation des tunnels GRE

Pour autoriser au niveau du noyau les tunnels de type GRE, il faut ajouter sur l'ensemble des serveurs, la ligne suivante dans /etc/sysctl.conf:

net.inet.gre.allow=1

Et pour l'appliquer immédiatement, taper la commande suivante:

# sysctl -w net.inet.gre.allow=1

Autorisation du routage

Pour activer le routage IP, il faut ajouter sur l'ensemble des serveurs la ligne suivante dans /etc/sysctl.conf:

net.inet.ip.forwarding=1

Et pour l'appliquer immédiatement, taper la commande suivante:

# sysctl -w net.inet.ip.forwarding=1

Configuration des tunnels GRE

La configuration des 3 liaisons est effectuées sur chaque serveur. Il n'y a aucune information sur le routage à ce niveau.

Sur tun.a

Configuration de la liaison gre0

Contenu du fichier de configuration /etc/hostname.gre0:

172.16.0.2 172.16.0.1 netmask 0xffffffff link0 up
tunnel 192.168.122.16 192.168.122.22
Configuration de la liaison gre1

Contenu du fichier de configuration /etc/hostname.gre1:

172.16.1.2 172.16.1.1 netmask 0xffffffff link0 up
tunnel 192.168.122.16 192.168.122.227
Configuration de la liaison gre2

Contenu du fichier de configuration /etc/hostname.gre2:

172.16.2.2 172.16.2.1 netmask 0xffffffff link0 up
tunnel 192.168.122.16 192.168.122.13

Sur tun.b

Configuration de la liaison gre0

Contenu du fichier de configuration /etc/hostname.gre0:

172.16.0.1 172.16.0.2 netmask 0xffffffff link0 up
tunnel 192.168.122.22 192.168.122.16
Configuration de la liaison gre3

Contenu du fichier de configuration /etc/hostname.gre3:

172.16.3.1 172.16.3.2 netmask 0xffffffff link0 up
tunnel 192.168.122.22 192.168.122.227
Configuration de la liaison gre4

Contenu du fichier de configuration /etc/hostname.gre4:

172.16.4.1 172.16.4.2 netmask 0xffffffff link0 up
tunnel 192.168.122.22 192.168.122.13

Sur tun.c

Configuration de la liaison gre1

Contenu du fichier de configuration /etc/hostname.gre1:

172.16.1.1 172.16.1.2 netmask 0xffffffff link0 up
tunnel 192.168.122.227 192.168.122.16
Configuration de la liaison gre3

Contenu du fichier de configuration /etc/hostname.gre3:

172.16.3.2 172.16.3.1 netmask 0xffffffff link0 up
tunnel 192.168.122.227 192.168.122.22
Configuration de la liaison gre5

Contenu du fichier de configuration /etc/hostname.gre5:

172.16.5.1 172.16.5.2 netmask 0xffffffff link0 up
tunnel 192.168.122.227 192.168.122.13

Sur tun.d

Configuration de la liaison gre2

Contenu du fichier de configuration /etc/hostname.gre2:

172.16.2.1 172.16.2.2 netmask 0xffffffff link0 up
tunnel 192.168.122.13 192.168.122.16
Configuration de la liaison gre4

Contenu du fichier de configuration /etc/hostname.gre4:

172.16.4.2 172.16.4.1 netmask 0xffffffff link0 up
tunnel 192.168.122.13 192.168.122.22
Configuration de la liaison gre5

Contenu du fichier de configuration /etc/hostname.gre5:

172.16.5.2 172.16.5.1 netmask 0xffffffff link0 up
tunnel 192.168.122.13 192.168.122.227

Sur l'ensemble des serveurs

Pour activer les connexions GRE:

# sh /etc/netstart

Elles sont de toute façon activées par défaut au démarrage.

Configuration du démon OSPF

Il s'agit ici d'une configuration très simple permettant d'indiquer sur quelles interfaces le protocole OSPF doit opérer. L'interface indiquée comme passive permet à OSPFd de connaitre le reseau de cette dernière, sans faire d'annonce sur celle-ci. Les démons OSPFd dans notre cas ne peuvent en effet communiquer que via les tunnels GRE.

Sur notre maquette, l'interface reliée au réseau privé est em0.

Sur tun.a

Contenu du fichier /etc/ospfd.conf:

auth-md 1 "secret"
auth-type crypt
auth-md-keyid 1
area 0.0.0.0 {
       interface gre0 {}
       interface gre1 {}
       interface gre2 {}
       interface em0 { passive }
}

Sur tun.b

Contenu du fichier /etc/ospfd.conf:

auth-md 1 "secret"
auth-type crypt
auth-md-keyid 1
area 0.0.0.0 {
       interface gre0 {}
       interface gre3 {}
       interface gre4 {}
       interface em0 { passive }
}

Sur tun.c

Contenu du fichier /etc/ospfd.conf:

auth-md 1 "secret"
auth-type crypt
auth-md-keyid 1
area 0.0.0.0 {
       interface gre1 {}
       interface gre3 {}
       interface gre5 {}
       interface em0 { passive }
}

Sur tun.d

Contenu du fichier /etc/ospfd.conf:

auth-md 1 "secret"
auth-type crypt
auth-md-keyid 1
area 0.0.0.0 {
       interface gre2 {}
       interface gre4 {}
       interface gre5 {}
       interface em0 { passive }
}

Sur l'ensemble des serveurs

Pour activer le démon ospfd par défaut au démarrage, il faut modifer le fichier /etc/rc.conf.local (le créer s'il n 'existe pas) pour avoir la ligne suivante:

ospfd_flags=""

Validation

Une fois tous les tunnels montés, et les services ospfd démarrés, ceux-ci devraient commencer à faire leurs découvertes sur les réseaux. Les routes seront échangées entre les différents démons via les annonces OSPF, constituant une base d'information de routage (ou RIB pour Routing Information Base). Pour consulter la RIB sur un serveur:

$ ospfctl show rib

Exemple sur la machine tun.a:

$ ospfctl show rib                                                                                                   
Destination          Nexthop           Path Type    Type      Cost    Uptime  
172.16.0.2/32        172.16.0.1        Intra-Area   Network   20      00:57:36
172.16.1.2/32        172.16.1.1        Intra-Area   Network   20      01:19:58
172.16.2.2/32        172.16.2.1        Intra-Area   Network   20      01:19:39
172.16.3.1/32        172.16.1.1        Intra-Area   Network   20      00:57:57
172.16.3.2/32        172.16.0.1        Intra-Area   Network   20      00:57:36
172.16.4.1/32        172.16.2.1        Intra-Area   Network   20      01:19:39
172.16.4.2/32        172.16.0.1        Intra-Area   Network   20      00:57:36 
172.16.5.1/32        172.16.2.1        Intra-Area   Network   20      01:19:27
172.16.5.2/32        172.16.1.1        Intra-Area   Network   20      01:19:33
192.168.13.0/24      172.16.2.1        Intra-Area   Network   20      01:19:39
192.168.22.0/24      172.16.0.1        Intra-Area   Network   20      00:57:36
192.168.227.0/24     172.16.1.1        Intra-Area   Network   20      01:19:58

A noté que le réseau 192.168.16.0/24 (réseau A) n'apparait pas vu qu'il s'agit du réseau local de la machine tun.a. Cette RIB nous informe que les démons ospfd a trouvé des routes pour les réseaux distants qui nous interessent, à savoir:

  • 192.168.13.0/24 (réseau D)
  • 192.168.22.0/24 (réseau B)
  • 192.168.227.0/24 (réseau C)

Un poids ou coût de 20 leur a été attribué.

Coupons maintenant la liaison GRE (numéro 0) entre tun.a et tun.b, en executant sur tun.b la commande suivante:

# ifconfig gre0 down

Regardons toujours sur tun.a, la RIB (les lignes inutiles sont masquées):

192.168.13.0/24      172.16.2.1        Intra-Area   Network   20      01:26:07
192.168.22.0/24      172.16.2.1        Intra-Area   Network   30      00:00:13
192.168.22.0/24      172.16.1.1        Intra-Area   Network   30      00:00:13
192.168.227.0/24     172.16.1.1        Intra-Area   Network   20      01:26:26

Le réseau B 192.168.22.0/24 n'est plus annoncé comme accessible via 172.16.0.1 (tun.a) mais par 2 nouvelles routes 172.16.2.1 (tun.d) et 172.16.1.1 (tun.c). Cela montre bien que la route défectueuse est contournée. Ce qui est confirmé par l'augmentation du coût de ces routes (30 au lieu de 20).

Coupons maintenant la liaison GRE (numero 2) entre tun.a et tun.d, voici la RIB:

192.168.13.0/24      172.16.1.1        Intra-Area   Network   30      00:00:09
192.168.22.0/24      172.16.1.1        Intra-Area   Network   30      00:04:56
192.168.227.0/24     172.16.1.1        Intra-Area   Network   20      01:31:09

Une route vers 192.168.22.0/24 a bien disparue.

Coupons maintenant la liaison GRE (numero 3) entre tun.c et tun.d, voici la RIB:

192.168.13.0/24      172.16.1.1        Intra-Area   Network   30      00:00:41
192.168.22.0/24      172.16.1.1        Intra-Area   Network   40      00:05:28
192.168.227.0/24     172.16.1.1        Intra-Area   Network   20      01:31:41

La route vers 192.168.22.0/24 est toujours disponible, mais a un coût elevée (40), vu que de tun.a, nous passons par tun.c puis tun.d pour joindre tun.b. Donc malgré 3 coupures notre réseau est toujours fonctionnel, du moment qu'un site possède toujours au moins 1 connexion GRE.

vendredi, octobre 4 2013 21:25

Tunnel GRE sous OpenBSD

Objectifs

Permettre de relier 2 réseaux distincts via un tunnel GRE.

Le protocole GRE permet de relier des réseaux IP différents en masquant le ou les réseaux routés intermédiaires. Pour cela un paquet IP d'un reseau A, à destination du réseau B, à l'entrée du tunnel, est encapsulé dans un autre paquet IP pour être transmis via les réseaux intermédaires (ex: internet, réseau WAN etc). Arrivé sur le réseau B, à l'autre bout du tunnel, le paquet IP est désencapsulé et peut reprendre son trajet sur le réseau B. Ainsi sur le réseau B, ce paquet ne porte plus aucune trace d'un transport sur d'autres réseaux intermédiaires.

Attention, par contre, vu qu'il s'agit d'une encapsulation d'IP sur IP, sans autre traitement, les données sont donc transmises en claire. Pour chiffrer les données, et ainsi sécuriser leur transport sur les réseaux intermédiaires, il est possible par exemple d'utiliser IPSec par dessus le tunnel GRE. Cependant, s'il s'agit de faire transiter que des flux déjà chiffrés (ssh, https, etc), GRE garde tout son intérêt, grâce à sa simplicité de mise en oeuvre, et à sa légèreté.

Topologie de la maquette

Plages d'adresses des 2 reseaux à relier:

  • 192.168.16.x pour le réseau A
  • 192.168.22.x pour le réseau B

Le réseau WAN utilisé pour le tunnel possède une plage d'ip en 192.168.122.x.

Le serveur OpenBSD sur le réseau A, appellé tun.a, possède les adresses IP suivantes:

  • 192.168.122.16 sur le réseau WAN
  • 192.168.16.254 sur le réseau A

Le serveur OpenBSD sur le réseau B, appellé tun.b, possède les adresses IP suivantes:

  • 192.168.122.22 sur le réseau WAN
  • 192.168.22.254 sur le réseau B

Voir le schéma suivant:

Tunnel GRE

Pré-requis

Pare-feu

Dans un premier temps, pour faciliter la mise en oeuvre, n'appliquons aucun filtrage sur les interfaces GRE.

Ajouter la ligne suivante, sur les 2 serveurs, dans le début du fichier /etc/pf.conf:

set skip on gre0

Autorisation des tunnels GRE

Pour autoriser au niveau du noyau les tunnels de type GRE, il faut ajouter sur les 2 serveurs, la ligne suivante dans /etc/sysctl.conf:

net.inet.gre.allow=1

Et pour l'appliquer immédiatement, taper la commande suivante:

# sysctl -w net.inet.gre.allow=1

Autorisation du routage

Pour activer le routage IP, il faut ajouter la ligne suivante dans /etc/sysctl.conf:

net.inet.ip.forwarding=1

Et pour l'appliquer immédiatement, taper la commande suivante:

# sysctl -w net.inet.ip.forwarding=1

Configuration

Il s'agit de configurer un tunnel utilisant les adresses suivantes à ses extrémités:

  • 172.16.0.1 sur tun.a
  • 172.16.0.2 sur tun.b

L'interface utilisée pour le tunnel sera nommée gre0 en rapport avec le protocole utilisé GRE.

Sur le serveur tun.a

Contenu du fichier /etc/hostname.gre0

172.16.0.1 172.16.0.2 netmask 0xffffffff link0 up
tunnel 192.168.122.16 192.168.122.22
!route add -net 192.168.22 -netmask 255.255.255.0 172.16.0.2

Sur le serveur tun.b

Contenu du fichier /etc/hostname.gre0

172.16.0.2 172.16.0.1 netmask 0xffffffff link0 up
tunnel 192.168.122.22 192.168.122.16
!route add -net 192.168.16 -netmask 255.255.255.0 172.16.0.1

Validation

Il faut s'assurer que le traffic est bien routé vers l'entrée du tunnel, soit le serveur OpenBSD fait office de passerelle par défaut pour les clients de son réseau, soit il faut ajouter sur ces derniers, une route pour indiquer que les flux vers réseau distant doit passer par le serveur OpenBSD.

Exemple de route à ajouter sur un client Linux du réseau A en 192.168.16.0/24:

# ip route add 192.168.22.0/24 via 192.168.16.254

La même chose pour un client Linux du réseau B en 192.168.22.0/24:

# ip route add 192.168.16.0/24 via 192.168.22.254

Ensuite un simple ping d'un client A vers un client B devrait fonctionner:

[client01.a] $ ping 192.168.22.1
host 192.168.22.1 is alive!

voila!

Exemple de trames interceptées par un tcpdump sur un des serveurs OpenBSD:

12:20:43.026311 FF:FF:00:e8:e7:aa 52:54:00:3f:44:e6 0800 122: gre 192.168.122.16 > 192.168.122.22:  192.168.16.1 > 192.168.22.1: icmp: echo request (id:7e77 seq:243) (ttl 254, id 22932, len 84) (ttl 64, id 30293, len 108)
12:20:43.027113 FF:FF:00:3f:44:e6 52:54:00:e8:e7:aa 0800 122: gre 192.168.122.22 > 192.168.122.16:  192.168.22.1 > 192.168.16.1: icmp: echo reply (id:7e77 seq:243) (ttl 254, id 7409, len 84) (ttl 64, id 33582, len 108)

Ce qui confirme que le ping est bien transmis, et que les trames GRE passent bien en claires, car on voit des paquets GRE entre nos serveurs OpenBSD avec leurs adresses IP du réseau WAN, et à l'intérieur du paquet, les requetes ICMP sur les réseaux A et B.

jeudi, mai 21 2009 15:07

Connexion SSH à travers un Proxy Web

Il est possible de faire passer une connexion SSH à travers un proxy web du moment que celui-ci autorise la méthode CONNECT. Cette méthode est utilisée lors des connexions HTTPs par exemple et sert à établir un tunnel HTTP. Il est de ce fait assez courant qu'un proxy (ou serveur mandataire) laisse passer ce genre de communication. Tant mieux car c'est ce que nous allons utiliser.

Pour nous faciliter cette tâche, il existe un utilitaire qui s'occupe d'établir une fausse connexion HTTP entre votre machine et la machine distante. Car un proxy n'est juste qu'un relai, entre une machine sur le réseau local qui demande une requête HTTP, et le serveur distant. Ce logiciel demande donc à notre proxy web, s'il peut se connecter à la machine distante pour communiquer avec elle. Le serveur proxy s'exécute en pensant qu'il va s'agir d'une communication HTTPs, notre logiciel communique donc maintenant avec la machine distante et passe maintenant le relai à la commande ssh. Cet utilitaire s'appelle "corkscrew" (tire-bouchon en anglais), son site officiel est ici.

corkscrew

L'avantage de cette méthode, c'est que la machine distante n'a pas à avoir de configuration spécifique. Le seul problème est quand le proxy web n'est pas autorisé à joindre le port 22 (ssh) sur une machine distante, car c'est assez rare que des machines s'échangent des données en HTTP avec ce port. Dans ce cas, il suffit soit de faire une redirection de port sur la machine distante (ip proxy => port 443 => port 22/ssh), soit de lancer le démon ssh en écoute sur un autre port. Il suffira de choisir le port 443 qui correspond habituellement au HTTPs pour être tranquille avec ce genre de filtrage.

Comment parler à votre proxy

Pour tester votre proxy:

[tipiak@client ~]$ nc proxy.reseau.local 3128
CONNECT serveur.distant.com:22 HTTP/1.1
Host: serveur.distant.com:22 (appuyer sur entrée 2 fois)
....
blabla...
Access Denied
...

Si le proxy vous répond par une page html, comme quoi vous n'avez pas acces, c'est donc que les communications vers le port 22 sont interdites. Restera la méthode vers le port 443 qui sera en fait redirigé vers votre démon ssh:

[tipiak@client ~]$ nc proxy.reseau.local 3128
CONNECT serveur.distant.com:443 HTTP/1.1
Host: serveur.distant.com:443

HTTP/1.0 200 Connection established

Voilà, c'est mieux.

Configuration du client SSH

La configuration du client SSH permet d'indiquer une commande qui sert à établir une connexion à un intermediaire. C'est avec ce paramètre que nous allons indiquer qu'il faille utiliser corkscrew. Soit vous modifier la configuration du client ssh sur la machine de manière globale, et donc toutes les connexions ssh passeront par corkscrew, soit vous utilisez un fichier de configuration annexe qui sera utilisé au cas par cas. Le fichier de configuration du client est /etc/ssh/ssh_config. Pour avoir la manière globale suffit de le modifier directement, sinon il faut le copier dans un autre fichier (par exemple cp /etc/ssh/ssh_config ~/corkscrew.conf).

Pour utiliser corkscrew, il faut ajouter cette ligne:

# remplacer proxy.reseau.local par l'adresse du proxy
# remplacer 3128 par le port du proxy
ProxyCommand /usr/local/bin/corkscrew proxy.reseau.local 3128 %h %p

L'appel à la commande "ssh serveur.distant.com" sera donc remplacé par "/usr/local/bin/corkscrew proxy.reseau.local 3128 serveur.distant.com 22", dans le cas de la configuration globale. Si vous avez opté pour la manière au cas par cas, il faut indiquer à la commande ssh notre fichier de configuration spécifique:

ssh -f ~/corkscrew.conf toto@serveur.distant.com

Si comme expliquez plus haut, le port 22 est interdit, on précisera le numero de port distant (ici 443):

ssh -f ~/corkscrew.conf toto@serveur.distant.com -p443

Et voilà.

Configuration éventuelle du serveur SSH

Cette configuration n'intervient que si le port 22 par défaut pour le protocole SSH est interdit par le serveur proxy. Il existe 2 méthode pour utiliser un autre port pour votre serveur SSH:

  • Associer le démon sur un autre port pour l'écoute en plus du port 22
  • Utiliser le pare-feu pour rediriger un flux vers le port 22

Associer le démon ssh au port 443

Il faut editer le fichier /etc/ssh/sshd_config et s'assurer d'avoir les lignes suivantes:

Port 22
Port 443

Il ne reste plus qu'à relancer le service sshd:

[root@serveur ~]# service sshd restart

Rediriger la connexion vers le port 22

Cette méthode est plus complexe mais si vous avez déjà un serveur web en HTTPs sur votre serveur distant vous n'aurez pas trop le choix. Pour cela on rajoute une configuration dans le pare-feu:

*nat
:PREROUTING ACCEPT [7:913]
:POSTROUTING ACCEPT [1:83]
:OUTPUT ACCEPT [1:83]
# Requetes entrantes
-A PREROUTING -s <IP PUBLIQUE DU PROXY> -p tcp -m tcp --dport 443 -j DNAT --to-destination <IP PUBLIQUE DU SERVEUR>:22
# Requetes sortantes
-A POSTROUTING -s <IP PUBLIQUE DU SERVEUR> -p tcp -m tcp --sport 22 -d <IP PUBLIQUE DU PROXY> -j SNAT --to-source <IP PUBLIQUE DU SERVEUR>:443
COMMIT
*filter
[...]
# HTTPS
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
[...]

Cette configuration se fait dans le fichier /etc/sysconfig/iptables associée au service iptables (à relancer après les modifications). Ceci est bien sûr un exemple, qu'il faudra adapter.

Autres méthodes

Il existe d'autres utilitaires que corkscrew, comme hts ou httptunnel (cf billet du blog de Nicolargo). Les man-pages de ssh_config semble aussi nous indiquer que c'est possible avec netcat/nc.

L'ultime solution, si le proxy n'accepte pas les tunnels HTTP, reste l'utilisation d'un shell dans une page web, avec l'excellent AjaxTerm (attention à la sécurité).