15,370 views
Using Fedora 9 as an OSPF / BGP router (Quagga / Zebra) and set up BGP between Linux and Juniper ScreenOS
In this post, I’m going to show you how to set up a Linux host (Fedora Core 9) and use it as a BGP enabled router.
In order to fully understand the setup & configuration, please have a look at this blog post first, because I’ll use the setup in that post as a foundation for this explanation.
Initial setup : basic Fedora 9 install, 2 network cards recognized by Fedora
eth0 : 192.168.100.100, mask 255.255.255.0 – no default gateway
eth1 : 192.168.3.1, mask 255.255.255.0 – no default gateway
This is what we will build :
( click to enlarge )
If you compare this drawing with the drawing in my post on BGP with ScreenOS, you’ll notice that I have simply added a linux host to the 192.168.100.0/24 network, and added a new network behind the linux host. The idea is to set up the Linux host to become part of BGP AS 65000 (IBGP). In a second phase, we’ll give the Linux host it’s own AS and we’ll form EBGP peers between the Linux host and one of the screenOS devices and see what the impact is. (I’ll write this procedure when I have more time in the next couple of days. We’ll start with IBGP first)
Set up Quagga Routing Suite
1. Install Quagga Routing Suite :
[root@router-3 /]# yum install quagga Loaded plugins: refresh-packagekit fedora | 2.4 kB 00:00 updates | 2.6 kB 00:00 Setting up Install Process Parsing package install arguments Resolving Dependencies --> Running transaction check ---> Package quagga.i386 0:0.99.9-6.fc9 set to be updated --> Finished Dependency Resolution Dependencies Resolved ============================================================================= Package Arch Version Repository Size ============================================================================= Installing: quagga i386 0.99.9-6.fc9 fedora 1.2 M Transaction Summary ============================================================================= Install 1 Package(s) Update 0 Package(s) Remove 0 Package(s) Total download size: 1.2 M Is this ok [y/N]: y Downloading Packages: (1/1): quagga-0.99.9-6.fc9.i386.rpm | 1.2 MB 00:06 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction Installing: quagga ######################### [1/1] Installed: quagga.i386 0:0.99.9-6.fc9 Complete!
2. Open /etc/services and see if the following entries are present. (On Fedora Core 9, most of these entries are present, except for ospfapi and isisd)
zebrasrv 2600/tcp # zebra service zebra 2601/tcp # zebra vty ripd 2602/tcp # RIPd vty ripngd 2603/tcp # RIPngd vty ospfd 2604/tcp # OSPFd vty bgpd 2605/tcp # BGPd vty ospf6d 2606/tcp # OSPF6d vty ospfapi 2607/tcp # ospfapi isisd 2608/tcp # ISISd vty
3. Set quagga global configuration options
The quagga configuration files can be found at /etc/quagga
We are interested in the OSPF / BGP components of quagga, which are provided by zebra. Thus we need to look at /etc/quagga/zebra.conf
After installing quagga, the only entry in the configuration file is the hostname. We need to add a password, otherwise the daemon will not allow us to connect to the configuration console. You can set an enable password as well, configure logging, etc
[root@router-3 quagga]# cat zebra.conf hostname router-3 password MyBadPassword enable password MyBadEnablePassword log file /var/log/quagga/zebra.log informational log stdout
You can now start the zebra daemon by running ‘service zebra start’. You can set the daemon to start at boot time by running ‘chkconfig zebra on’
[root@router-3 quagga]# chkconfig zebra on [root@router-3 quagga]# service zebra start Starting zebra: Nothing to flush. [ OK ] [root@router-3 quagga]#
Verify that the daemon is running :
[root@router-3 quagga]# netstat -vantu | grep 2601 tcp 0 0 127.0.0.1:2601 0.0.0.0:* LISTEN
4. Test if you can connect to the Quagga configuration console
[root@router-3 quagga]# telnet localhost 2601
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, this is Quagga (version 0.99.9).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
User Access Verification
Password:
router-3> enable
Password:
router-3# conf t
router-3(config)# sh
history Display the session command history
running-config running configuration
router-3(config)# sh r
Current configuration:
!
hostname router-3
password MyBadPassword
enable password MyBadEnablePassword
log file /var/log/quagga/zebra.log informational
log stdout
!
interface eth0
ipv6 nd suppress-ra
!
interface eth1
ipv6 nd suppress-ra
!
interface lo
!
interface pan0
ipv6 nd suppress-ra
!
interface sit0
ipv6 nd suppress-ra
!
ip forwarding
!
!
line vty
!
end
Configure Zebra BGP to form an IBGP peer with Juniper ScreenOS (and set up full mesh with ssg5-1 and ssg5-2)
First of all, we need to look at the connectivity between the Linux host and Juniper screenOS. The Linux host is not in the same IP subnet as the 2 screenOS devices, and if you look at the previous post, you can see that connectivity between the screenOS devices and the 192.168.100.0 network is handled via OSPF. This is fine, as long as you can make sure that connectivity between all hosts that need to become peers will work before you enable BGP. So you cannot rely on BGP to create routing between these hosts, because the routing needs to work before we can use BGP.
On ssg5-1, we can see that the route towards 192.168.100.0 is injected via OSPF (E2), which is ok. But on ssg5-2, the route is added via BGP (iB), and this may cause problems. Think about it : If you disable BGP and reenable BGP, the route will disappear, which will make the Linux host unreachable for ssg5-2, so it will not be able to reach the host again in order to become peers.
ssg5-1-> get route | incl 192.168.100.0 * 1057 192.168.100.0/24 eth0/1 192.168.0.7 E2 200 10 Root ss5-2-> get route | incl 192.168.100.0 * 28 192.168.100.0/24 eth0/1 192.168.0.7 iB 250 0 Root
So on ssg5-2, we need to add a static route to 192.168.100.0/24, and on the Linux host, we also need to set up some routing.
ss5-2-> set route 192.168.100.0/24 gate 192.168.0.7 ss5-2-> get route | incl 192.168.100.0 * 29 192.168.100.0/24 eth0/1 192.168.0.7 S 20 1 Root 28 192.168.100.0/24 eth0/1 192.168.0.7 iB 250 0 Root
This will ensure that, even if BGP is down, the static route will ensure that ssg5-2 can reach the 192.168.100.0/24 network. So while the active route is the one that is distributed via BGP, the static route will take over the moment BGP goes away, ensuring connectivity at all times.
On Linux, we can either count on a default gateway that points to 192.168.100.2 in order to be able to route to the 192.168.0.0/24 network, or you can simply add a route towards the 192.168.0.0/24 network. Either way, we will need some kind of route, because this is required for the Linux host to be able to talk to the other 2 IBGP hosts (ssg5-1 : 192.168.0.8 and ssg5-2 : 192.168.0.30). We won’t use a default gateway, we’ll just do direct routing :
Edit /etc/rc.d/rc.local and add the following line to the file :
/sbin/route add -net 192.168.0.0/24 gw 192.168.100.2
After making the change, the file should look like this :
[root@router-3 /]# cat /etc/rc.d/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local /sbin/route add -net 192.168.0.0/24 gw 192.168.100.2
This will make sure the static route is available when the Linux machine boots. (a.k.a. making the route permanent)
In order to add the route to the routing table right away, simply run the command from the command prompt :
[root@router-3 /] #/sbin/route add -net 192.168.0.0/24 gw 192.168.100.2
Look at the routing table, you should see this :
[root@router-3 ~]# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.100.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 192.168.0.0 192.168.100.2 255.255.255.0 UG 0 0 0 eth0
Or, verify the routing via the zebra daemon :
[root@router-3 ~]# telnet localhost 2601 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Hello, this is Quagga (version 0.99.9). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: router-3> enable Password: router-3# sh ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - ISIS, B - BGP, > - selected route, * - FIB route C>* 127.0.0.0/8 is directly connected, lo K>* 192.168.0.0/24 via 192.168.100.2, eth0 C>* 192.168.3.0/24 is directly connected, eth1 C>* 192.168.100.0/24 is directly connected, eth0
Furthermore, this linux host should now be able to connect to 192.168.0.8 and 192.168.0.30 :
[root@router-3 /]# ping 192.168.0.8 PING 192.168.0.8 (192.168.0.8) 56(84) bytes of data. 64 bytes from 192.168.0.8: icmp_seq=1 ttl=64 time=6.07 ms 64 bytes from 192.168.0.8: icmp_seq=2 ttl=64 time=1.75 ms 64 bytes from 192.168.0.8: icmp_seq=3 ttl=64 time=1.92 ms ^C --- 192.168.0.8 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2160ms rtt min/avg/max/mdev = 1.757/3.251/6.073/1.996 ms [root@router-3 /]# ping 192.168.0.30 PING 192.168.0.30 (192.168.0.30) 56(84) bytes of data. 64 bytes from 192.168.0.30: icmp_seq=1 ttl=64 time=4.95 ms 64 bytes from 192.168.0.30: icmp_seq=2 ttl=64 time=1.91 ms 64 bytes from 192.168.0.30: icmp_seq=3 ttl=64 time=1.45 ms ^C --- 192.168.0.30 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2406ms rtt min/avg/max/mdev = 1.452/2.772/4.954/1.554 ms
Next, we need to configure the Zebra based BGP daemon on the Linux host to become an IBGP peer of AS 65000
First, let’s set all IP properties of the Linux host using the Zebra daemon :
[root@router-3 /]# telnet localhost 2601
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, this is Quagga (version 0.99.9).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
User Access Verification
Password:
router-3> enable
Password:
router-3# conf t
router-3(config)# int eth0
router-3(config-if)# ip address 192.168.100.100/24
router-3(config-if)# exit
router-3(config)# int eth1
router-3(config-if)# ip address 192.168.3.8/24
router-3(config-if)# exit
router-3(config)# exit
router-3# write
Configuration saved to /etc/quagga/zebra.conf
router-3#
Now start the bgp daemon, so we can connect to it and set up the configuration.
[root@router-3 quagga]# service bgpd start Starting bgpd: [ OK ] [root@router-3 quagga]# netstat -vantu | grep 2605 tcp 0 0 127.0.0.1:2605 0.0.0.0:* LISTEN
[root@router-3 quagga]# telnet localhost 2605
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, this is Quagga (version 0.99.9).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
User Access Verification
Password:
router-3> enable
Password:
router-3# conf t
router-3(config)# router bgp 65000
router-3(config-router)# network 192.168.3.0/24
router-3(config-router)# neighbor 192.168.0.8 remote-as 65000
router-3(config-router)# exit
router-3(config)# write
Configuration saved to /etc/quagga/bgpd.conf
router-3(config)# exit
router-3# exit
At this point, the 192.168.3.0/24 network will be redistributed into BGP
There is another way of doing this, using the redistribute command, which may be more generic (but less specific if you want to) :
[root@router-3 ~]# telnet localhost 2605
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, this is Quagga (version 0.99.9).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
User Access Verification
Password:
router-3> enable
Password:
router-3# conf t
router-3(config)# router bgp 65000
router-3(config-router)# no network 192.168.3.0/24
router-3(config-router)# exit
router-3(config)# write
Configuration saved to /etc/quagga/bgpd.conf
#At this point, the 192.168.3.0 network is not being redistributed anymore. On ssg5-1 and ssg5-2, the network will be gone
#Since this is a connected net, we can redistribute this network using the redistribute command :
router-3(config-router)# redistribute connected
router-3(config-router)# exit
router-3(config)# write
Configuration saved to /etc/quagga/bgpd.conf
router-3(config)#
Set up ScreenOS to complete the peer with the Linux router
On ssg5-1 (192.168.0.8), set up the peer as well :
ssg5-1-> set vrouter trust-vr proto bgp neighbor 192.168.100.100 remote-as 65000 ssg5-1-> set vrouter trust-vr proto bgp neighbor 192.168.100.100 enable
ssg5-1-> get vrouter trust-vr proto bgp neighbor
Peer AS Remote IP Local IP Wt Status State ConnID Up/Down
--------------------------------------------------------------------------------
65000 192.168.0.30 192.168.0.8 100 Enabled ESTABLISH 3 20:40:49
65000 192.168.100.100 192.168.0.8 100 Enabled ESTABLISH 38 00:01:28
ssg5-1-> get route proto bgp IPv4 Dest-Routes for <untrust-vr> (0 entries) -------------------------------------------------------------------------------------- H: Host C: Connected S: Static A: Auto-Exported I: Imported R: RIP P: Permanent D: Auto-Discovered N: NHRP iB: IBGP eB: EBGP O: OSPF E1: OSPF external type 1 E2: OSPF external type 2 trailing B: backup route IPv4 Dest-Routes for <trust-vr> (36 entries) -------------------------------------------------------------------------------------- ID IP-Prefix Interface Gateway P Pref Mtr Vsys -------------------------------------------------------------------------------------- * 1072 192.168.3.0/24 eth0/1 192.168.0.7 iB 250 0 Root * 1044 192.168.2.0/24 eth0/1 192.168.0.30 iB 250 0 Root
So the route from router-3 (Linux) has now been added into the routing table of ssg5-1, which is what we have expected
Verify that everyting works
On Linux, the routing table looks fine :
[root@router-3 quagga]# telnet localhost 2601 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Hello, this is Quagga (version 0.99.9). Copyright 1996-2005 Kunihiro Ishiguro, et al. User Access Verification Password: router-3> enable Password: router-3# sh ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - ISIS, B - BGP, > - selected route, * - FIB route B>* 10.2.0.0/24 [200/0] via 192.168.0.8 (recursive via 192.168.100.2), 00:03:42 C>* 127.0.0.0/8 is directly connected, lo K>* 192.168.0.0/24 via 192.168.100.2, eth0 B>* 192.168.1.0/24 [200/0] via 192.168.0.8 (recursive via 192.168.100.2), 00:03:42 C>* 192.168.3.0/24 is directly connected, eth1 B 192.168.100.0/24 [200/0] via 192.168.0.7, 00:03:42 C>* 192.168.100.0/24 is directly connected, eth0 B>* 192.168.132.0/24 [200/0] via 192.168.0.1 (recursive via 192.168.100.2), 00:03:42
As you can see, despite the fact that the linux host and ssg5-1 are not directly connected, the routes table still looks fine. Network 192.168.1.0/24, which is a connected network behind ssg5-1, shows up in the routing table as reachable via 192.168.0.8, but recursive via 192.168.100.2 – BGP has ensured that the path towards the 192.168.1.0/24 network works and figured out the next hop itself.
Now you can use the same procedure to set up more peers (peer linux with ssg5-2). This should make the 192.168.2.0/24 network visible as well
Ok, so the routing tables on ssg5-1, ssg5-2 and router-3 are correct. But if you try to route from ssg5-1 towards 192.168.3.8, it doesn’t seem to work !
ssg5-1-> trace-route 192.168.3.8
Type escape sequence to escape
Send ICMP echos to 192.168.3.8, timeout is 2 seconds, maximum hops are 32,
1 3ms 2ms 2ms 192.168.0.7
2 * * *
3 * * *
4 * * *
5 * * *
6 Trace aborted
This is normal. We did not redistribute the new route (towards the 192.168.3.0/24 network) to OSPF, so router-1 doesn’t know about this new network yet
On ssg5-1, we need to create a new ACL (or edit the existing ACL) and route-map, and add this new network, so it can be redistributed from BGP into OSPF
ssg5-1-> get vrouter trust-vr route-map RedistBGPintoOSPF Route-map (RedistBGPintoOSPF) ---------------------- Entry (10) - Action (permit) ---------------------------- Match Fields ------------ ip-address: 5 (access-list) Set Fields ---------- ssg5-1-> get vrouter trust-vr route-map RedistBGPintoOSPF config set route-map name "RedistBGPintoOSPF" permit 10 set match ip 5 exit
ssg5-1-> set vrouter trust-vr ssg5-1(trust-vr)-> get access-list IPv4 Access Lists ------------------------------------------------ Access list (1) ---------------- Sequence 10: 0.0.0.0/0 -> Permit Access list (5) ---------------- Sequence 10: 192.168.2.0/24 -> Permit IPv6 Access Lists ------------------------------------------------ #edit the existing access-list that was used to redistribute from BGP into OSPF ssg5-1(trust-vr)-> set access-list 5 permit ip 192.168.3.0/24 20 ssg5-1(trust-vr)-> exit
On router-1 and router-2, the new route should be visible in the OSPF routing table. Furtmore, the trace-route from ssg5-1 towards 192.168.3.8 should now work :
ssg5-1-> trace-route 192.168.3.8
Type escape sequence to escape
Send ICMP echos to 192.168.3.8, timeout is 2 seconds, maximum hops are 32,
1 3ms 2ms 1ms 192.168.0.7
2 3ms 2ms 3ms 192.168.3.8
Everything works…
… but hosts on the 192.168.3.0/24 network cannot access the internet
Reason : router-3 does not have a default gateway. ssg5-1 has a connection to the internet (not shown on diagram), so the only thing you need to do is to distribute the default route on ssg5-1 into bgp
ssg5-1-> set vrouter trust-vr proto bgp network 0.0.0.0/0 ssg5-1> get vrouter trust-vr proto bgp network network weight check reachable-prefix rib-in route-map -------------------------------------------------------------------------------- 10.2.0.0/24 32768 yes 10.2.0.0/24 yes null 192.168.1.0/24 32768 yes 192.168.1.0/24 yes null 0.0.0.0/0 32768 yes 0.0.0.0/0 yes null
Check routing table on router-3, you should now see the default route. If not, make sure router-3 does not have an access list/setting to reject incoming default route
By default, bgpd itself does not advertise a default route, even if it is in the local routing table. You can change this behaviour using the no neighbor
Notes :
No Sync
In my first post about BGP, I discussed the “unset vrouter trust-vr proto bgp sync” command, that will ensure new routes are not being checked in IGP routing tables. In quagga, you can set the same behaviour with the following procedure :
[root@router-3 ~]# telnet localhost 2605
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello, this is Quagga (version 0.99.9).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
User Access Verification
Password:
router-3> enable
Password:
Password:
router-3# conf t
router-3(config)# router bgp 65000
router-3(config-router)# no bgp network import-check
router-3(config-router)# exit
router-3(config)# exit
router-3# write
Configuration saved to /etc/quagga/bgpd.conf
© 2008 – 2021, Peter Van Eeckhoutte (corelanc0d3r). All rights reserved.