LinuxJune 8, 2026 10 views

Configure a BGP session with FRRouting on a Linux VPS

Configure a BGP session with FRRouting on a Linux VPS

Prerequisites

Before you begin, you need to have:

  • A Linux VPS (Debian 12 or Ubuntu 22.04/24.04 recommended) with root access
  • Your own ASN (autonomous system number): private (64512–65534) or public (RIPE NCC)
  • Your own IP block (/24 IPv4 minimum, or /48 IPv6)
  • The BGP session information provided by OuiHeberg: neighbor IP, remote ASN, MD5 password (optional)
  • On a OuiHeberg VPS, the IP and routed block are automatically assigned by cloud-init during provisioning (no manual network configuration required)

Note: To obtain a public ASN and a portable IP block, you must join the RIPE NCC or go through a LIR (Local Internet Registry). For private or lab use, a private ASN (64512–65534) is sufficient.


1. Install FRRouting (FRR)

Do not use distro packages: the version in the Debian/Ubuntu repositories is often outdated (FRR 8.x vs current 10.x).

Use the official FRRouting repository:

# Add the official FRR GPG key
curl -s https://deb.frrouting.org/frr/keys.gpg | sudo tee /usr/share/keyrings/frrouting.gpg > /dev/null

# Set the target version (frr-stable = latest stable)
FRRVER="frr-stable"

# Add the APT repository
echo "deb [signed-by=/usr/share/keyrings/frrouting.gpg] https://deb.frrouting.org/frr $(lsb_release -s -c) $FRRVER" | \
  sudo tee /etc/apt/sources.list.d/frr.list

# Install FRR and Python tools
sudo apt install -y curl lsb-release ca-certificates gnupg sudo apt update && sudo apt install -y frr frr-pythontools

Check the installation:

vtysh --version
# Expected: frr version 10.x.x

2. Enable the BGP daemon

By default, all FRR daemons are disabled. Enable only bgpd:

sudo nano /etc/frr/daemons

Edit the line:

bgpd=yes

Enable and start FRR:

sudo systemctl enable frr
sudo systemctl restart frr
sudo systemctl status frr   # Check: active (running)

3. Configure the BGP session in vtysh

vtysh is the unified configuration shell of FRRouting. It works like a Cisco/Juniper CLI.

Enter vtysh:

sudo vtysh

Complete Configuration

! Enter configuration mode
configure terminal

! Declare your ASN
router bgp 65001

  ! Router-ID = main IP of your VPS (assigned by cloud-init)
  bgp router-id 203.0.113.1

  ! Disable default route exchange (security)
  no bgp default ipv4-unicast

  ! Declare the OuiHeberg neighbor (AS208226)
  neighbor 192.0.2.1 remote-as 208226
  neighbor 192.0.2.1 description OuiHeberg-upstream

  ! GTSM: TTL Security, protects against off-segment attacks
  neighbor 192.0.2.1 ttl-security hops 1

  ! MD5 Authentication (if provided by OuiHeberg)
  neighbor 192.0.2.1 password YourMD5Password

  ! Address-family IPv4
  address-family ipv4 unicast

    ! Activate the neighbor in IPv4
    neighbor 192.0.2.1 activate

    ! Announce your block
    network 203.0.113.0/24

    ! Apply filters (defined below)
    neighbor 192.0.2.1 prefix-list ALLOW-OUT out
    neighbor 192.0.2.1 prefix-list BOGON-IN in

    ! Limit received routes (protection against route leaks)
    neighbor 192.0.2.1 maximum-prefix 100

  exit-address-family

exit

! Outgoing prefix-list: announce ONLY your own block
ip prefix-list ALLOW-OUT seq 10 permit 203.0.113.0/24

! Incoming prefix-list: deny bogons and RFC1918
ip prefix-list BOGON-IN seq 5  deny 0.0.0.0/0
ip prefix-list BOGON-IN seq 10 deny 10.0.0.0/8 le 32
ip prefix-list BOGON-IN seq 20 deny 172.16.0.0/12 le 32
ip prefix-list BOGON-IN seq 30 deny 192.168.0.0/16 le 32
ip prefix-list BOGON-IN seq 40 deny 127.0.0.0/8 le 32
ip prefix-list BOGON-IN seq 50 deny 169.254.0.0/16 le 32
ip prefix-list BOGON-IN seq 100 permit 0.0.0.0/0 le 32

