Files
mototrbo/docs/tls-setup.md
William Gill 81c62ac012
Some checks failed
ci / test (ubuntu-latest) (push) Failing after 47s
ci / test (windows-latest) (push) Has been cancelled
ci / lint (push) Has been cancelled
Initial commit
2026-04-08 08:56:45 -05:00

3.3 KiB

mTLS setup

mototrbod requires mutual TLS for both gRPC and (by default) the REST API. This document walks through generating a small private CA, issuing a server cert for the daemon, and issuing a client cert for each Linux host that needs to talk to it. Everything below uses the OpenSSL CLI; nothing else is required.

The CA you create here is only trusted by your own daemon and clients. Do not put it in any system trust store.

1. Create the CA

mkdir -p tls && cd tls

openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
  -subj "/CN=mototrbo-ca" \
  -out ca.crt

Keep ca.key offline / on the daemon host only. ca.crt is the public bundle every client and the server will pin.

2. Issue the server certificate

Replace mototrbo.lan with whatever DNS name (or IP SAN) the clients will use to reach the daemon.

cat > server.cnf <<'EOF'
[req]
distinguished_name = dn
req_extensions = ext
prompt = no

[dn]
CN = mototrbo.lan

[ext]
subjectAltName = @alt
extendedKeyUsage = serverAuth

[alt]
DNS.1 = mototrbo.lan
IP.1  = 192.168.1.10
EOF

openssl genrsa -out server.key 4096
openssl req -new -key server.key -out server.csr -config server.cnf
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 825 -sha256 -extfile server.cnf -extensions ext

Files used by the daemon:

  • server.crt--tls-cert
  • server.key--tls-key
  • ca.crt--tls-client-ca

3. Issue a client certificate

Run this once per Linux host (or per user). The CN ends up in the client cert and is what shows up in audit logs if you add them later.

cat > client.cnf <<'EOF'
[req]
distinguished_name = dn
req_extensions = ext
prompt = no

[dn]
CN = laptop-eddie

[ext]
extendedKeyUsage = clientAuth
EOF

openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr -config client.cnf
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out client.crt -days 825 -sha256 -extfile client.cnf -extensions ext

Copy client.crt, client.key, and ca.crt to the client host. The CA's private key (ca.key) must never leave the daemon host.

4. Run the daemon

mototrbod.exe `
  --bind-ip 192.168.1.10 `
  --data-dir C:\ProgramData\mototrbo\badger `
  --grpc-addr :50051 `
  --rest-addr :8443 `
  --tls-cert  C:\ProgramData\mototrbo\tls\server.crt `
  --tls-key   C:\ProgramData\mototrbo\tls\server.key `
  --tls-client-ca C:\ProgramData\mototrbo\tls\ca.crt `
  --ntfy-topic radio-tms-bridge

For local debugging you can serve REST over plain HTTP on loopback by adding --rest-addr 127.0.0.1:8080 --rest-plain-http. gRPC always requires mTLS.

5. Use the CLI

mototrboctl \
  --addr mototrbo.lan:50051 \
  --ca   ./tls/ca.crt \
  --cert ./tls/client.crt \
  --key  ./tls/client.key \
  send-text 24044 "hello from linux"

6. Rotation

Server and client certs are issued for 825 days (the longest most TLS implementations still accept). When a cert is approaching expiry, re-run the matching step in this document; nothing on the daemon side needs to be re-bootstrapped as long as the CA does not change.

To revoke a client, simply remove its key material — there is no CRL or OCSP responder. If you need actual revocation, regenerate the CA and re-issue every cert.