GNS-3 Lab: 4-byte Autonomous System Number – interactions between 32 and 16 bit speaking BGP routers

Such as IPv4 addresses, 2-byte pool of Autonomous System (AS) Numbers is going to be exhausted soon. By the time I’m writing, it seems Internet will run out of 16-bit AS Number on 26-Sep-2012. To prevent this situation, IANA extended the AS Number field to 32 bits and, on 2007, RIRs started assigning them… or, at least, to offer them!
Of course, in order to let 4-byte ASN to work properly, a little adjustement was needed in the BGP protocol. Enter RFC 4893, BGP Support for Four-octet AS Number Space.

4-byte ASN - Lab topologyIn this post I don’t want to cover the mechanisms of this protocol extension, if you want to understand them I please you to follow some links in the References section; I prefer to show some interactions between OLD 2-byte ASN and NEW 4-byte ASN BGP speakers. I built a little GNS3/Dynamips lab using a couple of 7200s with IOS 12.2(33)SRE as NEW speakers, and a couple of 3640s as OLD peers.

In the topology every router announces any subnet to the others; BGP peering sessions follow the physical topology. Green ASs support 4-byte AS, while gray do not.
For the sake of readibility I’ll use asdot notation in this post, with the exception of some configuration blocks where I’ll use asplain just to show both notation usage.

I also uploaded two packet captures on PacketLife.net: they show BGP UPDATES with and without the NEW_AS_PATH attributes. They are 4-byte_AS_numbers_Full_Support.cap and 4-byte_AS_numbers_Mixed_Scenario.cap.

Partial 4-byte ASN support: A-B routers

Router A is on AS 10.1 / 655361 (asdot / asplain notation):

A#sh run | sec bgp
router bgp 655361
 no synchronization
 bgp log-neighbor-changes
 network 10.0.0.0
 neighbor 172.16.3.2 remote-as 2
 no auto-summary
B#sh run | sec bgp
router bgp 2
 no synchronization
 bgp log-neighbor-changes
 network 20.0.0.0
 neighbor 172.16.3.1 remote-as 23456
 no auto-summary

As you can see, on router B neighbor statement we can’t use the real ASN to peer with A, so we have to use the AS_TRANS (23456). Let’s wait until our sessions come up, then show BGP neighbors and tables:

A#sh ip bgp neighbors 172.16.3.2
BGP neighbor is 172.16.3.2,  remote AS 2, external link
  BGP version 4, remote router ID 20.0.0.1
  BGP state = Established, up for 00:00:27
  Last read 00:00:27, last write 00:00:27, hold time is 180, keepalive interval is 60 seconds
  Neighbor sessions:
    1 active, is not multisession capable
  Neighbor capabilities:
    Route refresh: advertised and received(new)
    Four-octets ASN Capability: advertised
    Address family IPv4 Unicast: advertised and received
    Multisession Capability: advertised
...

Please note the Four-octets ASN Capability: advertised line: A advertised this capability but did not receive it back from B.

A#sh ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0         0.0.0.0                  0         32768 i
*> 20.0.0.0         172.16.3.2               0             0 2 i

As expected, A receives the B‘s route but…

B#sh ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0         172.16.3.1               0             0 23456 i
*> 20.0.0.0         0.0.0.0                  0         32768 i

B only sees A‘s subnet as from AS_TRANS (23456).

This is because B does not support 4-byte ASN, and router A knows this (capabilities exchange during session setup), so it just sends AS_PATH attributes containing the 16-bit AS_TRANS in place of the real 32-bit AS number.

You can find a similar UPDATE on the first capture I sent on PacketLife.net (4-byte_AS_numbers_Mixed_Scenario.cap), packet number 2.

Full 4-byte ASN support: A-D routers

Let’s setup the BGP session between routers A and D; they both support 4-byte ASN.

A#sh run | sec bgp
router bgp 655361
 no synchronization
 bgp log-neighbor-changes
 network 10.0.0.0
 neighbor 172.16.1.2 remote-as 2621441
 neighbor 172.16.3.2 remote-as 2
 no auto-summary
D#sh run | sec bgp
router bgp 2621441
 no synchronization
 bgp log-neighbor-changes
 network 40.0.0.0
 neighbor 172.16.1.1 remote-as 655361
 no auto-summary

When sessions come up…

A#sh ip bgp neighbors 172.16.1.2
BGP neighbor is 172.16.1.2,  remote AS 40.1, external link
  BGP version 4, remote router ID 40.0.0.1
  BGP state = Established, up for 00:04:04
  Last read 00:00:46, last write 00:00:53, hold time is 180, keepalive interval is 60 seconds
  Neighbor sessions:
    1 active, is multisession capable
  Neighbor capabilities:
    Route refresh: advertised and received(new)
    Four-octets ASN Capability: advertised and received
    Address family IPv4 Unicast: advertised and received
    Multisession Capability: advertised and received
...

Here A both sent and received the 4-byte ASN capability to/by B, because it supports this feature.

A#sh ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0         0.0.0.0                  0         32768 i
*> 20.0.0.0         172.16.3.2               0             0 2 i
*> 40.0.0.0         172.16.1.2               0             0 2621441 i
D#sh ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0         172.16.1.1               0             0 655361 i
*> 20.0.0.0         172.16.1.1                             0 655361 2 i
*> 40.0.0.0         0.0.0.0                  0         32768 i

