rc.d: use absolute path for python3 in maltrailsensor + maltrailserver#5466
Merged
fichtner merged 1 commit intoJun 1, 2026
Merged
Conversation
service(8) invokes rc.d scripts with PATH=/sbin:/bin:/usr/sbin:/usr/bin
via `env -i`, which does not include /usr/local/bin where python3 lives.
daemon(8)'s execvp("python3") ENOENTs all four PATH entries and the
supervisor exits silently after the pre-detach parent has already
returned 0 to rc.subr. Net result: service start exits 0 with nothing
running, and boot-time autostart is broken when maltrailsensor_enable=YES.
Use absolute path /usr/local/bin/python3 to bypass the PATH lookup,
matching the convention used by other OPNsense plugin rc.d scripts
(stunnel, ddclient, tinc, openconnect).
Validated on OPNsense 26.4 / FreeBSD 14.3-RELEASE-p12 across
3 start/stop cycles + truss re-trace + full cold-start reboot.
Member
|
Merged, thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
service opnsense-maltrailsensor startfails silently on a stock OPNsense install: the command exits 0, printsStarting maltrailsensor., but nosensor.pyprocess is left running, no pidfile is written, and no log entry is produced. The same failure mode affectsopnsense-maltrailserver. The GUI Save path (System → Services → Maltrail → Sensor → Enabled → Apply) appears to work the first time, then subsequentservice startattempts fail — masking the underlying bug.Reproduction
On OPNsense 26.4 / FreeBSD 14.3-RELEASE-p12 with
os-maltrail-1.10_1:Root cause
The rc.d script passes
python3as a bare name todaemon(8):command_args="-f -P /var/run/maltrailsensor.pid python3 /usr/local/share/maltrail/sensor.py"daemon(8)callsexecvp("python3", ...)after its double-fork detach (FreeBSDdaemon.cstable/14 line 366), which performs a PATH search. When the rc.d is invoked viaservice(8), the PATH is reset narrow perservice.shstable/14 lines 196/198:env -iclears the inherited environment, then PATH is set to exactly four directories — none of which containpython3(which lives at/usr/local/bin/python3on a standard FreeBSD/OPNsense install). All fourexecvplookups ENOENT, the daemon supervisor writes its error to an internal pipe that never reaches syslog, the supervisor exits 1, but rc.subr's_doitalready returned 0 from the pre-detach parent. Net: exit 0, nothing running.service(8)man page (verbatim):This means the bug also breaks boot-time startup when
maltrailsensor_enable="YES"— the rc system at boot uses the same narrow PATH.Why the GUI Save path appeared to work
The GUI Save → Apply flow dispatches via
configd, which sets a wider PATH fromconfigd.conf [environment]:configd.pyreplaces the child process environment entirely (subprocess.run(..., env=self.config_environment)), so the same rc.d script invoked viaconfigctl maltrailsensor startsees/usr/local/binon PATH andexecvp("python3")resolves correctly. Different invoker, different PATH, same script.Syscall-level evidence
truss -fon a failingservice opnsense-maltrailsensor start(captured during local investigation):The four ENOENT paths match
service(8)'s PATH literal byte-for-byte.Project convention
Peer OPNsense plugins consistently use absolute paths to
/usr/local/-installed binaries in their rc.d scripts. The twoos-maltrailrc.d files are outliers:security/maltrailopnsense-maltrailsensorpython3incommand_argssecurity/maltrailopnsense-maltrailserverpython3incommand_argssecurity/stunnelidentd_stunnelcommand_interpreter=/usr/local/bin/python3dns/ddclientddclient_opncommand_interpreter=/usr/local/bin/python3security/tincopnsense-tincdstart_cmdsecurity/openconnectopnsense-openconnect/usr/local/sbin/openconnectFreeBSD's own rc-scripting guide (rc-scripting article §5) demonstrates the canonical pattern as absolute path:
command="/usr/sbin/${name}"Fix
One-line change in each of the two rc.d scripts: replace bare
python3with/usr/local/bin/python3incommand_args.security/maltrail/src/etc/rc.d/opnsense-maltrailsensorsecurity/maltrail/src/etc/rc.d/opnsense-maltrailserverNo other lines change. No behavioural change to
rcvar,pidfile,command, or any rc.subr defaults.Validation
Local fix applied on a test OPNsense 26.4 / FreeBSD 14.3-RELEASE-p12 host running
os-maltrail-1.10_1:Runtime validation (3/3 start/stop cycles passed):
service startexitservice stopexittrussre-trace of fixed path: 0 ENOENT for python3 (vs 4 in original failing trace).service statusworks correctly under default rc.subr behaviour (pidfile-direct verification).service opnsense-maltrailsensor start/stop3× completed without failure post-fix (had failed every attempt pre-fix).Boot-time validation — full cold-start reboot test:
A separate persistence test was run after the runtime fix had been validated: full OS reboot via
shutdown -r now, then post-boot inspection to confirm the rc system at boot correctly auto-starts the sensor viamaltrailsensor_enable="YES". Results from one reboot cycle:pgrep -f maltrail/sensor.pyshowed the daemon-supervised parent + worker children running./var/run/maltrailsensor.pidwas present with valid PID (the daemon supervisor PID).service opnsense-maltrailsensor statusreturnedis running as pid Nwith exit 0./var/log/maltrail/error.loghad no SIGTERM or execvp errors from the boot window.This empirically confirms the fix repairs boot-time autostart, not just runtime
service startinvocations. Without the fix, the rc system's narrow PATH at boot triggers the same silent failure as the runtimeservicepath.Compatibility / risk
/usr/local/bin/python3resolves on PATH (which is the post-fix configd path). The new line still invokes the same interpreter.name,rcvar,pidfile,command).config.xmlschema or any plugin templates.maltrailsensor_enable="YES"(previously broken by the same narrow PATH from/etc/rc). Empirically validated via full cold-start reboot test.opnsense-maltrailserverhas the identical bug and is fixed in the same PR.Files changed
References
service.shstable/14 lines 196/198 — narrow PATH set viaenv -i: https://github.com/freebsd/freebsd-src/blob/stable/14/usr.sbin/service/service.shdaemon.cstable/14 line 366 —execvpPATH-search call: https://github.com/freebsd/freebsd-src/blob/stable/14/usr.sbin/daemon/daemon.crc.subrstable/14 — does NOT modify PATH: https://github.com/freebsd/freebsd-src/blob/stable/14/libexec/rc/rc.subrconfigd.confwide-PATH environment section (explains GUI-only success): https://github.com/opnsense/core/blob/master/src/opnsense/service/conf/configd.conf