Quagga: installation-paramétrage

De wikiGite

D'après http://openmaniak.com/fr/quagga.php :
"Quagga est un logiciel de routage open source basé sur le routeur Zebra dont le développement fut arrêté en 2003. Il supporte les principaux protocoles de routage standardisés comme RIP, OSPF et BGP et peut être installé sur n'importe quel système Linux muni d'un noyau 2.4 ou supérieur."

Il présente l'avantage d'être simple et de proposer un jeu de commandes identiques, voire compatible, avec l'iOS de Cisco, leader du marché des routeurs.

Installation

# apt-get install quagga # sur Debian

ou

# yum install quagga # sur CentOS/RH
# chkconfig zebra on # pour l'activer au démarrage
# chown quagga /etc/quagga/*

Editer /etc/sysctl.conf, activer l'ip forwarding

net.ipv4.ip_forward=1

Et, pour permettre le BGP multihomed, désactiver les "rp filter"

net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0

Valider les modifications :

# sysctl -p

Il pourra être également utile de forcer la vitesse et le mode des interfaces réseau. On utilisera alors :

# apt-get install ethtool # sur Debian

ou

# yum install ethtool # sur CentOS/RH

Pour voir la configuration actuelle :

# ethtool eth0

Pour la modifier :

# ethtool -s eth0 speed 100 duplex full autoneg off

Note : pour revenir à l'autonégociation, il faudra relancer

ethtool -s eth0 autoneg on

La configuration des interfaces doit être minimum, les routes seront faites par BGP. Exemple pour eth1, connectée à un peer par BGP :

Debian: /etc/network/interfaces

auto eth1
iface eth1 inet static
   address 172.16.0.128
   netmask 255.255.0.0

CentOS: /etc/sysconfig/network

NETWORKING=yes
HOSTNAME=router.domain.com

Ce fichier ne doit pas contenir de ligne du genre

GATEWAY=192.168.1.254 # ou GATEWAYDEV

Dans /etc/sysconfig/network-scripts/ifcfg-ethX

DEVICE="eth0"
BOOTPROTO=static
NM_CONTROLLED="yes"
ONBOOT="yes"
NAME="System eth0"

Ces fichiers ne doivent pas contenir des lignes du genre

IPADDR=192.168.1.15
PREFIX=24 # ou NETMASK
GATEWAY=192.168.1.254

Configuration BGP

Editer /etc/quagga/daemons, activer zebra (le démon principal a gardé son ancien nom) et bgpd

# vi /etc/quagga/daemons

vtysh_enable=yes
zebra=yes
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no

Créer un fichier de configuration (même vide) pour chaque démon à lancer. Le plus simple est de copier les fichiers d'exemples fournis

# cp /usr/share/doc/quagga/examples/zebra.conf.sample /etc/quagga/zebra.conf
# cp /usr/share/doc/quagga/examples/bgpd.conf.sample /etc/quagga/bgpd.conf 

Modifier les permissions :

# chown quagga.quaggavty /etc/quagga/*.conf
# chmod 640 /etc/quagga/*.conf

Modifier ce qui doit l'être dans ces fichiers (hostname, password... voir plus bas).

Fichier DEBIAN.CONF

Ce fichier indique quelles adresses les démons doivent écouter (pour les connexions telnet distantes). Par défaut 127.0.0.1.

Contrairement aux tutoriels, on ne peut pas ajouter d'adresses. C'est une ou rien.

bgpd_options=" --daemon -A 192.168.1.104" # Ecoute sur l'interface 192.168.1.104

Ou

bgpd_options=" --daemon " # Ecoute sur toutes les interfaces

Comme on va paramétrer vtysh pour les connexions locales, on peut mettre ici l'adresse de l'interface interne pour autoriser les telnet en cas de problème.

Relancer Quagga

# /etc/init.d/quagga restart

Utilisation

On peut accéder aux démons individuellement avec telnet, en appelant leur numéro de port

# telnet localhost 1788

Mais il est plus simple d'utilise vtysh, qui permet de n'avoir qu'une seule interface. Vtysh doit être activé dans debian.conf (vtysh_enable=yes).

