Objectives
To define the function of a router
To configure a Linux host as a router
To configure the router firewall to support routing functions
To understand and create entries for a routing table
To install Fail2Ban, a tool that can dynamically modify the firewall to block various types of attacks
Introduction
At first glance, routing and firewalls might seem to have little to do with each other, but they are very closely entwined. Both are found at network boundaries and they work together to perform routing.
Routing is the task of ensuring that packets get routed to their specified destination. Every computer attached to a network requires some type of routing instructions for network TCP/IP packets when they leave the local host. This is usually very straightforward because most network environments are very simple and there are only two options for departing packets. All packets are sent either to a device on the local network or to some remote network via a router which may also be known as the default gateway. Multiple routers may be in use on a network, but only one router can be the default gateway.
Let’s be sure to define the “local” network as the logical and usually also the physical network in which the local host resides. Logically that means the local subnet in which the host is assigned is within the range of the local subnet’s IP addresses. Physically that means the host is connected to one or more switches that are also connected to the rest of the local network.
A firewall is responsible for protecting the firewall host and the internal network from network-based attacks of many kinds. Firewalls are also used to aid in router implementation by providing a mechanism to route packets from one network interface on the router host to another network interface.
In this chapter, we will look at routing on a workstation, StudentVM1, that is not used as a router. We will then convert our server, StudentVM2, into a router and change the DHCP configuration to use it as the router for the virtual network. Of course, the packets must still pass through the virtual router to get to the outside world. This is a common enough situation in many networks and we will explore that, too.
We are also going to cover installation and configuration of Fail2Ban, which is a tool for dynamically blocking IP addresses that are making attempts to crack into our systems. We did this on StudentVM1 in Volume 2, Chapter 17, but we also need to ensure that it is done on StudentVM2. It will also be a good review.
Every device on a network that will connect to another network, such as the Internet or other internal networks, needs to have its own routing table. By default, Fedora creates a routing table on every device on which it is installed.
If the network uses a static configuration, the IP address of the default gateway is defined during that configuration and is stored in the interface configuration file for the host. Fedora does not allow static configuration during the initial installation from the live image so it would need to be done later, as we did in the first book of this course. If DHCP is used to configure the host, no interface configuration file is required because the IP address of the default gateway is provided to the host at each boot.
When we created the StudentVM1 virtual machine in the first volume of this course, we eventually added an interface configuration file for the enp0s3 interface. Let’s go through that here again anyway.
NIC configuration files
By default, all current release images of Fedora default to DHCP configuration. No options are provided during installation to configure any aspect of the network interface. Starting with Fedora 29, Linux hosts using DHCP for network configuration no longer require interface configuration files if all of the DHCP default configurations are sufficient.
However, nonstandard configuration of the NICs for each network connection is still accomplished with ifcfg-X files in the /etc/sysconfig/network-scripts directory. Each NIC can have an interface configuration file named ifcfg-enp0s3, or something similar, where enp0s3 is the interface name assigned by the udev daemon. Each interface configuration file is bound to a specific physical NIC. Using the nmcli tool (network manager command-line interface) to configure an interface creates the interface configuration file for that interface.
The current strategy is to use the contents of the interface configuration files to generate the rules. However, if an interface configuration file does not exist, plugging in a new device or connecting with a new wireless network causes udev to notify NetworkManager of the new device or wireless connection. Then, in Fedora up through release 28, NetworkManager creates the new interface configuration file. As of Fedora 29 and higher, the Network Manager only creates the connection but does not create an interface configuration file.
The udev daemon creates an entry for each NIC installed in the system in the network rules file. The Network Manager uses these entries, along with information in the interface configuration files in the /etc/sysconfig/network-scripts/ directory to initialize each NIC.
Other distributions may keep their network configuration files in the /etc/NetworkManager/system-connections directory, with the name of the network as the file name. For example, my System76 laptop uses POP!_os which is based on Ubuntu. The /etc/NetworkManager/system-connections directory on that laptop contains files for the wired network as well as each of the wireless networks I have connected with. The structure of these files is different from the ifcfg files we will explore later in this chapter, but they are in ASCII plain text format and are readable and easily understandable.
The ip command
The ip command is designed to replace the ifconfig, arp, and some other network-related commands, so Red Hat has published a very nice IP command cheat sheet1 that I use frequently. The man page for the arp command contains the following note: “This program is obsolete. For replacement check ip neigh” and man page for the ifconfig command has a similar statement.
For now, those commands are still available and it may be years before they disappear completely.
Create an interface configuration File
Let’s do a quick experiment to see why creating an interface configuration file might be a good idea for a workstation even if it uses DHCP.
Experiment 6-1
Perform this experiment as the root user on the StudentVM1 host. When we need to turn the network interface up or down, we normally use the ifdown or the more recent ip commands to do that.
If the link is still up and active, that is the problem, so go ahead and perform Experiment 6-2. Skip the rest of this experiment.
After some experimentation of my own, I have learned that it is not possible to turn off an active link or to turn on an inactive one unless there is an interface configuration file for it. So let’s create one.
Experiment 6-2
This experiment must be performed as the root user on the StudentVM1 host.
Now bring interface enp0s3 back up again.
I find that remembering these commands is somewhat difficult because I don’t use them very often. Using tab completion will always give me a hint as to what the next possible entry might be.
The interface configuration file
Now let’s look at the contents of the ifcfg-enp0s3. Regardless of when you created the interface configuration file for enp0s3, it will be the same with the possible exception of the UUID.
Experiment 6-3
This is a typical interface configuration file as created by the nmcli command. It contains the bare minimum necessary for such a file. The primary purpose for creating this file is that it allows the SysAdmin to control the interface.


