jaredhendrickson13 / pfsense-api

The missing REST API package for pfSense
https://pfrest.org/
Apache License 2.0
669 stars 101 forks source link

PHP Fatal error on dhcpd update #488

Open cspoonerprice opened 2 months ago

cspoonerprice commented 2 months ago

Describe the bug Error and Crash when updating DHCPd. Seems to be reproducible on demand. It actually succeeds in the update and the configuration is applied, but the error/crash still occur. Here's the crash report:

Crash report begins. Anonymous machine information:

amd64 14.0-CURRENT FreeBSD 14.0-CURRENT amd64 1400094 #1 RELENG_2_7_2-n255948-8d2b56da39c: Wed Dec 6 20:45:47 UTC 2023 root@freebsd:/var/jenkins/workspace/pfSense-CE-snapshots-2_7_2-main/obj/amd64/StdASW5b/var/jenkins/workspace/pfSense-CE-snapshots-2_7_2-main/sources/F

Crash report details:

PHP Errors: [25-Jun-2024 10:37:59 Etc/UTC] PHP Fatal error: Uncaught TypeError: Unsupported operand types: int - string in /etc/inc/api/framework/APITools.inc:1042 Stack trace:

0 /etc/inc/api/models/APIServicesDHCPdUpdate.inc(97): APITools\is_ipv4_in_cidr(3232240740, 'dhcp/')

1 /etc/inc/api/models/APIServicesDHCPdUpdate.inc(40): APIServicesDHCPdUpdate->__validate_range_from()

2 /etc/inc/api/framework/APIModel.inc(199): APIServicesDHCPdUpdate->validate_payload()

3 /etc/inc/api/framework/APIModel.inc(211): APIModel->validate()

4 /etc/inc/api/endpoints/APIServicesDHCPd.inc(28): APIModel->call()

5 /etc/inc/api/framework/APIEndpoint.inc(66): APIServicesDHCPd->put()

6 /usr/local/www/api/v1/services/dhcpd/index.php(3): APIEndpoint->listen()

7 {main}

thrown in /etc/inc/api/framework/APITools.inc on line 1042

No FreeBSD crash data found.

To Reproduce curl -X 'PUT' \ 'https:///api/v1/services/dhcpd' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "interface": "\<name>", "enable": true, "range_from": "192.168.2.100", "range_to": "192.168.2.200" }'

Expected behavior DHCP server is created/updated on the specified interface without a crash

Screenshots or Response See above crash report

pfSense Version & Package Version:

Affected Endpoints:

jaredhendrickson13 commented 2 months ago

I can't seem to reproduce this on a fresh install of pfSense 2.7.2 running API v1.7.4:

curl -k -u admin:pfsense -X PUT 'https://localhost/api/v1/services/dhcpd' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"interface": "lan","enable": true,"range_from": "192.168.1.100","range_to": "192.168.1.200"}'

{"status":"ok","code":200,"return":0,"message":"Success","data":{"enable":true,"range":{"from":"192.168.1.100","to":"192.168.1.200"}}}

I'm assuming you are also on the latest version of the API? If so, the error seems to suggest that request data is either becoming malformed or the stored values of the object you are updating is corrupt/unexpected. Can you provide the XML config of the DHCP server you're updating?

cspoonerprice commented 2 months ago

I should be on the latest API version: pfsense-api --version PHP 8.2.11 (cli) (built: Nov 29 2023 06:03:46) (NTS) Copyright (c) The PHP Group Zend Engine v4.2.11, Copyright (c) Zend Technologies with Zend OPcache v8.2.11, Copyright (c), by Zend Technologies

pkg info | grep -i pfsense-pkg-api pfSense-pkg-API-1.7_4 pfSense API package

XML Config: dhcpd.txt

Full disclosure, I'm a noob and could be doing something very stupid. Apologies if I'm wasting time.

jaredhendrickson13 commented 2 months ago

Hmm doesn't seem like you're doing anything wrong here. Your API call and config look fine to me. Let's do some debugging:

  1. On pfSense, install the debug version of the dhcpd update model I just pushed. Feel free to review the debug changes beforehand if it's a concern:
    curl -o /etc/inc/api/models/APIServicesDHCPdUpdate.inc https://raw.githubusercontent.com/jaredhendrickson13/pfsense-api/debug/pfSense-pkg-API/files/etc/inc/api/models/APIServicesDHCPdUpdate.inc
  2. Run your API call again.
  3. Provide the contents of /tmp/dhcpd_update_debug.log. This should contain your request data as it's interpreted by PHP at various stages.
  4. Restore the model back to the normal v1.7.4 version:
    curl -o /etc/inc/api/models/APIServicesDHCPdUpdate.inc https://raw.githubusercontent.com/jaredhendrickson13/pfsense-api/v1.7.4/pfSense-pkg-API/files/etc/inc/api/models/APIServicesDHCPdUpdate.inc