Both A and D have subnets with the full 32-bit AS number.

You can see the capture on the file 4-byte_AS_numbers_Full_Support.cap on PacketLife.net.

As I already said, let’s switch to asdot notation now, just to improve readibility:

D#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
D(config)#router bgp 40.1
D(config-router)#bgp asnotation dot
D(config-router)#do show ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0         172.16.1.1               0             0 10.1 i
*> 20.0.0.0         172.16.1.1                             0 10.1 2 i
*> 40.0.0.0         0.0.0.0                  0         32768 i
A#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
A(config)#router bgp 10.1
A(config-router)#bgp asnotation dot

Ok, 10.1 is better than 655361, and 40.1 than 2621441!! :)

Mixed scenario: D-B routers

Let’s have more fun now and bring D-B session up!

D(config-router)#neighbor 172.16.2.1 remote-as 2
B(config-router)#neighbor 172.16.2.2 remote-as 23456

As we already saw, B doesn’t support 4-byte ASN, so we have to use AS_TRANS to peer with D.

D#show ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*  10.0.0.0         172.16.2.1                             0 2 10.1 i
*>                  172.16.1.1               0             0 10.1 i
*> 20.0.0.0         172.16.2.1               0             0 2 i
*                   172.16.1.1                             0 10.1 2 i
*> 40.0.0.0         0.0.0.0                  0         32768 i

The interesting thing we can see now on D is the presence of A‘s subnet (10.0.0.0) advertised by B: even if B does not support 4-octect ASN, D receives it with the real 32-bit path. When A advertises the subnet to B it makes the AS_PATH attribute up using AS_TRANS, but it also adds the transitive attribute NEW_AS_PATH, containing the full 32-bit AS numbers; when B advertises the subnet to D it adds this attribute and so D can rebuild the real 32-bit path.

As before, you can find a similar UPDATE on the capture I sent on PacketLife.net; the file is 4-byte_AS_numbers_Mixed_Scenario.cap, packet number 3.

Another interesting aspect of 4-byte AS lack of support can be seen in the following table:

B#sh ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*  10.0.0.0         172.16.2.2                             0 23456 23456 i
*>                  172.16.3.1               0             0 23456 i
*> 20.0.0.0         0.0.0.0                  0         32768 i
*> 40.0.0.0         172.16.2.2               0             0 23456 i
*                   172.16.3.1                             0 23456 23456 i

Here B has two entries for the 10.0.0.0 subnet: they both seem to be originated from the same AS, but that’s not true: the first comes from D (AS 40.1), while the second (the selected one) comes directly from A.

Similar behaviour is for the 40.0.0.0 subnet. Of course, this is not a really big problem, but may lead to false assumptions and compromise traffic patterns analysis.

16-bit stub router

Just to complete all the possible scenarios, here is C configuration:

B#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
B(config)#router bgp 2
B(config-router)#neighbor 172.16.4.2 remote-as 3
C#sh run | sec bgp
router bgp 3
 no synchronization
 bgp log-neighbor-changes
 network 30.0.0.0
 neighbor 172.16.4.1 remote-as 2
 no auto-summary
C#sh ip bgp | beg Network
   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0         172.16.4.1                             0 2 23456 i
*> 20.0.0.0         172.16.4.1               0             0 2 i
*> 30.0.0.0         0.0.0.0                  0         32768 i
*> 40.0.0.0         172.16.4.1                             0 2 23456 i

It has no idea of what 4-byte ASN are, so it sees both 10.0.0.0 and 40.0.0.0 subnets as originated from the same AS.

Thanks

I have to say thanks to Marco Rizzi for his kind support on helping me to build this lab! ;-) And, of course, I suggest you to visit his blog: Marco Rizzi Blog – networking with passion!!!

Download the lab

To download the lab and configuration files click here.

References

Report on consumption of AS Numbers: http://www.potaroo.net/tools/asns/

BGP Support for Four-octet AS Number Space: RFC 4893

APRICOT 2007: 4-Byte AS Numbers (PDF)

Cisco.com: Migration Guide for Explaining 4-Byte Autonomous System

Cisco.com: Cisco IOS BGP 4-Byte ASN Support

Cisco.com: Explaining 4-Byte Autonomous System (AS) ASPLAIN and ASDOT Notation for Cisco IOS

GNS3 Lab: Any Transport over MPLS (AToM) basic configuration for Ethernet 802.1q and Frame-relay

AToM stands for Any Transport over MPLS, a quite reassuring technology which, provided you have a MPLS enabled network and some good gears, let you set up L2 circuits across your IP backbone.

This lab offers a very simple topology with 2 AToM links; an ethernet with an 802.1q trunk and a frame-relay link.

Core

Core (P) routers configuration is pretty simple; we only enable MPLS switching on interfaces toward PE routers and setup LDP for labels exchange. A good core doesn’t care about what kind of traffic it switches!

P1:

mpls label protocol ldp
!
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
!
interface FastEthernet0/0
 description PE1 facing interface
 mpls ip
!
interface FastEthernet1/0
 description P2 facing interface
 mpls ip
!
mpls ldp router-id Loopback0 force

PE routers

The hard work is done on PE routers. PE routers face CE routers, which they receive L2 traffic from, and network core P routers, which they have to send MPLS encapsulated traffic to.
In order to build up a L2 circuit, PE routers have to setup a pseudowire connection between them, so they know how to switch traffic. Each pseudowire uses a virtual-circuit ID (VC ID), which is locally significant on each PE pair and is used to identify the pseudowire itself and to bind it to a specific MPLS label.

