Set Up a TLS-Protected sudo_logsrvd Server

A sudo I/O log can hold a typed password, so run sudo_logsrvd without TLS and you have built a network sniffer's dream. This guide gets you a log server configuration that listens for clients over TLS, stores I/O logs with restrictive permissions, and writes event logs to a file. The examples match sudo 1.9.15p5, installed here as Ubuntu package 1.9.15p5-3ubuntu5.24.04.3. Allow 30 to 60 minutes if you already have certificates, or longer if you must create and distribute them.

Before you start

You need root access on the log host, a DNS name that clients can resolve, and a server certificate whose name matches that host. You also need a CA bundle that clients trust. The log stream can contain terminal input and passwords, so do not use the plaintext listener on an untrusted network.

This guide configures the server side only. Each sudo client still needs its own sudoers logging configuration and client certificate settings, which are outside these two manpages. Do not copy the example certificate paths until the files exist and their ownership and permissions have been checked.

Checkpoint: Confirm the installed version and the command paths before changing configuration.

$ sudo_logsrvd -V
sudo_logsrvd version 1.9.15p5
$ dpkg-query -W -f='${Package} ${Version}\n' sudo
sudo 1.9.15p5-3ubuntu5.24.04.3

1. Create a working configuration copy

The default file is /etc/sudo_logsrvd.conf. Make a backup before editing it, then open the file as root.

# cp -p /etc/sudo_logsrvd.conf /etc/sudo_logsrvd.conf.backup
# sudoedit /etc/sudo_logsrvd.conf

The format is INI-style. Section and key names are case-insensitive, values are not. A hash starts a comment, and a backslash at the end of a line continues it. The recognised sections are server, relay, iolog, eventlog, syslog and logfile.

2. Bind a TLS listener

Start with one explicit TLS listener rather than accepting the defaults on every interface. The port is an example; choose one allowed by your firewall and client configuration.

[server]
listen_address = logs.example.invalid:30344(tls)
server_log = syslog
pid_file = /run/sudo/sudo_logsrvd.pid
timeout = 30
tls_verify = true
tls_checkpeer = true
tls_cacert = /etc/ssl/sudo/cacert.pem
tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem
tls_key = /etc/ssl/sudo/private/logsrvd_key.pem

Replace logs.example.invalid and every certificate path with real values. With no port, plaintext uses 30343 and TLS uses 30344. The documented default listens on all interfaces for both ports, so an uncommented default can expose a plaintext endpoint by accident. TLS 1.2 and 1.3 are supported; older TLS versions are not.

tls_checkpeer = true makes the server require a valid client certificate. That gives you mutual TLS, but clients without certificates signed by the CA in tls_cacert will be rejected. If you are deliberately using one-way TLS while commissioning the service, set it to false only with a clear plan to turn peer checking back on.

Security warning: The private key is equivalent to the server's identity. Keep it readable only by the account that starts the daemon, and do not paste it into tickets, shell history or log output.

3. Choose where logs are stored

The server stores I/O logs below /var/log/sudo-io by default. Set the mode explicitly so a later package or local default change does not widen access.

[iolog]
iolog_dir = /var/log/sudo-io
iolog_file = %{seq}
iolog_mode = 0600
iolog_user = root
iolog_group = root
iolog_flush = true
iolog_compress = false
log_passwords = false
passprompt_regex = [Pp]assword[: ]*

The %{seq} value is a monotonically increasing base-36 sequence, distributed into directory components. Other supported escapes include %{user}, %{runas_user}, %{hostname} and %{command}. The server creates files with owner read and write permission even if the configured mode omits them. New directories receive matching search permissions.

Checkpoint: Verify the directory and key permissions before starting the daemon.

# install -d -o root -g root -m 0700 /var/log/sudo-io
# stat -c '%U:%G %a %n' /var/log/sudo-io /etc/ssl/sudo/private/logsrvd_key.pem
root:root 700 /var/log/sudo-io
root:root 400 /etc/ssl/sudo/private/logsrvd_key.pem

4. Select an event log destination

Syslog is the default and is useful when your host already forwards authentication events. For a self-contained file, use the logfile section and select it from eventlog.

[eventlog]
log_type = logfile
log_exit = true
log_format = json

[logfile]
path = /var/log/sudo.log
time_format = %h %e %T

The file path must be absolute. JSON entries include the full accept, reject, exit and alert messages. If you prefer traditional sudo-style records, change log_format to sudo. Setting log_exit to true adds an event when a command exits or is terminated by a signal; the default is false.

For syslog instead, use log_type = syslog and configure the [syslog] section. The default facility is authpriv, successful commands use notice, rejects use alert, and server warnings use the daemon facility. JSON entries are not split by maxlen; sudo-style entries larger than the limit can be split.

5. Check the service without making it permanent

First check the command-line interface, then run the daemon in the foreground during commissioning. The -n option prevents detaching. Use a spare high port in a temporary configuration if the production port is already occupied.

$ sudo_logsrvd -h
$ sudo_logsrvd -V
# sudo_logsrvd -n -f /etc/sudo_logsrvd.conf

A healthy foreground start should remain attached without an immediate configuration or certificate error. Press Ctrl-C after checking the messages.

Warning: this is a service-disrupting test if clients are already pointed at the port, so schedule it appropriately. The daemon rereads its configuration after SIGHUP and writes state to its debug file after SIGUSR1, when debugging is configured through /etc/sudo.conf.

If startup fails, check the first reported path rather than changing several settings at once. Common traps are a certificate name that does not match the listener, a private key the daemon cannot read, a CA bundle that does not contain the issuing CA, an occupied port, and a client-certificate requirement that clients are not ready for.

6. Add relay mode only when you need it

Without a relay, logs are stored locally. Adding relay_host changes that behaviour: messages are forwarded to another sudo log server or compatible protocol endpoint instead of being stored locally. The wildcard address is not valid in this section.

[relay]
relay_host = archive.example.invalid:30344(tls)
connect_timeout = 30
retry_interval = 30
store_first = true
relay_dir = /var/log/sudo_logsrvd

store_first = true enables store-and-forward. Completed journals are kept until transmission succeeds, which is safer during an outage but consumes disk space. Monitor that directory and set an operational retention policy. The relay TLS settings inherit from [server] unless you override them in [relay].

Recovery and rollback

Recovery: to undo this guide, restore the backup and reload the service using the service manager that owns your installation. If you started it manually, stop that foreground process first. Removing logs is irreversible; preserve them according to your retention and incident-response policy rather than deleting them as a troubleshooting shortcut.

# cp -p /etc/sudo_logsrvd.conf.backup /etc/sudo_logsrvd.conf
# systemctl reload sudo-logsrvd

The unit name is packaging-dependent, so verify it with systemctl list-unit-files | grep sudo before running a reload. If no unit exists, use your process supervisor's own reload mechanism. A SIGHUP is the daemon-level alternative.

Done means