Récupérer le fichier de configuration d'exemple

# cp /usr/share/doc/quagga/examples/vtysh.conf.sample /etc/quagga/vtysh.conf

Modifier ce qui doit l'être (mot de passe, ...)

!
! Configuration file for vtysh.
!
!service integrated-vtysh-config
hostname quagga-router
username root nopassword
!

Modifier les permissions

# chown quagga.quaggavty /etc/quagga/*.conf
# chmod 640 /etc/quagga/*.conf

Et relancer Quagga

# /etc/init.d/quagga restart

Pour éviter un message "END" an haut à gauche au lancement de vtysh, ajouter dans etc/environment

VTYSH_PAGER=more

Ce paramètre sera pris en compte au prochain login. Pour le prendre en compte dans la session en cours :

export VTYSH_PAGER=more

Configuration BGP multihomed

On a au moins 2 lignes vers internet, le traffic doit passer plus vers l'un ou l'autre selon ce qu'on décide.

On paramètre tout d'abord /etc/quagga/zebra.conf qui nomme le routeur et décrit les interfaces

! -*- zebra -*-
!
hostname Bgp1
password zebra
enable password zebra
service advanced-vty
!
! Interface's description. 
!
interface lo
  no shutdown
interface eth0
  description ETH0-192.168.130
  no multicast
  no shutdown
interface eth1
  description ETH1-172.16.0
  no multicast
  no shutdown
interface eth2
  description ETH2-10.0.0
  no multicast
  no shutdown
interface eth3
  description ETH3-192.168.130
  no multicast
  no shutdown
!
! Static default route
!ip route 0.0.0.0/0 192.168.130.254
!
log file /var/log/quagga/zebra.log

Puis bgpd.conf qui définit la configuration BGP

! -*- bgp -*-
!
hostname bgpd1
! vtysh password
password zebra
! CLI advanced password (superuser)
enable password zebra
service advanced-vty
!
!bgp config-type cisco
!bgp mulitple-instance
!
! Debugging. Comment on production time.
debug bgp events
debug bgp filters
debug bgp fsm
debug bgp keepalives
debug bgp updates
!
! ASN
router bgp 197462
   bgp router-id 192.168.130.254
   bgp log-neighbor-changes
   network 192.168.130.0 mask 255.255.255.0
   no synchronization
!   redistribute connected
! Peer One
   neighbor 172.16.0.254 remote-as 51169
   neighbor 172.16.0.254 description PeerOne
   neighbor 172.16.0.254 version 4
   neighbor 172.16.0.254 password abcde12345
   neighbor 172.16.0.254 soft-reconfiguration inbound
!   neighbor 172.16.0.254 prefix-list local_nets in
   neighbor 172.16.0.254 route-map pictavixpref in
   neighbor 172.16.0.254 route-map pictavixprepend out
!
! Peer Two
   neighbor 10.0.0.254 remote-as 174
   neighbor 10.0.0.254 description PeerTwo
   neighbor 10.0.0.254 version 4
   neighbor 10.0.0.254 password efghi67890
   neighbor 10.0.0.254 soft-reconfiguration inbound
!   neighbor 10.0.0.254 prefix-list local_nets in
   neighbor 10.0.0.254 route-map cogentpref in
   neighbor 10.0.0.254 route-map cogentprepend out