! Save
write memory
end

Replace:

  • 65001 → your ASN
  • 192.0.2.1 → OuiHeberg neighbor IP
  • 208226 → OuiHeberg ASN (AS208226), already provided
  • 203.0.113.0/24 → your actual IP block

4. IPv6 Configuration (optional)

If you have an IPv6 block (/48 or /56):

configure terminal

router bgp 65001

  neighbor 2001:db8::1 remote-as 208226
  neighbor 2001:db8::1 description OuiHeberg-upstream-v6
  neighbor 2001:db8::1 ttl-security hops 1

  address-family ipv6 unicast
    neighbor 2001:db8::1 activate
    network 2001:db8:1::/48
    neighbor 2001:db8::1 prefix-list ALLOW-OUT-V6 out
    neighbor 2001:db8::1 maximum-prefix 50
  exit-address-family

exit

ipv6 prefix-list ALLOW-OUT-V6 seq 10 permit 2001:db8:1::/48

write memory
end

Replace:

  • 65001 → your ASN
  • 2001:db8::1 → OuiHeberg neighbor IPv6 IP
  • 208226 → OuiHeberg ASN (AS208226), already provided
  • 2001:db8:1::/48 → your actual IPv6 block

5. Check the BGP session

Essential vtysh Commands

! Overview of all sessions
show bgp summary

! Detail of a specific peer
show bgp neighbors 192.0.2.1

! Announced routes
show ip bgp

! Routes received from the peer
show ip bgp neighbors 192.0.2.1 received-routes

Target state in show bgp summary:

ColumnExpected Value
State/PfxRcdEstablished / number of routes received
Up/Downsession duration (e.g., 00:05:32)
MsgRcvd/Sentincreasing counters

If the state shows Active or Connect → see Troubleshooting section.

External Verification

Use a looking glass to confirm that your prefix is visible on the public Internet:

  • bgp.tools: search for your prefix or ASN, real-time view of BGP announcements

6. Secure the BGP session

iptables Firewall: restrict BGP port

Allow port 179 (BGP) only from the OuiHeberg neighbor IP:

# Allow loopback
sudo iptables -A INPUT -i lo -j ACCEPT

# Allow established sessions
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# BGP: only from the OuiHeberg neighbor
sudo iptables -A INPUT -p tcp -s 192.0.2.1 --dport 179 -j ACCEPT

# SSH (adjust the port if necessary)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Default policy: drop everything else (to be set last)
sudo iptables -P INPUT DROP

Persist the rules:

sudo apt install iptables-persistent
sudo netfilter-persistent save

Summary of Security Measures

MeasureFRR CommandEffect
MD5 Authenticationneighbor X password <secret>Authenticates BGP TCP packets
GTSM (TTL Security)neighbor X ttl-security hops 1Blocks off-segment network packets
Maximum-prefixneighbor X maximum-prefix 100Protects against massive route leaks
Outgoing prefix-listneighbor X prefix-list ALLOW-OUT outPrevents the announcement of unauthorized prefixes
Firewall port 179iptablesBlocks illegitimate BGP connections

7. RPKI / ROA: origin validation of routes

RPKI (Resource Public Key Infrastructure) allows validating that the received BGP prefixes are indeed announced by their legitimate owner. Without RPKI, your VPS accepts potentially hijacked routes.

In 2026, not enabling RPKI on a public BGP session is leaving a door open to route hijacks. The excuse "it's complex" no longer holds with a free public RTR server.

Configure the Cloudflare RTR server

configure terminal

! Add the Cloudflare RTR cache (free, public)
rpki
  rpki add cache rpki.cloudflare.com 8282
  rpki start
exit

! Enable validation in BGP
router bgp 65001
  address-family ipv4 unicast
    bgp bestpath prefix-validate allow-invalid
  exit-address-family
exit

write memory
end

Check the RTR connection:

show rpki cache-connection
show rpki prefix-table

