Setting Up Your Own BGP: Configure Pathvector and share the subnet with the LAN
Running your own Autonomous System (AS) and advertising your IPv4/IPv6 prefixes sounds complex, but modern tools like Pathvector and Bird2…
Setting Up Your Own BGP: Configure Pathvector and share the subnet with the LAN

Running your own Autonomous System (AS) and advertising your IPv4/IPv6 prefixes sounds complex, but modern tools like Pathvector and Bird2 make it approachable. I had this setup for some time, but this time I’m trying to share the BGP session with my LAN devices using an additional interface. In this guide, I’ll walk through how I set up a server to:
- Peer with an upstream provider (Route64) over GRE tunnels
- Announce my IPv4
/24and IPv6/48 - Expose those IPs to VMs on a local interface
- Ensure traffic flows correctly using Linux policy routing
1. Prerequisites
- A Linux host (Ubuntu 24.04+ works great)
- Your own ASN and IP allocations (in my case:
AS65001,198.51.100.0/24,2001:db8:abcd::/48) - A BGP upstream that supports tunneling (Route64 provided GRE endpoints)
2. Base Networking Setup
Your uplink (eth0) still uses your provider’s address (e.g. Hetzner), but you create a second interface for your LAN/VMs.
Example netplan config:
network:
version: 2
ethernets:
eth0:
match:
macaddress: "00:01:02:03:04:aa"
addresses:
- "2001:db8:1234::123/64"
nameservers:
addresses:
- 1.1.1.1
- 2606:4700:4700::1111
search:
- example.com
dhcp4: true
set-name: "eth0"
routes:
- on-link: true
to: "default"
via: "fe80::1"
After applying, your VMs can connect to eth1 and use:
Example netplan config:
network:
version: 2
ethernets:
eth1:
match:
macaddress: "00:01:02:03:04:bb"
addresses:
- "198.51.100.1/24"
- "2001:db8:abcd::1/64"
nameservers:
addresses:
- 1.1.1.1
- 2606:4700:4700::1111
search:
- example.com
set-name: "eth1"
routing-policy:
- from: 198.51.100.0/24
to: 198.51.100.0/24
table: 254
priority: 50
- from: 2001:db8:abcd::/48
to: 2001:db8:abcd::/48
table: 254
priority: 50
You can leave without a gateway or use something like this
- IPv4 gateway:
198.51.100.1 - IPv6 gateway:
2001:db8:abcd::1
3. GRE Tunnels to Your Upstream
Create tunnels for v4/v6 peering (example: /etc/netplan/route64-gre.yaml):
network:
version: 2
tunnels:
route64-gre:
mode: gre
local: X.X.X.X
remote: Y.Y.Y.Y
addresses:
- X.X.X.2/30
- X:X:X:X::2/64
ttl: 255
routes:
- to: X.X.X.0/30
table: 101
- to: X:X:X:X::/64
table: 101
# Static Route for Peer IP
- to: X.X.X.X/32
# Your Gateway IP
via: X.X.X.X
- to: X:X::X/128
via: X:X:X:X::1
Now you have point-to-point subnets to run BGP sessions.
4. Pathvector Configuration
First, install the necessary packages:
curl https://repo.pathvector.io/pgp.asc > /usr/share/keyrings/pathvector.asc
echo "deb [signed-by=/usr/share/keyrings/pathvector.asc] https://repo.pathvector.io/apt/ stable main" > /etc/apt/sources.list.d/pathvector.list
apt update && apt install -y pathvector bgpq4 bird2
Pathvector makes Bird2 configs simple. Example /etc/pathvector.yml:
# Your ASN Number
asn: 65001
# BIRD router ID
router-id: X.X.X.X
# RIRs to query for IRR filtering
bgpq-args: -S AFRINIC,APNIC,ARIN,LACNIC,RIPE
# Main IRR whois server
irr-server: rr.ntt.net
# Timeout for IRR lookups
irr-query-timeout: 30
# RPKI RTR validator
rtr-server: rtr.rpki.cloudflare.com:8282
# Auto-generate configs from PeeringDB
peeringdb-api-key: "REDUCTED"
# PeeringDB API Timeout
peeringdb-query-timeout: 30
# Send default route to peer
default-route: true
# Originate default route
#accept-default: true
# Allows multiple ECMP paths
merge-paths: true
# Keep filtered routes (useful for debugging)
keep-filtered: false
kernel:
# Import BIRD routes into system kernel
learn: true
# Don’t export system routes into BIRD
export: false
# Your announced prefixes
prefixes:
- 198.51.100.0/24
- 2001:db8:abcd::/48
# Communities Documentation
# 65001:0:12 → Learned from upstream
# 65001:0:13 → Learned from route server
# 65001:0:14 → Learned from peer
# 65001:0:15 → Learned from downstream (customer routes)
# 65001:0:16 → Own prefixes (your allocations)
templates:
upstream:
local-pref: 80
allow-local-as: false
add-on-import: ["65001:0:12"]
announce: ["65001:0:15", "65001:0:16"]
remove-all-communities: 65001
import-limit4: 2000000
import-limit6: 500000
filter-irr: false
filter-transit-asns: false
enforce-first-as: true
enforce-peer-nexthop: true
routeserver:
local-pref: 90
add-on-import: ["65001:0:13"]
announce: ["65001:0:15", "65001:0:16"]
remove-all-communities: 65001
filter-irr: true
filter-transit-asns: true
auto-import-limits: true
auto-as-set: true
enforce-first-as: false
enforce-peer-nexthop: false
next-hop-self: true
peer:
local-pref: 100
add-on-import: ["65001:0:14"]
announce: ["65001:0:15", "65001:0:16"]
remove-all-communities: 65001
filter-irr: true
filter-transit-asns: true
auto-import-limits: true
auto-as-set: true
enforce-first-as: true
enforce-peer-nexthop: true
next-hop-self: true
ibgp:
local-pref: 150
allow-local-as: true
add-on-import: ["65001:0:16"]
announce: ["65001:0:12", "65001:0:13", "65001:0:14", "65001:0:15", "65001:0:16"]
# Enable default route to iBGP
#announce-default: true
remove-all-communities: 65001
enforce-first-as: false
enforce-peer-nexthop: false
filter-rpki: false
filter-irr: false
next-hop-self: true
import-limit4: 10000
import-limit6: 5000
downstream:
local-pref: 200
add-on-import: ["65001:0:15"]
announce: ["65001:0:12", "65001:0:13", "65001:0:14", "65001:0:16"]
remove-all-communities: 65001
announce-default: true
filter-irr: true
filter-transit-asns: true
auto-import-limits: true
auto-as-set: true
next-hop-self: true
import-limit4: 50000
import-limit6: 25000
allow-blackhole-community: true
peers:
route64:
asn: 212895
template: upstream
neighbors:
- X.X.X.1
- X:X:X:X::1
local-pref: 80
#multihop: true
vultr:
asn: 64515
template: upstream
neighbors:
- 169.254.169.254
- 2001:19f0:ffff::1
password: REDUCTED
multihop: true
enforce-first-as: false
enforce-peer-nexthop: false
filter-bogon-asns: false
listen4: "YOUR_VPS_IPv4_ADDRESS"
listen6: "YOUR_VPS_IPv6_ADDRESS"
add-path-rx: true
homelab:
asn: XXXXXX
template: ibgp
rr-client: true
neighbors:
- X.X.X.X
- X:X:X:X::X
listen4: "X.X.X.X"
listen6: "X:X:X:X::X"
Apply pathvector config:
pathvector g
Restart Pathvector:
systemctl restart pathvector
Check sessions:
birdc show proto all
Check announcement:
birdc show route export ROUTE64_AS212895_v4
birdc show route export ROUTE64_AS212895_v6
You should see your peers established and your prefixes exported.
5. Linux Policy Routing (Source-Based Routing)
Without this, your VMs’ traffic may leak via eth0 and get dropped by your datacenter (BCP-38).
We use table 100 for all traffic sourced from our IP space.
Create /etc/systemd/system/bgp.service:
[Unit]
Description=BGP Policy Routing Rules
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/etc/bgp-rules.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
And the script /etc/bgp-rules.sh:
#!/bin/sh
# Cleanup existing rules and routes
ip rule del from 198.51.100.0/24 table 101 priority 101 2>/dev/null
ip -6 rule del from 2001:db8:abcd::/48 table 101 priority 101 2>/dev/null
ip route flush table 101
ip -6 route flush table 101
# ========== IPv4 rules ==========
ip rule add from 198.51.100.0/24 table 101 priority 101
# IPv4 defaults
ip route add table 101 default via X.X.X.X dev route64-gre
# ========== IPv6 rules ==========
ip -6 rule add from 2001:db8:abcd::/48 table 101 priority 101
# IPv6 defaults
ip -6 route add table 101 default via X:X:X:X::1 dev route64-gre
Make it executable:
chmod +x /etc/bgp-rules.sh
systemctl enable bgp
systemctl start bgp
Now, on every boot, Linux knows to send your /24 and /48 traffic out via the GRE.
6. Sysctl Tuning
Enable forwarding and disable reverse path filtering:
# /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
# Keep proxy ARP/NDP only where needed
net.ipv4.conf.all.proxy_arp=0
net.ipv6.conf.all.proxy_ndp=0
net.ipv4.conf.eth1.proxy_arp=1
net.ipv6.conf.eth1.proxy_ndp=1
# Disable redirects (security hardening)
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.default.accept_redirects=0
# Disable sending redirects
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
# Reverse path filtering OFF (needed for BGP/tunnels)
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
Apply:
sysctl -p
7. Testing
On the host:
ip route get 8.8.8.8 from 198.51.100.1
ip -6 route get 2001:4860:4860::8888 from 2001:db8:abcd::1
Should show via ... dev route64-gre table route64.
From a VM:
ping 8.8.8.8
ping6 2001:4860:4860::8888
curl -4 ifconfig.co
curl -6 ifconfig.co
You should see traffic sourced from your own prefixes.
8. Verify Global Visibility
Check that your prefixes are visible to the world:
bgp.he.net/AS65001 or with any public looking glass
Conclusion
With Pathvector + Bird2 + a bit of Linux policy routing, you can:
- Announce your own IPv4/IPv6 space
- Hand out public IPs directly to VMs
- Ensure traffic flows cleanly through your BGP upstream
This setup gives you real ISP-like control from a single server — a perfect lab for learning BGP or even production use for small providers.
메타데이터
- post_id
- ecf2d9291215
- slug
- announcing-your-own-bgp-network-configure-pathvector-and-share-a-subnet-with-the-network-interface-ecf2d9291215
- url
- https://medium.com/@amanjuman/announcing-your-own-bgp-network-configure-pathvector-and-share-a-subnet-with-the-network-interface-ecf2d9291215
- canonical_url
- https://medium.com/@amanjuman/announcing-your-own-bgp-network-configure-pathvector-and-share-a-subnet-with-the-network-interface-ecf2d9291215
- author_url
- https://medium.com/@amanjuman
- status
- ok
- fetched_at
- 2026-07-17 18:53:09