Border Gateway Protocol (BGP) is the backbone of the modern Internet, and many enterprises now run it on commodity Linux servers for cost‑effective, high‑performance routing. FRRouting (FRR) is an open‑source suite that implements BGP, OSPF, IS‑IS and more, and it has become the de‑facto standard for Linux‑based routing platforms. This guide walks you through a complete, production‑ready BGP configuration on a fresh Linux installation, covering everything from package installation to policy routing, with real commands, common mistakes, and expert tips along the way.
What You’ll Need
- A recent Linux distribution (Ubuntu 22.04 LTS, Debian 12, CentOS 8 Stream, or similar)
- Root or sudo access on the server
- At least two network interfaces (one for the internal LAN, one for the external BGP peer)
- AS numbers and IP prefixes for your own network and for the BGP neighbor(s)
- Basic familiarity with Linux networking and routing concepts
Step 1: Install FRRouting
First, add the FRR repository that matches your distro, then install the package set that includes the BGP daemon (bgpd). The commands below are for Ubuntu/Debian; adjust the package manager for RHEL‑based systems.
# Add the FRR signing key
wget -O - https://deb.frrouting.org/frr/keys.asc | sudo apt-key add -
# Add the repository (replace "$(lsb_release -sc)" with your codename if needed)
echo "deb https://deb.frrouting.org/frr $(lsb_release -sc) frr" | sudo tee /etc/apt/sources.list.d/frr.list
sudo apt-get update
# Install FRR with BGP support
sudo apt-get install frr frr-pythontools
# Enable the daemons you need (bgpd, zebra)
sudo bash -c 'cat > /etc/frr/daemons <<EOF
zebra=yes
bgpd=yes
ospfd=no
ospf6d=no
isisd=no
ripd=no
ripngd=no
EOF'
# Restart the service to apply the daemon list
sudo systemctl restart frr
After the restart, FRR creates a set of management sockets under /run/frr and a CLI called vtysh that lets you configure all routing protocols from a single prompt.
Step 2: Verify the Installation and Basic Connectivity
Before diving into BGP, confirm that the FRR daemons are up and that the kernel knows about your interfaces.
# Check daemon status
sudo systemctl status frr
# List interfaces and their IPs
ip -br addr
# Verify that zebra (the core routing daemon) is reachable via vtysh
vtysh -c "show version"
If you see a version string and the daemons are active, you’re ready to start configuring BGP.
Step 3: Define Your Router’s Identity
Enter the FRR CLI and set the router’s autonomous system (AS) number as well as a hostname. This information is advertised to peers and appears in log files, so choose something meaningful.
sudo vtysh
router bgp 65001 # Replace with your own AS number
bgp router-id 192.0.2.1 # A unique IPv4 address used as the router ID
exit
write
The router-id does not need to be an address assigned to an interface, but it must be globally unique within the BGP domain.
Step 4: Configure BGP Neighbors
Now add the external peers (also called neighbors). You’ll need each neighbor’s IP address and AS number. FRR supports both IPv4 and IPv6 peers.
configure terminal
router bgp 65001
neighbor 203.0.113.2 remote-as 65002
neighbor 203.0.113.2 description "Upstream ISP"
! Optional: enable password authentication (MD5)
neighbor 203.0.113.2 password mySecureKey
exit
write
Repeat the neighbor stanza for every BGP session you intend to run. You can also set timers, graceful‑restart, and route‑reflector attributes here if required.
Step 5: Advertise Your Own Networks
Tell BGP which prefixes you want to announce to your peers. Use the network command for each prefix, and make sure the prefix exists in the kernel routing table (or is redistributed from another daemon).
configure terminal
router bgp 65001
network 10.10.0.0/16 route-map ADVERTISE-MY-NET
exit
! Create a simple route‑map that permits the prefix
route-map ADVERTISE-MY-NET permit 10
set community no-export
exit
write
If the prefix is not present in the kernel, BGP will reject the advertisement. You can add the prefix manually with ip route or enable redistribution from another protocol (e.g., OSPF) using the redistribute command.
Step 6: Fine‑Tune Policies and Verify the Session
Real‑world BGP deployments rarely consist of a single network statement. You’ll often need inbound and outbound filters, prefix‑lists, and route‑maps to control which routes you accept and announce.
# Example inbound filter – only accept /24 prefixes from the ISP
ip prefix-list ISP-IN seq 10 permit 203.0.113.0/24 le 24
route-map INBOUND-FILTER permit 10
match ip address prefix-list ISP-IN
exit
# Apply the filter to the neighbor
configure terminal
router bgp 65001
neighbor 203.0.113.2 route-map INBOUND-FILTER in
exit
write
# Verify the BGP session and advertised/received routes
vtysh -c "show bgp summary"
vtysh -c "show bgp neighbors 203.0.113.2 advertised-routes"
vtysh -c "show bgp neighbors 203.0.113.2 received-routes"
At this point you should see a BGP state of Established and a list of routes flowing in both directions. If the session is stuck in Idle or Active, double‑check firewalls, MTU settings, and the MD5 password.
Common Mistakes to Avoid
Even seasoned engineers trip over a few recurring pitfalls when deploying BGP on Linux:
- Missing kernel route for advertised networks: BGP will silently drop any
networkstatement that isn’t present in the kernel. Useip route addor redistribute from another daemon. - Incorrect router‑ID: Two routers in the same AS must not share the same router‑ID. Choose a stable, unique address (often a loopback).
- Firewall blocking TCP/179: BGP uses TCP port 179. Ensure both inbound and outbound traffic on this port is allowed between peers.
- MTU mismatch on peering interfaces: A mismatched MTU can cause BGP packets to be dropped, leading to flapping sessions.
- Mis‑typed AS numbers or IP addresses: A single digit off can prevent session establishment; always verify with
show bgp neighbors.
Tips and Tricks
Here are a few expert shortcuts that make managing FRR smoother:
- Use a dedicated loopback for the router‑ID and BGP peering: This isolates the BGP session from physical interface failures.
- Leverage FRR’s daemon‑level logging: Edit
/etc/frr/frr.confand setlog syslog informationalto get granular logs in/var/log/syslogor/var/log/messages. - Batch configuration with a config file: Store the entire BGP stanza in
/etc/frr/bgpd.confand reload withsystemctl reload frrinstead of editing interactively. - Automate with Ansible: The
frrAnsible module can push the full configuration, ensuring consistency across many routers. - Enable graceful‑restart: Add
graceful-restartunderrouter bgpto keep traffic flowing during planned restarts.
Frequently Asked Questions
Can I run multiple BGP instances on the same server?
Yes. FRR supports virtual routing and forwarding (VRF) instances. Define a VRF under vrf, then enable a separate bgpd daemon inside that VRF context.
Do I need to disable SELinux or AppArmor for FRR?
Usually not. FRR ships with SELinux policies that allow the daemons to bind to the required sockets. If you encounter permission errors, check the audit log and adjust the policy rather than disabling security altogether.
How do I back up and restore my FRR configuration?
All configuration lives in /etc/frr/*.conf. Copy these files to a safe location, or use vtysh -c "write memory" to persist changes. Restoring is as simple as placing the files back and restarting the frr service.
Conclusion
Configuring BGP on Linux with FRRouting gives you the flexibility of a full‑featured routing suite without the cost of proprietary hardware. By following the six steps above—installing FRR, verifying connectivity, defining your router ID, adding neighbors, advertising networks, and polishing policies—you’ll have a robust, production‑ready BGP speaker that can interoperate with any ISP or data‑center fabric. Remember to double‑check common pitfalls, keep your daemon logs handy, and automate repetitive tasks with Ansible or VRFs for larger deployments. Happy routing!
Photo by Microsoft Copilot on Unsplash




