From Wiki
Jump to: navigation, search

Quagga is a Package to add advanced routing features in a Linux Box. http://www.quagga.net/

Installation Quagga with TCP_MD5SIGN Support on Debian Etch

Quagga version 0.99.11 includes the TCP_MD5SIGN authentication for BGP sessions

We need to compile the kernel with the experimental TCP_MD5SIG set to yes. This options is only available for kernel greater than 2.6.20 as experimental. On Debian etch you can download the sources of etchandhalf kernel.

root@kyle-mvno-bgp-01:/boot# grep TCP_MD5SIG config-2.6.24-tcpmd5

Instructions about how to compile the kernel can be found in:

- [[1]]

We don't need ipv6 enabled in the Debian, so we can disable it throw:

# vi /etc/modprobe.d/aliases 
alias net-pf-10 off
# alias net-pf-10 ipv6

We need to enable ipv4 fowarding in the kernel:

 # more /etc/sysctl.conf

We download the latest Quagga source available in our case 0.99.11 and we compile it

 # wget http://www.quagga.net/download/quagga-0.99.11.tar.gz
 # tar -zxvf quagga-0.99.11.tar.gz
 #  ./configure --enable-vtysh --sysconfdir=/etc/quagga --localstatedir=/var/quagga --disable-ipv6
 # make
 # make install

We need to create the user quagga, needs to be in a group that can write the /etc folder. So we add it in the root group

 # useradd quagga
 # chown -R quagga /etc/quagga/
 # mkdir /var/quagga
 # chown -R quagga /var/quagga/
 # chmod 775 /var/run
 # touch /var/log/zebra.log
 # touch /var/log/bgpd.log
 # chown quagga /var/log/zebra.log
 # chown quagga /var/log/bgpd.log

To start the daemon we just run

 # cp /etc/quagga/zebra.conf.sample /etc/quagga/zebra.conf
 # zebra -d

To connect to the vty:

debian:~# vtysh 

Hello, this is Quagga (version 0.99.11).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

In order to get it automatically started during boot time we need to set up /etc/init.d scrip like this one:

#! /bin/sh
set -e
# /etc/init.d/quagga: start and stop the Quagga routing suite daemons
test -x /usr/local/sbin/zebra || exit 0
export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"
case "$1" in
       echo -n "Starting Quagga Zebra Daemon"
	start-stop-daemon --start  --pidfile /var/quagga/zebra.pid --exec /usr/local/sbin/zebra -- -d
       echo "."

       echo -n "Starting Quagga BGPd Daemon"
  start-stop-daemon --start  --pidfile /var/quagga/bgpd.pid --exec /usr/local/sbin/bgpd -- -d
       echo "."

       echo -n "Stopping Quagga Zebra Daemon"
	start-stop-daemon --stop --quiet --oknodo --pidfile /var/quagga/zebra.pid
       echo "."

       echo -n "Stopping Quagga BGPd Daemon"
  start-stop-daemon --stop --quiet --oknodo --pidfile /var/quagga/bgpd.pid
       echo "."

       $0 stop
       sleep 1
       $0 start

	echo "Usage: /etc/init.d/quagga {start|stop|restart}"
	exit 1

exit 0

and update rc.d with:

update-rc.d quagga defaults

Adding TCP_MD5SIGN BGP support on the sources

To add the BGP protocol functionality we need to create a bgpd.conf file in the /etc/quagga/bgpd.conf. Quagga version 0.99.11 we can enable it, but we need to change some sources.

this is the patch that we need to apply to the source

diff -rupN quagga-0.99.11-ori/configure quagga-0.99.11/configure
--- quagga-0.99.11-ori/configure	2008-10-02 04:31:36.000000000 -0400
+++ quagga-0.99.11/configure	2009-01-23 09:43:12.000000000 -0500
@@ -28836,7 +28836,7 @@ cat >>conftest.$ac_ext <<_ACEOF
 # include <netinet/ip_icmp.h>

-      #include <netinet/tcp.h>
+#include <linux/tcp.h>

