Sudo 1.9.4: new options for logging

While most of the changes in sudo version 1.9.4 are under the hood, there are some user-visible changes as well. Locating problems in the sudoers file became even easier as the column number is now also displayed when an error is found. There are also two logging related changes. Sudo_logsrvd, the service that collects session recordings centrally, can now also collect rejection log messages, not just information about successful sessions. It is now also possible to log events in JSON format.

Before you begin

These new features were introduced in sudo version 1.9.4. There is a good chance that your operating system includes an older version of sudo. You can download ready-to-use binaries for many different operating systems directly from the sudo website or you can build sudo from source yourself.

Logging in JSON format

Traditionally, sudo logged to syslog in plain text mode and included only the most important information in the logs. This was necessary because of the constrains of the traditional BSD syslog, where the maximum message size was 1KiB. Here are a few examples:

Nov 18 12:31:33 centos7sudo sudo[30666]:   czanik : 3 incorrect password attempts ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
Nov 18 12:31:43 centos7sudo sudo[30670]:   czanik : TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
Nov 18 12:31:49 centos7sudo sudo[30670]:   czanik : command rejected by I/O plugin ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash

Recent syslog implementations support much longer messages. And most syslog servers and log analysis software supports parsing JSON-formatted messages. This way they can easily extract name-value pairs from messages and act on the content of specific fields, like alerting when a specific user runs sudo. While parsing of traditional sudo messages is also possible, JSON formatting does not require a dedicated parser and thanks to its structure it can include a lot more information in a straightforward way.

To enable JSON formatting of log messages, open the sudoers file with visudo and add the following line:

Defaults log_format=json

Once you save the configuration, new log messages will be sent to syslog in JSON format:

Nov 18 12:40:16 centos7sudo sudo[30887]: @cee:{"reject":{"reason":"3 incorrect password attempts","server_time":{"seconds":1605699616,"nanoseconds":430644301,"iso8601":"20201118114016Z","localtime":"Nov 18 11:40:16"},"submit_time":{"seconds":1605699607,"nanoseconds":258116087,"iso8601":"20201118114007Z","localtime":"Nov 18 11:40:07"},"submituser":"czanik","command":"/bin/bash","runuser":"root","runcwd":"/home/czanik","ttyname":"/dev/pts/0","submithost":"centos7sudo.localdomain","submitcwd":"/home/czanik","runuid":0,"columns":118,"lines":60,"runargv":["/bin/bash"],"runenv":["HOSTNAME=centos7sudo.localdomain","SHELL=/bin/bash","TERM=xterm-256color","PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/czanik/.local/bin:/home/czanik/bin","LANG=en_US.UTF-8","MAIL=/var/mail/root","LOGNAME=root","USER=root","HOME=/root","SUDO_COMMAND=/bin/bash","SUDO_USER=czanik","SUDO_UID=1000","SUDO_GID=1000"]}}
Nov 18 12:40:23 centos7sudo sudo[30891]: @cee:{"accept":{"server_time":{"seconds":1605699623,"nanoseconds":442604216,"iso8601":"20201118114023Z","localtime":"Nov 18 11:40:23"},"submit_time":{"seconds":1605699620,"nanoseconds":130500349,"iso8601":"20201118114020Z","localtime":"Nov 18 11:40:20"},"submituser":"czanik","command":"/bin/bash","runuser":"root","runcwd":"/home/czanik","ttyname":"/dev/pts/0","submithost":"centos7sudo.localdomain","submitcwd":"/home/czanik","runuid":0,"columns":118,"lines":60,"runargv":["/bin/bash"],"runenv":["HOSTNAME=centos7sudo.localdomain","SHELL=/bin/bash","TERM=xterm-256color","PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/czanik/.local/bin:/home/czanik/bin","LANG=en_US.UTF-8","MAIL=/var/mail/root","LOGNAME=root","USER=root","HOME=/root","SUDO_COMMAND=/bin/bash","SUDO_USER=czanik","SUDO_UID=1000","SUDO_GID=1000"]}}
Nov 18 12:40:30 centos7sudo sudo[30891]: @cee:{"reject":{"reason":"command rejected by I/O plugin","server_time":{"seconds":1605699630,"nanoseconds":933293911,"iso8601":"20201118114030Z","localtime":"Nov 18 11:40:30"},"submit_time":{"seconds":1605699620,"nanoseconds":130500349,"iso8601":"20201118114020Z","localtime":"Nov 18 11:40:20"},"submituser":"czanik","command":"/bin/bash","runuser":"root","runcwd":"/home/czanik","ttyname":"/dev/pts/0","submithost":"centos7sudo.localdomain","submitcwd":"/home/czanik","runuid":0,"columns":118,"lines":60,"runargv":["/bin/bash"]}}

I hope you noticed that these are the exact same log messages as the previous example, only the timestamp is different.

Logging to sudo_logsrvd

Even before version 1.9.4, there were already two ways for sudo to log events: logging to syslog and logging through the audit plugin API. Starting with sudo version 1.9.4 there is a third one: logging to sudo_logsrvd, the service that collects session recordings centrally (which in the end can also log to syslog). It seems to be a big step, but actually sudo was already sending logs about successful sessions together with the stream of the session, so sudoreplay could print information about the session. What is new is that sudo now also sends failure information to sudo_logsrvd. This way, the server collecting session recordings also has information about all sudo sessions, including failed sessions.

Even if you do not enable session recording on a host, you can still enable sending sudo logs to sudo_logsrvd by setting the server name or IP address, for example:

Defaults log_servers=172.16.167.150

By default, sudo_logsrvd logs in the traditional sudo log format. The log messages from the previous examples look exactly the same on the server hosting sudo_logsrvd. The only difference is the addition of the host name after the date:

Nov 18 12:40:16 centos8splunk.localdomain sudo[21028]:   czanik : 3 incorrect password attempts ; HOST=centos7sudo.localdomain ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash
Nov 18 12:40:23 centos8splunk.localdomain sudo[21028]:   czanik : HOST=centos7sudo.localdomain ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; TSID=00000A ; COMMAND=/bin/bash
Nov 18 12:40:30 centos8splunk.localdomain sudo[21028]:   czanik : command rejected by I/O plugin ; HOST=centos7sudo.localdomain ; TTY=pts/0 ; PWD=/home/czanik ; USER=root ; COMMAND=/bin/bash

And as you would expect, logging with JSON formatting is also available. Just make sure that the [eventlog] section of /etc/sudo_logsrvd.conf has the following line:

log_format = json

Change the parameter back to sudo or comment out the line if you want to restore the traditional sudo log formatting.

If you would like to be notified about new posts and sudo news, sign up for the sudo blog announcement mailing list.