First off, they must be MPLS aware:

PE2

mpls label protocol ldp
!
interface Loopback0
 ip address 1.1.2.2 255.255.255.255
!
interface FastEthernet0/1
 description P2 facing interface
 mpls ip
!
mpls ldp router-id Loopback0

Now, we have to set up pseudowires between PE and L2 connections with CEs.

Let’s start with the Ethernet 802.1q trunk.

Port mode Ethernet over MPLS (EoMPLS)

In port mode EoMPLS every frame received on a PE interface is forwarded to the other PE almost unchanged (just preamble and FCS are removed).

Basic configuration is very simple:

PE2

interface FastEthernet0/0
 description CE_Switch2 facing interface
 no ip address
 duplex auto
 speed auto
 xconnect 1.1.2.1 10 encapsulation mpls

The xconnect command does all the work! This command tells the PE router to encapsulate every frame in a MPLS packet and to forward it to the peer 1.1.2.1 using VC ID 10.
It also allow Label Distribution Protocol (LDP) to exchange informations about the pseudowire circuit between PEs (VC ID / label mapping, VC type, MTU).

Once we have applied this configuration to both PE routers (on PE1 we have to change the xconnect peer address!), we can verify if LDP did its work and if pseudowire is up:

PE2#show mpls l2transport vc 10 detail
Local interface: Fa0/0 up, line protocol up, Ethernet up
  Destination address: 1.1.2.1, VC ID: 10, VC status: up
    Output interface: Fa0/1, imposed label stack {18 16}
    Preferred path: not configured
    Default path: active
    Next hop: 172.16.2.0
  Create time: 01:16:07, last status change time: 01:15:44
  Signaling protocol: LDP, peer 1.1.2.1:0 up
    MPLS VC labels: local 16, remote 16
    Group ID: local 0, remote 0
    MTU: local 1500, remote 1500
    Remote interface description:
  Sequencing: receive disabled, send disabled
  VC statistics:
    [cut]

Now, setup and test VLAN connectivity on customer side:

Net1_H1#sh run int fa0/0 | beg interface
interface FastEthernet0/0
 ip address 192.168.1.1 255.255.255.0
 duplex auto
 speed auto
end
Net1_H2#sh run int fa0/0 | beg interface
interface FastEthernet0/0
 ip address 192.168.1.2 255.255.255.0
 duplex auto
 speed auto
end
Net1_H1#ping 192.168.1.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.1.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 148/168/192 ms

Frame-relay over MPLS, DLCI-to-DLCI mode

Frame-relay over MPLS requires a few more lines of configuration, but the pseudowire setup is the same as EoMPLS.

We have to enable frame-relay switching on the PE router, configure the Serial interface as DCE and setup the switching path for the DLCI:

PE2

frame-relay switching
!
interface Serial1/0
 no ip address
 encapsulation frame-relay IETF
 frame-relay intf-type dce
!
connect FR2-FR1 Serial1/0 201 l2transport
 xconnect 1.1.2.1 20 encapsulation mpls

PE1

frame-relay switching
!
interface Serial1/0
 no ip address
 encapsulation frame-relay IETF
 frame-relay intf-type dce
!
connect FR1-FR2 Serial1/0 102 l2transport
 xconnect 1.1.2.2 20 encapsulation mpls

Let’s verify everything is ok:

PE2#show mpls l2transport vc 20

Local intf     Local circuit              Dest address    VC ID      Status
-------------  -------------------------- --------------- ---------- ----------
Se1/0          FR DLCI 201                1.1.2.1         20         UP

With this configuration we have DLCI 102 for FR1-to-FR2 traffic, and DLCI 201 for FR2-to-FR1 traffic.

Customer side configuration:

FR1

interface Serial0/0
 no ip address
 encapsulation frame-relay IETF
!
interface Serial0/0.1 point-to-point
 ip address 172.16.0.1 255.255.255.252
 frame-relay interface-dlci 102

Similar configuration on FR2:

interface Serial0/0.1 point-to-point
 ip address 172.16.0.2 255.255.255.252
 frame-relay interface-dlci 201

Some tests…

FR1#show frame-relay lmi

LMI Statistics for interface Serial0/0 (Frame Relay DTE) LMI TYPE = CISCO
  Invalid Unnumbered info 0             Invalid Prot Disc 0
  Invalid dummy Call Ref 0              Invalid Msg Type 0
  Invalid Status Message 0              Invalid Lock Shift 0
  Invalid Information ID 0              Invalid Report IE Len 0
  Invalid Report Request 0              Invalid Keep IE Len 0
  Num Status Enq. Sent 615              Num Status msgs Rcvd 573
  Num Update Status Rcvd 0              Num Status Timeouts 42
  Last Full Status Req 00:00:24         Last Full Status Rcvd 00:00:24
FR1#
FR1#show frame-relay pvc

PVC Statistics for interface Serial0/0 (Frame Relay DTE)

              Active     Inactive      Deleted       Static
  Local          1            0            0            0
  Switched       0            0            0            0
  Unused         0            0            0            0