Some of the more common configuration items found in network interface configuration files
The lines in the interface configuration files are not sequence sensitive and work just fine in any order I have ever tried. By convention, the option names are in uppercase and the values are in lowercase. Option values can be enclosed in quotes, but that is not necessary unless the value is more than a single word or number.
For more information about configuration files, the file /usr/share/doc/initscripts/sysconfig.txt contains a list of all the files that can be found in the /etc/sysconfig directory and its subdirectories. This includes the network ifcfg-<interface> files. The descriptions of each file lists all of the possible configuration variables and their possible values along with terse explanations.
Routing on a workstation
Routing packets on a workstation is usually pretty straightforward. Packets go either to another device on the local network segment or they go to a device on another network. In the latter case, the network packets must be sent to a router in order to be sent to the correct network. In many cases, there is only a single router for a network segment because the local network is only connected to a single external network.
- 1.
If the destination host is on the local network, send the data directly to the destination host.
- 2.
If the destination host is on a remote network that is reachable via a local gateway listed in the routing table, send it to the explicitly defined gateway.
- 3.
If the destination host is on a remote network, and there is no other entry that defines a route to that host, send the data to the default gateway.
These rules mean that if all else fails because there is no match, send the packet to the default gateway.
So let’s look at the simple scenario of our StudentVM1 host.
Experiment 6-4
The default route set on StudentVM1 is that of the virtual router in our virtual network at the IP address of 10.0.2.1. If you recall, that is the configuration we set in the dhcpd.conf file of the DHCP server on StudentVM2.
This is a trivial and common routing configuration with only a single default gateway. It means that any packet that has a destination other than the local network, 10.0.2.0/24, will be sent to the default router from where it will be routed onward, perhaps through several more routers, to its final destination.
Network routing
The last sentence in Experiment 6-4 has some important implications. Routing to the default gateway is not usually the last router that the packets will traverse. We can trace the routes packets might take to arrive at a specific destination.
Experiment 6-5
This experiment can be performed as the student user on the StudentVM1 host. In this experiment, we will discover the list all of the routers through which packets travel to a destination and some interesting metrics pertaining to that.
This is a dynamic display and it keeps checking the route until you press q to quit. Because of this, mtr can display statistics for each hop along the way to the destination including response times and packet loss at each intermediate router along the way.
Another thing you might see for any given hop number (the sequential numbers down the left side of the display) is multiple routers indicating that the path to the remote host is not always through the same sequence of routers.
Note the packet loss at hop 8. Although this could indicate a problem, it is more likely that the router is discarding unimportant packets such as ICMP if the router is heavily loaded. If you try this at another time, the packet loss will probably be zero.
If you are actually having problems connecting with a site and mtr indicates a high packet loss, that could be the source of the problem. The only thing to be done is to report this to your ISP.
Creating a router
Let’s make a router out of the StudentVM2 host. We have previously configured our internal network to match the default defined by the virtual network router as generated by VirtualBox. Both of our hosts use the virtual router as the default gateway.
What we want to do now is to create an internal network that uses StudentVM2 as the default gateway while it, in turn, uses the virtual router as its default gateway. To do this, we need to set up a new network segment for the internal network using a different IP address range. We can select this arbitrarily, and since the current network defined by the virtual router is 10.0.2.0/24, we will create a Host-only network for this internal network and VirtualBox automatically selects the IP address range of 192.168.56.0/24. We could change this but there is really no need to do so. The use of the 192.168 address range also is different enough from the 10.0 address range to ensure that we are less likely to be confused about which network we are working with.

