Category Archives: Network Engineering

Configure a Linux Network Gateway / Firewall with DHCP & DNS

System Configuration


Configure hostname

echo gateway.lab.local > /etc/hostname
hostname $(cat /etc/hostname)

Add the following to /etc/sysctl.conf

# Disable IPv6 networking (if not required)
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
# Accept packets destined for other addresses
net.ipv4.ip_forward = 1

Apply settings defined in /etc/sysctl.conf

systemctl restart systemd-sysctl

Networking


[root@gateway ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 08:00:27:43:e6:71 brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000
    link/ether 08:00:27:a6:b8:f9 brd ff:ff:ff:ff:ff:ff

Determine the WAN and LAN ports by physically removing a network connection and view “dmesg”

[64476.759373] e1000: enp0s8 NIC Link is Down

This is the physical port connected on the LAN side, and so this will be the LAN port

Configure the relevant interface files for the WAN and LAN ports

sed -i '/^ONBOOT/s/=.*$/=yes/' /etc/sysconfig/network-scripts/ifcfg-enp0s3
sed -i '/^ONBOOT/s/=.*$/=yes/' /etc/sysconfig/network-scripts/ifcfg-enp0s8
sed -i '/^BOOTPROTO/s/=.*$/=none/' /etc/sysconfig/network-scripts/ifcfg-enp0s8
echo "IPADDR=172.24.10.1" >> /etc/sysconfig/network-scripts/ifcfg-enp0s8
echo "NETMASK=255.255.255.0" >> /etc/sysconfig/network-scripts/ifcfg-enp0s8
systemctl restart network
  •  ONBOOT=yes   Set network interface to be brought up on system boot
  •  BOOTPROTO=none  No protocol is used as static network details are supplied
  •  IPADDR=172.24.10.1   IP address for the interface that will be used as the gateway for the local network
  •  NETMASK=255.255.255.0   Netmask of the local network

Check that the new settings have been applied

[root@gateway ~]# ip addr
[...]
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:8d:83:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.12/24 brd 192.168.1.255 scope global dynamic enp0s3
       valid_lft 691072sec preferred_lft 691072sec
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:74:ee:ac brd ff:ff:ff:ff:ff:ff
    inet 172.24.10.1/24 brd 172.24.10.255 scope global enp0s8
       valid_lft forever preferred_lft forever

[root@testclient1 ~]# ip route
default via 192.168.1.1 dev enp0s3 proto static metric 100
172.24.10.0/24 dev enp0s8 proto kernel scope link src 172.24.10.1 metric 100
192.168.1.0/24 dev enp0s3 proto kernel scope link src 192.168.1.12 metric 100

Firewall


Re-enable the traditional iptables firewall and clear the default rules

systemctl disable firewalld && systemctl stop firewalld
yum install iptables-services
> /etc/sysconfig/iptables
systemctl enable iptables && systemctl start iptables

Define and save new rules

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i enp0s3 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -i enp0s3 -p tcp --dport 22 -j ACCEPT
iptables -P INPUT DROP
iptables -A FORWARD -i enp0s3 --dst 172.24.10.0/24 -j ACCEPT
iptables -A FORWARD -i enp0s8 --src 172.24.10.0/24 -j ACCEPT
iptables -P FORWARD DROP
iptables -t nat -A POSTROUTING --src 172.24.10.0/24 -j MASQUERADE
service iptables save
  • iptables -A FORWARD -i enp0s3 –dst 172.24.10.0/24 -j ACCEPT   Allow packets from WAN destined to LAN
  • iptables -A FORWARD -i enp0s8 –src 172.24.10.0/24 -j ACCEPT   Allow packets from LAN
  • iptables -t nat -A POSTROUTING –src 172.24.10.0/24 -j MASQUERADE   MASQUERADE packets originating from LAN. If WAN packets are masqueraded, the host connections will appear as “gateway”

Software Installation

BIND DNS

yum install bind bind-utils
sed -i '/listen-on/s/127.0.0.1;/& 172.24.10.1;/' /etc/named.conf
sed -i '/allow-query/s/localhost/any/' /etc/named.conf
systemctl enable named && systemctl start named
iptables -A INPUT -i enp0s8 -p udp --dport 53 -j ACCEPT
  • listen-on   Specify interface addresses to listen on
  • allow-query   Set to “any” to allow queries on all listening interfaces
  • iptables -A INPUT -i enp0s8 -p udp –dport 53 -j ACCEPT   Allow DNS queries on LAN port

DHCPD

yum install dhcp

Configure /etc/dhcp/dhcpd.conf:

authoritative; # This DHCP server is the official DHCP server for the LAN.

default-lease-time 600;
max-lease-time 7200;

subnet 172.24.10.0 netmask 255.255.255.0 {
    range 172.24.10.100 172.24.10.200;
    option domain-name-servers 172.24.10.1;
    option domain-name "lab.local";
    option routers 172.24.10.1;
    option broadcast-address 172.24.10.255;
}

Note:  DHCPD matches defined subnets to the IP address assigned to an interface and will not serve any that do not match. Subnet 172.24.10.0/24 will be served on enp0s8.

Enable the system service:

systemctl enable dhcpd && systemctl start dhcpd

Testing


Connect several clients to the LAN and activate network interfaces on boot. DHCP is enabled by default

sed -i '/^ONBOOT/s/=.*$/=yes/' /etc/sysconfig/network-scripts/ifcfg-enp0s3
systemctl restart network

Check that DHCP is functioning correctly

                   +---------------+    ------ Discover ---->    +---------------+
                   |      DHCP     |    <----- Offer --------    |      DHCP     |
                   |     Client    |    ------ Request ----->    |     Server    |
                   +---------------+    <----- Acknowledge --    +---------------+

DHCP Client Server Interaction Steps


[root@gateway ~]# systemctl status dhcpd
● dhcpd.service - DHCPv4 Server Daemon
Loaded: loaded (/usr/lib/systemd/system/dhcpd.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2018-06-20 10:16:10 BST; 8min ago
Docs: man:dhcpd(8)
man:dhcpd.conf(5)
Main PID: 2051 (dhcpd)
Status: "Dispatching packets..."
CGroup: /system.slice/dhcpd.service
└─2051 /usr/sbin/dhcpd -f -cf /etc/dhcp/dhcpd.conf -user dhcpd -group dhcpd --no-pid

Jun 20 10:23:05 gateway.lab.local dhcpd[2051]: DHCPDISCOVER from 08:00:27:b7:f0:59 via enp0s8
Jun 20 10:23:06 gateway.lab.local dhcpd[2051]: DHCPOFFER on 172.24.10.101 to 08:00:27:b7:f0:59 via enp0s8
Jun 20 10:23:06 gateway.lab.local dhcpd[2051]: DHCPREQUEST for 172.24.10.101 (172.24.10.1) from 08:00:27:b7:f0:59 via enp0s8
Jun 20 10:23:06 gateway.lab.local dhcpd[2051]: DHCPACK on 172.24.10.101 to 08:00:27:b7:f0:59 via enp0s8

[root@testclient1 ~]# ip addr show enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:dc:b5:90 brd ff:ff:ff:ff:ff:ff
    inet 172.24.10.100/24 brd 172.24.10.255 scope global dynamic enp0s3
       valid_lft 483sec preferred_lft 483se

[root@testclient2 ~]# ip addr show enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:7e:75:7f brd ff:ff:ff:ff:ff:ff
    inet 172.24.10.101/24 brd 172.24.10.255 scope global dynamic enp0s3
       valid_lft 441sec preferred_lft 441sec

Forward SSH to access test clients

iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 220 -j DNAT --to 172.24.10.100:22
iptables -t nat -A PREROUTING -i enp0s3 -p tcp --dport 221 -j DNAT --to 172.24.10.101:22
                                        Gateway
                                           __
                              Modem       |==|         LAN Switch
                               ____       |  |       _______________
             Internet  <------[_..°]------|__|------[_:::::::::::::_]
                                   (enp0s3)  (enp0s8)      | |
                                                       __  | |  __
                                                 ____ |==| | | |==| ____   
                                   testclient1  |    ||  |_| |_|  ||    |  testclient2
                                 172.24.10.100  |____||__|     |__||____|  172.24.10.101
                                                /::::/             /::::/

Test Client 1

$ ssh 192.168.1.12 -p 220
root@192.168.1.12's password:
Last login: Wed Jun 20 10:46:57 2018 from 192.168.1.19

[root@testclient1 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search lab.local
nameserver 172.24.10.1

[root@testclient1 ~]# ip addr show enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:1f:2d:84 brd ff:ff:ff:ff:ff:ff
    inet 172.24.10.100/24 brd 172.24.10.255 scope global noprefixroute dynamic enp0s3
       valid_lft 457sec preferred_lft 457sec

[root@testclient1 ~]# ping -c3 google.com
PING google.com (216.58.198.110) 56(84) bytes of data.
64 bytes from lhr25s07-in-f110.1e100.net (216.58.198.110): icmp_seq=1 ttl=56 time=6.30 ms
64 bytes from lhr25s07-in-f110.1e100.net (216.58.198.110): icmp_seq=2 ttl=56 time=6.41 ms
64 bytes from lhr25s07-in-f110.1e100.net (216.58.198.110): icmp_seq=3 ttl=56 time=7.43 ms

--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 6.303/6.717/7.431/0.507 ms

[root@testclient1 ~]# curl ipinfo.io/ip
212.42.180.148

Test Client 2

$ ssh 192.168.1.12 -p 221
root@192.168.1.12's password:
Last login: Wed Jun 20 10:45:01 2018 from 192.168.1.19

[root@testclient2 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search lab.local
nameserver 172.24.10.1

[root@testclient2 ~]# ip addr show enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:b7:f0:59 brd ff:ff:ff:ff:ff:ff
    inet 172.24.10.101/24 brd 172.24.10.255 scope global noprefixroute dynamic enp0s3
       valid_lft 450sec preferred_lft 450sec

[root@testclient2 ~]# ping -c3 google.com
PING google.com (216.58.198.110) 56(84) bytes of data.
64 bytes from lhr25s07-in-f110.1e100.net (216.58.198.110): icmp_seq=1 ttl=56 time=7.68 ms
64 bytes from lhr25s07-in-f110.1e100.net (216.58.198.110): icmp_seq=2 ttl=56 time=6.46 ms
64 bytes from lhr25s07-in-f110.1e100.net (216.58.198.110): icmp_seq=3 ttl=56 time=6.42 ms

--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 6.421/6.855/7.680/0.590 ms

[root@testclient2 ~]# curl ipinfo.io/ip
212.42.180.148

The clients have been automatically configured via DHCP, can resolve URLs via DNS, and are sending and receiving network traffic through the gateway.

Calculating IPv4 Subnets

To truly understand subnets it’s far easier to understand them from the perspective of the computer. Most people will be used to seeing a subnet written as, for example, 255.255.255.0, but decimal octets are purely for the readability of human eyes. Computers work with subnets on a binary level, and where a human sees 255.255.255.0, a computer sees 11111111111111111111111100000000.

So how does a subnet translate to network division? Well, every IP address has a network portion and a host portion, such as 192.168.2.128. In this example — if a subnet of 255.255.255.0 is used — 192.168.2 is the network and 128 is the host. The first question a computer asks itself is, “is the device I’m sending data to on the same network as me?”, and then proceeds to compare the destination IP address against its own IP address. If 192.168.2.128 is sending data to 192.168.2.206, then it can see by comparing it to the subnet 255.255.255.0 that they are both on the same network, and therefore the data only needs to be sent via the local network.

All of the 1′s in a subnet represent the network, and all of the 0′s represent the host; the computer aligns the subnet with the IP address to determine which numbers represent the network and which represents the host:

ipbinaries

Here, anything which shares the network address of 11000000.10101000.00000010 is on the same network. If bits are borrowed from the host portion of the address, then for every bit that’s borrowed the available hosts per network is halved.

IP Binaries2

If a subnet of 11111111.11111111.11111111.10000000 is used, then the address space is halved into binary addresses that start with 0 and addresses that start with 1, and there would now be 2 networks under 192.168.2 with 126 hosts each.

If a subnet of 11111111.11111111.11111111.11110000 is used, then the following happens:

IP Binaries3

The network has now been cut in to 16ths and has 14 hosts per network. Thus with a subnet of 255.255.255.240, all of the addresses from 1 to 14 are in one network, and 17 to 30 are in another.

It’s important to remember that where one see’s all 1′s as the host address, this is the broadcast address, and all 0′s is the network ID. In the above example, all host addresses of 0000 are the network ID, and 1111 are the broadcast address. With an 8 bit host address this is 255 (e.g. 192.168.2.255) and 0 (e.g. 192.168.2.0) respectively, and as the amount of bits change so do these boundaries.

Working in binary makes life a lot easier once one gets used to it. By having a list of binary IP addresses handy, one can immediately see which addresses are going to fall into which network. Additionally by keeping in mind how many bits are being borrowed for the subnet, it is easy to mentally calculate how many hosts there will be per network.

With 11111111.11111111.11111111.10000000 there are 7 bits for the host, and so 2^7 = 128 – 2 = 126 hosts per network.

To calculate the subnet, the following table is needed:

subnet

Add up the columns that have the number 1 under them, and the subnet is converted. 11111111 = 255, and so the subnet is 255.255.255.240. Keep in mind that a subnet must be a series of 1′s in a row, and so there are only 8 possible values for each octet.