How to Configure CloudRouter containers as a Route Server
For this article we will be using the CloudRouter bird docker container to show case how we can configure a bird daemon that's running inside multiple docker containers and still perform the usual functionality of being a Route Server.
Pull down the CloudRouter fedora bird container from the public repository – https://registry.hub.docker.com/repos/cloudrouter/
# docker pull cloudrouter/bird-fedora Pulling repository cloudrouter/bird-fedora 19e1acd93cd5: Download complete 511136ea3c5a: Download complete 782cf93a8f16: Download complete 6cece30db4f9: Download complete 4dcfc015c438: Download complete 60610127a187: Download complete fb814efbf4df: Download complete ecc97c347025: Download complete d32f32e5c395: Download complete f56201d4f627: Download complete 24f3dbad9ace: Download complete 2285b2b50350: Download complete f748483b1fec: Download complete 2a5bf0f8f1a8: Download complete 95486ef61dd0: Download complete 0b2057fe41b7: Download complete e1ac3c04bc1d: Download complete 4e203d55e43e: Download complete Status: Image is up to date for cloudrouter/bird-fedora:latest #
For this example we will use the following topology of 3 containers.
Lets start the 3 docker containers.
# docker run --publish-all=true -t -i cloudrouter/bird-fedora /bin/bash # docker run --publish-all=true -t -i cloudrouter/bird-fedora /bin/bash # docker run --publish-all=true -t -i cloudrouter/bird-fedora /bin/bash
Lets make sure all of our 3 containers are up and running and have the default networking in place.
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 02d05ac0aa07 cloudrouter/bird-fedora:latest "/bin/bash" 28 minutes ago Up 28 minutes cocky_bell 0896588f8664 cloudrouter/bird-fedora:latest "/bin/bash" 30 minutes ago Up 30 minutes prickly_sammet ba136e3fdb42 cloudrouter/bird-fedora:latest "/bin/bash" 38 minutes ago Up 38 minutes evil_torvalds #
Lets add an additional network interface (eth1) for each of our 3 docker containers. For this we will utilize the pipework script from https://github.com/jpetazzo/pipework
# sudo pipework docker0 -i eth1 02d05ac0aa07 10.0.0.1/24 # sudo pipework docker0 -i eth1 0896588f8664 10.0.0.8/24 # sudo pipework docker0 -i eth1 ba136e3fdb42 10.0.0.7/24
Lets configure bird.conf on each of our containers and start the bird daemon.
Container 1 bird.conf ( ID: ba136e3fdb42)
[root@ba136e3fdb42 etc]# cat /etc/bird.conf
/* Main configuration file for BIRD. This is ony a template,
* you will *need* to customize it according to your needs
* Beware that only double quotes '"' are valid. No singles. */
log "/var/log/bird.log" all;
debug protocols all;
#debug commands 2;
router id 10.0.0.1; # Mandatory for IPv6, may be automatic for IPv4
protocol kernel {
persist; # Don't remove routes on BIRD shutdown
scan time 200; # Scan kernel routing table every 200 seconds
export all;
import all;
}
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
/* This is a sample config that should be customized with appropriate AS numbers
* and peers; add one section like this for each neighbor */
protocol bgp toRouteServer {
local as 200; # Customize your AS number
neighbor 10.0.0.7 as 30351; # Customize neighbor AS number && IP
export all;
import all;
}
protocol direct {
interface "*";
}
Container 2 bird.conf ( ID: 02d05ac0aa07)
[root@02d05ac0aa07 log]# cat /etc/bird.conf
####
##BIRD Route Server Configuration
####
log "/var/log/bird.log" all;
debug protocols all;
#debug commands 2;
router id 10.0.0.7;
define myas = 30351;
# This function excludes weird networks
# rfc1918, class D, class E, too long and too short prefixes
function avoid_martians()
prefix set martians;
{
martians = [ 169.254.0.0/16+, 172.16.0.0/12+, 192.168.0.0/16+,
224.0.0.0/4+, 240.0.0.0/4+, 0.0.0.0/32-, 0.0.0.0/0{25,32}, 0.0.0.0/0{0,7} ];
# Avoid RFC1918 and similar networks
if net ~ martians then return false;
return true;
}
# BGP output filter (based on communities)
function bgp_out(int peeras)
{
# if ! (source = RTS_BGP ) then return false;
if peeras > 65535 then return true; # communities does not support AS32
if (0,peeras) ~ bgp_community then return false;
if (myas,peeras) ~ bgp_community then return true;
if (0, myas) ~ bgp_community then return false;
return true;
}
protocol kernel {
persist; # Don't remove routes on BIRD shutdown
scan time 200; # Scan kernel routing table every 200 seconds
export all;
import all;
}
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
###########################################
### START CustomerA BGP Config
###########################################
table T200;
filter bgp_in_AS200
{
if ! (avoid_martians()) then reject;
if (bgp_path.first != 200 ) then reject;
accept;
}
protocol pipe P200 {
description "CustomerA AS-200";
table master;
mode transparent;
peer table T200;
import filter bgp_in_AS200;
export where bgp_out(200);
}
protocol bgp toCustomerA {
local as myas;
neighbor 10.0.0.1 as 200;
export all;
import all;
route limit 1000;
table T200;
rs client;
}
###########################################
# END CustomerA BGP Config
###########################################
###########################################
### START CustomerB BGP Config
###########################################
table T300;
filter bgp_in_AS300
{
if ! (avoid_martians()) then reject;
if (bgp_path.first != 300 ) then reject;
accept;
}
protocol pipe P300 {
description "CustomerB AS-300";
table master;
mode transparent;
peer table T300;
import filter bgp_in_AS300;
export where bgp_out(300);
}
protocol bgp toCustomerB {
local as myas;
neighbor 10.0.0.8 as 300;
export all;
import all;
route limit 1000;
table T300;
rs client;
}
###########################################
# END CustomerA BGP Config
###########################################
[root@02d05ac0aa07 log]#
Container 3 bird.conf ( ID: 0896588f8664)
[root@0896588f8664 etc]# cat /etc/bird.conf
/* Main configuration file for BIRD. This is ony a template,
* you will *need* to customize it according to your needs
* Beware that only double quotes '"' are valid. No singles. */
log "/var/log/bird.log" all;
debug protocols all;
#debug commands 2;
router id 10.0.0.8; # Mandatory for IPv6, may be automatic for IPv4
protocol kernel {
persist; # Don't remove routes on BIRD shutdown
scan time 200; # Scan kernel routing table every 200 seconds
export all;
import all;
}
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
/* This is a sample config that should be customized with appropriate AS numbers
* and peers; add one section like this for each neighbor */
protocol bgp toRouteServer {
local as 300; # Customize your AS number
neighbor 10.0.0.7 as 30351; # Customize neighbor AS number && IP
export all;
import all;
}
protocol direct {
interface "*";
}
[root@0896588f8664 etc]#
Lets start the bird daemon and ensure the BGP Sessions are ESTABLISHED.
# bird -c /etc/bird.conf
[root@02d05ac0aa07 log]# birdc 'show protocols all toCustomerA'
BIRD 1.4.5 ready.
name proto table state since info
toCustomerA BGP T200 up 18:40:12 Established
Preference: 100
Input filter: ACCEPT
Output filter: ACCEPT
Import limit: 1000
Action: restart
Routes: 2 imported, 0 exported, 4 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 2 0 0 0 2
Import withdraws: 0 0 --- 0 0
Export updates: 3 2 0 --- 1
Export withdraws: 0 --- --- --- 1
BGP state: Established
Neighbor address: 10.0.0.1
Neighbor AS: 200
Neighbor ID: 10.0.0.1
Neighbor caps: refresh restart-aware AS4
Session: external route-server AS4
Source address: 10.0.0.7
Route limit: 2/1000
Hold timer: 140/240
Keepalive timer: 36/80
[root@02d05ac0aa07 log]# birdc 'show protocols all toCustomerB'
BIRD 1.4.5 ready.
name proto table state since info
toCustomerB BGP T300 up 18:33:54 Established
Preference: 100
Input filter: ACCEPT
Output filter: ACCEPT
Import limit: 1000
Action: restart
Routes: 2 imported, 1 exported, 1 preferred
Route change stats: received rejected filtered ignored accepted
Import updates: 2 0 0 0 2
Import withdraws: 0 0 --- 0 0
Export updates: 3 2 0 --- 1
Export withdraws: 0 --- --- --- 0
BGP state: Established
Neighbor address: 10.0.0.8
Neighbor AS: 300
Neighbor ID: 10.0.0.8
Neighbor caps: refresh restart-aware AS4
Session: external route-server AS4
Source address: 10.0.0.7
Route limit: 2/1000
Hold timer: 186/240
Keepalive timer: 25/80
[root@02d05ac0aa07 log]#
With this we have been able to demonstrate that we can run the bird daemon in a CloudRouter container and do some simple BGP sessions and make sure it does function as a Route Server.
#End of Article.