diff -rupN quagga-0.99.11-ori/lib/sockopt.c quagga-0.99.11/lib/sockopt.c
--- quagga-0.99.11-ori/lib/sockopt.c	2008-09-05 10:27:26.000000000 -0400
+++ quagga-0.99.11/lib/sockopt.c	2009-01-23 09:48:20.000000000 -0500
@@ -537,15 +537,22 @@ sockopt_tcp_signature (int sock, union s
       * Sadly, it doesn't seem to work at present. It's unknown whether
       * this is a bug or not.
+      /* GF - 20090123 - Disabled this part of code due to compilation errors,
+       *  disabled IPV6 so safe enough
       if (su2->sa.sa_family == AF_INET6
           && su->sa.sa_family == AF_INET)
            su2->sin6.sin6_family = AF_INET6;
+        */
           /* V4Map the address */
+       /*
            memset (&su2->sin6.sin6_addr, 0, sizeof (struct in6_addr));
            su2->sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
            memcpy (&su2->sin6.sin6_addr.s6_addr32[3], &su->sin.sin_addr, 4);
+      */
   memset (&md5sig, 0, sizeof (md5sig));
diff -rupN quagga-0.99.11-ori/lib/zebra.h quagga-0.99.11/lib/zebra.h
--- quagga-0.99.11-ori/lib/zebra.h	2008-09-24 11:22:51.000000000 -0400
+++ quagga-0.99.11/lib/zebra.h	2009-01-23 09:43:34.000000000 -0500
@@ -139,7 +139,7 @@ typedef int socklen_t;
 #endif /* HAVE_NETINET_IN_H */
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
-#include <netinet/tcp.h>
+#include <linux/tcp.h>
 #include <net/netopt.h>

to apply the patch we just copy this

tar -zxvf quagga-0.99.11.tar.gz
patch -p0 < program.patch

Configuring BGP

Create and edit /etc/quagga/bgpd.conf.

Start vtysh

etch32-bgp:~# vtysh
etch32-bgp# configure terminal
etch32-bgp(config)# router bgp 3
etch32-bgp(config-router)# neighbor remote-as 1
etch32-bgp(config-router)# neighbor password BGPtutorial
etch32-bgp(config-router)# network
etch32-bgp(config-router)# quit
etch32-bgp(config)# router-id
etch32-bgp(config)# exit
etch32-bgp# write
Building Configuration...
Configuration saved to /etc/quagga/bgpd.conf

Setting up BGP filters

ip prefix-list BGP-FILTER-IN seq 20 deny le 32
ip prefix-list BGP-FILTER-IN seq 21 deny le 32
ip prefix-list BGP-FILTER-IN seq 22 deny le 32
ip prefix-list BGP-FILTER-IN seq 30 deny le 32
ip prefix-list BGP-FILTER-IN seq 31 deny le 32
ip prefix-list BGP-FILTER-IN seq 32 deny le 32
ip prefix-list BGP-FILTER-IN seq 33 deny le 32     
ip prefix-list BGP-FILTER-IN seq 34 deny le 32
ip prefix-list BGP-FILTER-IN seq 35 deny le 32
ip prefix-list BGP-FILTER-IN seq 40 permit le 32 
ip prefix-list BGP-FILTER-OUT seq 10 permit
ip prefix-list BGP-FILTER-OUT seq 20 deny any

router bgp 65001
 bgp router-id
 neighbor remote-as 123
 neighbor prefix-list BGP-FILTER-IN in
 neighbor prefix-list BGP-FILTER-OUT out
 neighbor remote-as 123
 neighbor password passwrod
 neighbor prefix-list BGP-FILTER-IN in
 neighbor prefix-list BGP-FILTER-OUT out

How the Best Path Algorithm Works

Bgp Algorithm

BGP assigns the first valid path as the current best path. BGP then compares the best path with the next path in the list, until BGP reaches the end of the list of valid paths. This list provides the rules that are used to determine the best path:

1. Prefer the path with the highest WEIGHT. WEIGHT is a Cisco-specific parameter. It is local to the router on which it is configured.

2. Prefer the path with the highest LOCAL_PREF. A path without LOCAL_PREF is considered to have had the value set with the bgp default local-preference command, or to have a value of 100 by default.

3. Prefer the path that was locally originated via a network or aggregate BGP subcommand or through redistribution from an IGP. Local paths that are sourced by the network or redistribute commands are preferred over local aggregates that are sourced by the aggregate-address command.

4. Prefer the path with the shortest AS_PATH. This step is skipped if you have configured the bgp bestpath as-path ignore command. An AS_SET counts as 1, no matter how many ASs are in the set. The AS_CONFED_SEQUENCE and AS_CONFED_SET are not included in the AS_PATH length.

5. Prefer the path with the lowest origin type. Note: IGP is lower than Exterior Gateway Protocol (EGP), and EGP is lower than INCOMPLETE.

6. Prefer the path with the lowest multi-exit discriminator (MED). This comparison only occurs if the first (the neighboring) AS is the same in the two paths. Any confederation sub-ASs are ignored. In other words, MEDs are compared only if the first AS in the AS_SEQUENCE is the same for multiple paths. Any preceding AS_CONFED_SEQUENCE is ignored. If bgp always-compare-med is enabled, MEDs are compared for all paths. You must disable this option over the entire AS. Otherwise, routing loops can occur. If bgp bestpath med-confed is enabled, MEDs are compared for all paths that consist only of AS_CONFED_SEQUENCE. These paths originated within the local confederation. THE MED of paths that are received from a neighbor with a MED of 4,294,967,295 is changed before insertion into the BGP table. The MED changes to to 4,294,967,294. Paths received with no MED are assigned a MED of 0, unless you have enabled bgp bestpath med missing-as-worst . If you have enabled bgp bestpath med missing-as-worst, the paths are assigned a MED of 4,294,967,294. The bgp deterministic med command can also influence this step. Refer to How BGP Routers Use the Multi-Exit Discriminator for Best Path Selection for a demonstration.

7. Prefer eBGP over iBGP paths.

8. Prefer the path with the lowest IGP metric to the BGP next hop.

9. Determine if multiple paths require installation in the routing table for BGP Multipath.

10. When both paths are external, prefer the path that was received first (the oldest one).

11. Prefer the route that comes from the BGP router with the lowest router ID.

12. If the originator or router ID is the same for multiple paths, prefer the path with the minimum cluster list length.

13. Prefer the path that comes from the lowest neighbor address.

AS-path prepending

as-path prepend

Sometimes you are forced to deal with less than ideal ISPs (or the two ISPs you’re using are so far apart in the Internet topology that the BGP local preference solution doesn’t work). In these cases, the only means of influencing BGP route selection in the Internet is the extension of the AS path attribute (routes with shorter AS paths are preferred) with multiple copies of your own AS number: AS-path prepending. AS-path prepending is configured in Cisco IOS with route-map based per-neighbor outbound filter. The actual prepending is specified within the route-map with the set as-path prepend command, as illustrated in the following sample configuration:

router bgp 65001
neighbor remote-as 65200
neighbor description Backup ISP
neighbor route-map prepend out
route-map prepend permit 10
set as-path prepend 65001 65001 65001

To add the AS-PATH only in one network, we need to create an access-list for it, and a second access list to enable everything else. Then the route map we will add the path first to the routes we want to, and finally we allow everthing.

router bgp 64626
bgp router-id
timers bgp 30 90
neighbor remote-as 1234
neighbor password goodpass
neighbor route-map set-as-path out
access-list 1 permit
access-list 2 permit any
route-map set-as-path permit 10
match ip address 1
set as-path prepend 64626 64626 64626
route-map set-as-path permit 20
match ip address 2

The output of the advertised routes will be something like:

# show ip bgp neighbors advertised-routes 
BGP table version is 0, local router ID is
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>               0         32768 i
*>               0         32768 64626 64626 64626 i