!
no auto-summary
! IN : we deny unwanted networks routes
!ip prefix-list local_nets deny 0.0.0.0/8
!ip prefix-list local_nets deny 10.0.0.0/8
!ip prefix-list local_nets deny 127.0.0.0/8
!ip prefix-list local_nets deny 172.16.0.0/12
!ip prefix-list local_nets deny 192.168.0.0/16
!ip prefix-list local_nets deny 169.254.0.0/16
!ip prefix-list local_nets deny 224.0.0.0/4
!ip prefix-list local_nets deny 240.0.0.0/4
! Then we allow everything else (=public networks routes)
!ip prefix-list local_nets permit any
! OUT : we announce only our block, and no transit through us
ip prefix-list our_net description Only our allowed routing announcements
ip prefix-list our_net seq 10 permit 192.168.130.0/24
ip prefix-list our_net seq 20 deny 0.0.0.0/0 le 32
! Can also be said like that ?
!ip prefix-list our_net seq 10 permit ^$
!ip prefix-list our_net seq 20 deny any
!
!matches anything that goes over cogent's network. we'll use it to make sure upload to cogent-connected hosts goes also via Cogent line
ip as-path access-list tocogent permit ^174$
ip as-path access-list tocogent permit ^702$
!
! Route maps for outgoing traffic
route-map pictavixpref permit 10
   set local-preference 200
route-map cogentpref permit 10
   match as-path tocogent
   set local-preference 400
route-map cogentpref permit 20
   set local-preference 100
! Route maps for inbound traffic
route-map pictavixprepend permit 10
   match ip address prefix-list our_net
   set as-path prepend 0
route-map cogentprepend permit 10
   match ip address prefix-list our_net
   set as-path prepend 197462 197462 197462
!
! Limit route tables received from peers
!neighbor xx.xx.xx.xx maximum-prefix 250000
!
log file /var/log/quagga/bgpd.log
!
!log stdout
!
!line vty
!no login

Relancer quagga. Dans vtysh, "sh ip bgp" doit faire apparaitre petit à petit les routes.

Notes

Attention à ne pas confondre les termes. BGP ne s'occupe que de recevoir ou envoyer des informations concernant des ROUTES. Il ne s'occupe pas des données qui transite par lui à destination du réseau interne ou vers internet.

  • "OUTBOUND" ("out" dans le fichier de configuration) décrit les informations (prefixes IP) "envoyées aux voisins". On parle ici de ce que BGP a annoncé à internet pour que l'extérieur arrive jusqu'aux IPs qu'il gère. En terme de flux, ce sera donc le traffic de données "venant de l'extérieur" vers les IPs internes.

On va prioriser la ligne sur laquelle on veut recevoir le traffic venant de l'extérieur en faisant en sorte que le chemin (les différents AS à traverser) soit plus court pour cette route, et pour ça on augmente artificiellement le chemin de l'autre route en ajoutant plusieurs fois notre AS au début : c'est le prepend.

  • "INBOUND" ("in" dans le fichier de configuration) est par conséquent, ce que BGP "reçoit de ses voisins", les routes du monde entier, qui oriente le traffic "venant de l'intérieur" vers internet.

On priorise une des 2 lignes vers internet en définissant une local-preference sur cette ligne. BGP la choisira plutôt que l'autre pour tout ce qui sortira.

Exemples de commandes vtysh

Lancer vtysh pour avoir le prompt (ici "quagga-router#"), ou lancer ces commandes directement par vtysh -c "commande à lancer".

Tout comme sur Cisco, la touche tabulation permet l'auto-completion (et éventuellement l'affichage des options disponibles pour une commande).

Tout comme sur Cisco, les commandes peuvent être abrégées : "sh" pour "show", "sum" pour "summary", "nei" pour "neighbors", "int" pour "interface", etc... Du moment que l'abréviation ne porte pas à confusion entre 2 commandes.

Voir la configuration actuelle :

quagga-router# show running-config

vérifier si l'ip forwarding est activé sur le système :

quagga-router# show ip forwarding

Voir la configuration des interfaces

quagga-router# show interface

Voir les statistiques BGP, sessions et préfixes reçus

quagga-router# sh ip bgp sum
# Ici, "ip" signifie "ipv4", sinon il prend "ipv6" par défaut

Voir la configuration d'un des voisins

quagga-router# sh ip bgp neighbors 172.16.0.254

Voir les routes reçues des voisins

quagga-router# sh ip bgp

Voir un route spécifique, avec les chemins possibles et le "best"

quagga-router# sh ip bgp <IP à atteindre>

Voir les routes locales

quagga-router# sh ip route

Réinitialiser une session après changements dans les règles outbound :

quagga-router# clear ip bgp 172.16.0.254 soft out