Alternative public RTR servers:

ProviderHostPort
Cloudflarerpki.cloudflare.com8282
RIPE NCCrtr.rpki.cloudflare.com8282
NTTrtr.rpki.ntt.net8282

8. Complete Configuration: annotated frr.conf

After write memory, your configuration is saved in /etc/frr/frr.conf. Complete example:

frr version 10.1.1
frr defaults traditional
hostname my-vps-ouiheberg
log syslog informational
no ipv6 forwarding

!
ip prefix-list ALLOW-OUT seq 10 permit 203.0.113.0/24

ip prefix-list BOGON-IN seq 5  deny 0.0.0.0/0
ip prefix-list BOGON-IN seq 10 deny 10.0.0.0/8 le 32
ip prefix-list BOGON-IN seq 20 deny 172.16.0.0/12 le 32
ip prefix-list BOGON-IN seq 30 deny 192.168.0.0/16 le 32
ip prefix-list BOGON-IN seq 40 deny 127.0.0.0/8 le 32
ip prefix-list BOGON-IN seq 50 deny 169.254.0.0/16 le 32
ip prefix-list BOGON-IN seq 100 permit 0.0.0.0/0 le 32

!
router bgp 65001
 bgp router-id 203.0.113.1
 no bgp default ipv4-unicast
 neighbor 192.0.2.1 remote-as 208226
 neighbor 192.0.2.1 description OuiHeberg-upstream
 neighbor 192.0.2.1 ttl-security hops 1
 neighbor 192.0.2.1 password YourMD5Password
 !
 address-family ipv4 unicast
  neighbor 192.0.2.1 activate
  neighbor 192.0.2.1 prefix-list ALLOW-OUT out
  neighbor 192.0.2.1 prefix-list BOGON-IN in
  neighbor 192.0.2.1 maximum-prefix 100
  network 203.0.113.0/24
 exit-address-family
!

9. Troubleshooting

SymptomProbable CauseDiagnosisSolution
Session in ActiveNeighbor unreachable or port 179 blockedtelnet 192.0.2.1 179Check firewall, routing, neighbor IP
Session in ConnectTCP SYN sent but no responsetcpdump -i eth0 port 179Check remote ASN, source IP, MD5
Session Established but 0 prefixes receivedPrefix-list too restrictive on peer sideshow bgp neighbors X received-routesAdjust BOGON-IN or contact OuiHeberg
Prefix not visible on bgp.toolsnetwork absent or missing kernel routeshow ip bgp 203.0.113.0/24Check that the IP exists on the interface (ip route)
FRR does not startbgpd=yes not enabled in daemonsjournalctl -u frrEdit /etc/frr/daemons, restart
Session flappingBGP timer too short or unstable linkshow bgp neighbors X → Hold timeIncrease timers bgp 30 90 in vtysh

FAQ

What is the difference between FRRouting and BIRD2 for BGP?

FRR uses a Cisco/Juniper style CLI (vtysh), familiar to network admins. BIRD2 uses a more powerful declarative configuration language for complex setups (route reflectors, multi-table). For a simple BGP session on a VPS, FRR is quicker to get started.

Can I use FRR without my own ASN?

No for a public BGP session. For a private lab, a private ASN (64512–65534) is sufficient. To announce your own prefixes on the Internet, a public RIPE ASN is mandatory.

Does FRR consume a lot of resources on a VPS?

For a BGP session receiving only a default route (default): about 30–80 MB of RAM and less than 1% CPU in stable mode. For a full table BGP (about 900,000 routes): plan for at least 2–4 GB of RAM. A 2 GB RAM VPS is sufficient for most use cases (prefix announcement, receiving a default route, failover).

Can I configure BGP on a VPS without a dedicated public IP address?

No. BGP requires direct TCP connectivity (port 179) between the two peers. Your VPS must have a routable public IP and direct network access to the OuiHeberg neighbor.

How to update FRRouting without interrupting BGP sessions?

FRR supports Graceful Restart (RFC 4724). Enable with bgp graceful-restart in the BGP config. During an apt upgrade frr, sessions are maintained during the daemon restart (about 30–60 seconds of convergence).


Useful Sources