IOS + Linux = Quagga
Posted by Alex Juncu
Cisco IOS’s shell is a popular interface for devices in the networking world. But also in the network world, there are a lot of Linux/Open Source fans. The Quagga open source project tries to bring together IOS and Linux, by providing an IOS-like interface for configuring Linux’s interfaces, routing table and firewall, along side its own implementations of RIP, OSPF and BGP daemons.
The Quagga Software Routing Suite comes as a set of daemos. The main one is the zerbra daemon (Zebra is the old name of the project). This core daemon does the interaction with the Linux kernel and, also, with other daemons like ripd (RIP daemon), ospfd (OSPF daemon), bgpd (BGP daoemon). Quagga is modular, so you can implement new protocols if needed via a standard API.
To configure Quagga, you first need to start the daemons (at least the core one), in the /etc/quagga/daemons file. Each daemon has its own configuration file (ex. /etc/quagga/zebra.conf, /etc/quagga/ripd.conf etc.). Accessing the IOS-like shell is done via the vtysh command. Once in this shell, most commands available in Cisco’s IOS are available.
Router / # cd
Router ~ # vtyshHello, this is Quagga (version 0.99.18).
Copyright 1996-2005 Kunihiro Ishiguro, et al.Router# conf t
Router(config)# hostname LinuxRouter
LinuxRouter(config)# exit
LinuxRouter# show ?
bgp BGP information
clns clns network information
daemons Show list of running daemons
debugging State of each debugging option[...]
Keep in mind that some things are not 100% identical to a Cisco router (ex. the interface names). Here’s an example of how to configure an interface.
LinuxRouter# conf t
LinuxRouter(config)# interface eth0
LinuxRouter(config-if)# ip address 141.85.42.1 ?
A.B.C.D/M IP address (e.g. 10.0.0.1/8)
LinuxRouter(config-if)# ip address 141.85.42.1/24
LinuxRouter(config-if)# link-detect
Monitor output (show commands) are similar aside some Linux specific details (ex. Kernel routes are available in Linux, but not in IOS).
Router# sh ip route
Codes: K – kernel route, C – connected, S – static, R – RIP, O – OSPF,
I – ISIS, B – BGP, > – selected route, * – FIB routeK * 0.0.0.0/0 via 192.0.2.1, venet0 inactive
O 10.10.12.0/24 [110/10] is directly connected, eth0, 00:03:41
C>* 10.10.12.0/24 is directly connected, eth0
O 10.10.14.0/24 [110/10] is directly connected, eth1, 00:03:36
C>* 10.10.14.0/24 is directly connected, eth1
O>* 10.10.23.0/24 [110/20] via 10.10.12.2, eth0, 00:02:46
O>* 10.10.24.0/24 [110/20] via 10.10.12.2, eth0, 00:02:14
*via 10.10.14.4, eth1, 00:02:14
O>* 10.10.25.0/24 [110/20] via 10.10.12.2, eth0, 00:02:41
O>* 10.10.35.0/24 [110/30] via 10.10.12.2, eth0, 00:01:21
* via 10.10.14.4, eth1, 00:01:21
O>* 10.10.45.0/24 [110/20] via 10.10.14.4, eth1, 00:02:08
C>* 127.0.0.0/8 is directly connected, lo
C>* 127.0.0.1/32 is directly connected, venet0
C>* 172.10.10.0/32 is directly connected, venet0
K>* 192.0.2.1/32 is directly connected, venet0
Configuring a routing protocol instance is also similar:
LinuxRouter# conf t
LinuxRouter(config)# router ospf
LinuxRouter(config-router)# network 192.168.123.0/0 area 0
As you can see, coming from an IOS background, this tool is very easy to use on your Linux box. It is far from perfect since it doesn’t have the years in production like IOS or iproute2, but it is cool to test out.
ACL case study: The hidden defaults of ACLs
Posted by Alex Juncu
Unlike Linux’s iptables, Cisco’s filtering via Access Control Lists sometimes has hidden behavior.
Let us test how ACL filtering works using the following topology. We assume that we have Layer 3 connectivity via static routes. We will apply ACLs on the outbound direction of F1/0 on R2 (we want it to be somewhere in the path from R1 to R3)

With no ACLs applied anywhere, all traffic will flow.
R1#ping 3.3.3.3 source 1.1.1.1
Packet sent with a source address of 1.1.1.1
!!!!!
Success rate is 100 percent
Let’s start with the basics and make a classic standard access list that denies R1’s loopback.
R2(config)#access-list 42 deny host 1.1.1.1
R2(config)#int f1/0
R2(config-if)#ip access-group 42 out
The loopback on R1 is blocked…
R1#ping 3.3.3.3 source 1.1.1.1
U.U.U
Success rate is 0 percent (0/5)
… but so is any other traffic that goes out of R2’s F1/0.
R1#ping 3.3.3.3 source F0/0
U.U.U
Success rate is 0 percent (0/5)
The first rule of Cisco’s ACLs is that there is an implicit deny (ip) all (all) rule at the end of every ACL. But this is not visible anywhere. You have to know it.
R2#sh access-lists
Standard IP access list 42
10 deny 1.1.1.1 (8 matches)
Extended IP access list BLOCK_HTTP
But if that ACL is empty? What if you apply an access list that does not contain any rules (was not declared)?
R2(config)#int f1/0
R2(config-if)#ip access-group 28 out
R2(config-if)#do sh access-lists
Standard IP access list 42
10 deny 1.1.1.1 (8 matches)
Extended IP access list BLOCK_HTTPR1#ping 3.3.3.3 source 1.1.1.1
Type escape sequence to abort.
!!!!!
Success rate is 100 percent
Traffic passes. The inexistent ACL applied on an interface is ignored. But this is because you can’t have an empty classical (numbered) ACL. What if you do the same thing with a named ACL?
R2(config)#ip access-list standard EMPTY_ACL
R2(config-std-nacl)#exit
R2(config)#do sh ip access-list
Standard IP access list 42
10 deny 1.1.1.1 (8 matches)
Standard IP access list EMPTY_ACL
Extended IP access list BLOCK_HTTP
R2(config)#int f1/0
R2(config-if)#ip access-group EMPTY_ACL out
R1#ping 3.3.3.3 source 1.1.1.1
Type escape sequence to abort.
!!!!!
Success rate is 100 percent
Traffic is still not filtered. So, the rule is that a empty (inexistant or deleted) ACL is ignored by the interface filter.
One more ACL applied on R2 with a deny all rule (no traffic should pass out of F1/0).
R2(config)#ip access-list standard DENY_ALL_ACL
R2(config-std-nacl)#deny any
R2(config-std-nacl)#do sh ip access
Standard IP access list 42
10 deny 1.1.1.1 (8 matches)
Standard IP access list DENY_ALL_ACL
10 deny any (8 matches)
Standard IP access list EMPTY_ACL
10 deny any (8 matches)
Extended IP access list BLOCK_HTTP
R2(config-std-nacl)#int f1/0
R2(config-if)#ip access-group DENY_ALL_ACL out
Ping form R1 is filtered.
R1#ping 3.3.3.3 source 1.1.1.1
Packet sent with a source address of 1.1.1.1
U.U.U
Success rate is 0 percent (0/5)
Since no traffic should go out the interface, a ping from R2 to R3 should also fail, yet it doesn’t.
R2#ping 3.3.3.3
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/20/44 ms
As a final rule, traffic generated by a router is never filtered by an ACL applied any interface of that router.