Setup Ethernet Port Switch and Routing

Setup Ethernet Port Switch and Routing

On the previous page, the pis were connected via their built-in wifi to the router. For a more stable connection, we want a wired connection between them. To that end, we include an unmanaged ethernet port switch, which we connect here.

Since the switch is unmanaged, it will not do any routing. We will have to configure the routing ourselves, by creating a dhcp server on one of the pis and either by using static IP addresses or by configuring dynamic routing.

DHCP Server Setup

We will do the following on the head node, where we will be setting up the dhcp server.

Before plugging anything in, first check the status of the current network configuration: ip addr show. The entry for wlan0 should have a number of lines, whereas the entry eth0 (which probably appears before wlan0) should pretty much just have a line with a MAC address.

After plugging in (and turning on) the port switch, a new entry should appear in the eth0 section. However, it does not have an IPv4 address, only an IPv6 address.

Next, install the dhcpd server saemon: sudo apt-get install kea (see this page for why we choose kea over isc-dhcp-server). With this package, we can set up routing, as well as statically assign IP addresses from the routing head node (we could also set up each pi to request a static IP address in their /etc/dhcp/dhclient.conf file, but here we will use this method as it will allow us to configure everything all in one place).

Start by opening the file /etc/kea/kea-dhcp4.conf for editing: sudo nano /etc/kea/kea-dhcp4.conf. A sample configuration file follows:

{

"Dhcp4": {
    // Add names of your network interfaces to listen on.
    "interfaces-config": {
        "interfaces": [ "eth0" ]
    },

    "control-socket": {
        "socket-type": "unix",
        "socket-name": "/run/kea/kea4-ctrl-socket"
    },

    "lease-database": {
        // Memfile is the simplest and easiest backend to use. It's an in-memory
        // C++ database that stores its state in CSV file.
        "type": "memfile",
        "persist": true,
        "lfc-interval": 3600
    },

    // Kea allows storing host reservations in a database. If your network is
    // small or you have few reservations, it's probably easier to keep them
    // in the configuration file. If your network is large, it's usually better
    // to use database for it. To enable it, uncomment the following:
    // "hosts-database": {
    //     "type": "mysql",
    //     "name": "kea",
    //     "user": "kea",
    //     "password": "kea",
    //     "host": "localhost",
    //     "port": 3306
    // },
    // See Section 7.2.3 "Hosts storage" for details.

    // Setup reclamation of the expired leases and leases affinity.
    // Expired leases will be reclaimed every 10 seconds. Every 25
    // seconds reclaimed leases, which have expired more than 3600
    // seconds ago, will be removed. The limits for leases reclamation
    // are 100 leases or 250 ms for a single cycle. A warning message
    // will be logged if there are still expired leases in the
    // database after 5 consecutive reclamation cycles.
    "expired-leases-processing": {
        "reclaim-timer-wait-time": 10,
        "flush-reclaimed-timer-wait-time": 25,
        "hold-reclaimed-time": 3600,
        "max-reclaim-leases": 100,
        "max-reclaim-time": 250,
        "unwarned-reclaim-cycles": 5
    },

    // Global timers specified here apply to all subnets, unless there are
    // subnet specific values defined in particular subnets.
    "renew-timer": 900,
    "rebind-timer": 1800,
    "valid-lifetime": 3600,

    //"option-data": [
    //    {
    //        "name": "domain-name",
    //        "data": "example.local"
    //    },
    //    {
    //        "name": "domain-search",
    //        "data": "*.example.local, example.local"
    //    }
    //],

    "subnet4": [
        {
            // This defines the whole subnet. Kea will use this information to
            // determine where the clients are connected. This is the whole
            // subnet in your network. This is mandatory parameter for each
            // subnet.
            "subnet": "10.1.2.0/24",
            "id": 1,

            // Pools define the actual part of your subnet that is governed
            // by Kea. Technically this is optional parameter, but it's
            // almost always needed for DHCP to do its job. If you omit it,
            // clients won't be able to get addresses, unless there are
            // host reservations defined for them.
            "pools": [ { "pool": "10.1.2.5 - 10.1.2.200" } ],

            // These are options that are subnet specific. In most cases,
            // you need to define at least routers option, as without this
            // option your clients will not be able to reach their default
            // gateway and will not have Internet connectivity.
            //"option-data": [
                //{
                    // For each IPv4 subnet you most likely need to specify at
                    // least one router.
                    //"name": "routers",
                    //"data": "10.0.0.1"
                //}
            //],

            "reservations": [
                {
                    "hw-address": "00:00:00:00:00:01",
                    "ip-address": "10.1.2.1",
                    "hostname": "node00"
                },
                {
                    "hw-address": "00:00:00:00:00:02",
                    "ip-address": "10.1.2.2",
                    "hostname": "node01"
                },
                {
                    "hw-address": "00:00:00:00:00:03",
                    "ip-address": "10.1.2.3",
                    "hostname": "node02"
                },
                {
                    "hw-address": "00:00:00:00:00:04",
                    "ip-address": "10.1.2.4",
                    "hostname": "node03"
                }
            ]
            // You can add more subnets here.
        }
    ],

    // Logging configuration starts here. Kea uses different loggers to log various
    // activities. For details (e.g. names of loggers), see Chapter 18.
    "loggers": [
    {
        // This section affects kea-dhcp4, which is the base logger for DHCPv4
        // component. It tells DHCPv4 server to write all log messages (on
        // severity INFO or more) to a file.
        "name": "kea-dhcp4",
        "output_options": [
            {
                // Specifies the output file. There are several special values
                // supported:
                // - stdout (prints on standard output)
                // - stderr (prints on standard error)
                // - syslog (logs to syslog)
                // - syslog:name (logs to syslog using specified name)
                // Any other value is considered a name of the file
                "output": "stdout",

                // Shorter log pattern suitable for use with systemd,
                // avoids redundant information
                "pattern": "%-5p %m\n",

                // This governs whether the log output is flushed to disk after
                // every write.
                // "flush": false,

                // This specifies the maximum size of the file before it is
                // rotated.
                // "maxsize": 1048576,

                // This specifies the maximum number of rotated files to keep.
                // "maxver": 8
            }
        ],
        // This specifies the severity of log messages to keep. Supported values
        // are: FATAL, ERROR, WARN, INFO, DEBUG
        "severity": "INFO",

        // If DEBUG level is specified, this value is used. 0 is least verbose,
        // 99 is most verbose. Be cautious, Kea can generate lots and lots
        // of logs if told to do so.
        "debuglevel": 0
    }
  ]
}
}

