Running a DHCP Server on illumos
Posted by Dave Eddy on Nov 12 2024 - tags: techThis post will guide you through installing isc-dhcpd on OmniOS inside a zone (software virtualized container).
Configuring the system
To get started, first install zadm
on OmniOS inside the global zone.
This tool makes creating and managing zones simple and is reminiscent of the
vmadm
command on SmartOS.
Install zadm
:
pkg install zadm
I personally use this config for zadm
(shoutouts to
@papertigers for this), but feel free to customize this as you
like.
/etc/opt/ooce/zadm/zadm.conf
{
"CONFIG" : {
"format" : "toml"
},
"CONSOLE" : {
"auto_connect" : "off",
"auto_disconnect" : "on",
"escape_char" : "_"
},
"SNAPSHOT" : {
"prefix" : "zadm__"
}
}
Test that zadm
was installed and works as expected by running:
dave - GZ:amon sunos ~ $ zadm list
NAME STATUS BRAND RAM CPUS SHARES
global running ipkg 16G 4 1
Note that for this blog post I ran all of these commands on a fresh system so only 1 zone is running (the global zone).
Create the datasets needed, and you can customize these if you’d like but for the sake of this post I’ll be using these datasets:
zfs create -o mountpoint=/zones rpool/zones
zfs create rpool/zones/config
zfs create rpool/zones/root
Where:
/zones/config
toml files for each zone used during zone creation./zones/root
zone root FS data.
For example, a zone named foo
would have files like:
/zones/config/foo.toml
/zones/zones/foo
Creating the NICs
To get started we must create the NICs in the global zone before creating the
zone that will house the DHCP server. It is possible to have zadm
create NICs
for us for simple zone deployments but we need more control here to ensure the
NICs are persistent and can process DHCP traffic on multiple VLANs.
My physical server has 2 physical NICs - I plan on using this as my home router eventually. Until then, only 1 NIC is in use so we must find it by name to use for our zone NICs:
$ dladm show-phys
LINK MEDIA STATE SPEED DUPLEX DEVICE
rge0 Ethernet up 1000 full rge0
rge1 Ethernet unknown 0 unknown rge1
We can see that rge0
is the interface that is currently in use, so we will use
that to create the NICs for the zone.
My home network has multiple VLANs - this DHCP server will sit on all of them and properly tag them. A quick synopsis of my network looks like:
10.0.1.0/24
- untagged10.0.2.0/24
- vlan 310.0.3.0/24
- vlan 410.0.4.0/24
- vlan 510.0.5.0/24
- vlan 6
“But Dave, your VLAN IDs are off-by-one… isn’t that confusing?” YES. Yes it is, lol, I’ll get around to it a swear.
Now that we now the physical NIC we are going to create these NICs on and the
VLAN IDs we can create them with dladm
:
sudo dladm create-vnic -l rge0 dhcp_0
sudo dladm create-vnic -l rge0 -v 3 dhcp_3
sudo dladm create-vnic -l rge0 -v 4 dhcp_4
sudo dladm create-vnic -l rge0 -v 5 dhcp_5
sudo dladm create-vnic -l rge0 -v 6 dhcp_6
We can verify their creation with:
$ sudo dladm show-vnic | grep dhcp
dhcp_0 rge0 1000 2:8:20:fb:a1:19 random 0 --
dhcp_3 rge0 1000 2:8:20:cf:fd:7e random 3 --
dhcp_4 rge0 1000 2:8:20:81:1d:d3 random 4 --
dhcp_5 rge0 1000 2:8:20:30:d3:f6 random 5 --
dhcp_6 rge0 1000 2:8:20:46:c0:ca random 6 --
Creating the zone
Now we are ready to create the zone! Start by creating a toml file to represent the zone:
/zones/config/dhcp.toml
autoboot="true"
brand="lipkg"
dns-domain="rapture.com"
ip-type="exclusive"
limitpriv="default"
zonename="dhcp"
zonepath="/zones/root/dhcp"
resolvers=[
"10.0.1.3",
"10.0.1.2",
]
[[net]]
global-nic="rge0"
physical="dhcp_0"
[[net]]
global-nic="rge0"
physical="dhcp_3"
vlan-id="3"
[[net]]
global-nic="rge0"
physical="dhcp_4"
vlan-id="4"
[[net]]
global-nic="rge0"
physical="dhcp_5"
vlan-id="5"
[[net]]
global-nic="rge0"
physical="dhcp_6"
vlan-id="6"
[capped-memory]
physical="512M"
swap="2G"
Then, run zadm create
to create the zone!
$ sudo zadm create -b lipkg -t dhcp.toml dhcp
A ZFS file system has been created for this zone.
Sanity Check: Looking for 'entire' incorporation.
Image: Preparing at /zones/root/dhcp/root.
Cache: Using /var/pkg/publisher.
Installing: Packages (output follows)
Publisher: Using omnios (https://pkg.omnios.org/r151052/core/).
Publisher: Using omnios (https://us-west.mirror.omnios.org/r151052/core/).
Publisher: Using extra.omnios (https://pkg.omnios.org/r151052/extra/).
Publisher: Using extra.omnios (https://us-west.mirror.omnios.org/r151052/extra/).
Packages to install: 392
Mediators to change: 8
Services to change: 7
DOWNLOAD PKGS FILES XFER (MB) SPEED
Completed 392/392 32972/32972 307.2/307.2 --
PHASE ITEMS
Installing new actions 66485/66485
Updating package state database Done
Updating package cache 0/0
Updating image state Done
Creating fast lookup database Done
Postinstall: Copying SMF seed repository ... done.
Done: Installation completed in 142.004 seconds.
We can now boot the zone and login to it. You may have to wait a second or two after booting the zone to login to it:
sudo zadm boot dhcp
sudo zlogin dhcp
Once we are inside the zone we can verify we see the interfaces with:
root@dhcp:~# dladm
LINK CLASS MTU STATE BRIDGE OVER
dhcp_0 vnic 1500 up -- ?
dhcp_3 vnic 1500 up -- ?
dhcp_4 vnic 1500 up -- ?
dhcp_5 vnic 1500 up -- ?
dhcp_6 vnic 1500 up -- ?
Configuring networking in the zone
We can go through and manually set the IP addresses to each interface in the
zone - these will be persistent so you only need to run these commands once.
For my setup I’m using .4
as the last octet for this server on each network it
lives on.
Inside the zone run these commands:
ipadm create-addr -T static -a 10.0.1.4/24 dhcp_0/v4
ipadm create-addr -T static -a 10.0.2.4/24 dhcp_3/v4
ipadm create-addr -T static -a 10.0.3.4/24 dhcp_4/v4
ipadm create-addr -T static -a 10.0.4.4/24 dhcp_5/v4
ipadm create-addr -T static -a 10.0.5.4/24 dhcp_6/v4
The last step is to add the default gateway so we can hit the internet from the zone:
route -p add default 10.0.1.1
Installing the software
Now we can install the isc-dhcp
package to get the DHCP server:
root@dhcp:~# pkg install isc-dhcp
Packages to install: 1
Services to change: 7
Create boot environment: No
Create backup boot environment: No
DOWNLOAD PKGS FILES XFER (MB) SPEED
Completed 1/1 20/20 4.7/4.7 2.0M/s
PHASE ITEMS
Installing new actions 34/34
Updating package state database Done
Updating package cache 0/0
Updating image state Done
Creating fast lookup database Done
Updating package cache 2/2
This will install the package and create an SMF manifest for the service without actually starting it for us. We can get the service ready by copying the example config into place, editing it, and starting the service!
cp /usr/share/isc-dhcp/examples/dhcpd.conf.example /etc/dhcpd.conf
vim /etc/dhcpd.conf
# edit, edit, edit, :wq
Start the service with:
svcadm enable dhcp:ipv4
And that’s it! You now have a working DHCP server on OmniOS. You can verify it is running with:
root@dhcp:~# svcs dhcp:ipv4
STATE STIME FMRI
online 0:45:51 svc:/network/service/dhcp:ipv4
Helpful hints
It took me a bit to find the example config until I remember I could ask the package manager what files it installed:
dave@dhcp:~$ pkg contents isc-dhcp
PATH
etc/security/auth_attr.d/network%2Fservice%2Fdhcp
lib/svc/manifest/network/isc-dhcp.xml
lib/svc/method/isc-dhcp
usr/bin/omshell
usr/sbin/dhcpd
usr/sbin/dhcrelay
usr/share/isc-dhcp
usr/share/isc-dhcp/examples
usr/share/isc-dhcp/examples/dhcpd.conf.example
usr/share/man/man1/omshell.1
usr/share/man/man5/dhcp-eval.5
usr/share/man/man5/dhcp-options.5
usr/share/man/man5/dhcpd.conf.5
usr/share/man/man5/dhcpd.leases.5
usr/share/man/man8/dhcpd.8
usr/share/man/man8/dhcrelay.8
var/db
var/db/dhcpd.leases
var/db/dhcpd.leases~
var/db/dhcpd6.leases
var/db/dhcpd6.leases~
This clarified where pkg
placed the package files during installation.