Hello, and welcome to What's New in Sudo 1.9. I'm Todd Miller. I'm the Sudo maintainer. And I work for One Identity. And One Identity has sponsored Sudo development for the past 10 years. So today, I'm going to talk about what is Sudo, with a brief overview, and also review what the major changes were Sudo 1.8 and then talk about what's new in 1.9.
So what is Sudo? The answer really depends on your use case. If you're using a single-user workstation, it can be just a way to run privileged commands without any real access control. On a large installation like enterprise, higher ed, government, it's often used as a way to manage privilege with fine-grained access control and logging, both commands and, optionally, sessions.
So basically, in a nutshell, Sudo allows running privileged commands without using either a root shell or the su command. So each command is logged. And optionally, the terminal can be logged, too. Commands are run by using the Sudo prefix-- so for instance, Sudo vi/etc/hosts, something like that. And the policy configuration is stored in a file called "sudoers."
So a brief history of Sudo-- first version was in 1980 at SUNY Buffalo. And then five years later, there was an updated version posted to the net.sources newsgroup. In 1986, one of the people from SUNY Buffalo moved to the University of Colorado Boulder, and they brought Sudo with them. So at CU, Sudo was updated, modified. And it was really the release of the UNIX system administrators' handbook from Evi Nemeth and others that really popularized Sudo.
Now, in 1991, a group of programmers who worked at the university released a new version of Sudo. They also worked for a consultancy called the Root Group. And this is often referred to as the Root Group version of Sudo. And that version was notable because it had the concept of host-based rules. So you could have specific sudoers rules for different hosts.
In 1994, I started making my own Sudo releases. 2003 saw the support for LDAP sudoers, so sudoers rules in an LDAP directory. And that was contributed by another programmer. And then in 2010, we saw session logging. And then, in 2011, the release of Sudo 1.8 brought plugin support, which I'll talk about later. And then now here we are in 2020 with Sudo 1.9, which has support for Python plugins and a logging server, all of which I'll talk about in just a moment.
So what does a sudoers rule look like? Basically, it answers a couple questions-- who can do the command, where the command could be executed, as whom-- by default, that's root-- and what the command is itself. So Sudo does log about every successful and unsuccessful attempt to run a command. So there are different possible log destinations.
By default, Sudo logs distance log. So you can do centralized logging. And for instance, advanced-- syslog daemon, syslog-ng, will automatically pass the sudoers logs for you. You can also log to a local file on the local system. But that does have the possibility where someone could tamper with it. Also, it's possible to log the email. But usually, that's only for the most serious issues, such as a problem with the sudoers file itself.
So Sudo does support session recording. And what this means is it records the output of the terminal, so what the user sees on the screen, as well as the input, so what gets typed in. It also can log standard input and standard output and standard error if, for some reason, those are not hooked up to the terminal-- for instance, if there is a pipe or redirection to or from the file.
The session logs are stored on the local system. And they're compressed, but they're not encrypted, which does mean they could be tampered with. You can replay the session logs with the command called sudoreplay. That lets you pause the log, slow down, speed up. But it doesn't currently support things like fast forward and rewind. But I'll talk about that a little bit later.
So the major Sudo 1.8 features-- the main change is that Sudo has kind of been broken up into some separate constituent parts. So the front end is now separate from the policy. So this means that plugins are used to implement both the policy and the logging, including the session logging.
There's a conversation plugin used by-- excuse me, conversation function used by the plugins for things like password entry or information or warning messages. And then the front end queries the policy and runs the command.
Now, because of this, the split, we needed a way to configure the plugins themselves. So that's what's done in the new sudo.conf file. And it also has some other front-end-specific settings.
So the two plugins in Sudo 1.8 are the policy plugin, which determines who can do what. But there can only be a single policy plugin in use. And that's because it's difficult to compose multiple policies that may be very different.
And there is also an I/O logging plugin, which is what does the session recording. And that does the terminal input and output, as well as standard in an standard output and standard error if they're not hooked up to the terminal. Now, multiple I/O logging plugins may be used. There's no problem having multiple ones there. And they're evaluated in the order in which they appear in the sudo.conf file.
Now, on to the new stuff in 1.9. So the major features here are a log server, which supports centralized event and I/O logging, a new audit plugin type, which can support custom logging, an approval plugin type, which can add additional policy constraints on top of the existing policy plugin, and Python support for all the plugin types, both the old ones and the new.
So the log server-- the basic idea here is that we want to be able to collect the event and I/O logs in a central location. So this is implemented as the Sudo logsrvd daemon. And on the client side, the sudoers I/O plugin will support streaming events and I/O logs to this service in daemon.
There's also the Sudo sendlog utility, which can be used to send existing logs that are on the local system. And as I said, the logs are streamed in real time, and the protocols built with Google Protocol Buffers and secured with TLS, either 1.2 or 1.3, although that does require that you build Sudo with the open cell library to get that TLS support.
And on the server system, we can use sudoreplay, just as we would normally. The logs on the log server are the exact same format as they would be on the local system. And so the workflow there is exactly the same when you're looking at the log and replaying them.
So the obvious question here is, why not use syslog? So there are a couple problems with syslog. Historically, it hasn't really been reliable because it's used the EGP protocol. That's the unreliable datagram protocol. And that meant that it's not possible to detect a log failure.
Also, another issue is the entries could arrive out of order, which makes replay difficult. And just in general, replaying a session out of a log file that contains potentially multiple sessions, as well as other log information, is just a more difficult problem. And it's hard to do it reliably.
Another issue is that for syslog, the maximum message size varies among different implementations. And we don't want to be sending data that gets truncated on the receiver side. Another possible issue is that end-to-end encryption is not guaranteed.
So potential problems here-- what happens if the server is unavailable? Well, we can have multiple servers in the configuration file. And the connection failures can be handled either as a fatal error or something that gets ignored and where the command is allowed to run anyway. And these are all configurable settings in the sudoers file.
There are a few things left on my to-do list for the log server. I'd like to support server-side load balancing. There's support for this in the protocol. The basic idea is that if the log server is overloaded, it can redirect the client to another one in a group. And I'd also like to add support on the client side for transmitting logs if the log server was unavailable for some period of time, to transfer the offline logs to that server when it comes back online.
So now to the new plugin types-- the audit plugin is basically an API to access the various data that Sudo has about the logging. So there are a couple of different logging event types. There's an accept event when a command is allowed, a reject event when a command is denied by the policy, an exit event when the command completes, and error events if there is an error in the front end or any of the plugins.
So this required a minor change to the policy in I/O plugin API. Basically, the plugins now have a way to report an error stream back, whereas before, it was just a yes or no, did it work, or did it not? Now, multiple audit plugins are supported. And Sudo comes with an example plugin that just writes JSON out to a local file. So the audit plugin doesn't really replace the existing sudoers logging. In fact, the sudoers plugin now uses the audit API directly, as of Sudo 1.9.3.
So the advantage of the audit plugin is we can have more details than the default Sudo logs provide. That means the full details of the invoking user, things like alt error, various IDs, and groups, their environment, process ID, the parent process ID, things like that. It also gives us access to the full execution environment, so everything that Sudo uses to run the command. That means the groups and users that it will run as, as well as things like the environment that the command runs in, which can be different from the invoking user's environment.
It can also get status from the other plugins if there's a problem. Or every time any of the plugins approves or rejects a command, that goes to the audit plugin. And this can be particularly useful from Python, because a lot of the cloud-based services, things like logging as a service, these have client code written in Python, not necessarily in C. So this lets us talk to some of these cloud-based services directly without having to use some kind of external tool, such as something like syslog-ng.
So the API is pretty simple. There's an open function that gets called before any of the other plugins. And that gets the user info as well as the original argument vector that Sudo is run with and the user's initial environment. There's a closed function that gets called last, just before Sudo exits, and that gets the command's exit status or signal number that was killed by signal. There's also a show version function, which just displays the plugin version, and all the plugins have this.
So the real interesting things are the accept, reject, and error functions. And these are called after the policy and approval plugins are called. And the accept and reject receive the plugin name type. And in the case of the accept function, it also gets the execution environment that the command was run with. The error function is called if any of the plugins or the front end report an error, and it also gets the plugin name and type and an error string that describes the problem if one is available.
So the approval plugin is additional policy that we can add without replacing sudoers or the policy plugin. And multiple approval plugins are supported. So some potential uses for this are time-of-day restrictions. So for instance, if we wanted to allow the user only to be able to run commands during business hours or some specific time, just-in-time authorization. We could combine this with a permissive sudoers policy to allow users to run any command, but only if it's approved by a third party.
We could also integrate a ticket system of some kind so that the user can only run commands to solve a specific problem, so where their access is enabled when a ticket is assigned to them, and then it's revoked when the ticket is finished. Another possible use could be multifactor authentication. I think, for some reason, the authentication provided by Sudo is not sufficient.
So the API looks like this. There's an open function very similar to the audit plugin API that receives the user information, the original argument vector and environment. There's a check function that gets run after the policy approves the command. And that gets the command to run, as well as the full execution environment as the policy plugin has sent it.
Close function gets called pretty much immediately after the check. This doesn't wait for a command to complete. It's just a way of cleaning up resources. And then there's the show version function, just like the other plugins have. This just displays a version.
So the other major change in Sudo 1.9 is the Python plugin support. So this means that we can now run or write our plugins in Python instead of in C. It's the same basic API. And the policy I/O plugins, audit plugin, the approval plugins are all supported. And you can run those-- write those in Python.
So an advantage to this is that there's no compilation required. This makes it a lot easier to distribute the Python plugins to multiple machines. You don't have to worry about rebuilding them for different architectures, things like that.
So Sudo comes with a Python plugin, a shared object. And that has a Python interpreter embedded in it. And it also comes with a number of examples. The Sudo blog has multiple articles about how to write Python plugins, and I encourage you to check that out.
So future directions, there are a few things that I have kind of in my mind for future changes here. I'd like to finish some of the log server tasks, such as load balancing and the automated log forwarding when the offline server comes back online, better shell integration. This would mean the ability to log commands run within a shell session. Right now, we can log when the shell is started, and we can log the session itself. But we don't have log entries when there's an individual command run from within that shell.
Another thing that people have asked for is the ability to merge multiple sudoers files. If you have a disparate set of sudoers files, the ability to merge them into a single cohesive file that could be distributed would be a useful thing. Sudoreplay improvements-- I alluded to some of these before, things like fast forward, rewind, jump to the beginning, jump to the end, things like that, just to make it a little more usable.
And then the final thing is reporting utility. Some users have asked for an easier way to see who is allowed to run what and to make queries on the sudoers file in that way. So those are some of my things on the to-do list there.
So that's it for what's new with Sudo 1.9. There's more information on the Sudo website. That's www.sudo.ws. And the Sudo blog also has more information, blog.sudo.ws. Thank you for coming.