Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Adding Custom Configuration in Kea DHCP Server with pfSense+ 25.03

    Scheduled Pinned Locked Moved DHCP and DNS
    26 Posts 8 Posters 4.7k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • GertjanG
      Gertjan @EDaleH
      last edited by Gertjan

      @EDaleH

      Example :
      I've 5 "Unifi UB Pro 6" APs on a pfSense, OPT1 network, which is a captive portal.
      There are also 2 of these "Unifi UB Pro 6" on my pfSense LAN for wireless company devices.

      I've chosen to use the DHCP method of announcing the IP of the UNIFI controller, so I need to create a

      {
        "option-def": [
          {
            "space": "dhcp4",
            "name": "custom-option-vendor",
            "code": 43,
            "type": "binary" 
          }
        ]
      }
      

      on the main Services > DHCP Server > Settings page.

      On the Services > DHCP Server > LAN page :

      {
        "option-data":  [
            {
              "name": "custom-option-vendor",
              "data": "0104C0A80106" 
            }
          ]
      }
      

      where "0104C0A80106" stands for the IP 192.168.1.6, the IP of my Unifi controller.

      The Services > DHCP Server > PORTAL (OPT1) which hosts the captive portal :
      Here I announce the RFC8910 method - and also the Unifi controller location :

      {
        "option-data":  [
            {
              "name": "v4-captive-portal",
              "data":  "https://portal.bhf.tld:8003/rfc8910.php?zone=cpzone1" 
            },
            {
              "name": "custom-option-vendor",
              "data": "0104C0A80106" 
            }
          ]
      }
      

      Btw : "cpzone1" is the name of the captive portal zone present on the OPT interface, 8003 is the port I used for this interface.

      The latest pfSense Beta version 25.03.b.20250306.0140 offers two new things here :
      There is now a Custom JSON Configuration general config section, valid for the entire DHCP scope, and a Custom JSON Configuration for each interface.
      Whatever you enter in the Custom JSON Configuration section is sanity-checked using "lint", and not taken in account when issues (syntax errors) are found.
      Be ware : if errors are found, the manually entered data into a Custom JSON Configuration isn't used, so the server will start without it and you'll have a system notification asking you to look at the system log, where you will find, for example :

      534b5d71-878c-4d83-9099-0bf1032499fb-image.png

      The actual error

      /services_dhcp.php: The command '/usr/local/sbin/kea-dhcp4 -t /usr/local/etc/kea/kea-dhcp4.conf' returned exit code '1', the output was 'Syntax check failed with: /usr/local/etc/kea/kea-dhcp4.conf:114.25-29: got unexpected keyword "lan" in pools map.'

      so you'll know there was a "'Syntax check failed".
      Double check your JSON structure ^^

      The good thing here is, if there was an JSON error, the DHCPv4 still runs, not leaving you without DHCP active.

      No "help me" PM's please. Use the forum, the community will thank you.
      Edit : and where are the logs ??

      F 1 Reply Last reply Reply Quote 1
      • M
        marcosm Netgate
        last edited by

        The space vendor-encapsulated-options-space is set up differently; code specifies the sub-option and the length can be omitted. Hence what would previously be defined in the ISC DHCP GUI as 0104c0000203 can be specified as either c0000203 or 0xc0000203 (the hex prefix is optional). To get this value, use an IP to hex converter.

        However, missing from the example in the OP was "csv-format": false (referenced in the Kea docs) - I've updated the example accordingly.

        1 Reply Last reply Reply Quote 1
        • F
          FCS001FCS @Gertjan
          last edited by

          @Gertjan

          I have a test minipc system I just installed pfSense CE 2.8 beta and want to go with KEA DCHP but need to inform my 2 Unifi Mini Flex Switches via the DCHP-Option 43 for a Unifi Network Controller that is on another sub-net. It worked with ISC on CE 2.7 so wanted to have the same function using KEA.

          I followed as best I could your examples and think it works. I did not find any "php-frm" errors in the General Log after a Reboot, so can I assume it works?

          How can I check that the Option 43 is actually sent/working?

          Screenshots of my entries:

          "Services > DHCP Server > Settings":
          84c87393-abb7-4875-bb18-6e2f02f5f5ed-image.png

          "Services > DHCP Server > LAN": (last few digits changed in "data" for security but are actually correct for my IP)
          58e84184-89fa-4ee7-b5b6-18cdaa4fa047-image.png

          GertjanG 1 Reply Last reply Reply Quote 0
          • GertjanG
            Gertjan @FCS001FCS
            last edited by

            @FCS001FCS said in Adding Custom Configuration in Kea DHCP Server with pfSense+ 25.03:

            How can I check that the Option 43 is actually sent/working?

            That's the easy part ^^
            Ask it ? ( ! )

            Here :

            dfde85a4-339b-4846-b247-8db6be8dbbce-image.png

            Select :
            The interface, for example your LAN
            View options : you want details : High
            Protocol : UDP
            Ports : 67 and 68

            and hit Start.

            Fire up you favorite SSH client, for example, Putty.
            SSH into your Unifi AP on LAN, mine is 192.168.1.254
            This will works, as the real admin want control, so the've set up their devices with :

            c57d3a83-d36c-4c18-bec9-8bff0561a60c-image.png

            so there is the login user name and password ๐Ÿ˜Š

            Your in !
            type

            info
            

            To see more, type

            ps | grep 'dhcp'
            

            and now you see the dhcp client config file, so you can find even more, like the /etc/persistent/cfg/mgmt file.
            Anyway, I can see that my controller is :

            U6ProBureau-BZ.6.6.77# info
            
            Model:       U6-Pro
            Version:     6.6.77.15402
            MAC Address: 28:70:4e:62:31:5d
            IP Address:  192.168.1.254
            Hostname:    U6ProBureau
            Uptime:      1454 seconds
            NTP:         Synchronized
            
            Status:      Connected (http://192.168.1.6:8080/inform)
            

            From the unifi command line, type

            reboot
            

            You can also do what all the others do : remove the power for a moment ^^

            Now you'll see the pfSense capture showing the result : after 5 seconds or so : first

            08:05:16.976611 IP (tos 0x0, ttl 64, id 0, offset 0, flags [none], proto UDP (17), length 328)
                0.0.0.0.68 > 255.255.255.255.67: [udp sum ok] BOOTP/DHCP, Request from 28:70:4e:62:31:5d, length 300, xid 0x53bf373d, secs 51400, Flags [none] (0x0000)
            	  Client-Ethernet-Address 28:70:4e:62:31:5d
            	  Vendor-rfc1048 Extensions
            	    Magic Cookie 0x63825363
            	    DHCP-Message (53), length 1: Request
            	    Client-ID (61), length 7: ether 28:70:4e:62:31:5d
            	    Requested-IP (50), length 4: 192.168.1.254
            	    Server-ID (54), length 4: 192.168.1.1
            	    MSZ (57), length 2: 576
            	    Parameter-Request (55), length 8: 
            	      Subnet-Mask (1), Default-Gateway (3), Domain-Name-Server (6), Hostname (12)
            	      Domain-Name (15), BR (28), NTP (42), Vendor-Option (43)
            	    Vendor-Class (60), length 4: "ubnt"
            	    Hostname (12), length 11: "U6ProBureau"
            

            Note that it knew it had "192.168.1.254" before, so it's asking again for this IP.
            See also the "Option 43 request".

            The answer from Kea :

            08:05:16.982496 IP (tos 0x10, ttl 128, id 0, offset 0, flags [DF], proto UDP (17), length 347)
                192.168.1.1.67 > 192.168.1.254.68: [udp sum ok] BOOTP/DHCP, Reply, length 319, xid 0x53bf373d, Flags [none] (0x0000)
            	  Your-IP 192.168.1.254
            	  Client-Ethernet-Address 28:70:4e:62:31:5d
            	  Vendor-rfc1048 Extensions
            	    Magic Cookie 0x63825363
            	    DHCP-Message (53), length 1: ACK
            	    Subnet-Mask (1), length 4: 255.255.255.0
            	    Default-Gateway (3), length 4: 192.168.1.1
            	    Domain-Name-Server (6), length 4: 192.168.1.1
            	    Hostname (12), length 7: "ub6pro4"
            	    Domain-Name (15), length 20: "bhf.tld"
            	    NTP (42), length 4: 192.168.1.1
            	    Vendor-Option (43), length 6: 1.4.192.168.1.6
            	    Lease-Time (51), length 4: 21600
            	    Server-ID (54), length 4: 192.168.1.1
            

            Kea agreed for the requested IP : 192.168.1.254 - yours will be different.
            And see also the Option 43 proposal :

            Vendor-Option (43), length 6: 1.4.192.168.1.6
            

            and I presume this the 'encoded' ("1" for IPv4, "4" for 4bytes and 192.168.1.6 which is my controller IP.

            A even better test would be : instead of rebooting your AP, reset it with the button on the back.
            This will wipe all internal AP settings, and it should find all the correct settings when doing it's initial DHCP request.
            After a total reset, and an initial setup, it should show up in your controller like nothing happened.
            I didn't test this .....

            Be ware of the Plan B :
            Resolver settings, Host Overrides :
            Set :
            8393091b-8f3a-4c37-8705-8f3a4d8d7669-image.png

            If the DHCP method didn't work out, the DNS method is used : it searches for the "unifi" host name and uses that IP as the controller IP.

            No "help me" PM's please. Use the forum, the community will thank you.
            Edit : and where are the logs ??

            F G 2 Replies Last reply Reply Quote 0
            • F
              FCS001FCS @Gertjan
              last edited by

              @Gertjan said in Adding Custom Configuration in Kea DHCP Server with pfSense+ 25.03:

              Kea agreed for the requested IP : 192.168.1.254 - yours will be different.
              And see also the Option 43 proposal :

              Vendor-Option (43), length 6: 1.4.192.168.1.6

              Excellent, that worked great!

              I setup the packet capture as you detailed and ran it, then for good measure, unplugged and plugged the LAN RJ45 to the Flex-Mini Switch. In the packet capture I got exactly as you stated, the "Vendor Option (43)" but with the IP of my Unifi Network Controller.

              Thanks for the confirmation and I hope others going to KEA on pfSense CE 2.8 Beta can find this thread to also help them out.

              BTW, the Unifi USW Flex-Mini (old 1G version) is one of the only Unifi Switches that does not have SSH capability, so the DCHP Option 43 is the only way to set the "Inform" IP for an out of sub-network Unifi Controller. Just some info for others in the same situation as I am.

              GertjanG 1 Reply Last reply Reply Quote 0
              • GertjanG
                Gertjan @FCS001FCS
                last edited by

                @FCS001FCS said in Adding Custom Configuration in Kea DHCP Server with pfSense+ 25.03:

                that does not have SSH capability, so the DCHP Option 43 is the only way to set the "Inform" IP for an out of sub-network Unifi Controller

                If the " Flex-Mini Switch" doesn't have SSH ... not an issue.
                It probably still supports DNS.
                So it will request the "unifi" host name, thus finding your controller's IP. ... I guess.

                And thanks, I never thought about that : I've a "US 8 60W" POE 8 port switch myself, and it has an SSH access :

                US-8-60W-US.7.1.26# info
                
                Model:       US-8-60W
                Version:     7.1.26.15869
                MAC Address: d8:b3:70:83:49:88
                IP Address:  192.168.2.2
                Hostname:    US-8-60W
                Uptime:      6661215 seconds
                NTP:         Synchronized
                
                Status:      Connected (http://192.168.1.6:8080/inform)
                

                This switch and several AP live on the 192.168.2.0/24 network, my captive portal, and the Unifi controller is on the pfSense LAN, 192.168.1.6.
                I've also 3 Unifi APs on the 192.168.1.0/24 LAN network.

                No "help me" PM's please. Use the forum, the community will thank you.
                Edit : and where are the logs ??

                1 Reply Last reply Reply Quote 0
                • F
                  FCS001FCS
                  last edited by FCS001FCS

                  FYI - Just for confirmation, I factory reset the 2 USW Flex Mini Switches (White steady LED) to see if they would be available for adoption again in the Unifi Controller.

                  One showed up after some restarts of switches and pfSense and I could adopt it without removing it from the Unifi Network Controller (steady Blue LED).

                  The other switch would just not show up as adoptable in the Unifi Controller. I ended up removing that switch from the Controller and adopting it fresh. I had to re-setup the VLANs on that switch, but it was not much of an issue, as its a very simple setup.

                  I do not think it was a KEA issue, as I checked with the Packet Capture process and the DCHP Option 43 seemed to have been set in the switches, but the Controller just did not see it.

                  So, if someone else is in a similar situation, maybe a fresh start for the Unifi Controller may be the easiest approach, i.e. remove all old devices and see if they comeback for adoption as new devices.

                  Note: Your mileage may vary :)

                  All working now in my test setup, so happy days.

                  GertjanG 1 Reply Last reply Reply Quote 0
                  • GertjanG
                    Gertjan @FCS001FCS
                    last edited by

                    @FCS001FCS said in Adding Custom Configuration in Kea DHCP Server with pfSense+ 25.03:

                    One showed up after some restarts of switches ....

                    Note: Your mileage may vary :)

                    That's what I saw a while back when was learning how ti work with Unifi stuff.

                    New unifi devices - or unifi devices I've reset, can be hooked up to the networks and from then it is adoptable right way (reboot after a device 'button' reset take some time to get awake - or yo have to try again). Or, that's how I understood the procedure.
                    Didn't understand what was happening as one in a while this just fails ... the reset wasn't done good enough ?
                    I wanted to know, back then, if it was a hassle every time, or if I rally could add more 'unifi' stuff easily, create a situation where I can unbox the device, hook it, and wait for the "do you want to adopt the new device ?" controller message. I figured out that that would be the way to go : everything is set up in pfSense so I can add physically the new unifi device, set them up from the controller and call it a day. No need to get my phone, approach the device, have it point to a 'controller IP' etc.

                    No "help me" PM's please. Use the forum, the community will thank you.
                    Edit : and where are the logs ??

                    1 Reply Last reply Reply Quote 0
                    • P
                      pescew
                      last edited by

                      How can we define custom client-classes options? I tried this but seems to have no effect:

                      {
                          "client-classes": [
                              {
                                  "name": "UEFI-64-1-1",
                                  "test": "((substring(option[vendor-class-identifier].hex,0,20) == 'PXEClient:Arch:00007') and ((option[user-class].exists) and (substring(option[user-class].text,0,7) == 'iVentoy'))",
                                  "boot-file-name": "iventoy_loader_16000_uefi",
                                  "next-server": "172.26.2.18"
                              },
                              {
                                  "name": "UEFI-64-1-2",
                                  "test": "(substring(option[vendor-class-identifier].hex,0,20) == 'PXEClient:Arch:00007')",
                                  "boot-file-name": "efi64/syslinux.efi",
                                  "next-server": "172.26.2.19"
                              },
                              {
                                  "name": "Legacy",
                                  "test": "(substring(option[vendor-class-identifier].hex,0,20) == 'PXEClient:Arch:00000')",
                                  "boot-file-name": "pxelinux.0",
                                  "next-server": "172.26.2.19"
                              }
                          ]
                      }
                      
                      M 1 Reply Last reply Reply Quote 0
                      • M
                        marcosm Netgate @pescew
                        last edited by marcosm

                        @pescew The structure is correct. A quick test here shows there's an issue with the first item (seen in the DHCP logs). Removing it and keeping only "UEFI-64-1-2" and "Legacy" let's Kea start.

                        P 1 Reply Last reply Reply Quote 0
                        • P
                          pescew @marcosm
                          last edited by

                          @marcosm Thanks for the quick reply, I didn't realize that info was in the log. After cleaning up the parenthesis on that line it's working perfectly and PXE booting. I still need to troubleshoot the user-class rule to get the chain-loading working but that should be easy from here.

                          GertjanG 1 Reply Last reply Reply Quote 0
                          • GertjanG
                            Gertjan @pescew
                            last edited by

                            @pescew said in Adding Custom Configuration in Kea DHCP Server with pfSense+ 25.03:

                            After cleaning up the parenthesis

                            Yeah, more '(' then ')', that's normally not a good sign ๐Ÿ‘

                            "((substring(option[vendor-class-identifier].hex,0,20) == 'PXEClient:Arch:00007') and ((option[user-class].exists) and (substring(option[user-class].text,0,7) == 'iVentoy'))"
                            

                            No "help me" PM's please. Use the forum, the community will thank you.
                            Edit : and where are the logs ??

                            1 Reply Last reply Reply Quote 0
                            • G
                              Garet Jax @Gertjan
                              last edited by

                              @Gertjan Thank you brother. All you suggestions worked great. I joined the forums just to tell you so.

                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post
                              Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.