App-OpenHAP
view release on metacpan or search on metacpan
man/openhap/openhapd.8 view on Meta::CPAN
.Pp
Nothing exits from inside the signal handler, thus a connection is
never dropped in the middle of a response.
.It Dv SIGHUP
Reload.
The daemon opens its log again and keeps serving.
Use this after
.Xr newsyslog 8
rotates
.Pa /var/log/openhapd.log .
.Pp
.Cm rcctl reload openhapd
sends this signal.
In releases before 2026 the signal ended the daemon, which is the
opposite of a reload.
.El
.Pp
The daemon does not remove
.Pa /var/run/openhapd.pid
at exit.
See
.Sx FILES .
.Sh EXAMPLES
Do a check of the configuration file:
.Bd -literal -offset indent
# openhapd -n
.Ed
.Pp
Run in the foreground with verbose logging:
.Bd -literal -offset indent
# openhapd -f -v
.Ed
.Pp
Start the daemon the usual way, through
.Xr rc 8 :
.Bd -literal -offset indent
# rcctl enable openhapd
# rcctl start openhapd
.Ed
.Sh DIAGNOSTICS
.Nm
logs to
.Xr syslog 3
with the
.Dq daemon
facility.
When the daemon runs in the foreground with
.Fl f ,
it writes the messages to
.Em stderr .
.Pp
These are some of the log messages:
.Bl -tag -width "Not pairedXX"
.It Dq Starting OpenHAP server
The daemon started correctly and now listens for connections.
.It Dq Not paired - use Home app with PIN: XXX-XX-XXX
The accessory is not paired with a HomeKit controller.
Use the PIN from the message to pair through the iOS Home app.
.It Dq Connected to MQTT broker at host:port
The daemon connected to the MQTT broker.
.It Dq MQTT broker not available, will retry in background
The daemon did not connect to the MQTT broker at startup.
.Nm
continues to try to connect in the background.
.It Dq Paired with controller: identifier
The pairing with a new HomeKit controller was successful.
.It Dq Secure session established
The daemon started an encrypted session with a paired controller.
.El
.Pp
A configuration file that does not parse is a fatal error.
.Nm
writes the file, the line number, and the reason to
.Em stderr ,
and it exits 1 before it opens the log:
.Bd -literal -offset indent
/etc/openhapd.conf:14: cannot parse: hap_prt 51827
.Ed
.Pp
The daemon does not fall back to the defaults, because the operator
did not choose them.
Use
.Fl n
to check a file before you restart the daemon.
.Sh SEE ALSO
.Xr syslog 3 ,
.Xr openhapd.conf 5 ,
.Xr hapctl 8 ,
.Xr mdnsd 8 ,
.Xr rc 8 ,
.Xr rc.conf 8
.Pp
HomeKit Accessory Protocol Specification (Non-Commercial Version):
.Lk https://developer.apple.com/homekit/
.Sh STANDARDS
.Nm
obeys the HomeKit Accessory Protocol Specification R2 for IP
accessories.
These documents specify the cryptography that it uses:
.Bl -bullet -compact
.It
RFC 5054: Using the Secure Remote Password (SRP) Protocol for TLS Authentication
.It
RFC 7539: ChaCha20 and Poly1305 for IETF Protocols
.It
RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
.It
RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA)
.It
RFC 7748: Elliptic Curves for Security (Curve25519)
.El
.Sh HISTORY
The
.Nm
daemon was first available in 2025.
.Sh AUTHORS
.An Dick Olsson Aq Mt hi@senzilla.io
.Sh CAVEATS
For correct operation,
.Nm
needs an MQTT broker, for example,
.Xr mosquitto 8 ,
and
.Xr mdnsd 8 .
Both must run.
If one of them is not available, the daemon starts and does what it
can.
The daemon tries the MQTT connection again in the background.
The mDNS discovery is not available until you restart the daemon.
.Pp
At the first startup, if the accessory is not paired, the daemon
writes the HAP PIN code to the log.
Thus, limit the access to the system logs.
.Pp
The pairing data in
.Pa /var/db/openhapd/
holds cryptographic keys.
The owner of the directory must be
.Dq _openhap ,
and the mode must be 0700.
.Sh BUGS
.Nm
operates only with Tasmota devices over MQTT.
It does not implement HAP over Bluetooth Low Energy.
.Sh SECURITY CONSIDERATIONS
.Nm
starts as root to set the correct ownership of
.Pa /var/db/openhapd .
Then it drops to the
.Dq _openhap
user and publishes its mDNS advertisement.
Then it restricts itself:
first the filesystem view with
.Xr unveil 2 ,
and then the syscall surface with
.Xr pledge 2 .
The daemon accepts network connections only after these steps.
.Pp
Because the restrictions come after the privilege drop, they apply to
all code that receives untrusted input.
They do not, and cannot, apply to the short root phase.
But that phase receives no untrusted input.
.Pp
The promise set is
.Dq stdio rpath wpath cpath fattr flock inet dns unix :
.Bl -tag -width "wpath cpathXX" -compact
.It Cm stdio
always necessary.
.It Cm rpath
.Pa /dev/urandom ,
state reads, and the MQTT module that the daemon loads late.
.It Cm wpath , cpath
to write, create, and remove the state files and the daemon log.
.It Cm fattr
the daemon sets the mode of the key material to 0600.
.It Cm flock
locks protect the state files.
.It Cm inet
the HAP listener and the MQTT connections.
.It Cm dns
to resolve
.Cm mqtt_host
when it is a name.
.It Cm unix
after a pairing change, the daemon makes a new connection to
.Xr mdnsd 8
to advertise again.
.El
( run in 1.457 second using v1.01-cache-2.11-cpan-0fb53d1c279 )