Pages

5.18.2017

BIRD Route Server Install | BGP Peer with Juniper MX

I was recently faced with a challenge whereby I needed to inject 30,000 BGP routes into a test environment for a DOCSIS 3.1 POC. Typically I would use IXIA to form the BGP session and inject the routes. However, all 5 IXIA testers were in use thus I needed a quick alternative. 

I was already aware of BIRD and it's use as a route server in a number of IXP environments so figured it would be a good fit. The following steps detail how to install BIRD on Ubuntu and how to instantiate a BGP session with a Juniper MX router. 

For more info on BIRD check here

Topology:



For this install I'm using a VM running Ubuntu server 12.04LTS:
lab@ubuntu-server1:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.3 LTS
Release:        12.04
Codename:       precise

First up we need to enable Linux to support IPv4 forwarding. Two options here; we can either use the sysctl net.ipv4.ip_forward=1 command, although this setting will reset when the server is rebooted. Alternatively we can modify /etc/sysctl.conf to make the change permanent. Edit /etc/sysctl.conf and uncomment net.ipv4.ip_forward=1
root@ubuntu-server1:~# cat /etc/sysctl.conf
#
# /etc/sysctl.conf - Configuration file for setting system variables
# See /etc/sysctl.d/ for additional system variables
# See sysctl.conf (5) for information.
#

#kernel.domainname = example.com

# Uncomment the following to stop low-level messages on console
#kernel.printk = 3 4 1 3

##############################################################3
# Functions previously found in netbase
#

# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1

# Uncomment the next line to enable TCP/IP SYN cookies
# See http://lwn.net/Articles/277146/
# Note: This may impact IPv6 TCP sessions too
#net.ipv4.tcp_syncookies=1

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1


###################################################################
# Additional settings - these settings can improve the network
# security of the host and prevent against some network attacks
# including spoofing attacks and man in the middle attacks through
# redirection. Some network environments, however, require that these
# settings are disabled so review and enable them as needed.
#
# Do not accept ICMP redirects (prevent MITM attacks)
#net.ipv4.conf.all.accept_redirects = 0
#net.ipv6.conf.all.accept_redirects = 0
# _or_
# Accept ICMP redirects only for gateways listed in our default
# gateway list (enabled by default)
# net.ipv4.conf.all.secure_redirects = 1
#
# Do not send ICMP redirects (we are not a router)
#net.ipv4.conf.all.send_redirects = 0
#
# Do not accept IP source route packets (we are not a router)
#net.ipv4.conf.all.accept_source_route = 0
#net.ipv6.conf.all.accept_source_route = 0
#
# Log Martian Packets
#net.ipv4.conf.all.log_martians = 1
#

Download and install bird6 using the apt-get install command. bird6 is essentially a dual-stack version supporting IPv4 and IPv6.
lab@ubuntu-server1:~$ sudo apt-get install bird6
Once bird is installed we can now start modifying the bird config file. Start by making a copy of original config file located in /etc directory. This allows us to rollback to a default state if required.
root@ubuntu-server1:/etc# cp bird.conf bird.old1.conf
Now lets modify bird.conf to form an eBGP session with our MX router. We need to uncomment the following settings and add our specific variables:

router id 192.168.10.44 ---- this matches our eth0 ip address
protocol static ---- required in order to advertise a static route into BGP
protocol bgp ---- enables BGP 
local as 666 ---- defines local bird AS
neighbor 192.168.10.108 as 64512 ---- define neighboring MX address and AS
export where source=RTS_STATIC ---- exports static routes to BGP
root@ubuntu-server1:/etc# cat bird.conf
/*
 *      This is an example configuration file.
 */

# Yes, even shell-like comments work...

# Configure logging
#log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };
#log stderr all;
#log "tmp" all;

# Override router ID
router id 192.168.10.44;

# You can define your own symbols...
#define xyzzy = (120+10);
#define '1a-a1' = (30+40);

# Define a route filter...
#filter test_filter {
#       if net ~ 10.0.0.0/16 then accept;
#       else reject;
#}

#filter sink { reject; }
#filter okay { accept; }

#include "filters.conf";

# Define another routing table
#table testable;

# Turn on global debugging of all protocols
#debug protocols all;

# The direct protocol automatically generates device routes to
# all network interfaces. Can exist in as many instances as you wish
# if you want to populate multiple routing tables with device routes.
#protocol direct {
#       interface "-eth*", "*"; # Restrict network interfaces it works with
#}

# This pseudo-protocol performs synchronization between BIRD's routing
# tables and the kernel. If your kernel supports multiple routing tables
# (as Linux 2.2.x does), you can run multiple instances of the kernel
# protocol and synchronize different kernel tables with different BIRD tables.
protocol kernel {
#       learn;                  # Learn all alien routes from the kernel
        persist;                # Don't remove routes on bird shutdown
        scan time 20;           # Scan kernel routing table every 20 seconds
#       import none;            # Default is import all
        export all;             # Default is export none
#       kernel table 5;         # Kernel table to synchronize with (default: main)
}

# This pseudo-protocol watches all interface up/down events.
protocol device {
        scan time 10;           # Scan interfaces every 10 seconds
}

# Static routes (again, there can be multiple instances, so that you
# can disable/enable various groups of static routes on the fly).
protocol static {
#       disabled;               # Disable by default
#       table testable;         # Connect to a non-default table
#       preference 1000;        # Default preference of routes
#       debug { states, routes, filters, interfaces, events, packets };
#       debug all;
#       route 0.0.0.0/0 via 198.51.100.13;
#       route 198.51.100.0/25 reject;
#       route 10.0.0.0/8 reject;
        route 10.1.1.0:255.255.255.0 via 192.168.10.44;
#       route 10.1.2.0:255.255.255.0 via 198.51.100.3;
#       route 10.1.3.0:255.255.255.0 via 198.51.100.4;
#       route 10.2.0.0/24 via "arc0";
}

# Pipe protocol connects two routing tables... Beware of loops.
#protocol pipe {
#       peer table testable;
# Define what routes do we export to this protocol / import from it.
#       import all;             # default is all
#       export all;             # default is none
#       import none;            # If you wish to disable imports
#       import filter test_filter;              # Use named filter
#       import where source = RTS_DEVICE;       # Use explicit filter
#}

# RIP aka Rest In Pieces...
#protocol rip MyRIP {   # You can also use an explicit name
#       preference xyzzy;
#       debug all;
#       port 1520;
#       period 7;
#       infinity 16;
#       garbage time 60;
#       interface "*" { mode broadcast; };
#       honor neighbor;         # To whom do we agree to send the routing table
#       honor always;
#       honor never;
#       passwords {
#               password "nazdar";
#       };
#       authentication none;
#       import filter { print "importing"; accept; };
#       export filter { print "exporting"; accept; };
#}

#protocol ospf MyOSPF {
#       tick 2;
#       rfc1583compat yes;
#       area 0.0.0.0 {
#               stub no;
#               interface "eth*" {
#                       hello 9;
#                       retransmit 6;
#                       cost 10;
#                       transmit delay 5;
#                       dead count 5;
#                       wait 50;
#                       type broadcast;
#                       authentication simple;
#                       password "pass";
#               };
#               interface "arc0" {
#                       rx buffer large;
#                       type nonbroadcast;
#                       poll 14;
#                       dead 75;
#                       neighbors {
#                               10.1.1.2 eligible;
#                               10.1.1.4;
#                       };
#                       strict nonbroadcast yes;
#               };
#               interface "xxx0" {
#                       passwords {
#                               password "abc" {
#                                       id 1;
#                                       generate to "22-04-2003 11:00:06";
#                                       accept to "17-01-2004 12:01:05";
#                               };
#                               password "def" {
#                                       id 2;
#                                       generate from "22-04-2003 11:00:07";
#                                       accept from "17-01-2003 12:01:05";
#                               };
#                       };
#                       authentication cryptographic;
#               };
#       };
#       area 20 {
#               stub 1;
#               interface "ppp1" {
#                       hello 8;
#                       authentication none;
#               };
#               interface "fr*";
#               virtual link 192.168.0.1 {
#                       password "sdsdffsdfg";
#                       authentication cryptographic;
#               };
#       };
#}


protocol bgp {
#       disabled;
#       description "My BGP uplink";
        local as 666;
        neighbor 192.168.10.108 as 64512;
        import all;
#       export where proto = "static"
#       multihop;
#       hold time 240;
#       startup hold time 240;
#       connect retry time 120;
#       keepalive time 80;      # defaults to hold time / 3
#       start delay time 5;     # How long do we wait before initial connect
#       error wait time 60, 300;# Minimum and maximum time we wait after an error (when consecutive
#                               # errors occur, we increase the delay exponentially ...
#       error forget time 300;  # ... until this timeout expires)
#       disable after error;    # Disable the protocol automatically when an error occurs
#       next hop self;          # Disable next hop processing and always advertise our local address as nexthop
#       path metric 1;          # Prefer routes with shorter paths (like Cisco does)
#       default bgp_med 0;      # MED value we use for comparison when none is defined
#       default bgp_local_pref 0;       # The same for local preference
#       source address 198.51.100.14;   # What local address we use for the TCP connection
#       password "secret";      # Password used for MD5 authentication
#       rr client;              # I am a route reflector and the neighor is my client
#       rr cluster id 1.0.0.1;  # Use this value for cluster id instead of my router id
        export where source=RTS_STATIC;
#       export filter {
#               if source = RTS_STATIC then {
#                       bgp_community = -empty-; bgp_community = add(bgp_community,(65000,5678));
#                       bgp_origin = 0;
#                       bgp_community = -empty-; bgp_community.add((65000,5678));
#                       if (65000,64501) ~ bgp_community then
#                               bgp_community.add((0, 1));
#                       if bgp_path ~ [= 65000 =] then
#                               bgp_path.prepend(65000);
#                       accept;
#               }
#               reject;
#       };
}

