Rr. Kavajes, Square 21, Tirana, Albania +355 68 400 500 9 info@ernesthena.com

IPv6 DHCP server on Ubuntu with web interface

Home Solutions

 

Requirements

  • Mini PC machine with ubuntu installed on it

  • Connected to the network using a single port as Trunk (RJ45)

  • It should run IPv6 DHCP Server

  • The IPv6 leases should be a readable manner

  • There will be Mikrotik Routers per each network to push the defaul route, ensure no SLAAC are generated from them
    (SLAAC pushes autogenerated IPv6 which is not easy readable)

  • The first IP of the subnet will be at Mikrotik gateway, and the second at IPv6 DHCP server

  • Web page to show the IPv6 leases

  • Main IPv6 subnet is 2807:a00::/32

 
Below is the mini pc to be installed

Solution

 

Modify the network interface IPs. Its taken as example the IPv6 subnets:
2807:a00:1::/64 for the Main interface (enp2s0)
2807:a00:2::/64 for vlan 2 that is on Main interface as subinterface


Modify the file
sudo vi /etc/netplan/00-installer-config.yaml

Paste the commands as below:
network:
  ethernets:
    enp2s0:
      dhcp4: no
      dhcp6: no
      addresses:
        - 192.168.1.2/24
        - 2807:a00:1::2/64
      routes:
          - to: default
            via: 192.168.1.1
         - to: default
            via: 2807:a00:1::1
     nameservers:
        addresses:  
         - 8.8.8.8  
         - 1.1.1.1  
         - 2001:4860:4860::8888  
         - 2620:fe::9
  vlans:
    enp2s0.2:
         id: 2
         dhcp4: no  
        dhcp6: no  
        addresses:  
          - 192.168.2.2/24  
          - 2807:a00:2::2/64  
        link: enp2s0 
  version: 2

Write and Quit with below commands
esc
:wq!

Now install kea ipv6 dhcp server
sudo apt update
sudo apt install kea-dhcp6-server


Check if IPv6 kea is running fine (active means is fine)
systemctl status kea-dhcp6-server



Modify the kea dhcp file
vi /etc/kea/kea-dhcp6.conf

Paste the commands as below:
{
    "Dhcp6": {
        "interfaces-config": {
            "interfaces": ["*"]
        },
        "lease-database": {
            "type": "memfile",
            "persist": true,
            "name": "/var/lib/kea/kea-leases6.csv",
            "lfc-interval": 86400,
            "max-row-errors": 100
        },
        "preferred-lifetime": 500000,
        "valid-lifetime": 601200,
        "renew-timer": 100,
        "rebind-timer": 200,

        "subnet6": [
           {
               "subnet": "2807:a00:1::/64",
               "interface": "enp2s0",
               "pools": [
                   { "pool": "2807:a00:1::101-2807:a00:1::109" },
                   { "pool": "2807:a00:1::110-2807:a00:1::119" },
                   { "pool": "2807:a00:1::120-2807:a00:1::129" },
                   { "pool": "2807:a00:1::130-2807:a00:1::139" },
                   { "pool": "2807:a00:1::140-2807:a00:1::149" },
                   { "pool": "2807:a00:1::150-2807:a00:1::159" },
                   { "pool": "2807:a00:1::160-2807:a00:1::169" },
                   { "pool": "2807:a00:1::170-2807:a00:1::179" },
                   { "pool": "2807:a00:1::180-2807:a00:1::189" },
                   { "pool": "2807:a00:1::190-2807:a00:1::199" },
                   { "pool": "2807:a00:1::290-2807:a00:1::299" },
                   { "pool": "2807:a00:1::390-2807:a00:1::399" },
                   { "pool": "2807:a00:1::490-2807:a00:1::499" },
                   { "pool": "2807:a00:1::590-2807:a00:1::599" },
                   { "pool": "2807:a00:1::690-2807:a00:1::699" },
                   { "pool": "2807:a00:1::790-2807:a00:1::799" },
                   { "pool": "2807:a00:1::890-2807:a00:1::899" },
                   { "pool": "2807:a00:1::990-2807:a00:1::999" }
               ]
   },
 
   
   {
              "subnet": "2807:a00:2::/64",
               "interface": "enp2s0.2",
               "pools": [
                   { "pool": "2807:a00:2::101-2807:a00:2::109" },
                   { "pool": "2807:a00:2::110-2807:a00:2::119" },
                   { "pool": "2807:a00:2::120-2807:a00:2::129" },
                   { "pool": "2807:a00:2::130-2807:a00:2::139" },
                   { "pool": "2807:a00:2::140-2807:a00:2::149" },
                   { "pool": "2807:a00:2::150-2807:a00:2::159" },
                   { "pool": "2807:a00:2::160-2807:a00:2::169" },
                   { "pool": "2807:a00:2::170-2807:a00:2::179" },
                   { "pool": "2807:a00:2::180-2807:a00:2::189" },
                   { "pool": "2807:a00:2::190-2807:a00:2::199" }
               ]
}

        ],           "option-data": [
            {
                "name": "dns-servers",
                "data": "2001:4860:4860::8888, 2606:4700:4700::1111"
            }
        ],
        "loggers": [
            {
                "name": "kea-dhcp6",
                "output_options": [
                    {
                        "output": "/tmp/kea-dhcp6.log"
                    }
                ],
                "severity": "DEBUG",
                "debuglevel": 0
            }
        ]
    } }

