OBSD4* : wiki

Version de traduction basée sur la 6.2 officielle


PF - Pools d'Adresses et Équilibrage de Charge

Introduction

Un pool d'adresses est une fourniture de deux ou plusieurs adresses dont l'utilisation est partagée par un groupe d'utilisateurs. Il peut être spécifié en tant qu'adresse ciblée dans les options de filtrage que sont nat-to, rdr-to, route-to, reply-to et dup-to.

Il y a quatre manières d'utiliser un pool d'adresse :

  • bitmask - greffe la partie réseau d'un pool d'adresse au-dessus de l'adresse qui doit être modifiée (adresse source de règles nat-to, adresse de destination des règles rdr-to). Par exemple : si un pool d'adresse est 192.0.2.1/24 et que l'adresse modifiée est 10.0.0.50, l'adresse résultante sera 192.0.2.50. Si le pool d'adresse est 192.0.2.1/25 et que l'adresse modifiée est 10.0.0.130, alors l'adresse résultante sera 192.0.2.2.
  • random - sélectionne aléatoirement une adresse depuis un pool.
  • source-hash - utilise un hachage d'une adresse source pour déterminer quelle adresse utiliser depuis le pool. Cette méthode assure qu'une adresse source donnée soit toujours liée à un même pool d'adresses. La clé qui est fournie à l'algorithme de hachage peut en option être spécifiée après le mot-clé source-hash dans un format hexadécimal ou depuis une chaîne de caractères. Par défaut, pfctl(8) génère une clé aléatoire chaque fois que le jeu de règles est chargé.
  • round-robin - boucle au-travers du pool d'adresses de manière séquentielle. C'est la méthode par défaut et aussi la seule méthode permise quand le pool d'adresses est spécifié depuis une table.

Exceptée pour la méthode round-robin, le pool d'adresses doit être expressément un bloc réseau CIDR (Classless Inter-Domain Routing - Routage Inter-domaine Sans Classe). La méthode round-robin acceptera de multiples adresses individuelles par l'usage de listes ou de tables.

L'option sticky-address peut être utilisée avec les types de pool random et round-robin pour s'assurer qu'une adresse source particulière soit toujours liée à la même adresse de redirection.

Pool d'adresses NAT

Un pool d'adresses peut être utilisé comme traduction d'adresses dans une règle nat-to. Les connexions auront leur adresse source traduite vers une adresse depuis le pool selon la méthode choisie. Cela peut être pratique dans les situations où PF doit faire du NAT sur un très grand réseau. Puisque le nombre de connexions NATées par traduction d'adresse est limité, l'ajout de traduction d'adresse additionnelle permettra à la passerelle NAT de s'adapter à un nombre croissant d'utilisateurs.

Dans cet exemple, un pool de deux adresses est utilisé pour traduire les paquets sortants. Pour chaque connexion sortante, PF fera tourner les adresses de manière circulaire :

  match out on egress inet nat-to { 192.0.2.5, 192.0.2.10 }

Un inconvénient avec cette méthode est que les connexions successives à partir d'une même adresse interne ne seront pas toujours traduites à la même adresse de traduction. Cela peut causer des interférences, par exemple, lors de la consultation de sites web qui surveillent les connexions des utilisateurs en fonction de l'adresse IP. Une approche alternative consiste à utiliser la méthode source-hash afin que chaque adresse interne soit toujours traduite à la même adresse de traduction. Pour ce faire, le pool d'adresses doit être un bloc réseau CIDR.

  match out on egress inet nat-to 192.0.2.4/31 source-hash

Cette règle utilise le pool d'adresses 192.0.2.4/31 (192.0.2.4 - 192.0.2.5) comme traduction d'adresse pour les paquets sortants. Chaque adresse interne sera toujours traduite vers la même adresse de traduction à cause du mot-clé source-hash.

Équilibrage de charge des connexions entrantes

Les pools d'adresses peuvent aussi être utilisés pour équilibrer la charge des connexions entrantes. Par exemple, les connexions entrantes d'un serveur web peuvent être distribuées au-travers d'une ferme de serveurs web :

  web_servers = "{ 10.0.0.10, 10.0.0.11, 10.0.0.13 }"
  
  match in on egress proto tcp to port 80 rdr-to $web_servers \
      round-robin sticky-address