Next, the kea-ctrl-agent service, which controls the server, must be configured and started. The default configuration file /etc/kea/kea-ctrl-agent.conf is likely sufficient and can be left alone, but the kea-ctrl-agent service does require a password or else it won’t start. The password should be put in /etc/kea/kea-api-password, with ownership root:_kea and permissions 0640. So first enter a password into the file with sudo nano /etc/kea/kea-api-password, then do sudo chown root:_kea /etc/kea/kea-api-password and sudo chmod 640 /etc/kea/kea-api-password.

Now the DHCP server is ready to be started. First, enable and start the service:

sudo systemctl enable kea-ctrl-agent
sudo systemctl start kea-ctrl-agent

Check that is is running successfully with sudo systemctl status kea-ctrl-agent.

If the configuration files need to be subsequently changed, the service can reload the configuration while running by using the command sudo kea-shell --host 127.0.0.1 --port 8000 --auth-user kea-api --auth-password $(sudo cat /etc/kea/kea-api-password) --service dhcp4 config-reload and then pressing the ctrl-d keyboard combination. If the response is [ { "result": 0, "text": "Configuration successful." } ], then the configuration was successfully reloaded. Or just restart the server: sudo systemctl restart kea-dhcp4-server.

The leases can be viewed in the file /var/lib/kea/kea-leases4.csv.

It may (or may not) be necessary to manually add an IP address for this pi. To do so, sudo ip addr add 10.0.0.1/24 dev eth0 will manually add an IP address.

Connect Other Nodes

Now, just plug in the other pis to the port switch, and the server should automatically assign them the correct IP addresses.

Finally, add/modify the entries in each pis ~/.ssh/config file to refer to the ethernet IP address of each pi (the ones fixed in the /etc/kea/kea-dhcp4.conf file), instead of their WiFi IP address. (If these steps have been followed out of order, also modify the entry on the head node’s /etc/exports, the entry in each pi’s fstab file to load the shared drive from the ethernet IP address, and the entry in each pi’s /scripts/mount-shared.sh to look for it on the ethernet IP address as well.)

“option-data”: [ { “name”: “domain-name”, “data”: “bramble.local” }, { “name”: “domain-search”, “data”: “*.bramble.local, bramble.local” } ]