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.