← Back to list

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…

Aman Ullah Juman · 2025-09-22 23:15 · 0 claps · 4.8 min read
#bgp #pathvector #ipv4 #ipv6 #networking
Open on Medium ↗
Wiki topics: RAG · RAG & Retrieval AGT · AI Agents 🐾 · Pets & Animals 🏃 · Running & Endurance

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 /24 and 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