<#25 Restart osctrld on every platform> Pull reque...
# osctrl
g
#25 Restart osctrld on every platform Pull request opened by javuto Restart osqueryd on every platform, run the service as root, harden extensions and HTTP Two changes, one per repo, make an operator's flag edits in osctrl reach osquery on every node. jmpsec/osctrl#1089 makes the server serve the flags operators actually edit. This PR makes osctrld apply them on every platform: it writes the flagfile and restarts osqueryd. It builds on #24, which aligned osctrld's requests with the current server. Server side: jmpsec/osctrl#1089 Before #1089, osctrl's osctrld endpoints served a freshly generated default flag set, so an operator's edits to an environment's flags never reached nodes managed by osctrld. •
FlagsHandler
and
VerifyHandler
now use the new
NodeFlags
. It serves the environment's stored, operator-edited flags with the secret and certificate paths filled in. Environments with no stored flags still get the generated defaults. •
FillFlagPaths
is shared.
It replaces
__SECRET_FILE__
and `__CERT_FILE__`; an empty path keeps its placeholder, the same as the generated flags. osctrl-api's per-platform flag substitution now uses it too. • Verify compares against the same flags the flags endpoint serves, so osctrld's
verify
no longer reports a mismatch against defaults nobody deployed. •
osctrld_flags_test.go
covers four cases: stored flags are served with paths filled, placeholders are kept when no paths are given, generated flags are the fallback when nothing is stored, and a wrong secret is rejected. Client side: this PR (osctrld) Problems • Linux restart only tried
systemctl
, so hosts without systemd never applied new flags. • Windows restart wasn't implemented, even though
install
already managed the service through the Windows service manager. • The packaged systemd unit never started. It required
/opt/osctrld
, but the deb, rpm and apk packages install to
/usr/bin/osctrld
. • The unit ran as
User=osctrld
, which can't write
/etc/osquery
or restart osqueryd, the daemon's whole job. • The macOS plist shipped with
/path/to/
placeholders.
• Extension names went unchecked into
filepath.Join
, so a manifest entry named
../x
could write anywhere the daemon can. • HTTP requests had no timeout, so a server that never answered hung the service loop forever. Changes • Restart: • Linux tries
systemctl
, then
service
, then
/etc/init.d/osqueryd
, the same chain
install
uses for stop and start. • Windows stops the service, waits until it has stopped, then starts it. • macOS is unchanged. • Extensions: a manifest entry must be a plain file name. Others are logged and skipped, and the rest still install. • HTTP: a 10-minute timeout per request, body included. It's that long because the same client downloads osquery packages of around 100 MB. • systemd unit: runs
/usr/bin/osctrld
as root after
network-online.target
, and logs to journald. • macOS plist: runs
/usr/local/bin/osctrld
and logs to
/var/log/osctrld.log
. • Packaging and README:
/etc/osctrld/osctrld.yaml
is installed
0600
, since it holds the osctrl secret. The README install steps match the packaged paths. Security and operational impact • Root: osctrld runs as root under systemd. It already needed equivalent privileges on macOS and Windows. • Path traversal: extension names can no longer write outside the extensions directory. • Manual installs: hosts installed to
/opt/osctrld
per the old README must move the binary to
/usr/bin/osctrld
or edit the unit. • Restart behaviour: Windows hosts and hosts without systemd now restart osqueryd when the flags, certificate or extensions change. Before, the restart failed and logged an error. Validation • `go test ./cmd/osctrld/ -race`: all 109 tests ran, 0 failures •
go vet
and
golangci-lint run ./...
for
GOOS=darwin
,
linux
and `windows`: clean, 0 issues •
plutil -lint
on the plist: OK • New tests: •
TestOsqueryRestartCandidates
,
TestRestartOsqueryDarwin
,
TestSyncExtensions_RejectsNamesOutsideTheDirectory
and
TestSendRequestTimesOut
pass. •
TestRestartOsqueryFallsBackWithoutSystemd
is Linux-only; it runs in CI on
ubuntu-latest
and skips on macOS. • `goreleaser check`: the config is valid. The check still fails on the existing
brews
deprecation, which this PR doesn't touch. jmpsec/osctrld