Sales:+1 408 351 7911 (US)
The Sales Team is online during working days
logo
logo

June 17, 2025

Testing 1

Many of our clients ask for help with configuration of BIRD deamon (mostly for BGP). While you'll still need our help to make configuration on the network side, it'll still be necessary to configure your server correctly.

BIRD is an Internet Routing Daemon designed to avoid all of shortcomings, to support all the routing technology used in the today's Internet or planned to be used in near future and to have a clean extensible architecture allowing new routing protocols to be incorporated easily. Unfortunately, no solution just works as-is. You'll have to configure not only BIRD but network interfaces and firewalls as well. These configs are NOT optional and will cause problems if done wrong.

All settings should be done on (at least mostly) a clean-install server to avoid problems with debugging.

To make the process easier, we have prepared an ansible playbook to ease the process. We strongly recommend you use it to avoid misconfiguration.

Ansible According to their website:

Ansible is the simplest way to automate apps and IT infrastructure. Application Deployment + Configuration Management + Continuous Delivery. And I couldn't agree more. If you don't use it yet, you really should. All it needs to work is ssh access and python installed on the target machine. After that, you simply cd to playbook directory and run ansible-playbook bgp.yml and watch everything config by itself.

To make everything work, Ansible will install the following packages:

vlan iptables-persistent bird ifupdown It's important to mention that this playbook is prepared with ifupdown, iptables, and Debian in mind. If you use netplan.io (now default in Ubuntu) to manage your interfaces, you should either uninstall netplan (after you run the playbook, you would end up with no connectivity on your server otherwise) or bend the playbook to configure netplan instead. To uninstall netplan, follow these steps:

in /etc/default/grub edit this line GRUBCMDLINELINUX="netcfg/donotuse_netplan=true" update-grub rm /etc/netplan/* apt purge netplan.io make sure you have ifupdown installed & configured Playbook description for dummies You can get the playbook here. You'll need to make a couple of changes based on your current setup. Let's get to it.

ansible.cfg By default Ansible will look at /etc/ansible/hosts for hosts. We'll want to change that, same as path to roles. A little dictionary:

inventory - a set of servers you'll want to configure by Ansible roles - what exactly you wish to happen there [defaults] callbackwhitelist = profiletasks stdoutcallback = yaml rolespath = your/path/toplaybook/roles/ inventory = your/path/toplaybook/hosts hosts In the example, we call the set of hosts we want to configure with bird "bgp". It's generally not advised to use root as ansibleuser as it can be unsafe. It's also the fastest way to get the work done, however. If you ssh into your machines using a password, you can add the ansiblepassword parameter, but you'll also need to install sshpass in addition to Ansible. This is considered unsafe, and you should definitely use passwordless authentication by setting ansiblesshprivatekeyfile=path/to/private_key.

[bgp] Server1 ansibleport=61234 ansibleuser=root ansiblehost={URL or IP address} Server2 ansibleport=61234 ansibleuser=root ansiblehost={URL or IP address} hostvars/server1/vars This file contains the actual configuration used for interfaces and bird. You will have to contact support to get all the information, such as datapacketasnip or vlanid. You'll also have to create and modify a copy of this file for every single server in your hosts file.

you can learn vlan_id from support

vlan_id: 3502

set to your IP address, gateway and name, set on your main network interface

ipaddress: 192.0.2.0/24 gateway: 192.0.2.254 mainiface: enp2s0f0

asn of datapacket - you don't need to change this

datapacket_asn: 60068

asn you wish to propagate

customer_asn: 64511

a unique identifier of our router - learn this from support

datapacketasnip: 198.51.100.0

unique identifier of your router

customerasnip: 192.168.101.111

prefix you want to propagate

networkstopropagate: "203.0.113.0/24" propagatedipassign:

  • 203.0.113.100/24 To better understand the settings, you should take a look at the files that will actually be changed. Namely:

/etc/network/interfaces /etc/iproute2/rt_tables /etc/iptables/rules.v4 /etc/bird/bird.conf /etc/sysctl.conf You can also use following templates to manually configure each component.

Interfaces ifupdown package stores network configuration in /etc/network/interfaces. We recommend bonding your interfaces even if you are using a single uplink simply to save time in the future. It's not completely necessary, however.

As we are also setting up VLANs, you'll need to coordinate with our team to correctly set up the network side.

loopback

auto lo iface lo inet loopback {% for ip in propagatedipassign %}

up ip a a dev lo brd + {{ ip }}

{% endfor %}

{% if main_iface == "bond0" %}

auto bond0 iface bond0 inet static

address {{ ip_address }}
   gateway {{ gateway }}
   dns-nameservers 8.8.8.8 8.8.4.4
   dns-search datapacket.com
   bond-xmit_hash_policy encap3+4
   bond-mode 802.3ad
   bond-miimon 100
   bond-downdelay 200
   bond-updelay 200
   bond-slaves {{ bond_slave1 }} {{ bond_slave2 }}

auto {{ bondslave1 }} iface {{ bondslave1 }} inet manual bond-master bond0

auto {{ bondslave2 }} iface {{ bondslave2 }} inet manual bond-master bond0

{% else %}

auto {{ mainiface }} iface {{ mainiface }} inet static

address {{ ip_address }}
   gateway {{ gateway }}
   dns-nameservers 8.8.8.8 8.8.4.4
   dns-search datapacket.com

{% endif %}

----------BGP vlan {{ vlan_id }}

auto {{ mainiface }}.{{ vlanid }} iface {{ mainiface }}.{{ vlanid }} inet static address {{ customerasnip }}/31 vlan-raw-device {{ mainiface }} up ip r a table vlan{{ vlanid }}int default via {{ datapacketasnip }} up ip rule add priority 70 from {{ datapacketasnip }}/31 table vlan{{ vlanid }}int up ip rule add fwmark 2 table vlan{{ vlanid }}int down ip rule del priority 70 from {{ datapacketasnip }}/31 table vlan{{ vlanid }}int down ip rule del fwmark 2 table vlan{{ vlanid }}_int

{% if vlanidsecondary is defined %}

----------BGP vlan {{ vlanidsecondary }}

auto {{ mainiface }}.{{ vlanidsecondary }} iface {{ mainiface }}.{{ vlanidsecondary }} inet static address {{ customerasnipsecondary }}/31 vlan-raw-device {{ mainiface }} up ip r a table vlan{{ vlanidsecondary }}int default via {{ datapacketasnipsecondary }} up ip rule add priority 71 from {{ datapacketasnipsecondary }}/31 table vlan{{ vlanidsecondary }}int up ip rule add fwmark 3 table vlan{{ vlanidsecondary }}int down ip rule del priority 71 from {{ datapacketasnipsecondary }}/31 table vlan{{ vlanidsecondary }}int down ip rule del fwmark 3 table vlan{{ vlanidsecondary }}int {% endif %} rttables If you're not familiar with /etc/iproute2/rttables don't worry about it too much. My favourite description of it comes from stackexchange:

That's just the flat file used by the iproute2 utilities which translates user friendly names given on the command line into integer values used by the kernel. It's just to maintain a consistent mapping of "this name is this integer" #

reserved values

# 255 local 254 main 253 default 0 unspec #

local

#

1 inr.ruhep

250 vlan{{ vlanid }}int Iptables Iptables is probably the most well-known tool for IP packet filtering. If you use any other, you'll have to set it up equivalently. The rules are stored at /etc/iptables/rules.v4. For instant apply do iptables-restore /etc/iptables/rules.v4.

Generated by iptables-save v1.6.1

*nat :PREROUTING ACCEPT [0:0] :INPUT ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] COMMIT

Completed

Generated by iptables-save v1.6.1

*filter :INPUT ACCEPT [137377297:94770129917] :FORWARD ACCEPT [768366:46389689] :OUTPUT ACCEPT [146520452:85216948160] -A INPUT -i lo -j ACCEPT COMMIT

Completed

*mangle :PREROUTING ACCEPT [309818506:257622963617] :INPUT ACCEPT [309818506:257622963617] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [152148313:642044956423] :POSTROUTING ACCEPT [152148313:642044956423] -A INPUT -i {{ mainiface }}.{{ vlanid }} -j MARK --set-mark 2 -A INPUT -j CONNMARK --save-mark -A OUTPUT -j CONNMARK --restore-mark COMMIT BIRD All the work we've done so far leads to configuring BIRD for BGP. This config is stored at /etc/bird/bird.conf. Make sure to enable bird service to autostart: systemctl enable bird.service

BIRD uses an internal routing table. We use import and export rules to keep it in sync with kernel's routing table.

log syslog { debug, trace, info, remote, warning, error, auth, fatal, bug };

define myas = {{ customerasn }}; define myip = {{ customerasnip }}; {% if vlanidsecondary is defined %} define myip2 = {{ customerasnipsecondary }}; {% endif %} router id {{ customerasnip }}; listen bgp address myip;

Change this into your BIRD router ID. It's a world-wide unique identification

of your router, usually one of router's IPv4 addresses.

protocol device { scan time 60; }

protocol direct {

export none;
    import where net ~ [ {{ networks_to_propagate }} ] ;

}

protocol kernel {

import none;            # Default is import all
    export all;             # Default is export none

}

template bgp PEERS { local myip as myas; neighbor {{ datapacketasnip }} as {{ datapacket_asn }}; import none; export all; import limit 1000 action restart; bfd on; interpret communities off; connect retry time 5; }

protocol bgp BGP1 from PEERS { import none; export all; next hop self; }

{% if vlanidsecondary is defined %} template bgp PEERS2 { local myip2 as myas; neighbor {{ datapacketasnipsecondary }} as {{ datapacketasn }}; import none; export all; import limit 1000 action restart; bfd on; interpret communities off; connect retry time 5; }

protocol bgp BGP2 from PEERS2 { import none; export all; next hop self; } {% endif %} sysctl With /etc/sysctl.conf you can configure various Linux networking and system settings. There's a bit more settings in the file itself, but this part is important for you.

net.ipv4.conf.all.rpfilter = 0 net.ipv4.conf.lo.rpfilter = 0 net.ipv4.conf.{{ mainiface }}/{{ vlanid }}.rpfilter = 0 net.ipv4.conf.all.arpannounce = 1 net.ipv4.conf.{{ mainiface }}/{{ vlanid }}.arpannounce = 1 net.ipv4.ipforward = 1 When you run ansible playbook and perform a reboot, everything should work as expected. You should be able to see with birdc show protocols something along the lines of:

BGP1 in state Established And that's it! BIRD should now be able to propagate your AS using BGP without any problems. Of course, if you run into any trouble, don't hesitate to contact our support.

Experience Unmatched Connectivity