DLCI = 102, DLCI USAGE = LOCAL, PVC STATUS = ACTIVE, INTERFACE = Serial0/0.1

  input pkts 115           output pkts 120          in bytes 32266
  out bytes 33844          dropped pkts 0           in pkts dropped 0
  out pkts dropped 0                out bytes dropped 0
  in FECN pkts 0           in BECN pkts 0           out FECN pkts 0
  out BECN pkts 0          in DE pkts 0             out DE pkts 0
  out bcast pkts 100       out bcast bytes 31764
  5 minute input rate 0 bits/sec, 0 packets/sec
  5 minute output rate 0 bits/sec, 0 packets/sec
  pvc create time 01:43:39, last time pvc status changed 01:10:26
FR1#
FR1#ping 172.16.0.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.16.0.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 164/185/220 ms

Please note how the subnet 172.16.0.0/32 on the FR routers does not conflict with 172.16.0.0/31 between P routers; it’s on a totally different L3 domain and it is not routed by the network, but transparently encapsulated in L2 over MPLS packets.

Packet captures

You can find some nice packet captures about this lab at PacketLife.net Captures section, under the MPLS category; they have been taken on P1-P2 link, with inner (pseudowire) and outer MPLS label on top of every packet. They are “LDP_Ethernet_FrameRelay”, which shows how LDP setup the pseudowire circuit, “EoMPLS_802.1q” and “Frame-Relay over MPLS”, which show an ICMP ping encapsulated in Ethernet and Frame-relay respectively.

Anyway, if you don’t know PacketLike.net you must take a tour of that great website, really worth it!

Conclusion and download

This post only shows a little basic configuration of some AToM solutions; there are many more capabilities than which I wrote on this blog. A good starting point is to read documents you can find using links below.

If you want to download this GNS3/Dynamips lab, you can find it here.

References

Cisco.com: MPLS AToM Technical Overview

Cisco.com: Any Transport over MPLS

GNS3 Labs: Source-based Remote Triggered Black Hole (RTBH) Filtering with Unicast Reverse Path Forwarding (uRPF)

This post is part of a series about “ISP Security Tools and Techniques“; in this series I talk about some (I think) useful practices:

1. Remote Triggered Black Holing

2. BGP Customer triggered black holing

3. BGP triggered rate limiting and less-than-best-effort (LBE) with QPPB

4. Source-based RTBH with Unicast Reverse Path Forwarding (uRPF)

Stay tuned! ;)

Today I drew inspiration from a brand new RFC to add a post to this little series: RFC-5635, Remote Triggered Black Hole Filtering with Unicast Reverse Path Forwarding (uRPF).

Especially, I would like to focus on section 4 of this RFC, Source Address RTBH Filtering.

To fully understand this post I would suggest to read my previous post Remote Triggered Black Holing.

What is source-based RTBH? and what are the differences with destination-based RTBH?

Source and destination based RTBH differences Until now, in my previous posts, I always talked about destination-based RTBH. But a source-based RTBH filtering exists too.

This mitigation technique allows an ISP to stop malicious traffic (let’s think to DDOS) on the basis of the source address it comes from. Indeed, destination-based RTBH can just be used to stop traffic on the basis of the attacked hosts addresses, or in the best case, on the couple attacked-hosts/incoming-upstream-provider (you can use different BGP communities to black-hole a prefix only on specific edge routers).

As mentioned in the RFC, if a DDOS software is instructed to attack an host name rather than an IP address, even if you change the IP address resolved by that host name, the attack won’t stop. In this scenario you just have to disrupt the whole service by filtering out the attacked prefix. Source-based RTBH can help you!

How does it work?

Source-based RTBH uses Unicast Reverse Path Forwarding (uRPF) as background mechanism to work.
As RFC says…

uRPF performs a route lookup of the source address of the packet and checks to see if the ingress interface of the packet is a valid egress interface for the packet source address (strict mode) or if any route to the source address of the packet exists (loose mode). If the check fails, the packet is typically dropped.

So, in order to stop incoming traffic from hosts A, B and C toward host Z through router R we just need to add discard routes for A, B and C on router R. And, as seen for destination-based RTBH, we can do it using BGP and communities.

Is that all?

Well, no! Some policy enforcements are due!

As first, in the same way we did for destination-based RTBH, we must use the no-export community to be sure our black-holed prefix doesn’t leave our AS.

Our policy must accept prefixes outside our network (while destination-based RTBH only accepts prefixes within our network) and, as a rule of thumb, we should not accept source-based RTBH prefixes from our customers, but we should just use this tool from management workstations under our control.

Configuration

Source-based RTBH The starting configuration is the one we left on the post BGP triggered rate limiting and less-than-best-effort (LBE) with QPPB.

In our scenario source-based RTBH is triggered from the Core router, using tagged static routes redistribution in BGP; nothing different from destination-based RTBH. So, let’s define the tags and communities:

300:300 - tag 300 - global source-based black-hole
300:301 - tag 301 - ISP1 source-based black-hole
300:302 - tag 302 - ISP2 source-based black-hole

On the Core router, here used as RTBH trigger, we have to enable BGP redistribution of static routes tagged with the news tags; indeed, we will trigger RTBH by adding tagged static routes:

route-map RTBH permit 50
 match tag 300
 set local-preference 200
 set origin igp
 set community 300:300 no-export
route-map RTBH permit 60
 match tag 301
 set local-preference 200
 set origin igp
 set community 300:301 no-export
route-map RTBH permit 70
 match tag 302
 set local-preference 200
 set origin igp
 set community 300:302 no-export

On edge routers facing upstream providers we have to implement our new communities in the route-map:

