sudo_logsrvd to centrally collect sudo session recordings from your network is a huge step forward in security: users cannot delete or modify session recordings locally. However, by default, transmission of recordings is not encrypted, making it open to modifications and eavesdropping. Encrypting the connection between
sudo_logsrvd can eliminate these problems. Larger environments usually either have in-house PKI tooling in place, or colleagues who know all openssl options off the top of their heads. However, small and medium enterprises often lack the infrastructure or knowledge to work with TLS certificates.
This blog can help you to secure connections between
sudo_logsrvd when there is no PKI tooling available to you, or you want to create all the certificates yourself using
openssl. It is based on the
sudo_logsrvd manual, but changed in such a way that all information is entered on the command line. While interactive certificate generation works fine for a single cert, generating multiple client certificates is easier when everything is on the command line.
To collect sudo recordings you need to use at least sudo version 1.9.0. There were many minor bug fixes related to this feature, so it is recommended to use the latest version available. At the time of writing, this is version 1.9.7p2. Another requirement is to have OpenSSL support enabled in
sudo_logsrvd. Fedora merged my request, so Rawhide has the latest sudo version with OpenSSL support enabled. OpenSUSE Tumbleweed has an up-to-date version and OpenSSL support is expected to be enabled soon. Sudo in FreeBSD works out of box.
For other distributions you can either try to download a binary package from the sudo website, or compile sudo on your own.
You will also need the
openssl command line utility to generate the certificates. It is installed by default on most systems.
Note: this blog assumes that OpenSSL configuration is stored in the
/etc/ssl directory. If it is not the case, you will have to adjust the path names in configuration files and command line examples.
We do everything under the
/etc/ssl/sudo directory. As a first step we set up a few files and directories and fix their permissions.
mkdir /etc/ssl/sudo cd /etc/ssl/sudo mkdir certs csr newcerts private chmod 700 private touch index.txt echo 1000 > serial
Now copy the openssl configuration file over here and open it in your favorite text editor:
cp ../openssl.cnf . vi openssl.cnf
Edit the openssl.cnf file in the current directory. Most likely it already has a [CA] and a [CA_default] section, similar to this:
[ ca ] default_ca = CA_default [ CA_default ] dir = /etc/ssl/sudo certs = $dir/certs database = $dir/index.txt certificate = $dir/cacert.pem serial = $dir/serial
In this case, all you have to change is to make sure that “dir” points to the newly created
/etc/ssl/sudo directory. Otherwise, copy the example into your
In order to create and sign our own certificates, we need to create a private key and a certificate for the root of the CA. First, create the private key and protect it with a pass phrase:
openssl genrsa -aes256 -out private/cakey.pem 4096 chmod 400 private/cakey.pem
Next, generate the root certificate. While doing it interactively might be easier at first, we provide all values on the command line. You can check the list below to see what the different fields mean:
- “C” stands for country
- “L” for location, usually city name
- “ST” for state (we do not use that here in Hungary, but openssl sometimes complains if it is missing)
- “O” organization
- “OU” organizational unit (or department)
- “CN” stands for common name. In case of a CA, it is the name displayed when you list certificate authorities. In case of client or server certificates, it is the FQDN of the host or its IP address.
Note that from now on you cannot blindly copy and paste command lines from this blog. The command line contains organization and site specific information as well. Change the values according to your environment as necessary.
openssl req -config openssl.cnf -key private/cakey.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out cacert.pem -subj '/C=HU/L=Budapest/ST=Budapest/O=My Home Ltd/OU=sudo/CN=sudo Root CA' chmod 444 cacert.pem openssl x509 -noout -text -in cacert.pem
The last command is not strictly necessary. However it helps you to verify if you entered all information as intended. Here is an example:
localhost:/etc/ssl/sudo # openssl x509 -noout -text -in cacert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 78:af:5a:28:fa:1c:e2:07:2c:44:4a:17:28:60:00:01:5c:86:27:26 Signature Algorithm: sha256WithRSAEncryption Issuer: C = HU, L = Budapest, ST = Budapest, O = My Home Ltd, OU = sudo, CN = sudo Root CA Validity Not Before: Aug 6 11:23:49 2021 GMT Not After : Aug 1 11:23:49 2041 GMT Subject: C = HU, L = Budapest, ST = Budapest, O = My Home Ltd, OU = sudo, CN = sudo Root CA Subject Public Key Info: [...]
The server and client certificates will be signed by the previously created root CA. Usually, the root CA is not used to sign server/client certificates directly. Instead, intermediate certificates are created and signed with the root CA and the intermediate certs are used to sign CSRs (Certificate Signing Request). In this example we’ll skip this part for simplicity’s sake and sign the CSRs with the root CA.
First, generate the private key without a pass phrase.
openssl genrsa -out private/logsrvd_key.pem 2048 chmod 400 private/logsrvd_key.pem
Next, create a certificate signing request (CSR) for the server’s certificate and sign it. The organization name must match the name given in the root certificate. The common name should be either the server’s IP address or a fully qualified domain name. The abbreviation of field names is the same as in the previous section, you can check them there.
openssl req -config openssl.cnf -key private/logsrvd_key.pem -new -sha256 -out csr/logsrvd_csr.pem -subj '/C=HU/L=Budapest/ST=Budapest/O=My Home Ltd/OU=sudo/CN=172.16.167.164' openssl ca -config openssl.cnf -days 375 -notext -md sha256 -in csr/logsrvd_csr.pem -out certs/logsrvd_cert.pem
You can verify the results using:
# openssl verify -CAfile cacert.pem certs/logsrvd_cert.pem certs/logsrvd_cert.pem: OK
If you want to use peer authentication, you also need to create client certificates. Otherwise, you can skip ahead to configuring TLS in
Creating the client certificates is practically the same as for
sudo_logsrvd. You only need to change the file names and the CN (Common Name) on the command lines. Here are the command lines for your first
openssl genrsa -out private/client_key.pem 2048 chmod 400 private/logsrvd_key.pem openssl req -config openssl.cnf -key private/client_key.pem -new -sha256 -out csr/client_csr.pem -subj '/C=HU/L=Budapest/ST=Budapest/O=My Home Ltd/OU=sudo/CN=172.16.167.153' openssl ca -config openssl.cnf -days 375 -notext -md sha256 -in csr/client_csr.pem -out certs/client_cert.pem
While not strictly part of certificate creation, copying the right files to the right host is important. Here is an example command sequence helping you to figure out which files to copy when you setup a client:
cd .. tar cvf sudo_client_certs.tgz sudo/cacert.pem sudo/certs/client_cert.pem sudo/private/client_key.pem scp sudo_client_certs.tgz [email protected]:
So, we changed to the
/etc/ssl directory, created a tar archive from the three necessary files and copied the file to the host, where we configure sudo to forward session recordings to
sudo_logsrvd through a TLS encrypted connection.
Now that we have the freshly generated certificates available on the server and possibly also on the client, it is time to configure
sudo. The configuration examples assume that you use the directory structure from the certificate generation command line examples.
I learned the hard way:
/etc/sudo_logsrvd.conf, the configuration file for
sudo_logsrvd, has several different sections in it. Make sure that you edit the
[server] section when you enable TLS, otherwise you will receive some frightening error messages. The content of some sections is similar, so double-check that you are in the right section.
# Listen on port 30344 for TLS connections to any address. listen_address = *:30344(tls) # Path to the certificate authority bundle file in PEM format. tls_cacert = /etc/ssl/sudo/cacert.pem # Path to the server's certificate file in PEM format. tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem # Path to the server's private key file in PEM format. tls_key = /etc/ssl/sudo/private/logsrvd_key.pem
With these settings you should already be able to receive TLS encrypted connections from
sudo clients. You can configure two additional settings to further secure communications:
- tls_verify -
sudo_logsrvdwill validate its own certificate at startup
- tls_checkpeer -
sudo_logsrvdwill validate the certificates of clients that connect to it
If peer authentication is enabled on the client, a copy of cacert.pem must be present on the client system too. And this leads us to client configuration. Here is a minimal configuration:
Defaults log_servers = 172.16.167.164:30344(tls) Defaults log_output
This configuration enables session recording and sends the results to the given address using TLS encryption. There is no peer verification, but at least the data is not clear text on the wire. There are many more possible configuration options:
Defaults ignore_iolog_errors Defaults log_servers = 172.16.167.164:30344(tls) Defaults log_output Defaults log_input Defaults log_server_cabundle = /etc/ssl/sudo/cacert.pem Defaults log_server_peer_cert = /etc/ssl/sudo/certs/client_cert.pem Defaults log_server_peer_key = /etc/ssl/sudo/private/client_key.pem Defaults log_server_verify
The names are pretty self-explanatory, but let me give you a quick explanation for each of them.
- By default
sudodoes not authorize commands to execute when
sudo_logsrvdis inaccessible; ignore_iolog_errors makes sure that sudo works even in this situation
- log_server_cabundle / log_server_peer_cert / log_server_peer_key point to the various certificates enabling peer authentication
- log_server_verify instructs the client to verify the server’s certificate
If you configured everything properly, using
sudo should not be any different. Just enter commands as usual and they should work just as they did before. The difference is that you should now be able to see your session recordings on the host running
Here is the output of
sudoreplay on an openSUSE host running
sudo_logsrvd, showing recordings from
sudo running on a Fedora 34 host:
Aug 3 14:31:50 2021 : czanik : TTY=/dev/pts/0 ; CWD=/home/czanik ; USER=root ; HOST=fedora34.localdomain ; TSID=000015 ; COMMAND=/usr/bin/ls /root/ Aug 6 13:49:17 2021 : czanik : TTY=/dev/pts/0 ; CWD=/home/czanik ; USER=root ; HOST=fedora34.localdomain ; TSID=000016 ; COMMAND=/bin/bash
If you would like to be notified about new posts and sudo news, sign up for the sudo blog announcement mailing list.