Les connexions successives seront redirigées vers les serveurs web de manière circulaire, les connexions provenant de la même source étant envoyées au même serveur web. Cette “connexion collante” existera tant qu'il y aura des états qui font référence à cette connexion. Une fois que les états expirent, la connexion collante expire aussi. Les connexions ultérieures de cet hôte seront redirigées vers le serveur web suivant dans le Round Robin.

Équilibrage de charge des connexions sortantes

Les pools d'adresses peuvent être utilisés en combinaison avec l'option de filtrage route-to pour équilibrer la charge de deux ou plusieurs connexions internet quand un protocole approprié de routage multi-voies (tel que BGP4) est indisponible. Par l'usage de route-to avec un pool d'adresses round-robin, les connexions sortantes peuvent être uniformément distribuées sur de multiples trajets sortants. Une autre partie additionnelle de l'information nécessaire pour faire cela est l'adresse IP du routeur adjacent à chaque connexion internet. Ceci est alimenté par l'option route-to pour contrôler la destination des paquets sortants.

L'exemple suivant équilibre le trafic sortant au-travers deux connexions internet :

  lan_net = "192.168.0.0/24"
  int_if  = "dc0"
  ext_if1 = "fxp0"
  ext_if2 = "fxp1"
  ext_gw1 = "198.51.100.100"
  ext_gw2 = "203.0.113.200"
  
  pass in on $int_if from $lan_net route-to \
     { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } round-robin

L'option route-to est utilisée sur le trafic entrant d'une interface interne pour spécifier les interfaces réseaux de sortie sur lesquelles le trafic sera équilibré au-travers de leur passerelle respective. Notez que l'option route-to doit être présente sur chaque règle de filtrage qui doit équilibrer le trafic (il ne peut être utilisé avec des règles match).

Pour s'assurer que les paquets ayant une adresse source appartenant à $ext_if1 sont toujours routés vers $ext_gw1 (et de la même manière pour $ext_if2 et $ext_gw2), les deux lignes suivantes doivent être incluses dans le jeu de règles :

  pass out on $ext_if1 from $ext_if2 route-to ($ext_if2 $ext_gw2)
  pass out on $ext_if2 from $ext_if1 route-to ($ext_if1 $ext_gw1)

Finalement, la NAT peut être aussi utilisée sur chaque interface sortante :

  match out on $ext_if1 from $lan_net nat-to ($ext_if1)
  match out on $ext_if2 from $lan_net nat-to ($ext_if2)

Un exemple complet d'équilibre de charge de trafic sortant peut ressembler à quelque chose comme cela :

  lan_net = "192.168.0.0/24"
  int_if  = "dc0"
  ext_if1 = "fxp0"
  ext_if2 = "fxp1"
  ext_gw1 = "198.51.100.100"
  ext_gw2 = "203.0.113.200"
  
  #  nat outgoing connections on each internet interface
  match out on $ext_if1 from $lan_net nat-to ($ext_if1)
  match out on $ext_if2 from $lan_net nat-to ($ext_if2)
  
  #  default deny
  block in
  block out
  
  #  pass all outgoing packets on internal interface
  pass out on $int_if to $lan_net
  #  pass in quick any packets destined for the gateway itself
  pass in quick on $int_if from $lan_net to $int_if
  #  load balance outgoing traffic from internal network.
  pass in on $int_if from $lan_net \
      route-to { ($ext_if1 $ext_gw1), ($ext_if2 $ext_gw2) } \
      round-robin
  #  keep https traffic on a single connection; some web applications,
  #  especially "secure" ones, don't allow it to change mid-session
  pass in on $int_if proto tcp from $lan_net to port https \
      route-to ($ext_if1 $ext_gw1)
  
  #  general "pass out" rules for external interfaces
  pass out on $ext_if1
  pass out on $ext_if2
  
  #  route packets from any IPs on $ext_if1 to $ext_gw1 and the same for
  #  $ext_if2 and $ext_gw2
  pass out on $ext_if1 from $ext_if2 route-to ($ext_if2 $ext_gw2)
  pass out on $ext_if2 from $ext_if1 route-to ($ext_if1 $ext_gw1)

Cette page est la traduction officieuse de la page “Address pools and load balancing de la FAQ officielle d'OpenBSD.
En cas de doute, merci de vous y référer !

Si vous voulez participer à l'effort de traduction, merci de lire ce topic.