Edge1:

ip community-list 5 permit 19661100     ! 300:300
ip community-list 5 permit 19661101     ! 300:301
ip community-list 6 permit 19661102     ! 300:302
!
ip as-path access-list 2 permit ^$
!
ip access-list extended InternalNetworks
 permit ip 192.168.0.0 0.0.255.255 255.255.0.0 0.0.255.255
 deny   ip any any
!
route-map FROM_RR deny 30
 match community 6
!
route-map FROM_RR deny 35
 match ip address InternalNetworks
 match community 5
!
route-map FROM_RR permit 40
 match as-path 2
 match community 5
 set community no-export no-advertise
 set ip next-hop 192.0.2.1

Here, 300:300 and 300:301 communities (community-list 5) are welcome, while 300:302 community is not accepted – it’s only for ISP2 facing router. Moreover, we just accept prefixes external to our network (192.168.0.0/16).

Similar config is on Edge2:

ip community-list 5 permit 19661100     ! 300:300
ip community-list 5 permit 19661102     ! 300:302
ip community-list 6 permit 19661101     ! 300:301
!
ip as-path access-list 2 permit ^$
!
ip access-list extended InternalNetworks
 permit ip 192.168.0.0 0.0.255.255 255.255.0.0 0.0.255.255
 deny   ip any any
!
route-map FROM_RR deny 30
 match community 6
!
route-map FROM_RR deny 35
 match ip address InternalNetworks
 match community 5
!
route-map FROM_RR permit 40
 match as-path 2
 match community 5
 set community no-export no-advertise
 set ip next-hop 192.0.2.1

Finally, we have to enable uRPF on ISP-facing interfaces; we use the loose mode here:

Edge1:

interface Serial1/0
 ip address 172.16.1.1 255.255.255.252
 ip verify unicast source reachable-via any

Edge2:

interface Serial1/0
 ip address 172.16.2.1 255.255.255.252
 ip verify unicast source reachable-via any

Tests

To test the solution we have to add another loopback interface to ISPs routers, in order to have two different source IP addresses for each ISP:

ISP1:

interface Loopback1
 ip address 10.0.1.2 255.255.255.255
!
router bgp 100
 network 10.0.1.2 mask 255.255.255.255

ISP2:

interface Loopback1
 ip address 10.0.2.2 255.255.255.255
!
router bgp 200
 network 10.0.2.2 mask 255.255.255.255

Now, suppose we have an attack from ISP1 Loopback1 toward Cust10 (so, from 10.0.1.2 to 192.168.10.1).

We can stop the attack using destination-based RTBH, but traffic from Loopback0 will be disrupted too:

Core(config)#ip route 192.168.10.1 255.255.255.255 null0 tag 101
ISP1#ping 192.168.10.1 so lo1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.1.2
.....
Success rate is 0 percent (0/5)


ISP1#ping 192.168.10.1 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.1.1
.....
Success rate is 0 percent (0/5)

As you can see, both source addresses can’t reach our host.

So, let’s try our new solution; as first remove the previous RTBH filter:

Core(config)#no ip route 192.168.10.1 255.255.255.255 null0 tag 101

then trigger the source-based filtering for the attacking IP address:

Core(config)#ip route 10.0.1.2 255.255.255.255 null0 tag 301

Edge1 receives the new BGP announcement and it adds the discard interface route:

Edge1#sh ip route bgp | i 10.0.1.2
B       10.0.1.2 [200/0] via 192.0.2.1, 00:01:03

Edge1#sh ip cef 10.0.1.2
10.0.1.2/32, version 32, epoch 0
0 packets, 0 bytes
  via 192.0.2.1, 0 dependencies, recursive
    next hop 192.0.2.1, Null0 via 192.0.2.1/32
    valid null adjacency

As we can see, packets from ISP1 Loopback1 are dropped at Edge1, while packets from Loopback0 pass:

ISP1#ping 192.168.10.1 so lo1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.1.2
.....
Success rate is 0 percent (0/5)


ISP1#ping 192.168.10.1 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.1, timeout is 2 seconds:
Packet sent with a source address of 10.0.1.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 476/608/724 ms

Download

You can download the updated GNS3 file and configs here. The ZIP file contains multiple config subdirectories, one for each step covered on previous posts, and the new “6. Source-based RTBH filtering”.

References

IETF: RFC-5635, Remote Triggered Black Hole Filtering with Unicast Reverse Path Forwarding (uRPF)

GNS3 Labs: BGP triggered rate limiting and less-than-best-effort (LBE) with QPPB

This post is part of a series about “ISP Security Tools and Techniques“; in this series I talk about some (I think) useful practices:

1. Remote Triggered Black Holing

2. BGP Customer triggered black holing

3. BGP triggered rate limiting and less-than-best-effort (LBE) with QPPB

4. Source-based RTBH with Unicast Reverse Path Forwarding (uRPF)

Stay tuned! ;)

As I already wrote in my previous posts, an ISP can provide their customers some useful tools to mitigate (D)DoS attacks: Remote Triggered Black Holing and its NOC-independent version, Customer triggered black holing are tools that, once identified attacked hosts or networks, let us to stop malicious traffic at the provider’s edge.

Anyway, when we drop traffic toward attacked hosts, we can’t investigate the attack anymore; we would need a tool which allowed us to analyze traffic and, in the meantime, that would avoid wasting network resources. Our (dear) provider could provide it by implementing rate limiting and less-than-best-effort services using QoS Policy Propagation via BGP (QPPB).

