Installing and configuring Quagga Open Source Routing


Quagga is an open source routing package for TCP/IP networks. It has evolved out of the Zebra routing code formally  Kunishiro Ishiguro’s zebra routing package. You can implement IP routing protocols such as RIP, RIPng, OSPF and ISIS and uses the standard Linux kernel for forwarding.


Installing Quagga

Add user and group quagga

groupadd quagga
useradd -g quagga -s /bin/false quagga

Before installing quagga, it is necessary to prepare the quagga directories and files; and change ownership:

mkdir /etc/quagga
mkdir /var/state/quagga
touch /var/log/zebra.log
touch /var/log/ospfd.log
touch /var/log/bgpd.log
chown quagga:quagga /etc/quagga
chown quagga:quagga /var/state/quagga

Install quagga :

./configure --enable-user=quagga --enable-group=quagga --enable-vty-group=quagga \
 --prefix=/usr --sysconfdir=/etc/quagga -localstatedir=/var/state/quagga
 make install

2) Configuring and running Zebra

Run Zebra daemon. Flags: -d – run as daemon, -A listen to, –retain – if quagga crashes don’t remove routes learned form it(can be dangerous).

zebra -d -A --retain

Login to zebra VTY. Default password is zebra

telnet 2601

After logging in change to read-write mode. Password is also zebra


Configure the basics. Remove comments before pasting

 conf t                    #enter configuration mode
 hostname Quagga-zebra            #change hostname
 enable password your_enable_password    #enable password, 8 alphanums MAX!
 password your_vty_password        #VTY(ro) password is 8 alphanums MAX!
 service password-encryption        #encrypts password (weak encryption - protect anyway!)
 access list 1 permit        #create ACL allowing only localhost
 log file /var/log/zebra.log debugging    #configure logging
 log record-priority             #includes severity to log messages
 line vty                #configure terminal lines
 login                    #enforrce loging
 access-class 1                #allow only ACL 1 to login
 end                    #exit configuration
 wr mem                    #write configuration

3) Configuring and running Ospfd

Allow other OSPF routers’s to pass data to ospfd daemon. Since OSPF doesn’t use TCP nor UDP only working ruleset I could think of is(add to the end of the INPUT chain):

iptables -A INPUT -i ethX -s PEER_IP -p tcp -j DROP
 iptables -A INPUT -i ethX -s PEER_IP -p udp -j DROP
 iptables -A INPUT -i ethX -s PEER_IP -j ACCEPT

Where ethX is the interface connecting to the OSPF speaker and PEER_IP is its IP address.

Start the ospfd daemonand login to read-write mode. Password is zebra.

ospfd -d -A
telnet 2604

Configure the basics, copy/paste from zebra config. Remember to change hostname and log file form zebra to ospfd!

Configure OSPF related settings. Remove comments and replace keywords before pasting.

conf t
 router ospf                #configure ospf process
 passive-interface default        #disable OSPF on all interfaces
 no passive-interface ethX        #enable OSPF on int ethX
 log-adjacency-changes detail        #log some fancy stuff
 network X.X.X.X/prefix    area 0        #announce network X.X.X.X/prefix and enable ospf on that interface
 area 0 authentication message-digest    #configure md5 authentication between peers
 int ethX                #configure interface ethX
 ip ospf message-digest-key 1 md5 ospf_peer_password #configure peer password, max 16 alphanums

Remember that every interface you wan’t to use must have it’s primary network configured with network statement or secondary IPs won’t be announced.
3) Configuring and running Bgpd

BGP listens on port 179, but like FTP it must also listen to other ports for connections from port 179. First, we must allow that packet through. Repeat for every BGP peer:

iptables -A INPUT -p tcp -s neighbor_ip --dport 179 -i neighbor_interface -j ACCEPT
iptables -A INPUT -p tcp -s neighbor_ip --sport 179 -i neighbor_interface -j ACCEPT

Run bgpd:

bgpd -d -A

Configure the basics, copy/paste from zebra config. Remember to change hostname and log file form zebra to bgpd!

Configure your AS(remove comments):
configure terminal
 router bgp your_as_number
 bgp log-neighbor-changes    //usefull for debuging
 bgp always-compare-med         //compares MED from different peers
 bgp graceful-restart         //makes reseting bgp sessions less invasive
 network x.x.x.x/prefix         //announces our network over BGP

NOTE: Quagga doesn’t care if network specified in network statement in BGP is present in routing table. It announces it anyway, unlike other routers like Cisco.

Next we need to prepare inbound and outbound filters because we don’t want to be transit AS or recive crappy routes.

We announce only our AS:

ip as-path access-list 1 permit ^$

Now, lets filter crappy and bogous routes. We will also create simple MED based route selector(Remember bgp always-compare-med?):

First create matches to use with a route-map:

! matches any local routes - we don't want that!
 ip prefix-list no_local seq 5 permit le 32
 ip prefix-list no_local seq 10 permit le 32
 ip prefix-list no_local seq 15 permit le 32
 ip prefix-list no_local seq 20 permit le 32
 ip prefix-list no_local seq 25 permit your_prefix le 32
! matches multicast and reserved address space
 ip prefix-list no_multi seq 5 permit le 32
 ip prefix-list no_multi seq 10 permit le 32
!matches a route going through our AS - bad
 ip as-path access-list with_our_as permit _yourASnumber_

And the route-map itself

route-map peer_1_in deny 10
 match ip address prefix-list no_local
route-map peer_1_in deny 20
 match ip address prefix-list no_multi
route-map peer_1_in deny 30
 match as-path  with_our_as
route-map peer_1_in permit 65535
 set metric 50

Numbers on the end of lines above are sequence numbers – lower numbers gets processed first. Exception is the last line, it sets MED to 50. If we have multiple peers, and routes to same destinations are of same length, routes with lower MED will be used .

And now for peers themselves:

neighbor neighbor_ip remote-as neighbor_as
 neighbor neighbor_ip description neighbor_name
 neighbor neighbor_ip capability dynamic
 neighbor neighbor_ip soft-reconfiguration inbound
 neighbor neighbor_ip maximum-prefix 1000000
 neighbor neighbor_ip route-map peer_1_in in
 neighbor neighbor_ip filter-list 1 out

You should be set by now. Verify by checking: sh ip bgp neighbors(look for established status)


Comments are closed.

%d bloggers like this: