Build a BGP ISP Lab with FRRouting - Part 1

In the world of network engineering, hands-on experience with BGP and ISP-grade routing is invaluable. This comprehensive tutorial guides you through building a complete, functional ISP environment on your laptop using lightweight Linux VMs and FRRouting.

What You'll Learn:

  • BGP route reflection and iBGP/eBGP relationships
  • Multi-AS path selection and traffic engineering
  • ISP peering relationships and policies
  • Production-grade routing with FRRouting
  • Network convergence and failure testing

Lab Overview

We'll create a 5-router topology that mirrors a real ISP network:

  • AS 65001: Your ISP core network (3 routers)
  • AS 65002: Upstream provider
  • AS 65003: Customer network

Prerequisites and Requirements

Hardware Requirements

Component Minimum Recommended
RAM 8 GB 16 GB
CPU Cores 4 8
Storage 50 GB 100 GB SSD

Software Requirements

  • A hypervisor of your choice
  • Ubuntu Server 24 LTS Noble (x86)
  • SSH client
  • Basic knowledge of Linux CLI and networking

Important:

Ensure you have x86 virtualization support enabled on your system.

Network Architecture

Topology Design


                      VM2 (Provider)
                   10.2.2.2/32 | AS 65002
                               |
                          eBGP |
                               |
                      VM1 (Route Reflector)
                   10.1.1.1/32 | AS 65001
                               |
                 +-------------+-------------+
                 |                           |
            iBGP |                      iBGP |
                 |                           |
         VM3 (ISP Router)            VM4 (ISP Router)
      10.3.3.3/32 | AS 65001      10.4.4.4/32 | AS 65001


                      VM1 (Route Reflector)
                   10.1.1.1/32 | AS 65001
                               |
                          eBGP |
                               |
                     VM5 (Customer)
                   10.5.5.5/32 | AS 65003

BGP Relationships:
------------------
• VM2 ←→ VM1: eBGP (External BGP between different AS)
• VM1 ←→ VM3: iBGP (Internal BGP within AS 65001)
• VM1 ←→ VM4: iBGP (Internal BGP within AS 65001)
• VM1 ←→ VM5: eBGP (External BGP between different AS)

IP Addressing Scheme

VM Hostname AS Number Router ID Loopback IP Management IP
VM1 vm1 65001 1.1.1.1 10.1.1.1/32 192.168.139.115
VM2 vm2 65002 2.2.2.2 10.2.2.2/32 192.168.139.145
VM3 vm3 65001 3.3.3.3 10.3.3.3/32 192.168.139.225
VM4 vm4 65001 4.4.4.4 10.4.4.4/32 192.168.139.147
VM5 vm5 65003 5.5.5.5 10.5.5.5/32 192.168.139.17

Note:

The Management IP addresses shown above (192.168.139.x) are specific to my lab setup. Your hypervisor may assign different IP addresses based on your network configuration. Use these as a reference and adjust according to your environment.

Step-by-Step VM Setup

1 Create Base VM Template

VM Configuration

Create a base VM with the following specifications:

  • Name: ubuntu-base
  • OS: Linux, Ubuntu (64-bit)
  • Memory: 1024 MB
  • Disk: 10GB (dynamic allocation)

Install Ubuntu Server

# Download Ubuntu Server 24.04 LTS Noble ISO (x86)
wget https://releases.ubuntu.com/24.04.1/ubuntu-24.04.1-live-server-amd64.iso

During installation:

  • Language: English
  • Network: DHCP (we'll configure static later)
  • Storage: Use entire disk
  • Username: netadmin
  • Install OpenSSH server: Yes
  • No additional packages

2 Prepare Base Template

After installation, log in and run these commands:

# Update system
sudo apt update && sudo apt upgrade -y

# Install essential tools
sudo apt install -y net-tools vim curl wget htop tcpdump

# Disable cloud-init (causes issues with cloning)
sudo touch /etc/cloud/cloud-init.disabled

# Clear machine ID for cloning
sudo truncate -s 0 /etc/machine-id
sudo rm /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id

# Shutdown for cloning
sudo shutdown -h now

3 Spin Up 5 VMs

Clone the base VM to create 5 virtual machines:

  • vm1 - Route Reflector (AS 65001)
  • vm2 - Provider (AS 65002)
  • vm3 - ISP Router (AS 65001)
  • vm4 - ISP Router (AS 65001)
  • vm5 - Customer (AS 65003)

Note:

Ensure each VM has a unique MAC address and is connected to an isolated network for the lab environment.

Network Configuration

1 Configure Static IPs

Important:

The IP addresses used in the examples below (192.168.139.x) are from my specific lab environment. Your network configuration will likely differ. Replace these IPs with addresses appropriate for your hypervisor's network setup.

On each VM, configure the network interface. Example for VM1:

# Edit netplan configuration
sudo vim /etc/netplan/00-installer-config.yaml

VM1 Netplan Configuration

network:
  version: 2
  ethernets:
    enp0s3:  # Adjust interface name as needed
      addresses:
        - 192.168.139.115/24
      routes:
        - to: default
          via: 192.168.139.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 8.8.4.4
# Apply configuration
sudo netplan apply

# Verify
ip addr show
ping 8.8.8.8

2 Set Hostnames

On each VM, set the appropriate hostname:

# For VM1 (repeat with vm2, vm3, vm4, vm5 on respective VMs)
sudo hostnamectl set-hostname vm1
sudo bash -c 'echo "127.0.1.1 vm1" >> /etc/hosts'

# Verify
hostname

3 Configure /etc/hosts

Add all VMs to /etc/hosts on each machine:

sudo bash -c 'cat >> /etc/hosts << EOF
192.168.139.115 vm1
192.168.139.145 vm2
192.168.139.225 vm3
192.168.139.147 vm4
192.168.139.17  vm5
EOF'

4 Test Connectivity

# From each VM, test connectivity
for i in vm1 vm2 vm3 vm4 vm5; do
    ping -c 1 $i && echo "$i is reachable" || echo "$i is NOT reachable"
done

FRRouting Installation

1 Install FRRouting Package

Run on all VMs:

# Update package list
sudo apt update

# Install FRRouting
sudo apt install -y frr frr-pythontools

# Verify installation
vtysh -v

2 Enable Required Daemons

# Edit daemon configuration
sudo vim /etc/frr/daemons

# Enable these daemons (set to yes):
# zebra=yes
# bgpd=yes
# staticd=yes

# Or use sed commands:
sudo sed -i 's/^zebra=.*/zebra=yes/' /etc/frr/daemons
sudo sed -i 's/^bgpd=.*/bgpd=yes/' /etc/frr/daemons
sudo sed -i 's/^staticd=.*/staticd=yes/' /etc/frr/daemons

3 Configure Loopback Interfaces

Add loopback IPs on each VM:

# VM1
sudo ip addr add 10.1.1.1/32 dev lo

# VM2
sudo ip addr add 10.2.2.2/32 dev lo

# VM3
sudo ip addr add 10.3.3.3/32 dev lo

# VM4
sudo ip addr add 10.4.4.4/32 dev lo

# VM5
sudo ip addr add 10.5.5.5/32 dev lo

# Make persistent (add to /etc/network/interfaces or netplan)

BGP Configuration

Automated Setup Script

Create and run this script on each VM:

#!/usr/bin/env bash
# Save as setup-bgp.sh
set -euo pipefail

echo "=== BGP lab setup starting on host: $(hostname) ==="

HOSTNAME=$(hostname)

# LAN IPs
VM1_IP="192.168.139.115"
VM2_IP="192.168.139.145"
VM3_IP="192.168.139.225"
VM4_IP="192.168.139.147"
VM5_IP="192.168.139.17"

case "$HOSTNAME" in
  vm1)
    # Route Reflector Configuration
    cat << 'EOF' | sudo tee /etc/frr/frr.conf
hostname vm1
password zebra
!
router bgp 65001
 bgp router-id 1.1.1.1
 neighbor 192.168.139.225 remote-as 65001
 neighbor 192.168.139.225 route-reflector-client
 neighbor 192.168.139.147 remote-as 65001
 neighbor 192.168.139.147 route-reflector-client
 neighbor 192.168.139.145 remote-as 65002
 neighbor 192.168.139.17 remote-as 65003
 !
 address-family ipv4 unicast
  network 10.1.1.1/32
  neighbor 192.168.139.225 activate
  neighbor 192.168.139.147 activate
  neighbor 192.168.139.145 activate
  neighbor 192.168.139.17 activate
 exit-address-family
!
EOF
    ;;

  vm2)
    # Upstream Provider Configuration
    cat << 'EOF' | sudo tee /etc/frr/frr.conf
hostname vm2
password zebra
!
router bgp 65002
 bgp router-id 2.2.2.2
 neighbor 192.168.139.115 remote-as 65001
 !
 address-family ipv4 unicast
  network 10.2.2.2/32
  neighbor 192.168.139.115 activate
 exit-address-family
!
EOF
    ;;

  vm3)
    # iBGP Client 1 Configuration
    cat << 'EOF' | sudo tee /etc/frr/frr.conf
hostname vm3
password zebra
!
router bgp 65001
 bgp router-id 3.3.3.3
 neighbor 192.168.139.115 remote-as 65001
 !
 address-family ipv4 unicast
  network 10.3.3.3/32
  neighbor 192.168.139.115 activate
 exit-address-family
!
EOF
    ;;

  vm4)
    # iBGP Client 2 Configuration
    cat << 'EOF' | sudo tee /etc/frr/frr.conf
