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 ASN192.0.2.1→ OuiHeberg neighbor IP208226→ OuiHeberg ASN (AS208226), already provided203.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 ASN2001:db8::1→ OuiHeberg neighbor IPv6 IP208226→ OuiHeberg ASN (AS208226), already provided2001: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:
| Column | Expected Value |
|---|---|
| State/PfxRcd | Established / number of routes received |
| Up/Down | session duration (e.g., 00:05:32) |
| MsgRcvd/Sent | increasing 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
| Measure | FRR Command | Effect |
|---|---|---|
| MD5 Authentication | neighbor X password <secret> | Authenticates BGP TCP packets |
| GTSM (TTL Security) | neighbor X ttl-security hops 1 | Blocks off-segment network packets |
| Maximum-prefix | neighbor X maximum-prefix 100 | Protects against massive route leaks |
| Outgoing prefix-list | neighbor X prefix-list ALLOW-OUT out | Prevents the announcement of unauthorized prefixes |
| Firewall port 179 | iptables | Blocks 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:
| Provider | Host | Port |
|---|---|---|
| Cloudflare | rpki.cloudflare.com | 8282 |
| RIPE NCC | rtr.rpki.cloudflare.com | 8282 |
| NTT | rtr.rpki.ntt.net | 8282 |
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
| Symptom | Probable Cause | Diagnosis | Solution |
|---|---|---|---|
Session in Active | Neighbor unreachable or port 179 blocked | telnet 192.0.2.1 179 | Check firewall, routing, neighbor IP |
Session in Connect | TCP SYN sent but no response | tcpdump -i eth0 port 179 | Check remote ASN, source IP, MD5 |
Session Established but 0 prefixes received | Prefix-list too restrictive on peer side | show bgp neighbors X received-routes | Adjust BOGON-IN or contact OuiHeberg |
| Prefix not visible on bgp.tools | network absent or missing kernel route | show ip bgp 203.0.113.0/24 | Check that the IP exists on the interface (ip route) |
| FRR does not start | bgpd=yes not enabled in daemons | journalctl -u frr | Edit /etc/frr/daemons, restart |
| Session flapping | BGP timer too short or unstable link | show bgp neighbors X → Hold time | Increase 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).