The new network configuration
This means we need to “install” a second virtual network interface for StudentVM2. It also means reconfiguring both DHCP and name services on the servers already present on StudentVM2 to reflect the new network. This will take a good bit of work and it is possible to make mistakes. To make recovery easier, we will also make snapshots of both virtual machines.
Preparation
We need to do a bit of preparation before we can set up our new network. We will define a new host-only network and add the new NIC to StudentVM1. We do not need to make any changes directly to the internal configuration for StudentVM1 as it gets its network configuration from the DHCP server, but we will need to connect it to the new network using VirtualBox Manager.
Experiment 6-6
Power off both StudentVM1 and StudentVM2. We will create a new network, make one change to StudentVM1, and add a new NIC to StudentVM2.
The VirtualBox documentation contains a description of the different networking types it supports.2 We are going to create a Host-only network that will allow us to connect the second NIC on StudentVM2 and the only NIC on StudentVM1 to it.
Create a new snapshot of both virtual machines. Add a comment to clearly identify these snapshots. I used something like, “Starting Chapter 7 before network reconfiguration.” Now if we make a mess, we can easily recover by rebooting to these snapshots.
Open the VirtualBox Manager and use the menu bar to select File ➤ Host Network Manager. Click the Create icon to create a new network. Do not enable the DHCP server because StudentVM2 will perform that function for this network. Click Close to finish creating this virtual network. This network is named vboxnet0.
Open the VirtualBox settings for StudentVM1. Open the Network Settings page. For Adapter 1, find the Attached to: selection box and choose Host-only Adapter. The name of the vboxnet0 network will appear in the Name field because it is the only host-only network available. Click the OK button to complete this change.
Open the VirtualBox settings for StudentVM2. Open the Network Settings page. For Adapter 2, place a check in the Enable Network Adapter box, and then, in the Attached to: selection box, choose Host-only Adapter. Click the OK button to complete this change.
Check the /etc/hosts file for both StudentVM1 and StudentVM2 and make sure that only the first two lines are active. Delete and comment out all lines except the ones for localhost. We have already turned off the DHCP server on the virtual router so we do not need to do that at this time. We will leave StudentVM1 powered off until we have configured DHCP and DNS for the new network.
Configure the new NIC
Now that we have made the network changes in VirtualBox, we can start StudentVM2, perform some initial testing, and configure the new network interface card.
Experiment 6-7
Launch the StudentVM1 virtual machine and log in to the desktop. Perform the rest of this experiment as the root user.
We need to first verify that network adapter 1 still has connectivity to the virtual router on 10.0.2.1. Ping the router. If that is not successful, resolve any problems and try again. If it is successful, ping an external host such as www.example.org.
You may notice the network icon in the system tray will continue trying to connect to the network. It is attempting to obtain a configuration from DHCP for adapter 2. This will continue until we generate a static configuration.
At this point, our initial changes to StudentVM1 have all been made and tested. Both NICs are configured and connected to the network although we cannot yet do a good test of enp0s8.
Reconfiguring DHCP
The DHCP server needs to be reconfigured to provide IP addresses, gateway information, and name service data using the new IP address for StudentVM2 on the new internal network.
Experiment 6-8
Perform this experiment as the root user on StudentVM2. In it we will reconfigure the IP addresses that the DHCP server offers to the clients on the new 192.168.56.0/26 network.
Now use Vim, or another editor if you have installed one, to edit /etc/dhcp/dhcpd.conf.
We need to use the IP address of the new NIC, and we have kept the virtual router as our secondary server. These are the name server IP addresses that other hosts within our network will be served by the DHCP server.
We also needed to change the IP addresses in the subnet declaration to reflect those of the newly created subnet on 192.168.56.0/24 and the IP address we have explicitly defined for StudentVM2.
After correcting any and all errors start the DHCP server again.
Now we can test StudentVM1 to verify that our network connection and DHCP are both working.
Experiment 6-9
Start the StudentVM1 virtual machine. Login to the desktop. You should notice right away that the network monitor in the system tray shows that the network is connected.
Perform the rest of this experiment as the student user on StudentVM1. Verify that the IP address for enp0s8 on StudentVM1 is 192.168.56.21. Then ping the server, StudentVM2, but we need to use the IP address of 192.168.56.1 instead of the hostname because we don’t have name services up and running for the new network yet.
At this point, we have tested as much as we can. The new network is working as expected and both student hosts have access to it.
Reconfiguring DNS
The last thing we need to do to reconfigure our network is to reconfigure the addresses in the DNS server.
Experiment 6-10
- 1.
In the /etc/named.conf file, change all instances of “10.0.2” to “192.168.56”.
- 2.
Change the “Listen on” line to the IP address of NIC 2 on StudentVM2, 192.168.56.1.
- 3.
Comment out the recursion line because we want this to be the authoritative name server for our domain.
- 4.
Change the first line of the reverse zone stanza to “zone 56.168.192.in-addr.arpa” IN {“ to reflect the new reverse zone IP address.
Save the file and exit from Vim. This file should look like the following when the changes are complete. The modified portions have been highlighted in bold.//// named.conf//// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS// server as a caching only nameserver (as a localhost DNS resolver only).//// See /usr/share/doc/bind∗/sample/ for example named configuration files.//options {listen-on port 53 { 127.0.0.1; 192.168.56.1; };// listen-on-v6 port 53 { ::1; };// forwarders { 192.168.56.1; 8.8.8.8; }; // Forwarders not useddirectory "/var/named";dump-file "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";secroots-file "/var/named/data/named.secroots";recursing-file "/var/named/data/named.recursing";allow-query { localhost; 192.168.56.0/24; };/∗- If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.- If you are building a RECURSIVE (caching) DNS server, you need to enable recursion.- If your recursive DNS server has a public IP address, you MUST enable access control to limit queries to your legitimate users. Failing to do so will cause your server to become part of large scale DNS amplification attacks. Implementing BCP38 within your network would greatly reduce such attack surface∗/// recursion yes;dnssec-enable yes;dnssec-validation yes;managed-keys-directory "/var/named/dynamic";pid-file "/run/named/named.pid";session-keyfile "/run/named/session.key";/∗ https://fedoraproject.org/wiki/Changes/CryptoPolicy ∗/include "/etc/crypto-policies/back-ends/bind.config";};logging {channel default_debug {file "data/named.run";severity dynamic;};};zone "." IN {type hint;file "named.ca";};zone "example.com" IN {type master;file "example.com.zone";};zone "56.168.192.in-addr.arpa" IN {type master;file "example.com.rev";};include "/etc/named.rfc1912.zones";include "/etc/named.root.key";
Save the file. I like to leave the files open in Vim so I can make changes if necessary.
- 1.
Change the serial number to the current date and add a 2-digit sequence number at the end. It should have the format YYYYMMDDSS where SS is the sequence number, not seconds.
- 2.
Change all instances of “10.0.2” to “192.168.56”.
- 3.
Change the IP address for StudentVM2 to 192.168.56.1.
The file will look like this when the changes are completed.; Authoritative data for example.com zone;TTL 1D@ IN SOA studentvm2.example.com root.studentvm2.example.com.(2019162201 ; serial1D ; refresh1H ; retry1W ; expire3H ) ; minimum$ORIGIN example.com.example.com. IN NS studentvm2.example.com.router IN A 192.168.56.1studentvm2 IN A 192.168.56.1server IN CNAME studentvm2studentvm1 IN A 192.168.56.21workstation1 IN CNAME studentvm1ws1 IN CNAME studentvm1wkst1 IN CNAME ws1studentvm3 IN A 192.168.56.22studentvm4 IN A 192.168.56.23testvm1 IN A 192.168.56.50
A lack of error messages is a good sign. If you encounter any errors, fix them and continue until there are no further errors and named is running.
Setting up the router
Finally, we are ready to configure the StudentVM2 host as a router. There are two things that we need to do to accomplish that and they are both easy. We need to tell the Linux kernel that it can act as a router, and we need to reconfigure the firewall so that it can route packets between the appropriate network interfaces.
Kernel configuration
Configuring the kernel to support routing is trivial. Really! We do not need to recompile the kernel and we do not even need to reboot. We only need to turn on packet forwarding which allows packets to be accepted on one network interface and sent back out on another. Keeping packet forwarding turned off when it is not required is a smart security precaution.
Experiment 6-11
Perform this experiment as the root user on StudentVM2. We will turn on packet forwarding and set that up so that it is permanent.
First, let’s set packet forwarding on in the /proc filesystem. We could do this with the sysctl command, but that would not really show you how simple and easy it really is.
We have set ip forwarding on, but it is not permanent. The value of this file will return to 0 at the next reboot. To make this change permanent, we need to add a new file to the /etc/sysctl.d/ directory.
This file will now be read at each boot.
Notice that the file name contains a partial path indicating the location of the file referred to by this statement. The base path is proc/sys/ and the separators are dots (.) instead of slashes (/).
Save the new file. The default permissions are fine.
We explored the /proc filesystem in some detail in Chapter 5 of Volume 2.
Changing the firewall
The final step in creating a router on StudentVM2 is adding some new rules to the firewall. This includes creating a new table, the NAT table.
Experiment 6-12
Perform this experiment as root on StudentVM2. Edit the /etc/sysconfig/iptables file and add the lines highlighted in bold.
Our firewall just got more complex, but it is still simpler than had we used firewalld instead of IPTables.
Understanding the rule set
Filter: The filter table is the one chain defined in the tiny default rule set. It is used to filter packets and to discard them or accept them. This chain is the one most commonly used in very simple firewalls.
NAT: The NAT table is used for Network Address Translation. Internal private addresses like the 10.0.0.0/8 addresses used by our virtual router or the 192.168.0.0/16 range are not routable through the Internet. So outbound request packets to, for example, a web site must have the return IP address of the router at the edge of the internal network and the Internet. NAT substitutes the routable IP address in place of the nonroutable one for outbound packets and the nonroutable IP in place of the routable one for the return packets.
Mangle: The mangle table is used to change – mangle – various portions of a packet. One example is to redefine the source IP address of the packet. Although such mangling does have legitimate uses, it can also be used by crackers to spoof the source address of packets as part of distributed denial of service (DDOS) attacks.
Raw: This table would be used to configure exemptions to packet tracking rules.
Security: This table would be used to implement Mandatory Access Control rules. It is generally used in conjunction with SELinux to enhance security.


A description of the rules in the IPTables firewall
So now we have a complete working router. Now we need to test it.
Experiment 6-13
Perform this experiment as the student user on StudentVM1.
We have now determined that our local name server is working and providing internal and external name resolution. We also see that the routing functions of StudentVM2 are working correctly.
Try using the Firefox web browser on StudentVM1 to access www.example.org.
Verify that the SSH connection from StudentVM1 to StudentVM2 is working.
Complex routing
It is possible to add more complexity to our router. We won’t actually do that, but this section will explore what that looks like.

A more complex routing table from my own network router
Note that there is still only one default gateway, and that is on interface enp2s0.
Of course, it is also necessary to have appropriate rules in the firewall to allow routing.
Fail2Ban
A dynamic firewall is one that can adapt as the threats change. I needed something like this to stem the large number of attacks via SSH I had been experiencing a few years ago. After a good bit of exploring and research, I found fail2ban, an open source software which automates what I was previously doing manually.
Fail2Ban has a complex series of configurable matching rules and separate actions that can be taken when attempts are made to crack into a system. It has rules for many types of attacks that include web, email, and many other services that might have vulnerabilities. Fail2Ban works by detecting attacks and then adding a rule to the firewall that will block further attempts from that specific, single IP address for a specified and configurable amount of time. After the time has expired, it removes the blocking rule.
Let’s install Fail2Ban and see how it works.
Experiment 6-14
Fail2Ban is not started by the installation, so we will need to do so after we do a bit of configuration. Make /etc/fail2ban the PWD and list the files there. The jail.conf file is the main configuration file but it is not used for most configuration because it might get overwritten during an update. We will create a jail.local file in the same directory. Any settings defined in jail.local will override ones set in jail.conf.
Copy jail.conf to jail.local. Edit the jail.local file and delete the comment near the beginning that tells you not to modify this file. It is, after all, the one we will be modifying.
Scroll down to the line bantime = 10m and change that to 5 minutes. Since we have no other hosts to test from, we will test using StudentVM1. We do not want it banned for long so that we can resume experiments quickly, but this also gives us enough time to look at the IPTables rule set before the address is automatically unbanned. In the real world, I would set this to several hours so that the crackers cannot get more attempts for a long time.
Change maxretry = 5 to 2. This is the maximum number of retries allowed after any type of failed attempt. Two retries is a good number for experimental purposes. I normally set this to three because anyone failing three tries to get into my system using SSH does not belong there.
We could also change both of these configuration options in the [sshd] filter section which would limit them to sshd while the original settings would apply to all other filters.
Read the comments for the other miscellaneous options in this section of the file, and then scroll down to the [sshd] section in JAILS.
This means that the sshd jail is working. Look at the active firewall rules. Remember that these fail2ban rules are stored in memory and are not added to the /etc/sysconfig/iptables file.
On StudentVM2 list, the IPTables rule set. There is a line in the output below that rejects connections from 192.168.56.21 which is the IP address of StudentVM1. The IPTables rejection lines are removed after one minute, so if you don’t see that line, force the failed logins again.
Now let’s look at a couple log files on StudentVM2. In /var/log, first look at /var/log/secure. You should see a number of entries indicating failed passwords. These are the log entries checked by Fail2Ban for failures.
Look at the /var/log/fail2ban.log file. This log file shows the times that triggering entries were found in the secure log and the ban and unban actions taken to protect the system.
Be aware that the f2b-sshd chain entries do not appear in the IPTables rule set until the first time a ban is triggered. Once there, the first and last lines of the chain are not deleted, but the lines rejecting specific IP addresses are removed as they time out. It took me a bit of work to figure out this bit.
The installation of Fail2Ban installs the configuration files needed for logwatch to report on Fail2Ban activity. It is possible to create your own filters and actions for Fail2Ban but that is beyond the scope of this course.
Chapter summary
In this chapter, we converted the StudentVM2 host into a router, adding a new virtual network adapter to it, and reconfigured the internal network to a new IP address range. We modified the DHCP and DNS servers to accommodate that change.
We configured the kernel to perform IP forwarding which is the functional basis for routing. We added the NAT table and a FORWARD chain to our IPTables firewall to complete the transformation. And – of course – we tested the results.
Exercises
- 1.
Why is a router required when connecting two networks?
- 2.
What is the function of the default router?
- 3.
Can there be more than one router on a network segment?
- 4.
Can there be more than one default router on a network segment?
- 5.
Why did we use the domain example.org instead of example.com in Experiment 6-5?
- 6.
Before StudentVM2 is made into a router, why do DNS queries from StudentVM2 regarding external hosts, such as example.org and cnn.com, return the correct responses?
- 7.
List the routers between your StudentVM1 host and www.apress.com. Are any of the routers dropping packets?