Now lets jump to the MX - Here we need to define a local AS under routing-options and configure a eBGP session towards the bird server.
lab@MX1-SDN-LAB> show configuration routing-options autonomous-system
64512;

lab@MX1-SDN-LAB> show configuration protocols bgp group BIRD
type external;
local-address 192.168.10.108;
peer-as 666;
neighbor 192.168.10.44;

Verification:
On the MX we can see we have successfully formed an eBGP session with our bird route server.
lab@MX1-SDN-LAB> show bgp neighbor 192.168.10.44
Peer: 192.168.10.44+39614 AS 666 Local: 192.168.10.108+179 AS 64512
  Group: BIRD                  Routing-Instance: master
  Forwarding routing-instance: master
  Type: External    State: Established    Flags: <Sync>
  Last State: OpenConfirm   Last Event: RecvKeepAlive
  Last Error: None
  Options: <Preference LocalAddress PeerAS Refresh>
  Local Address: 192.168.10.108 Holdtime: 90 Preference: 170
  Number of flaps: 0
  Peer ID: 192.168.10.44   Local ID: 172.16.255.51     Active Holdtime: 90
  Keepalive Interval: 30         Group index: 5    Peer index: 0  
  BFD: disabled, down
  Local Interface: fxp0.0                          
  NLRI for restart configured on peer: inet-unicast
  NLRI advertised by peer: inet-unicast
  NLRI for this session: inet-unicast
  Peer supports Refresh capability (2)
  Stale routes from peer are kept for: 300
  Peer does not support Restarter functionality
  Peer does not support Receiver functionality
  Peer does not support LLGR Restarter or Receiver functionality
  Peer supports 4 byte AS extension (peer-as 666)
  Peer does not support Addpath
  Table inet.0 Bit: 10001
    RIB State: BGP restart is complete
    Send state: in sync
    Active prefixes:              30000
    Received prefixes:            30000
    Accepted prefixes:            30000
    Suppressed due to damping:    0
    Advertised prefixes:          0
  Last traffic (seconds): Received 7    Sent 7    Checked 1  
  Input messages:  Total 238    Updates 69      Refreshes 0     Octets 156204
  Output messages: Total 168    Updates 0       Refreshes 0     Octets 3236
  Output Queue[0]: 0            (inet.0, inet-unicast)
You may have noticed that we are receiving 30000 prefixes via the session. These are redistributed static routes that I mentioned earlier that I have defined on the bird server.

We can also verify via the bird command line. Enter bird cli.
root@ubuntu-server1:/etc# birdc
Issue the show protocols all command to verify BGP status. Here we can see we have successfully established an eBGP session with our adjacent Juniper MX router. We can also see that we are exporting 30,000 prefixes.
bird> show protocols all
name     proto    table    state  since       info
kernel1  Kernel   master   up     Dec12      
  Preference:     10
  Input filter:   ACCEPT
  Output filter:  ACCEPT
  Routes:         0 imported, 30000 exported, 0 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:          30000          0          0        ---      30000
    Export withdraws:            0        ---        ---        ---          0

device1  Device   master   up     Dec12      
  Preference:     240
  Input filter:   ACCEPT
  Output filter:  REJECT
  Routes:         0 imported, 0 exported, 0 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:              0          0          0        ---          0
    Export withdraws:            0        ---        ---        ---          0

static1  Static   master   up     Dec12      
  Preference:     200
  Input filter:   ACCEPT
  Output filter:  REJECT
  Routes:         30000 imported, 0 exported, 30000 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:          30000          0          0          0      30000
    Import withdraws:            0          0        ---          0          0
    Export updates:              0          0          0        ---          0
    Export withdraws:            0        ---        ---        ---          0

bgp1     BGP      master   up     20:21       Established  
  Preference:     100
  Input filter:   ACCEPT
  Output filter:  <NULL>
  Routes:         0 imported, 30000 exported, 0 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:              0          0          0          0          0
    Import withdraws:            0          0        ---          0          0
    Export updates:          30000          0          0        ---      30000
    Export withdraws:            0        ---        ---        ---          0
  BGP state:          Established
    Neighbor address: 192.168.10.108
    Neighbor AS:      64512
    Neighbor ID:      172.16.255.51
    Neighbor caps:    refresh AS4
    Session:          external AS4
    Source address:   192.168.10.44
    Hold timer:       72/90
    Keepalive timer:  15/30

No comments:

Post a Comment