Scenario and goals

Remote Triggered Black HolingThe scenario I will use in this post is the same I used for previous posts I already mentioned before. We are the AS 300 provider, we have 2 customers and 2 upstream providers connected with BGP sessions. Edge1 and Edge2 are routers toward the upstream providers, Edge3 is the router our customers are connected to.

Startup configurations are the same I left on my last post, “Customer triggered black holing”.

As said, the goal is to provide a tool customers can use to rate-limit traffic toward attacked hosts, in order to let them to investigate attacks. This tool should be used by customers avoiding NOC intervention. Scalability is a must.

The solution and how it works

QoS Policy Propagation via BGP (QPPB)The solution proposed here is based on QoS Policy Propagation via BGP (QPPB).

Cisco defines it as a feature that “allows you to classify packets by IP precedence based on BGP community lists, BGP autonomous system paths, and access control lists” (see Cisco 10000 Series Router Quality of Service Configuration Guide). And, of course, that is all! There’s not much more to say!

How does it work? A BGP router running QPPB receives a prefix and matches it using a route-map, then it sets that prefix’s IP precedence or QoS-group accordingly; router’s interfaces are configured to match traffic’s source or destination address against the prefix and to classify packets; once classified, packets can be matched against normal QoS class-matches and policies. Take a look at the picture for a diagram.

Be aware, no attributes or other infos are added to BGP UPDATEs; it’s just a local mechanism to mark routes and classify packets.

Implementation

Now that we know how QPPB works we can use it to implement rate-limiting QoS policies and to trigger them via BGP.

As first, we have to define on each edge router a QoS policy with two class-maps: one used to rate-limit traffic, and the other used to mark the traffic as less-than-best-effort (LBE): lets say we’ll use QoS-group 1 to rate-limit traffic at 8Kbps and QoS-group 2 to mark traffic as LBE.

Edge1 and Edge2:

class-map match-all QPPB-QoSGroup-1
 match qos-group 1
class-map match-all QPPB-QoSGroup-2
 match qos-group 2
!
policy-map QPPB
 class QPPB-QoSGroup-1
   police cir 8000
     conform-action transmit
     exceed-action drop
 class QPPB-QoSGroup-2
  set dscp cs1

Then we can apply our policy to the core facing interfaces, for outgoing traffic (traffic from upstream providers toward our core/customers):

Edge1 and Edge2:

interface FastEthernet0/0
 service-policy output QPPB

Now, we have to define BGP communities to map QoS groups: we will use the following mapping:

300:201 - QoS group 1 (rate-limit to 8 Kbps)
300:202 - QoS group 2 (LBE marking)

Once defined, we have to implement communities in BGP:

Edge1 and Edge2:

ip community-list 3 permit 300:201
ip community-list 4 permit 300:202
!
route-map QPPB permit 10
 match community 3
 set ip qos-group 1
route-map QPPB permit 20
 match community 4
 set ip qos-group 2
route-map QPPB permit 1000
!
router bgp 300
 table-map QPPB

As you can see, the route-map used for QPPB can’t be the same used for the inbound BGP UPDATEs. We must add another route-map to the BGP process using the table-map subcommand: as Cisco says in the Command Lookup Tool this command is used “to modify metric and tag values when the IP routing table is updated with BGP learned routes”.

Now we can enable QPPB on upstream ISPs facing interfaces to classify incoming traffic based on its destination IP address:

Edge1 and Edge2:

interface Serial1/0
 bgp-policy destination ip-qos-map

For the sake of completion, I say you can use this command to match source or destination address of a packet, and to use IP precedence or QoS-groups for classification. Here we use destination based matching and QoS-groups.

Now, let our customer routers to trigger the services: as usual, we will use a tagged static route redistributed in BGP. We already configured the route-map and redistribution in previous posts, so we just need to add some entries to it:

Cust10 and Cust20:

route-map RTBH permit 100
 match tag 201
 set community 300:201
!
route-map RTBH permit 110
 match tag 202
 set community 300:202

Tests

To test the solution we just have to add a static route toward the prefix we want to rate-limit (or to mark as LBE) on the customer router:

Cust10(config)#ip route 192.168.10.20 255.255.255.255 fa1/0 tag 201

On the edge router we have the new /32 prefix with the expected community:

Edge1#sh ip bgp 192.168.10.20
BGP routing table entry for 192.168.10.20/32, version 12
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Flag: 0x820
  Advertised to update-groups:
     2
  65310
    192.168.0.2 (metric 66) from 192.168.255.0 (192.168.255.0)
      Origin incomplete, metric 0, localpref 100, valid, internal, best
      Community: 19661001
      Originator: 192.168.3.2, Cluster list: 192.168.255.0

and we also have a route and a CEF entry tagged with QoS-group 1:

Edge1#sh ip route 192.168.10.20
Routing entry for 192.168.10.20/32
  Known via "bgp 300", distance 200, metric 0
  Tag 65310, qos-group 1, type internal
  Last update from 192.168.0.2 00:00:55 ago
  Routing Descriptor Blocks:
  * 192.168.0.2, from 192.168.255.0, 00:00:55 ago
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65310

