From ee1f1efc983e013aa2a5185939488c5447f2cf17 Mon Sep 17 00:00:00 2001 From: Julian Harty Date: Tue, 31 Dec 2024 22:10:42 +0000 Subject: [PATCH] A skeletal configuration that uses static routing to connect 3 networks. Please read the README file for details of how to run the script. --- README.md | 8 +++++++ configs/birdrouter1-bird.conf | 39 ++++++++++++++++++++++++++++++++++ configs/birdrouter2-bird.conf | 40 +++++++++++++++++++++++++++++++++++ getting-started.py | 28 ++++++++++++++++++++++-- 4 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 configs/birdrouter1-bird.conf create mode 100644 configs/birdrouter2-bird.conf diff --git a/README.md b/README.md index 4726a27..b1ace52 100644 --- a/README.md +++ b/README.md @@ -34,4 +34,12 @@ vim getting-started.py python getting-started.py ``` +Currently two instances of routers are configured with `bird` for routing using static routes over logical network `C` between the `pc` instances in logical network `A` and a `webserver` in logical network `B`. the bird configurations are configured as part of the `getting-started.py` script but `bird` needs starting manually using the CLI on each instance of the bird router machines: `birdrouter1` and `birdrouter2`. Run the command `systemctl start bird` to do so. +## Troubleshooting +If/when the python script crashes or fails to complete, various orphaned resources remain in kathara's microcosm locally. These can be removed using the following command: `kathara wipe` and then enter `y` when asked `[y/n]`. + +## Interactive testing +First start bird on both router instances. Then you can run `wget 100.1.3.90` from any running instance on the kathara network to request the default web page from the `webserver`. Running this command should download a copy of `index.html` from the `webserver` to the local folder on the machine you're currently connected to. + +There are lots of networking-related commands available to check routing, etc. Some examples will be added shortly. diff --git a/configs/birdrouter1-bird.conf b/configs/birdrouter1-bird.conf new file mode 100644 index 0000000..d88f615 --- /dev/null +++ b/configs/birdrouter1-bird.conf @@ -0,0 +1,39 @@ +# This is a skeletal configuration with static routes between 2 bird nodes. +# It's unlikely to be fully-correct or optimal. You're welcome to improve it. + +# Please refer to the documentation in the bird-doc package or BIRD User's +# Guide on http://bird.network.cz/ for more information on configuring BIRD and +# adding routing protocols. + +# Change this into your BIRD router ID. It's a world-wide unique identification +# of your router, usually one of router's IPv4 addresses. +router id 10.0.0.1; + +# The Kernel protocol is not a real routing protocol. Instead of communicating +# with other routers in the network, it performs synchronization of BIRD's +# routing tables with the OS kernel. +protocol kernel { + scan time 20; + import none; + export all; # Actually insert routes into the kernel routing table + persist; +} + +# The Device protocol is not a real routing protocol. It doesn't generate any +# routes and it only serves as a module for getting information about network +# interfaces from the kernel. +protocol device { + scan time 20; +} + +protocol rip { + export all; + import all; + interface "*"; +} + +protocol static { + route 100.1.2.0/24 via "eth0"; + route 100.1.3.0/24 via 10.0.0.2; + route 10.0.0.0/24 via "eth1"; +} diff --git a/configs/birdrouter2-bird.conf b/configs/birdrouter2-bird.conf new file mode 100644 index 0000000..4aa565f --- /dev/null +++ b/configs/birdrouter2-bird.conf @@ -0,0 +1,40 @@ +# This is a skeletal configuration with static routes between 2 bird nodes. +# It's unlikely to be fully-correct or optimal. You're welcome to improve it. + +# Please refer to the documentation in the bird-doc package or BIRD User's +# Guide on http://bird.network.cz/ for more information on configuring BIRD and +# adding routing protocols. + +# Change this into your BIRD router ID. It's a world-wide unique identification +# of your router, usually one of router's IPv4 addresses. +router id 10.0.0.2; + +# The Kernel protocol is not a real routing protocol. Instead of communicating +# with other routers in the network, it performs synchronization of BIRD's +# routing tables with the OS kernel. +protocol kernel { + scan time 20; + import none; + export all; # Actually insert routes into the kernel routing table + persist; +} + +# The Device protocol is not a real routing protocol. It doesn't generate any +# routes and it only serves as a module for getting information about network +# interfaces from the kernel. +protocol device { + scan time 20; +} + +protocol rip { + export all; + import all; + interface "*"; +} + +protocol static { + route 100.1.3.0/24 via "eth0"; + route 100.1.2.0/24 via 10.0.0.1; + route 10.0.0.0/24 via "eth1"; +} + diff --git a/getting-started.py b/getting-started.py index d1bf62c..9ffbd9c 100644 --- a/getting-started.py +++ b/getting-started.py @@ -2,6 +2,7 @@ # NB: AFAIK the wipe command removes any Kathara lab instance created by # this linux user's (i.e. your user) account. +import os import yaml from rich import print from Kathara.model.Lab import Lab @@ -15,12 +16,15 @@ # Create a router, here using the bird.cz docker image birdrouter1 = lab.new_machine("birdrouter1", **{"image": "kathara/bird"}) +birdrouter2 = lab.new_machine("birdrouter2", **{"image": "kathara/bird"}) lab.connect_machine_to_link(pc1.name, "A") lab.connect_machine_to_link(pc2.name, "A") lab.connect_machine_to_link(webserver.name, "B") lab.connect_machine_to_link(birdrouter1.name, "A") -lab.connect_machine_to_link(birdrouter1.name, "B") +lab.connect_machine_to_link(birdrouter1.name, "C") +lab.connect_machine_to_link(birdrouter2.name, "B") +lab.connect_machine_to_link(birdrouter2.name, "C") # NB: the following commands silently fail without the commas. # I think the last of the commands is processed as the web server does start apache2 @@ -53,24 +57,44 @@ lab.create_file_from_list( [ "ip address add 100.1.2.1/24 dev eth0", - "ip address add 100.1.3.1/24 dev eth1", + "ip address add 10.0.0.1/24 dev eth1", ], "birdrouter1.startup" ) +lab.create_file_from_list( + [ + "ip address add 100.1.3.1/24 dev eth0", + "ip address add 10.0.0.2/24 dev eth1", + ], + "birdrouter2.startup" +) + +birdrouter1.create_file_from_path(os.path.join("configs", "birdrouter1-bird.conf"), "/etc/bird/bird.conf") +birdrouter2.create_file_from_path(os.path.join("configs", "birdrouter2-bird.conf"), "/etc/bird/bird.conf") + Kathara.get_instance().deploy_lab(lab) lab_status = next(Kathara.get_instance().get_machines_stats(lab_name=lab.name)) print(lab_status) Kathara.get_instance().connect_tty(birdrouter1.name, lab_name=lab.name) +Kathara.get_instance().connect_tty(birdrouter2.name, lab_name=lab.name) Kathara.get_instance().connect_tty(webserver.name, lab_name=lab.name) Kathara.get_instance().connect_tty(pc1.name, lab_name=lab.name) Kathara.get_instance().connect_tty(birdrouter1.name, lab_name=lab.name) +Kathara.get_instance().connect_tty(birdrouter2.name, lab_name=lab.name) +Kathara.get_instance().connect_tty(webserver.name, lab_name=lab.name) +Kathara.get_instance().connect_tty(pc1.name, lab_name=lab.name) +Kathara.get_instance().connect_tty(webserver.name, lab_name=lab.name) +Kathara.get_instance().connect_tty(pc1.name, lab_name=lab.name) + print("Network A follows") print(Kathara.get_instance().get_link_stats(lab_name=lab.name, link_name="A")) print("Network B follows") print(Kathara.get_instance().get_link_stats(lab_name=lab.name, link_name="B")) +print("Network C follows") +print(Kathara.get_instance().get_link_stats(lab_name=lab.name, link_name="C")) # Currently there are 3 python errors reported, seemingly one for each connect_tty call. Kathara.get_instance().wipe()