Réinitialiser une session après changements dans les règles inbound :

quagga-router# clear ip bgp 172.16.0.254

Passer en mode config immediate (sans redémarrage de quagga) :

quagga-router# conf t

Plus tard, lorsque des modifications seront faites sur le routeur, la sauvegarde se fera par

quagga-router# copy running-config startup-config

Couper une des sessions BGP (en réalité : couper l'interface correspondante) :

conf t
int eth1
shut

Pour la relancer

conf t
int eth1
no shut

Failover avec keepalived (vrrp)

On peut avoir 2 routeurs redondants côté BGP (si les peer acceptent 2 sessions pour le même bloc IP), mais côté réseau interne se pose le problème de la passerelle par défaut. Les postes ne peuvent en avoir qu'une, et les deux routeurs ne peuvent pas avoir la même adresse. On utilise donc une IP virtuelle.

Pour mettre en place VRRP et partager une adresse IP entre les routeurs, on installe keepalived qui inclut vrrp et est notoirement stable (par rapport au démon vrrpd seul qui semble buggué et qui n'est pas documenté du tout).

apt-get install keepalived

Configurer un des noeuds en MASTER et l'autre en BACKUP. Ils ont chacun une adresse physique + une adresse virtuelle partagée sur le même sous-réseau.

/etc/keepalived.conf sur le MASTER :

# Configuration File for Keepalived

# Global Configuration
global_defs {
  notification_email {
    admin@domaine.net
  }
  notification_email_from keepalived@domaine.net
  smtp_server localhost
  smtp_connect_timeout 30
  lvs_id KA_MASTER		# string identifying the machine
}

# describe virtual service ip
vrrp_instance VI_INT {
  state MASTER
  interface eth0
  virtual_router_id 1
  priority 100
  garp_master_delay 5
  advert_int 2
#  authentication {
#    auth_type PASS
#    auth_pass zebra
#  }
  virtual_ipaddress {
    192.168.130.254/24
  }
  notify_backup "/etc/keepalived/start_stop_bgp.sh stop"
  notify_master "/etc/keepalived/start_stop_bgp.sh start"
  notify_fault  "/etc/keepalived/start_stop_bgp.sh stop"
}

/etc/keepalived.conf sur le BACKUP :

# Configuration File for Keepalived

# Global Configuration
global_defs {
  notification_email {
    admin@domaine.net
  }
  notification_email_from keepalived@domaine.net
  smtp_server localhost
  smtp_connect_timeout 30
  lvs_id KA_BACKUP		# string identifying the machine
}

# describe virtual service ip
vrrp_instance VI_INT {
  state BACKUP
  interface eth0
  virtual_router_id 1
  priority 50
  garp_master_delay 5
 advert_int 2
#  authentication {
#    auth_type PASS
#    auth_pass zebra
#  }
  virtual_ipaddress {
    192.168.130.254/24
  }
  notify_backup "/etc/keepalived/start_stop_bgp.sh stop"
  notify_master "/etc/keepalived/start_stop_bgp.sh start"
  notify_fault  "/etc/keepalived/start_stop_bgp.sh stop"
}

Pour BGP, on peut créer un script qui arrête quagga si l'adresse virtuelle quitte le MASTER, et le démarre sur le BACKUP qui devient la passerelle. Dans /etc/keepalived, créer start_stop_bgp.sh :

#!/bin/bash
if [ "$1" == "start" ]
then
# Start BGP interfaces then Quagga
  ifup eth1
  ifup eth2
  /etc/init.d/quagga restart
else
# Stop Quagga then BGP interfaces
  /etc/init.d/quagga stop
  ifdown eth1
  ifdown eth2
fi

Keepalives se charge de lancer le script avec le bon paramètre au besoin.

Note : Ici les peers n'acceptent pas 2 sessions BGP simultanées de la part de 2 routeurs (en clair : ils n'acceptent qu'un seul connexion venant d'un seul routeur), il faut donc également arrêter/démarrer les interfaces pour être sûr qu'un seul routeur se connecte.