Edge1#sh ip cef 192.168.10.20
192.168.10.20/32, version 34, epoch 0, cached adjacency 192.168.1.1
0 packets, 0 bytes, qos-group 1
  via 192.168.0.2, 0 dependencies, recursive
    next hop 192.168.1.1, FastEthernet0/0 via 192.168.0.0/30
    valid cached adjacency

Now, we ping 192.168.10.20 from ISP1 (don’t expect echo replies, there is not a host at that address, but we just need traffic going toward it):

ISP1#ping 192.168.10.20 source lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.10.20, timeout is 2 seconds:
Packet sent with a source address of 10.0.1.1
.....
Success rate is 0 percent (0/5)

On Edge1, fa0/0 output policy counters show 5 packets classified as QPPB-QoSGroup-1 class-match:

Edge1#sh policy-map interface fa0/0 output
 FastEthernet0/0

  Service-policy output: QPPB

    Class-map: QPPB-QoSGroup-1 (match-all)
      5 packets, 570 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: qos-group 1
      police:
          cir 8000 bps, bc 1500 bytes
        conformed 5 packets, 570 bytes; actions:
          transmit
        exceeded 0 packets, 0 bytes; actions:
          drop
        conformed 0 bps, exceed 0 bps

[cut]

Let’s try with Cust20 and LBE service:

Cust20(config)#ip route 192.168.20.40 255.255.255.255 fa1/0 tag 202

The prefix is on Edge2, right community, right route tag:

Edge2#sh ip bgp 192.168.20.40
BGP routing table entry for 192.168.20.40/32, version 15
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Flag: 0x820
  Advertised to update-groups:
     2
  65320
    192.168.0.6 (metric 66) from 192.168.255.0 (192.168.255.0)
      Origin incomplete, metric 0, localpref 100, valid, internal, best
      Community: 19661002
      Originator: 192.168.3.2, Cluster list: 192.168.255.0

Edge2#sh ip route 192.168.20.40
Routing entry for 192.168.20.40/32
  Known via "bgp 300", distance 200, metric 0
  Tag 65320, qos-group 2, type internal
  Last update from 192.168.0.6 00:01:15 ago
  Routing Descriptor Blocks:
  * 192.168.0.6, from 192.168.255.0, 00:01:16 ago
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65320

Edge2#sh ip cef 192.168.20.40
192.168.20.40/32, version 32, epoch 0, cached adjacency 192.168.2.1
0 packets, 0 bytes, qos-group 2
  via 192.168.0.6, 0 dependencies, recursive
    next hop 192.168.2.1, FastEthernet0/0 via 192.168.0.4/30
    valid cached adjacency

We try to ping the host from ISP2…

ISP2#ping 192.168.20.40 so lo0

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.20.40, timeout is 2 seconds:
Packet sent with a source address of 10.0.2.1
.....
Success rate is 0 percent (0/5)

… and Edge2 policy counters go up for QPPB-QoSGroup-2:

Edge2#sh policy-map interface fa0/0 output
 FastEthernet0/0

  Service-policy output: QPPB

    Class-map: QPPB-QoSGroup-1 (match-all)
      0 packets, 0 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: qos-group 1
      police:
          cir 8000 bps, bc 1500 bytes
        conformed 0 packets, 0 bytes; actions:
          transmit
        exceeded 0 packets, 0 bytes; actions:
          drop
        conformed 0 bps, exceed 0 bps

    Class-map: QPPB-QoSGroup-2 (match-all)
      5 packets, 570 bytes
      5 minute offered rate 0 bps, drop rate 0 bps
      Match: qos-group 2
      QoS Set
        dscp cs1
          Packets marked 5

[cut]

Download

In the RateLimit_LBE.zip file you can find the GNS3 Lab with previous and current configuration files. On the RTBH_Configs directory you will find the “5. Rate-limit and LBE” subdirectory with the configuration discussed in this post.

References

QoS Policy Propagation with BGP (QPPB) on Informit: http://www.informit.com/content/images/9781587201240/appendix/QPPBSection.pdf

Cisco 10000 Series Router Quality of Service Configuration Guide: http://www.cisco.com/en/US/docs/routers/10000/10008/configuration/guides/qos/10qqppb.html

GNS3 Labs: BGP Customer triggered black holing

This post is part of a series about “ISP Security Tools and Techniques“; in this series I talk about some (I think) useful practices:

1. Remote Triggered Black Holing

2. BGP Customer triggered black holing

3. BGP triggered rate limiting and less-than-best-effort (LBE) with QPPB

4. Source-based RTBH with Unicast Reverse Path Forwarding (uRPF)

Stay tuned! ;)

Remote Triggered Black Holing In this post I’ll show you how to let your customers to trigger black holing for their prefixes. What I will write is based on my previous post GNS3 Lab: Remote Triggered Black Holing: same scenario, same startup config (the final one of that post).

What is customer triggered blackholing?

Suppose a customer notices one of its hosts is under attack; using customer triggered black holing he can stop malicious traffic toward the attacked host at the ISP edge, and he can do this without the need to ask the provider’s NOC to run RTBH.

While the customer’s staff is analyzing the attack, other hosts remain reachable from the outside, because just the attacked host has been black-holed. Furthermore, all RTBH features can be used: if the customer knows the attack is coming into ISP network from a specific upstream provider, he can just black-hole the attacked prefix on the ISP edge routers facing this specific provider, maintaining full service for networks behind other upstream providers. Of course, when the attack is over, he can resume the prefix and the regular traffic toward it, always avoiding to ask provider’s NOC.