Install apache
sudo apt install apache2 -y
sudo systemctl start apache2
sudo systemctl enable apache2

Configure apache to use the a directory for web files, and ensure to have "DocumentRoot /var/www/html"
sudo vi /etc/apache2/sites-available/000-default.conf

Create a file as below, what it does is as below:
Checks the IPv6 leases
Orders this leases from small to big (using awk)
Creates a web file
Copies the web file to folder of apache

sudo vi /usr/local/bin/web.sh

host=`hostname`
now=`date +"%d-%b-%y"`
now=`echo $now| tr '[a-z]' '[A-Z]'`
yest=`TZ=CST+24 date +%d-%b-%y`
yest=`echo $yest| tr '[a-z]' '[A-Z]'`
sub="Jobs-$host-$now-HealthReport"
awk -F, '!seen[$1]++' /var/lib/kea/kea-leases6.csv > /var/lib/kea/kea-leases6-clean1.csv
sort -k1 /var/lib/kea/kea-leases6-clean1.csv > /var/lib/kea/kea-leases6-clean.csv
if [ -s /var/lib/kea/kea-leases6-clean.csv ]
then

awk 'BEGIN{
FS=","
print """IPV6 DHCP LEASES - LIVE DATABASE"
print ""
print ""
print ""
print "IPv6 LEASEHOSTNAMEMAC ADDRESS"
}
{
    printf ""
            for(i=1;i<=1;i++){

                      if(i == 1 && $i == "N" || i == 4 && $i == n || i == 4 && $i == y )
                    {
                            printf "%s", $i
                    }
                    else if(i == 1 && $i == "Y" || i == 4 && $i != n && $i != y)
                    {
                            printf "%s", $i
                    }
                    else
{
                            printf "%s", $i
}
            }
 for(i=12;i<=13;i++){
                      if(i == 1 && $i == "N" || i == 4 && $i == n || i == 4 && $i == y )
                    {
                            printf "%s", $i
                    }                     else if(i == 1 && $i == "Y" || i == 4 && $i != n && $i != y)
                    {
                            printf "%s", $i
                    }
                    else
{
                            printf "%s", $i
}
            }
            print ""
    }
END{
            print ""
    }' y="$yest" n="$now" /var/lib/kea/kea-leases6-clean.csv > ip-addresses.html
cp ip-addresses.html /var/www/html/IPV6-ADDRESSES.html
else
echo "file not found"
fi

Make it executable
sudo chmod +x /usr/local/bin/web.sh

Execute this script every 1min, insert the "* * * * * /usr/local/bin/web.sh" on crontab
crontab -e
* * * * * /usr/local/bin/web.sh
esc
:wq!


Now we need to disable SLAAC at Mikrotik. IPv6 > Addresses
Click "Advertise" and "Autolink local". Advertise is to push default route over RA.



Add the prefix manually add disable "On Link" and "Autonomous". IPv6 > ND > Prefixes



The results will be as below



 

 

All Rights Reserved, Ernest Hëna ©2025