Network Configuration¶
This guide covers BIRD (BGP routing) and WireGuard (VPN) configuration management.
BIRD Configuration¶
BIRD is used for BGP routing on core, IXP, and VLT servers to announce AS215011 routes.
Configuration Files¶
BIRD configurations are Jinja2 templates under templates/config/{group}/.../bird/:
templates/config/
├── core/coreams01/bird/bird.conf.j2 # core (applied manually — see warning below)
├── ixp/{hostname}/bird/
│ ├── bird.conf.j2
│ └── peerlab.conf.j2 # optional, present on some IXP hosts
├── vlt/bird/bird.conf.j2 # shared across all VLT hosts
└── shared/bird/bird.service # systemd unit (all hosts)
Templated and rendered
BIRD configs are Jinja2 templates. make render renders them — injecting the host's IPv6 address from Terraform output, secrets, and inventory vars — into .rendered/{hostname}/bird/bird.conf. make sync-bird deploys the rendered file, never the template directly.
Update BIRD Configuration¶
- Edit the template (pick the right scope):
- IXP host:
templates/config/ixp/{hostname}/bird/bird.conf.j2 - All VLT hosts:
templates/config/vlt/bird/bird.conf.j2
- Render and sync to the servers:
This renders the templates and runs playbooks/sync-bird.yml against the ixp and vlt groups (prompts for your BECOME / sudo password).
!!! warning "Core BIRD is manual"
sync-bird does not target coreams01. make sync-config rsyncs the rendered core config to /home/nxthdr/bird/, but applying it to /etc/bird/bird.conf and reloading is a manual step on the core host (sudo cp + sudo birdc configure).
- Verify the change:
BIRD Playbook Details¶
The sync-bird playbook (playbooks/sync-bird.yml):
- Creates the
/etc/birddirectory - Copies the rendered
.rendered/{hostname}/bird/bird.conf→/etc/bird/bird.conf - Copies the rendered
peerlab.confif it exists - Copies
templates/config/shared/bird/bird.service→ systemd - Reloads the systemd daemon
- Enables and reloads the BIRD service
Target hosts: ixp, vlt (not core — see the warning above)
Common BIRD Operations¶
Check BIRD status:
View BGP sessions:
View routing table:
Reload BIRD configuration:
Restart BIRD service:
WireGuard Configuration¶
WireGuard VPN tunnels connect IXP servers to the core server.
Configuration Files¶
WireGuard configurations are Jinja2 templates under templates/config/{group}/{hostname}/wireguard/:
templates/config/
├── core/coreams01/wireguard/
│ ├── wg0.conf.j2
│ └── wg1.conf.j2
└── ixp/{hostname}/wireguard/
└── wg0.conf.j2 # some IXP hosts also have wg1.conf.j2
Templated and rendered
WireGuard configs are Jinja2 templates (they reference keys from secrets.yml and inventory vars). make render writes them to .rendered/{hostname}/wireguard/, and make sync-wireguard deploys the rendered .conf files.
Update WireGuard Configuration¶
-
Edit the template:
-
Render and sync to the servers:
This renders the templates and deploys the rendered configs to the core and ixp groups (prompts for your BECOME password).
- Verify the tunnel:
WireGuard Playbook Details¶
The sync-wireguard playbook (playbooks/sync-wireguard.yml):
- Copies the rendered
.rendered/{hostname}/wireguard/*.conf→/etc/wireguard/(mode0600) - Restarts
wg-quick@wg0.service - Restarts
wg-quick@wg1.service
Target hosts: core, ixp
Common WireGuard Operations¶
Check tunnel status:
Restart WireGuard interface:
View WireGuard logs:
Test connectivity through tunnel:
Generate WireGuard Keys¶
To create new WireGuard keys:
# Generate private key
wg genkey
# Generate public key from private key
echo "<private_key>" | wg pubkey
Store the private key in secrets/secrets.yml:
Add:
Use in config:
Network Topology¶
Core to IXP Tunnels¶
┌─────────────┐ ┌─────────────┐
│ coreams01 │◄──── WireGuard ────►│ ixpams01 │
│ (Core) │ Tunnel │ (IXP) │
└─────────────┘ └─────────────┘
│ │
│ Announces │ Peers with
│ 2a06:de00:50::/44 │ other ASes
│ │
└────────────────────────────────────┘
Traffic flows through AS215011
Prefix Announcements¶
- Core services:
2a06:de00:50::/44 - Announced by core to IXP servers
-
IXP servers propagate to Internet via BGP
-
Probing infrastructure:
2a0e:97c0:8a0::/44 - Announced by VLT servers
- Enables unicast/anycast measurements
Firewall Configuration¶
Docker Firewall Rules¶
By default, Docker networks are isolated. To allow external access:
ssh nxthdr@ams01.core.infra.nxthdr.dev
sudo ip6tables -I DOCKER-USER -d 2a06:de00:50:cafe:100::/80 -j ACCEPT
This allows traffic to the DMZ network.
Manual Configuration
This firewall rule is not managed by the infrastructure code and must be applied manually.
View Current Rules¶
Troubleshooting¶
BIRD Not Starting¶
Check logs:
Common issues:
- Syntax error in config: sudo bird -p -c /etc/bird/bird.conf
- Port already in use: sudo netstat -tulpn | grep 179
- Missing dependencies: sudo apt install bird2
WireGuard Tunnel Down¶
Check interface status:
Common issues:
- Firewall blocking UDP port: sudo ufw allow 51820/udp
- Incorrect endpoint: Check Endpoint in config
- Key mismatch: Verify public/private key pairs
Restart tunnel:
BGP Session Not Establishing¶
Check BIRD logs:
Common issues: - Incorrect neighbor IP - AS number mismatch - Firewall blocking TCP port 179 - Peer not configured on remote side
Test connectivity:
Routes Not Propagating¶
Check export filters:
Verify static routes:
Check kernel routing table:
Best Practices¶
-
Test BIRD config syntax before deploying:
-
Monitor BGP sessions after changes:
-
Keep WireGuard keys secure in Ansible Vault
-
Document peering arrangements in comments
-
Use BGP communities for route tagging and filtering
-
Set up monitoring for tunnel and BGP session status
Next Steps¶
- Adding Services - Add new services
- Common Tasks - Day-to-day operations
- Architecture - Technical details