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

Custom DHCP script

Scheduled Pinned Locked Moved DHCP and DNS
dhcpexecute
5 Posts 2 Posters 746 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.
  • S
    Slyke
    last edited by Slyke Jun 25, 2023, 11:17 AM Jun 25, 2023, 11:17 AM

    Hello, I have created the following script:

    /usr/local/etc/rc.d/dhcpdoverride.sh file:

    #/bin/bash
    killall -3 dhcpd
    cat /var/dhcpd/etc/dhcpd.conf.ext >> /var/dhcpd/etc/dhcpd.conf
    # Run: 'ps axww | grep dhcpd' to get /var/run/dhcpd.pid args
    /usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot /var/dhcpd -cf /etc/dhcpd.conf -pf /var/run/dhcpd.pid igb1
    

    In the /var/dhcpd/etc/dhcpd.conf.ext file I have:

    on commit {
      set clip = binary-to-ascii(10, 8, ".", leased-address);
      set clhw = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
      execute("/etc/dhcp_update.sh", "commit", clip, clhw);
    }
    
    on expiry {
      set clip = binary-to-ascii(10, 8, ".", leased-address);
      set clhw = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
      execute("/etc/dhcp_update.sh", "expiry", clip, clhw);
    }
    
    on release {
      set clip = binary-to-ascii(10, 8, ".", leased-address);
      set clhw = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6));
      execute("/etc/dhcp_update.sh", "release", clip, clhw);
    }
    

    This should execute the script every time one of those events is fired.

    AFAIK dhcpd is chrooted, so the path /etc/dhcp_update.sh should be used, but I also tried /var/dhcpd/etc/dhcp_update.sh just in case.

    However, I'm getting the following errors in dhcpd logs for both paths:

    Jun 25 02:56:14	dhcpd	90788	execute_statement argv[0] = /etc/dhcp_update.sh
    Jun 25 02:56:14	dhcpd	90788	execute_statement argv[1] = commit
    Jun 25 02:56:14	dhcpd	90788	execute_statement argv[2] = 10.1.1.123
    Jun 25 02:56:14	dhcpd	90788	execute_statement argv[3] = XX:XX:XX:XX:XX:XX
    Jun 25 02:56:14	dhcpd	23476	Unable to execute /etc/dhcp_update.sh: No such file or directory
    Jun 25 02:56:14	dhcpd	90788	execute: /etc/dhcp_update.sh exit status 32512
    

    I have run chmod +x /var/dhcpd/etc/dhcp_update.sh from the webui, as I was getting permission denied errors before that.

    I believe the error code 32512 is actually -127, but something funky is happening when reporting it.

    S 1 Reply Last reply Jun 25, 2023, 7:40 PM Reply Quote 0
    • S
      Slyke @Slyke
      last edited by Jun 25, 2023, 7:40 PM

      I think there is something wrong with dhcp. I tried using ls and /bin/ls and got the same error:

        execute("/bin/pwd");
        execute("/bin/ls");
      

      Returned:

      Jun 25 12:38:21	dhcpd	76036	execute_statement argv[0] = /bin/pwd
      Jun 25 12:38:21	dhcpd	86801	Unable to execute /bin/pwd: No such file or directory
      Jun 25 12:38:21	dhcpd	76036	execute: /bin/pwd exit status 32512
      Jun 25 12:38:21	dhcpd	76036	execute_statement argv[0] = /bin/ls
      Jun 25 12:38:21	dhcpd	87045	Unable to execute /bin/ls: No such file or directory
      Jun 25 12:38:21	dhcpd	76036	execute: /bin/ls exit status 32512
      
      B 1 Reply Last reply Jun 25, 2023, 11:24 PM Reply Quote 0
      • B
        bmeeks @Slyke
        last edited by bmeeks Jun 25, 2023, 11:28 PM Jun 25, 2023, 11:24 PM

        @Slyke said in Custom DHCP script:

        I think there is something wrong with dhcp. I tried using ls and /bin/ls and got the same error:

          execute("/bin/pwd");
          execute("/bin/ls");
        

        Returned:

        Jun 25 12:38:21	dhcpd	76036	execute_statement argv[0] = /bin/pwd
        Jun 25 12:38:21	dhcpd	86801	Unable to execute /bin/pwd: No such file or directory
        Jun 25 12:38:21	dhcpd	76036	execute: /bin/pwd exit status 32512
        Jun 25 12:38:21	dhcpd	76036	execute_statement argv[0] = /bin/ls
        Jun 25 12:38:21	dhcpd	87045	Unable to execute /bin/ls: No such file or directory
        Jun 25 12:38:21	dhcpd	76036	execute: /bin/ls exit status 32512
        

        I am pretty sure the dhcpd daemon on pfSense runs in a chroot environment and possibly even a FreeBSD jail. That means certain binary utilities that are present on the main pfSense image will not be present and available for the chroot or jail clients.

        If you are not familiar with the concept of jails, here is the official FreeBSD documentation: https://docs.freebsd.org/en/books/handbook/jails/. Jails are essentially isolated environments that have the minimum files and permissions needed for the particular binary the jail was created for to execute and perform its assigned tasks.

        S 2 Replies Last reply Jun 26, 2023, 4:47 AM Reply Quote 1
        • S
          Slyke @bmeeks
          last edited by Slyke Jun 26, 2023, 4:47 AM Jun 26, 2023, 4:47 AM

          @bmeeks Ah, that makes sense. I'm reading up on it now. Essentially what I'm trying to do is send a GET request when a client connects or disconnects to the network (using DHCP events). I'm just parsing the args and attempting to send a wget/curl command in the /etc/dhcp_update.sh script.

          Is there an easier way to do this while keeping dhcpd chrooted still? Or is there an easy way to add bash and/or curl to the process' chrooted environment? Or should I write some executable in c/c++ and send it that way? Not sure what's the easiest way to achieve this task, and the more I'm digging, the more complex and fragile the solution seems to become.

          1 Reply Last reply Reply Quote 0
          • S
            Slyke @bmeeks
            last edited by Jun 26, 2023, 5:08 AM

            @bmeeks I solved it by copying both the curl and sh binaries into the chrooted folder and specifying the path to them directly:

            mkdir -p /var/dhcpd/bin
            mkdir -p /var/dhcpd/usr/local/bin
            
            cp /bin/bash /var/dhcpd/bin/
            cp /usr/local/bin/curl /var/dhcpd/usr/local/bin/
            

            Then in my /var/dhcpd/etc/dhcp_update.sh script:

            #!/bin/sh
            
            BASE_URL="http://your-web-server.com/your-endpoint"
            
            EVENT_TYPE="$1"
            IP_ADDRESS="$2"
            MAC_ADDRESS="$3"
            
            case "$EVENT_TYPE" in
              "1")
                ONLINE_STATE="online"
                ;;
              "2"|"3")
                ONLINE_STATE="offline"
                ;;
              *)
                ONLINE_STATE="unknown"
                ;;
            esac
            
            URL="${BASE_URL}?ip=${IP_ADDRESS}&mac=${MAC_ADDRESS}&state=${ONLINE_STATE}&event=${EVENT_TYPE}"
            echo "DHCP Announce: $URL"
            
            /usr/local/bin/curl -X GET "$URL"
            

            It aborted with exit code 6, which means that cURL couldn't resolve the hostname (good news!). I still haven't tested this with my proper endpoint, but I think it will work now.

            1 Reply Last reply Reply Quote 0
            5 out of 5
            • First post
              5/5
              Last post
            Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.
              This community forum collects and processes your personal information.
              consent.not_received