About this answer (tutorial):
This tutorial is intended to demonstrate a "success case" for the ISC KEA DHCP (DHCPv4) configuration and deploy. Particularly demonstrate the push of routes to DHCP clients. Other points are also considered for the specific case and are there to make the demonstration more didactic.
In the specific case (simulation using VirtualBox) we use an OpenVPN tunnel and we demonstrate how to do a routing to use it in two ways in a LAN-TO-LAN infrastructure.
This tutorial was constructed considering a scenario where we have a server on the Internet (Serverloft) running a Hypervisor (Xen) at one end of the VPN and a corporate LAN at the other end of the VPN where all the servers of both networks are able to communicate in a transparent way.
Other considerations are made throughout this tutorial and we recommend that you read it fully.
We feel the need to do this tutorial since nothing "practical" like it can be found on the internet. This tutorial also targets an audience that like us has greater difficulty with the basic concepts presented here.
Before we continue we would like to thanks the many people who helped in this process. In particular we thank the users: @Filipe Brandenburger , @Rui F Ribeiro , @A.B , @Isaac, @slm and others (unfortunately we can not quote everyone).
Servers in this tutorial:
Server #1 - DHCPv4 Client (ips ending with 3);
Server #2 - DHCPv4 Client and OpenVPN Server (ips ending with 4);
Server #3 - DHCPv4 Client and OpenVPN Client (ips ending with 5);
Server #4 - DHCPv4 Client (ips ending with 6);
Server #5 - ISC KEA DHCP (DHCPv4) Server (ips ending with 2).
NOTE: All servers are CentOS 7.
Subnets:
192.168.56.0/24
10.1.2.0/24
10.1.4.0/24
10.1.6.0/24
10.8.0.1/24 (VPN tunnel)
Server #5 - ISC KEA DHCP (DHCPv4) Server:
. Installing ISC KEA DHCP (DHCPv4) on CentOS 7
yum -y install gcc-c++ openssl-devel wget
cd /usr/local/src/
wget https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.gz
tar -zxvf boost_1_67_0.tar.gz
cd boost_1_67_0
./bootstrap.sh
./b2 install
rm -rf /usr/local/src/boost_1_67_0*
cd /usr/local/src/
wget https://github.com/log4cplus/log4cplus/releases/download/REL_2_0_1/log4cplus-2.0.1.tar.gz
tar zxvf log4cplus-2.0.1.tar.gz
cd log4cplus-2.0.1
./configure
make
make install
rm -rf /usr/local/src/log4cplus-2.0.1*
cd /usr/local/src/
wget https://ftp.isc.org/isc/kea/1.4.0/kea-1.4.0.tar.gz
tar zxvf kea-1.4.0.tar.gz
cd kea-1.4.0
./configure --enable-shell
make
make install
rm -rf /usr/local/src/kea-1.4.0*
. Create settings (startup settings) for KEA services in systemd (systemctl)...
vi '/usr/lib/systemd/system/kea-dhcp4.service'
[Unit]
Description=Kea DHCPv4 Server
Documentation=man:kea-dhcp4(8)
Wants=network-online.target
After=network-online.target
After=time-sync.target
[Service]
ExecStart=/usr/local/sbin/kea-dhcp4 -c /usr/local/etc/kea/kea-dhcp4.conf
[Install]
WantedBy=multi-user.target
vi '/usr/lib/systemd/system/kea-dhcp6.service'
[Unit]
Description=Kea DHCPv6 Server
Documentation=man:kea-dhcp6(8)
Wants=network-online.target
After=network-online.target
After=time-sync.target
[Service]
ExecStart=/usr/local/sbin/kea-dhcp6 -c /usr/local/etc/kea/kea-dhcp6.conf
[Install]
WantedBy=multi-user.target
vi '/usr/lib/systemd/system/kea-dhcp-ddns.service'
[Unit]
Description=Kea DHCP-DDNS Server
Documentation=man:kea-dhcp-ddns(8)
Wants=network-online.target
After=network-online.target
After=time-sync.target
[Service]
ExecStart=/usr/local/sbin/kea-dhcp-ddns -c /usr/local/etc/kea/kea-dhcp-ddns.conf
[Install]
WantedBy=multi-user.target
. Create (adjust) the configuration file "/usr/local/etc/kea/kea-dhcp4.conf"...
cp '/usr/local/etc/kea/kea-dhcp4.conf' '/usr/local/etc/kea/kea-dhcp4.conf_BAK'
vi '/usr/local/etc/kea/kea-dhcp4.conf'
{
"Dhcp4": {
"interfaces-config": {
"interfaces": ["enp0s8", "enp0s9", "enp0s10", "enp0s17"]
},
"control-socket": {
"socket-type": "unix",
"socket-name": "/tmp/kea-dhcp4-ctrl.sock"
},
"lease-database": {
"type": "memfile",
"lfc-interval": 1800
},
"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
},
"valid-lifetime": 4000,
"renew-timer": 1000,
"rebind-timer": 2000,
// Defines the "rfc3442-classless-static-routes" option.
// More details https://unix.stackexchange.com/a/460147/61742 .
"option-def": [{
"name": "rfc3442-classless-static-routes",
"code": 121,
"space": "dhcp4",
"type": "record",
"array": true,
"record-types": "uint8,uint8,uint8,uint8,uint8,uint8,uint8,uint8"
}
],
"subnet4": [{
"interface": "enp0s8",
"subnet": "10.1.2.0/24",
"pools": [{
"pool": "10.1.2.3 - 10.1.2.254"
}
]
}, {
"interface": "enp0s9",
"subnet": "10.1.4.0/24",
"pools": [{
"pool": "10.1.4.3 - 10.1.4.254"
}
],
// Reserve ips for the interfaces that have these MAC ADDRESS on that network.
"reservations": [{
// Server 3# (4)
"hw-address": "08:00:27:71:77:07",
"ip-address": "10.1.4.5"
}, {
// Server 4# (6)
"hw-address": "08:00:27:e0:d2:c8",
"ip-address": "10.1.4.6"
}
],
// Defines a route to be pushed to this subnet.
// More details https://unix.stackexchange.com/a/460147/61742 .
"option-data": [{
"name": "rfc3442-classless-static-routes",
"data": "24,10,1,6,10,1,4,5"
}
]
}, {
"interface": "enp0s10",
"subnet": "10.1.6.0/24",
"pools": [{
"pool": "10.1.6.3 - 10.1.6.254"
}
],
// Reserve ips for the interfaces that have these MAC ADDRESS on that network.
"reservations": [{
// Server 1# (3)
"hw-address": "08:00:27:56:84:1f",
"ip-address": "10.1.6.3"
}, {
// Server 2# (4)
"hw-address": "08:00:27:2c:d1:58",
"ip-address": "10.1.6.4"
}
],
// Defines a route to be pushed to this subnet.
// More details https://unix.stackexchange.com/a/460147/61742 .
"option-data": [{
// Server 3# (4) e Server 4# (6)
"name": "rfc3442-classless-static-routes",
"data": "24,10,1,4,10,1,6,4"
}
]
}, {
"interface": "enp0s17",
"subnet": "192.168.56.0/24",
"pools": [{
"pool": "192.168.56.3 - 192.168.56.254"
}
],
"option-data": [{
"name": "domain-name-servers",
"data": "192.168.56.1"
}, {
"name": "routers",
"data": "192.168.56.1"
}
],
// Reserve ips for the interfaces that have these MAC ADDRESS on that network.
"reservations": [{
// Server 1# (3)
"hw-address": "08:00:12:26:e2:6c",
"ip-address": "192.168.56.3"
}, {
// Server 2# (4)
"hw-address": "08:00:1c:a6:b9:59",
"ip-address": "192.168.56.4"
}, {
// Server 3# (5)
"hw-address": "08:00:ea:4e:40:ae",
"ip-address": "192.168.56.5"
}, {
// Server 4# (6)
"hw-address": "08:00:27:aa:e7:60",
"ip-address": "192.168.56.6"
}
]
}
]
},
"Logging": {
"loggers": [{
"name": "kea-dhcp4",
"output_options": [{
"output": "/usr/local/var/log/kea-dhcp4.log"
}
],
"severity": "INFO",
"debuglevel": 0
}
]
}
}
. Configure network interfaces
These network interfaces will provide the DHCP server for all machines (see "kea-dhcp4.conf" above).
NOTE: In a REAL WORLD SCENARIO the machines that are on the "OpenVPN server side network" would own a DHCP server and machines that are on the "OpenVPN client side network" would own another DHCP server. This division works perfectly as we are talking about the "layer 2" of the OSI model, which is therefore isolated from "layer 3" where there will be "routing", "ip forward" etc, which will be part of the integration between the two networks.
vi '/etc/sysconfig/network-scripts/ifcfg-enp0s17'
BOOTPROTO=static
DEVICE=enp0s17
DNS1=192.168.56.1
GATEWAY=192.168.56.1
IPADDR=192.168.56.2
IPV6INIT=NO
NETMASK=255.255.255.0
NM_CONTROLLED=yes
ONBOOT=yes
USERCTL=NO
vi '/etc/sysconfig/network-scripts/ifcfg-enp0s8'
BOOTPROTO=static
DEVICE=enp0s8
IPADDR=10.1.2.2
IPV6INIT=NO
NETMASK=255.255.255.0
NM_CONTROLLED=yes
ONBOOT=yes
USERCTL=NO
vi '/etc/sysconfig/network-scripts/ifcfg-enp0s9'
BOOTPROTO=static
DEVICE=enp0s9
IPADDR=10.1.4.2
IPV6INIT=NO
NETMASK=255.255.255.0
NM_CONTROLLED=yes
ONBOOT=yes
USERCTL=NO
vi '/etc/sysconfig/network-scripts/ifcfg-enp0s10'
BOOTPROTO=static
DEVICE=enp0s10
IPADDR=10.1.6.2
IPV6INIT=NO
NETMASK=255.255.255.0
NM_CONTROLLED=yes
ONBOOT=yes
USERCTL=NO
Server #2 - Client DHCPv4 and OpenVPN Server:
. OpenVPN server settings
vi '/etc/openvpn/server/server.conf'
IMPORTANT: We are only considering the CONFIGURATIONS STRICTLY NECESSARY FOR THE OPENVPN OPERATION IN THE PROPOSED INFRASTRUCTURE ("server.conf" and "client0"). Other settings are required. For more information, check out the OpenVPN documentation. More details on the needs addressed here at this link https://openvpn.net/index.php/open-source/documentation/howto.html#scope .
dev tun
topology subnet
server 10.8.0.0 255.255.255.0
push "route 10.1.6.0 255.255.255.0"
push "route 10.1.4.0 255.255.255.0"
client-to-client
ifconfig 10.8.0.1 255.255.255.0
. OpenVPN client settings
NOTE: These settings are consumed by the client on the server side.
vi '/etc/openvpn/ccd/client0'
ifconfig-push 10.8.0.6 255.255.255.0
iroute 10.1.4.0 255.255.255.0
route 10.1.4.0 255.255.255.0
Server #3 - Client DHCPv4 and OpenVPN Client
. OpenVPN client settings
vi '/etc/openvpn/client/client0.conf'
dev tun
remote 192.168.56.4 1194
Server #2 e #3:
. Open the firewall for "OpenVPN" (Server #2 and #3)
NOTE: Openvpn is not the focus of the thread so we will not go into details here!
firewall-cmd --permanent --add-service openvpn
firewall-cmd --permanent --add-masquerade
firewall-cmd --reload
. Enable "ip_forward" (Server #2 and #3)
echo -n "net.ipv4.ip_forward=1
" >> /etc/sysctl.d/ip_forward.conf
sysctl -w net.ipv4.ip_forward=1
Server #1, #2, #3 e #4:
. Configure network interfaces
vi '/etc/sysconfig/network-scripts/ifcfg-enp0s8'
NOTE: All interfaces in all machines follow this same model since the network configurations will be provided by Server #5 (KEA DHCP Server).
BOOTPROTO=dhcp
DEVICE=enp0s8
IPV6INIT=NO
ONBOOT=yes
ZONE=public
vi '/etc/sysconfig/network'
NETWORKING=yes
Test:
. This tutorial will have been successfully executed if all of these tests are positive:
Server #1
ping 10.1.4.5 # (#3)
ssh <USER>@10.1.4.5 # (#3)
ping 10.1.4.6 # (#4)
ssh <USER>10.1.4.6 # (#4)
Server #2
ping 10.1.4.5 # (#3)
ssh <USER>10.1.4.5 # (#3)
ping 10.1.4.6 # (#4)
ssh <USER>10.1.4.6 # (#4)
Server #3
ping 10.1.6.3 # (#1)
ssh <USER>10.1.6.3 # (#1)
ping 10.1.6.4 # (#2)
ssh <USER>10.1.6.4 # (#2)
Server #4
ping 10.1.6.3 # (#1)
ssh <USER>10.1.6.3 # (#1)
ping 10.1.6.4 # (#2)
ssh <USER>10.1.6.4 # (#2)
Tips:
Internet (WAN) test
curl http://www.google.com
Renew DHCP on clients
dhclient -r
Remove DHCP leases settings from clients:
NOTE: Important to test the operation of the DHCP server.
rm -rf $(find /var/lib/NetworkManager/ -name "*.lease" | egrep <NETWORK_INTERFACE_NAME>)
Remove DHCP leases settings from server:
NOTE: Important to test the operation of the DHCP server.
rm -rf /usr/local/var/kea/kea-leases4.csv*
Other guidelines:
General guidelines and about the environment used for this tutorial:
This configuration tutorial was built in a test environment using VirtualBox;
All networks in use are "Host-only" and one of them (192.168.56.0/24) has internet (see 3). None of them should have VirtualBox DHCP enabled;
By default "Host-only" networks have no internet access ( https://www.virtualbox.org/manual/ch06.html#networkingmodes ). However, in this tutorial https://forum.manjaro.org/t/manjaro-and-virtualbox-host-only-with-internet/28722/12 I teach how to "circumvent" this limitation;
The internet (WAN) for the 192.168.56.0/24 network must be activated only when it is necessary. Must be disabled for running tests except to check internet access (curl http://www.google.com
) on Servers #1, #2, #3 and #4 (see 3);
Services such as "dnsmasq" and "iptables" should be disabled on the host when the network tests are executed (ping, ssh, etc) (see 3);
Generally speaking, no DHCP should be present on layer 2 of the networks during the tests except what is on Server #5.
Use tun or tap (OpenVPN) - A Discussion:
We transpose below part of a chat ( chat.stackexchange.com ) between @Eduardo Lucio and @Isaac about the deploy model in this answer. We ( @Eduardo Lucio ) opted, at the moment, for using "tun", even though it was a "more laborious" configuration. However if you want a truly transparent integration between the networks on both sides of the VPN opt for tap (with all its pros and cons). I believe that the clarifications of @Isaac are very relevant to decide what to use (tap or tun) and so are transposed here so that it can reach more people.
Eduardo Lucio Sat 15:22 @Isaac
https://serverfault.com/questions/21157/should-i-use-tap-or-tun-for-openvpn/21168#21168
I believe this is the way to get things done without a router. Look:
"if you need to bridge two ethernet segments in two different
locations - then use tap. in such setup you can have computers in the
same ip subnet (eg 10.0.0.0/24) on both ends of vpn". So "vpn will act
like ethernet switch". But there comes another question ... With this
model I could have, for example, machines that are in the network
10.7.1.0/24 (VPN side A) communicating transparently with the network 192.168.58.0/24 (VPN side B)?
Isaac Sat 22:19 You are starting to make the right questions.
But you do have a router on each network!! Well, kind of.
There are only two ways in which a packet will reach a computer: (1)
The computer is part of the same wire as another computer (the
same layer 2 scope) like all ports of a (simple) switch (or the old
name of hub) or belong to the same VLAN (if you do not have experience
with VLANs please just keep this data point for future reference and
forget I ever mentioned it for now).
Isaac Sat 22:52 (2) The packet gets routed between two layer 2
scopes by a router. The decision of whether to route a packet (or not)
is taken by following the route table of the switch.
Up to this point that is just a general network description that you
might find irrelevant to your specific use case until you also realize
that when you tell a computer to forward packets that computer is
acting as a routing device, in short, a router. That router needs to
have routing tables. For example, Assuming ( you really have a mess of
numbers on every question they are different, it makes quite difficult
to being specific) the server 4 (at 10.1.4.6) which is the VPN client
should have forward activated and must be set to route all packets it
see that have 10.1.6.x as destination to the tun interface. The
packets will enter the VPN, and exit the VPN on the other side. Server
3 (on the same network range 10.1.4.y at 10.1.4.5) just need to have a
default (gateway) route to send all packets that are not in its
own network range (10.1.4.0/24) to the GW of 10.1.4.6.
Once the packets from the VPN reach the other computer server2 (at
10.1.6.4) they must be routed as well to the router at the office and the router at the office must have a route entry to send
any packet with destination 10.1.4.x to server 2. Server 2 must
internally route (and have such route entry) all packets it receive to
the tun interface. Is it clearly explained? All of that routing is
needed because the device used is a tun (a layer 3 device).
A much simpler (and more insecure) device is a tap (a layer 2 device).
Think of it as a switch to which you add computers. It will forward
all packets it receive, be those directed to any (level 3) IP address
or be those broadcast packets, ARP resolutions and others. In such
sense, that will open computers on your office LAN to ARP attacks from
computers on the other side of the VPN. All the computers on both
sides of the VPN will become a large happy (everyone trust every
other) family. Having said that, then yes packets that originate on IP
address 10.7.1.0/24 will appear at the other side of the VPN. But the
way you phrase your question: (machines at 10.7.1.0/24 and
192.168.58.0/24 will be able to communicate?) forces a NO answer. The only way in which computers at dissimilar (private) networks could
communicate each other is when they have their local addresses
translated to the external (remote) addresses via NAT (Network Address
Translation) or similar. So each side of the NAT will see the same
network range. All the above just covers IPv4. You will need to review
it and extend for IPv6.
ip route get a.b.c.d
on server #1 and server #3." That should tell you what is wrong. You can also look atip route
output to dump the whole route table. Your question here is still not specific enough. Try to find out what the root problem is and then ask e.g. "How can I push a static route using Kea DHCP?" and include whatip route
currently is and what you would like it to be... That way you might get more of a chance of an answer. – filbranden Jul 26 '18 at 17:04