Skip to content

Commit

Permalink
A skeletal configuration that uses static routing to connect 3 networks.
Browse files Browse the repository at this point in the history
Please read the README file for details of how to run the script.
  • Loading branch information
julianharty committed Dec 31, 2024
1 parent 9a9db59 commit ee1f1ef
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 2 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
39 changes: 39 additions & 0 deletions configs/birdrouter1-bird.conf
Original file line number Diff line number Diff line change
@@ -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";
}
40 changes: 40 additions & 0 deletions configs/birdrouter2-bird.conf
Original file line number Diff line number Diff line change
@@ -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";
}

28 changes: 26 additions & 2 deletions getting-started.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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()

0 comments on commit ee1f1ef

Please sign in to comment.