hostname vm4
password zebra
!
router bgp 65001
 bgp router-id 4.4.4.4
 neighbor 192.168.139.115 remote-as 65001
 !
 address-family ipv4 unicast
  network 10.4.4.4/32
  neighbor 192.168.139.115 activate
 exit-address-family
!
EOF
    ;;

  vm5)
    # Customer Configuration
    cat << 'EOF' | sudo tee /etc/frr/frr.conf
hostname vm5
password zebra
!
router bgp 65003
 bgp router-id 5.5.5.5
 neighbor 192.168.139.115 remote-as 65001
 !
 address-family ipv4 unicast
  network 10.5.5.5/32
  neighbor 192.168.139.115 activate
 exit-address-family
!
EOF
    ;;

  *)
    echo "Unknown hostname: $HOSTNAME"
    exit 1
    ;;
esac

# Restart FRR
sudo systemctl restart frr
echo "=== BGP setup completed on $(hostname) ==="
# Make script executable and run
chmod +x setup-bgp.sh
./setup-bgp.sh

Verification and Testing

1 Verify BGP Sessions

# Check BGP summary
sudo vtysh -c "show ip bgp summary"

# Expected output shows established sessions (state = number of prefixes)

Expected BGP Summary Output (VM1)

IPv4 Unicast Summary:
BGP router identifier 1.1.1.1, local AS number 65001
Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd
192.168.139.145 4      65002        12        15        0    0    0 00:05:23            1
192.168.139.225 4      65001        10        12        0    0    0 00:04:15            1
192.168.139.147 4      65001        10        12        0    0    0 00:04:10            1
192.168.139.17  4      65003        11        14        0    0    0 00:03:45            1

2 View BGP Routing Table

# Show all BGP routes
sudo vtysh -c "show ip bgp"

# Show specific route details
sudo vtysh -c "show ip bgp 10.5.5.5/32"

3 Test End-to-End Connectivity

# From VM2 (Provider), ping VM5 (Customer) loopback
ping -c 4 10.5.5.5

# Traceroute to see path
traceroute 10.5.5.5

Success Indicators:

  • All BGP sessions show "Established" state
  • Each router sees 5 total prefixes (5 loopbacks)
  • Ping between any loopback IPs succeeds
  • AS paths show correct transit through AS 65001

Advanced BGP Configuration

Implementing Route Filtering

Implement a route filter on VM1 to prevent VM5's routes from reaching VM2:

# On VM1
sudo vtysh
configure terminal

ip prefix-list BLOCK_VM5 seq 10 deny 10.5.5.5/32
ip prefix-list BLOCK_VM5 seq 20 permit 0.0.0.0/0 le 32

router bgp 65001
  neighbor 192.168.139.145 prefix-list BLOCK_VM5 out

end
write
clear ip bgp 192.168.139.145 soft out

Configuring AS Path Prepending

Make VM2 prefer routes through a longer path:

# On VM1
sudo vtysh
configure terminal

route-map PREPEND_TO_VM2 permit 10
  set as-path prepend 65001 65001

router bgp 65001
  neighbor 192.168.139.145 route-map PREPEND_TO_VM2 out

end
write
clear ip bgp 192.168.139.145 soft out

Setting Local Preference

Set local preference to control outbound traffic:

# On VM1
sudo vtysh
configure terminal

route-map SET_LOCALPREF permit 10
  set local-preference 200

router bgp 65001
  neighbor 192.168.139.145 route-map SET_LOCALPREF in

end
write
clear ip bgp 192.168.139.145 soft in

Troubleshooting Guide

BGP Session Not Establishing

Symptoms: Session stuck in Active or Idle state

Solutions:

  1. Check IP connectivity: ping <neighbor-ip>
  2. Verify firewall: sudo iptables -L
  3. Check BGP configuration: show run | section bgp
  4. Verify TCP port 179: sudo netstat -an | grep 179

Diagnostic Commands

# BGP Diagnostics
sudo vtysh -c "show ip bgp summary"
sudo vtysh -c "show ip bgp"
sudo vtysh -c "show ip bgp neighbors"

# System Diagnostics
sudo systemctl status frr
sudo journalctl -u frr -f
sudo tcpdump -i any -n port 179

Conclusion

Lab Accomplishments:

  • Deployed a multi-AS BGP topology
  • Configured route reflection and iBGP/eBGP sessions
  • Implemented routing policies and filters
  • Tested failover and convergence
  • Hands-on experience with FRRouting

Next Steps

  1. Add IPv6 support (MP-BGP)
  2. Implement MPLS and VRFs
  3. Configure BGP FlowSpec for DDoS mitigation
  4. Add OSPF/IS-IS for IGP
  5. Integrate with SDN controllers
← Back to Blog