cspoonerprice commented 2 months ago

dhcpd_update_debug.log

Sorry for the delay, took a bit for security to let this through (aka, I went on vacation)

jaredhendrickson13 commented 2 months ago

No worries, thanks for providing that. What does your opt2 interface's configuration look like? The error suggests its IP assignment is via DHCP and does not have a static IPv4 address.

cspoonerprice commented 2 months ago

Only dhcp interface is WAN. interface.txt

jaredhendrickson13 commented 1 month ago

The behavior here is very strange because the line that causes the error is stating that the interface's ipaddr value is currently set to dhcp:

#0 /etc/inc/api/models/APIServicesDHCPdUpdate.inc(97): APITools\is_ipv4_in_cidr(3232240740, 'dhcp/')

But the endpoint does checks beforehand on the provided interface to ensure the interface has a static IPv4, which would return an error if it's ipaddr was really dhcp:

https://github.com/jaredhendrickson13/pfsense-api/blob/5db64cd7be7d236a0b5cd840a1768058e1b42d84/pfSense-pkg-API/files/etc/inc/api/models/APIServicesDHCPdUpdate.inc#L63-L64


I'd like to do a little more debugging if you don't mind:

  1. On pfSense, install the revised debug version of the dhcpd update model I just pushed. Feel free to review the debug changes beforehand again if it's a concern:
    curl -o /etc/inc/api/models/APIServicesDHCPdUpdate.inc https://raw.githubusercontent.com/jaredhendrickson13/pfsense-api/debug/pfSense-pkg-API/files/etc/inc/api/models/APIServicesDHCPdUpdate.inc
  2. Run your API call again.
  3. Provide the contents of /tmp/dhcpd_update_debug.log. This time it should contain the interface configuration seen throughout various stages of the API call
  4. Restore the model back to the original version:
    curl -o /etc/inc/api/models/APIServicesDHCPdUpdate.inc https://raw.githubusercontent.com/jaredhendrickson13/pfsense-api/v1.7.4/pfSense-pkg-API/files/etc/inc/api/models/APIServicesDHCPdUpdate.inc

Hopefully this will provide some better insight into what's happening here.

cspoonerprice commented 1 month ago

Don't think this'll help :(

# cat /tmp/dhcpd_update_debug.log before_if_check: {"descr":"test","if":"vtnet3","enable":"","spoofmac":"","ipaddr":"192.168.3.1","subnet":"24"} after_if_check: {"descr":"test","if":"vtnet3","enable":"","spoofmac":"","ipaddr":"192.168.3.1","subnet":"24"} before_ipv4_in_cidr: {"descr":"test","if":"vtnet3","enable":"","spoofmac":"","ipaddr":"192.168.3.1","subnet":"24"}

jaredhendrickson13 commented 1 month ago

Hmm yeah that's definitely not what I was hoping for. From everything I'm seeing there is no reason this error should be being thrown here and so far I still haven't been able to reproduce the issue. It's possible there's a bigger problem with the PHP environment or your pfSense instance. There are a few things you can try if you haven't already:

  1. Try to restart both the web GUI and PHP-FPM on your pfSense instance: /etc/rc.restart_webgui && /etc/rc.php-fpm_restart. Then retry the request.
  2. Try rebooting pfSense and see if the problem persists afterward.
  3. Try to reproduce the issue on a different pfSense system if possible.
  4. If you're able, backup your pfSense configuration and restore it to the default. Then restore your config, install the API, and try the request again.
  5. Worst case scenario, you could try doing a fresh install of pfSense and slowly reintroduce your configuration. Try the request at various points throughout the process and see if anything suddenly changes.
cspoonerprice commented 1 month ago

Figured it out. I had the interface incorrect and was pointing to the WAN, which although is set to dhcp on the backend, isn't actually dhcp and can't be enabled/changed.

I'd say it is a bug however, that the call would return a 200. I'd expect it to error out gracefully, or at least complain about it.