Customer-triggered blackholing let our customers to lower their response time against attacks and it also lower work load and liability of our NOC.

How does it work?

To let our customers to activate RTBH we just need them to announce prefixes they want to black-hole using the specific BGP community. For example, if customer 10 (AS 65310) wants to black-hole 192.168.10.20/32 toward ISP2 (AS 200) he just has to announce that prefix with community 300:102.

As we already did in the Core router, our customers will trigger RTBH just adding a tagged static route toward the prefix they want to blackhole.

Configuration

On the customers routers we need to add the send-community keyword to the neighbor, in order to let them to send communities to our Edge router:

Cust10(config)#router bgp 65310
Cust10(config-router)#neighbor 192.168.0.1 send-community
Cust20(config)#router bgp 65320
Cust20(config-router)#neighbor 192.168.0.5 send-community

We need to set send-community in our Edge router too, so that it could send communities to our RR:

Edge3(config)#router bgp 300
Edge3(config-router)#neighbor 192.168.255.0 send-community

Our RR router already has the send-community keyword, so it already sends communities to other peers (RR clients):

Core#sh run | sec bgp
router bgp 300
 no synchronization
 bgp log-neighbor-changes
 redistribute static route-map RTBH
 neighbor Edge peer-group
 neighbor Edge remote-as 300
 neighbor Edge update-source Loopback0
 neighbor Edge route-reflector-client
 neighbor Edge send-community
 neighbor Edge soft-reconfiguration inbound
 neighbor 192.168.1.2 peer-group Edge
 neighbor 192.168.2.2 peer-group Edge
 neighbor 192.168.3.2 peer-group Edge
 no auto-summary

(look at the neighbor Edge send-community line)

Now, we need to add the RTBH route-map to our customers routers; we will match static route tags in order to add the AS300 RTBH community to prefixes:

route-map RTBH permit 10
 match tag 100
 set community 19660900
route-map RTBH permit 20
 match tag 101
 set community 19660901
route-map RTBH permit 30
 match tag 102
 set community 19660902
route-map RTBH permit 40
 match tag 199
 set community 19660999
route-map RTBH deny 1000

As opposed to the Core router’s RTBH route-map, here we have to remove the no-export community from the set community statements, otherwise black-holed prefixes will not cross the customer’s AS borders.

Now we just have to redistribute static routes into BGP using the route-map:

Cust10(config)#router bgp 65310
Cust10(config-router)#redistribute static route-map RTBH
Cust20(config)#router bgp 65320
Cust20(config-router)#redistribute static route-map RTBH

Testing

At this point, customers just have to add static routes for their attacked prefixes to black-hole traffic at AS300 edges:

Cust10(config)#ip route 192.168.10.20 255.255.255.255 fa1/0 tag 100

In the example, Cust10 announces 192.168.10.20/32 prefix to our Edge3 router with community 300:100 (19660900):

Edge3#sh ip bgp 192.168.10.20
BGP routing table entry for 192.168.10.20/32, version 19
Paths: (1 available, best #1, table Default-IP-Routing-Table)
Flag: 0x820
  Advertised to update-groups:
     1          2
  65310
    192.168.0.2 from 192.168.0.2 (192.168.10.1)
      Origin IGP, metric 0, localpref 100, valid, external, best
      Community: 19660900

Edge3 sends it to our RR wich, in turn, reflects it to Edge1 and Edge2 routers:

Edge1#sh ip bgp
BGP table version is 3, local router ID is 192.168.1.2
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i192.168.10.0     192.168.0.2              0    100      0 65310 i
*>i192.168.10.20/32 192.0.2.1                0    100      0 65310 ?

Edge1#sh ip bgp 192.168.10.20
BGP routing table entry for 192.168.10.20/32, version 3
Paths: (1 available, best #1, table Default-IP-Routing-Table, not advertised to any peer)
Flag: 0x820
  Not advertised to any peer
  65310
    192.0.2.1 from 192.168.255.0 (192.168.255.0)
      Origin incomplete, metric 0, localpref 100, valid, internal, best
      Community: no-export no-advertise
      Originator: 192.168.3.2, Cluster list: 192.168.255.0

Edge1#sh ip cef 192.168.10.20
192.168.10.20/32, version 22, epoch 0
0 packets, 0 bytes
  via 192.0.2.1, 0 dependencies, recursive
    next hop 192.0.2.1, Null0 via 192.0.2.1/32
    valid null adjacency
Edge2#sh ip cef 192.168.10.20
192.168.10.20/32, version 22, epoch 0
0 packets, 0 bytes
  via 192.0.2.1, 0 dependencies, recursive
    next hop 192.0.2.1, Null0 via 192.0.2.1/32
    valid null adjacency

Of course we need strong policy enforcement on the customers facing edge router (Edge3) in order to avoid customers to announce prefixes assigned to other customers, or to use unproper communities.

In this post what I missed to implement is customer triggered blackholing on the same Edge3 router. Indeed there is not a route-map which sets next-hop to null0 for blackholed prefixes. This solution works fine for global and ISP-specific blackholing, but not for customers blackholing. To achieve this goal more work is needed, maybe I will write another post about this! ;)

Download the lab

You can download the GNS3 Lab here. Within the .zip file, in the config directory, you can find the previous post configurations and the new “4. Customer trigger blackholing” subdirectory containing the final config.

Follow

Get every new post delivered to your Inbox.