 Good morning, everyone. OK, so now it's the real thing. So first of all, hi. Welcome to the Python Dev Room at Boston 2020. Let me introduce you, Peter, who's going to tell us more about the possibilities to interface pseudo with Python. Hi. Thanks. Can you hear me? OK. No? OK. So first of all, let me give you a quick overview of what I will be talking about today. I try to define pseudo, even if most of you know it most likely. Then I will talk about a bit about a few lesser known features of pseudo. And then I will change to our main topic, extending pseudo in Python, which is a brave new feature of pseudo. So what is pseudo? For many years, I didn't know much about pseudo. Just I knew just what everyone else that I can use it for administrative problem comments. Then last year I learned that Todd Miller, maintainer of pseudo, is my colleague. We became colleagues through an acquisition. And then I became interested in pseudo, what it is, what it does, and I learned quite a lot about it. And then I started to ask people at different events what they know about pseudo. And it turned out that many people see this little tool as a way to complicate life. If that is a root user, then why use something different, or why not use the pseudo command or whatever. But even seasoned administrators told me that, well, it's a prefix for administrative comments, which is technically correct, but it's a lot more. According to the pseudo website, pseudo allows a system administrator to delegate authority by giving certain users the ability to run some comments as root or other user by providing an audit trail of the comments and their arguments. So as you can see, even from this description, it's a lot more. But we will learn quickly that, yes, there are a lot more possibilities. Well, with the help of pseudo, you can even make some sandwiches, at least according to XKCD. So let's jump into some lesser-known features. For example, you can store the digest of applications in the pseudors file. And this way, you can prevent modified binaries from running. While this database is quite difficult to maintain, on the other hand, it can give you an additional layer of protection. Another possibility is session recording. You can record everything what is happening on a terminal and play back like a video. So even if you need to give shell access to your users, you can follow what they are doing. Recordings are difficult to modify, as they are not clear text. On the other hand, as they are saved locally, it's quite easy to delete. But stay tuned. Here, I was supposed to give a quick demo. But as I'm not presenting from my own laptop, due to technical difficulties, I have to skip it. But practically, I wanted to show that I'm typing a few comments in a pseudo session, and then I can play it back and view everything as it was happening. Version 1.8 of sudo introduced plugin-based architecture, which means that even basic features of sudo are not implemented as plugins. And you can replace or extend functionality of sudo using plugins. There are both open source and commercial plugins everywhere. An important but often overlooked feature of sudo is logging and alerting. Sudo itself supports only email-based alerts, so you can configure what events you want to receive an email alert. All events are also recorded to syslog. Make sure that your log messages are centralized, otherwise your logs are easy to delete it if your users have too much rights, like they can open a shell. If you use syslog ng, then sudo logs are automatically parsed. And you can easily send alerts to Slack, Splunk, any of the cloud services where you want. If you are lucky, you never have to use sudo debug logs. This can be used to debug the rules or to report problems. Here, you can see a screenshot from Slack with only comments executed by me listed here. So until now, we talked about sudo 1.8 features. But sudo 1.9 is right around the corner. A beta release is already on the sudo website. And it brings many new features to us. First of all, there will be a recording service. So you can collect session recording centrally. An audit plugin is coming, approval framework plugin. And the main feature is support for Python-based plugins. That alone is worth for a completely new version. So what is the recording service? You can collect session recording centrally. And that way, as you run a sudo session, your session is streamed in real time to another location on an encrypted channel. Central session collection is not just convenient, but also means availability. Even if the sending machine is down, you can reach your sessions. And it's also security, as no one can tamper them on the local machines. The audit plugin doesn't introduce anything user-visible. On the other hand, it gives API access to any kinds of sudo logs, which is especially useful from when the Python API will be available for it. Using the audit plugin, you will be able to send logs and alerts from sudo directly without using third-party applications like Cisco GNG, as I mentioned earlier. The approval framework makes possible to approve sessions. So it's not just checking permissions in the sudoers file, but also another user needs to approve what you are doing in a session right now. It's possible only through third-party plugins. And as they are developed in Rust, it's not so easy to package or distribute. Once the approval plugin framework is ready, it's still under development. You will be able to use it from Python as well. And for example, in this way, you can connect sudo to ticketing systems and check if a given sysadmin is on duty. And that is an open ticket and only allow the session when it's there. And Python support is coming, as I mentioned, which means that you can easily extend sudo using Python. It's using the same API as the C-based plugins. On the other hand, you don't need any specialized development environment. And instead of packaging, you can simply distribute Python code using your config management system. The API is the same as the C-based plugins. So there is a link here for that plugin documentation. And the Python plugin itself also has its own docs. But those are mainly referring to Python-specific parts. The first plugin I want to mention is the policy plugin API. The policy plugin within sudo decides who can do what. Normally, it's in the sudoers file. But if you use a plugin like one done in Python, then you replace it completely. So you need to enable the policy plugins in sudo.conf. I have a Python example which allows you to run the command ID and nothing else. Here is the code. As you can see, it starts by importing the sudo module. The sudo module itself is not something you can find on your disk, but it's provided by the sudo Python plugin. And you need to define a class for your Python code. You can name it whatever you want, but you need to base it on the sudo Python class. In case of the policy API, you need to have a method called check policy, which receives a few arguments from sudo. Arcway contains data related to the commands. What the user wants to execute and embed the environment provided by the user. The first argument within Arcway is the command name. We check this one. And if it's different from ID, then we print an error message on screen that you are not allowed to run this command and the sudo session is rejected. If it's not the case, then we go on and create a variable containing the minimum information necessary to execute a command. It's the command name, the user ID, and group ID. And finally, we return it to sudo that we accept this command and the data to execute this application. So this is how it looks on screen. And I'm happy that I screenshotted everything and not just prepared to demo it live. As now I can show you, first, I try to run the ls command, but it's rejected. And when I run ID, then it runs with root privileges, just as it accepted. The next API is IOLOX. This is related to session recording. It means that you get access to all input and output of your sudo command. At the moment, only one Python implementation of IOLOX is allowed, but it will be changed soon. There are quite a few possibilities what you can do using the IOLOX API. For example, break the session if a given text appears on screen, or when someone types RM minus FR on the command line. Or you can even use it to ask for a reason why someone is starting a session. The first example here is checking the output on the screen. We import the sudo module, create a class, and the log ttyout method receives, anytime a new text appears on screen, it receives in the buffer. And you can check the content of this buffer from Python. And in my case, if my secret appears on screen, then we print that don't look at my secret and reject the session. You can see here how it works. We start a session. We change to the root directory, list it. We find an interesting looking directory called do not enter, but still we enter it. But when we list it, it has a file called mysecret, but it's not printed on screen. Before it would be printed, we check it from our Python code, see that it's there, and break the session. The next example is a bit more complicated. When you type anything using sudo, the typed characters printed on the screen one by one. So we need to collect these together and check the collected letters if what we are looking for is included in that. In this case, we are checking if Rn minus effort is included in these collected letters. And if it is, then we break the session before the command is executed. This is how it looks like. We start the sudo session, list the directory, and then start entering Rn minus effort. But before R is printed, the Python code shown previously already finds that something that is happening, and it prints the warning message and stops the session. Here is the third example. It's asking for a reason why the sudo session is started. Actually, for two reasons. One is a public reason, and there is a second secret reason. The difference is that for the first one, what the user is typing is shown on the screen. For the second one, only stars are shown on the screen, like when you enter a password. So when someone is behind you with a gun, you can type something nice in the public reason and write in the private reason that I'm threatened by a gun. And obviously, everything is saved into a file, so later on, you can show your boss that, well, even if it was not a nice thing to do, but I was threatened to do it. And here is how it looks on the screen. First, my public reason is stated there and entered there, and you cannot see on the screen what I typed for secret reason. The last API I want to talk about is the group API, which allows you to do non-unix group lookups. For example, if you can check here, you can use here external databases or check if an admin is on duty. In my sample calls, I used something a lot more simple, and it obviously could be done much more easier using the sudoers, but here I load... And actually, this one is loaded from the sudoers file and not from sudo.conf, as you can have multiple of these. Here, we load the Python plugin with grouppy and the given class name. And if the given user is in the group, then one can use... Then he doesn't have to use a password, but the session is approved immediately. Here is the code. If we import sudo, create class, it receives some data from sudo, and we have some hard-coded groups here, and my group here includes my username. So here we check if the username is included in this group and send back accept. This is how I used it in my demos, so that's why I didn't have to type a password in my example screenshots. So we could see sudo is not just a prefix, but a lot more fine-tuned permissions, session recording, plugin API, and 1.9, which already available for testing, will include Python plugin, which you can already test, session recording, and logging API and approval API. Do we have any questions? We have probably two minutes left for questions. Three. Thanks for the talk. If you do a lot of processing in your Python plugin, is that going to make the session seem laggy or badly performing? So the question was, if it's using too much resources... Yeah, if your Python plugin does a lot of processing, is your sudo session going to seem laggy? Personally, I didn't feel... I didn't do measurements, but I just tested it. I didn't feel that it was... I didn't feel that it was slower, but I didn't do extensive testing, just a few comments. Obviously, if you have lots of directory listings, whatever appearing on screen, then it might slow a bit down, but I didn't feel anything when I tried it. Great, thanks. Okay, we have time for one more question. Here it is. So when you match up the commands, how are you sure that nobody will inject some examples which break out of them? Obviously, this is a very simple example I have shown you here. If you change the order of the parameters, it will already not match. So it was a dumb example, but it works. If you want to use it in real-world situations, then you need to have more complex matches, but that's not an example of it in the screen.