Entry tags:
- doas,
- floss,
- foss,
- free software,
- musl,
- open source,
- please,
- sudo,
- sup
sudo alternatives
I recently had an issue doing an upgrade of AIX Toolbox on an AIX machine and it caused the sudo program to fail because it couldn't find dependencies it needed to execute successfully. I started searching to see if there were simpler alternatives that could do a job similar to sudo and would not have so many dependencies. Of the various options out there, I found three that were interesting.
Doas was created for OpenBSD. There are different versions of the program, including a portable fork called OpenDoas. I tried this version, so I can't say much about the others at this point:
https://github.com/slicer69/doas
The program does build on Linux as well as on the BSD systems. It can use BSD functions on BSD systems for authentication but uses PAM on Linux and other systems. The pam_start function needs struct pam_conv to initialize and part of pam_conv points to a function that handles input. Linux, Solaris and some systems provide functions as part of their PAM library. However, not all systems have a library function to pass to pam_start. I wasn't able to find a supplied function on AIX. OpenDoas appears to have a function as part of the OpenDoas program itself. There are also some simple examples of a function that can be used with PAM available online if you're on an operating system that doesn't have one readily available.
Another option I came across was called please. It only offers the option of PAM authentication. It has the same issues for portability with regards to the function needed by pam_conv. You can find the source code for please here:
https://github.com/gblach/please
The last alternative I experimented with is sup. It's on the recommendations page at suckless.org. The interesting thing about this program is that it doesn't require PAM to work on various systems. That's a nice feature if you're building a minimal operating system and don't have the PAM library built and installed. It has an option to use a hash function to make sure that the user is running the program they're supposed to and not a program with the same name that has been substituted for it. The hash function has a less lenient license than the program on its own. I was thinking it would be nice to use a system library with a hash function instead of needing to use the one provided by the program. However, that would increase the number of dependencies the program requires. The sup program also has a feature to run a program with a fork. As I'm not a fan of the fork function and how many resources it uses and its lack of portability, I avoid that option at all costs. I remember the topic of fork coming up on the musl mailing list. The spawn function was mentioned as a more efficient alternative. Another difference between this program and the other two is that it uses hard-coded settings rather than needing external settings files. This requires recompiling to change options, but it makes it harder for someone else to modify the settings from a security standpoint. Source code for sup is available at:
https://github.com/dyne/sup
Upon further investigation, the sup that the suckless.org site recommends is the earlier version found here:
https://oldgit.suckless.org/sup/files.html
It does not include the hash and fork options and offers a more minimal implementation with straight-forward code.
I've seen some complaints that using sudo or operating/logging in as root can be more insecure. Alternatives may be more secure when they have less code and are easier to maintain and debug. That's one reason they may be attractive. However, the alternatives need to be well written or well tested and debugged or they can be more insecure than the standards. There's also the advantage of security through obscurity. If exploits use sudo, they may not be expecting or looking for an alternative like doas on a system. Many people prefer using whatever's standard assuming that it's secure enough or so many other people wouldn't be using it too. Just as having less code can be more secure, requiring less dependencies can also have security advantages. It's another way to limit the amount of code in a program. Using a shared library can also create security issues for a program that may need to be addressed.
As a cross-platform programmer, I always look for programs that will work on a variety of operating systems. The sudo alternatives port to many systems but many of their concepts won't transfer well to Windows or DOS operating systems. While you can have multiple users on some DOS variants, it's more of a single user operating system and restricting who can run things is not typically an issue. On Windows, this can be important. However, Windows has a completely different way of handling permissions and rights from Unix and Linux systems. I did run across some samples of sudo-like alternatives designed for Windows. However, they work very differently.
It was interesting to find out how programs like sudo or the alternatives I've mentioned function. A sudo-like program is owned by root and has a special permission set on the program file. By setting the suid bit on the file permission of the program, a non-root user can run the program as if they are the root user. A technique like this would not work natively on Windows. One can elevate permissions in Windows using the Windows API. However, it doesn't work in all cases. There's a way to use SeDebugPrivilege to elevate permissions in a program but some organizations turn that privilege off for their users.
Basically any of these types of sudo like programs uses a function such as execute or spawn or CreateProcess to run other programs. They allow a user who typically doesn't have permission on a particular operating system to have that permission by starting another program or process through that program. In some form or other, that program needs to have special rights to run other programs whether the user has the rights to or not.
I find it interesting that root automatically has permissions to copy, move or remove files, no matter what directory. On POSIX systems, running as root really solves a lot of permission issues especially when building and trying to install programs. While Puppy Linux embraces the idea of running as root and some small, single user systems work fine this way, many Unix and Linux systems highly discourage running as root. While it's nice to be able to easily install a program you built, it's not helpful if you accidentally install something over another library or program and cause your system to fail in the process. It's also easier to accidentally remove needed files in a critical directory when you have the permissions to remove anything. For instance, a misbehaving install script could easily wipe out files needed for the system to operate properly. I do feel that critical programs with dependencies, if built statically, have several advantages to programs using shared libraries. They won't fail if there are issues with finding or loading a shared library on the system. Also, someone can't hack the system by having that program load the wrong library with a function that doesn't do what's intended. At this time, static building isn't widely embraced on Linux systems and the GNU glibc library cannot be used to build static programs. One would need to use a C library such as musl if static builds are desired. I personally happen to think there are many advantages to using musl over glibc. However, at this point most Linux operating systems still use glibc. Both using alternatives to glibc and running as root are not mainstream practices and both can be controversial in many sectors. There are pros and cons to running as root versus running as another user. That's what makes programs like sudo and similar alternatives so useful. They give the power of root but can limit what you can do with it to make sure you don't accidentally run commands that could disrupt or cripple the operating system.
Personally, I'd like to see a cross-platform sudo alternative that would work with Windows as well as Unix (including AIX) and Linux operating systems. It would be nice to have a small, simple program that would work for most multi-user operating systems available. I prefer the idea of a more compact program with very limited dependencies. A static build or no extra libraries would have avoided my shared library issue on AIX which caused sudo to fail.
I'd be very intrigued to hear about other sudo alternatives that are available. I'd also be interested in hearing about the pros and cons of security with regards to use of some of these programs. What do you regularly use on your system? What alternatives to root or sudo have you found? What works well on multi-user operating systems beyond Linux and Unix? What are your security concerns using sudo or some of these alternatives and how do you work around them? Feel free to share some of your comments on the topic on Mastodon. I'll be updating this article with more information if I find other lightweight, low dependency sudo alternatives that I like.
Doas was created for OpenBSD. There are different versions of the program, including a portable fork called OpenDoas. I tried this version, so I can't say much about the others at this point:
https://github.com/slicer69/doas
The program does build on Linux as well as on the BSD systems. It can use BSD functions on BSD systems for authentication but uses PAM on Linux and other systems. The pam_start function needs struct pam_conv to initialize and part of pam_conv points to a function that handles input. Linux, Solaris and some systems provide functions as part of their PAM library. However, not all systems have a library function to pass to pam_start. I wasn't able to find a supplied function on AIX. OpenDoas appears to have a function as part of the OpenDoas program itself. There are also some simple examples of a function that can be used with PAM available online if you're on an operating system that doesn't have one readily available.
Another option I came across was called please. It only offers the option of PAM authentication. It has the same issues for portability with regards to the function needed by pam_conv. You can find the source code for please here:
https://github.com/gblach/please
The last alternative I experimented with is sup. It's on the recommendations page at suckless.org. The interesting thing about this program is that it doesn't require PAM to work on various systems. That's a nice feature if you're building a minimal operating system and don't have the PAM library built and installed. It has an option to use a hash function to make sure that the user is running the program they're supposed to and not a program with the same name that has been substituted for it. The hash function has a less lenient license than the program on its own. I was thinking it would be nice to use a system library with a hash function instead of needing to use the one provided by the program. However, that would increase the number of dependencies the program requires. The sup program also has a feature to run a program with a fork. As I'm not a fan of the fork function and how many resources it uses and its lack of portability, I avoid that option at all costs. I remember the topic of fork coming up on the musl mailing list. The spawn function was mentioned as a more efficient alternative. Another difference between this program and the other two is that it uses hard-coded settings rather than needing external settings files. This requires recompiling to change options, but it makes it harder for someone else to modify the settings from a security standpoint. Source code for sup is available at:
https://github.com/dyne/sup
Upon further investigation, the sup that the suckless.org site recommends is the earlier version found here:
https://oldgit.suckless.org/sup/files.html
It does not include the hash and fork options and offers a more minimal implementation with straight-forward code.
I've seen some complaints that using sudo or operating/logging in as root can be more insecure. Alternatives may be more secure when they have less code and are easier to maintain and debug. That's one reason they may be attractive. However, the alternatives need to be well written or well tested and debugged or they can be more insecure than the standards. There's also the advantage of security through obscurity. If exploits use sudo, they may not be expecting or looking for an alternative like doas on a system. Many people prefer using whatever's standard assuming that it's secure enough or so many other people wouldn't be using it too. Just as having less code can be more secure, requiring less dependencies can also have security advantages. It's another way to limit the amount of code in a program. Using a shared library can also create security issues for a program that may need to be addressed.
As a cross-platform programmer, I always look for programs that will work on a variety of operating systems. The sudo alternatives port to many systems but many of their concepts won't transfer well to Windows or DOS operating systems. While you can have multiple users on some DOS variants, it's more of a single user operating system and restricting who can run things is not typically an issue. On Windows, this can be important. However, Windows has a completely different way of handling permissions and rights from Unix and Linux systems. I did run across some samples of sudo-like alternatives designed for Windows. However, they work very differently.
It was interesting to find out how programs like sudo or the alternatives I've mentioned function. A sudo-like program is owned by root and has a special permission set on the program file. By setting the suid bit on the file permission of the program, a non-root user can run the program as if they are the root user. A technique like this would not work natively on Windows. One can elevate permissions in Windows using the Windows API. However, it doesn't work in all cases. There's a way to use SeDebugPrivilege to elevate permissions in a program but some organizations turn that privilege off for their users.
Basically any of these types of sudo like programs uses a function such as execute or spawn or CreateProcess to run other programs. They allow a user who typically doesn't have permission on a particular operating system to have that permission by starting another program or process through that program. In some form or other, that program needs to have special rights to run other programs whether the user has the rights to or not.
I find it interesting that root automatically has permissions to copy, move or remove files, no matter what directory. On POSIX systems, running as root really solves a lot of permission issues especially when building and trying to install programs. While Puppy Linux embraces the idea of running as root and some small, single user systems work fine this way, many Unix and Linux systems highly discourage running as root. While it's nice to be able to easily install a program you built, it's not helpful if you accidentally install something over another library or program and cause your system to fail in the process. It's also easier to accidentally remove needed files in a critical directory when you have the permissions to remove anything. For instance, a misbehaving install script could easily wipe out files needed for the system to operate properly. I do feel that critical programs with dependencies, if built statically, have several advantages to programs using shared libraries. They won't fail if there are issues with finding or loading a shared library on the system. Also, someone can't hack the system by having that program load the wrong library with a function that doesn't do what's intended. At this time, static building isn't widely embraced on Linux systems and the GNU glibc library cannot be used to build static programs. One would need to use a C library such as musl if static builds are desired. I personally happen to think there are many advantages to using musl over glibc. However, at this point most Linux operating systems still use glibc. Both using alternatives to glibc and running as root are not mainstream practices and both can be controversial in many sectors. There are pros and cons to running as root versus running as another user. That's what makes programs like sudo and similar alternatives so useful. They give the power of root but can limit what you can do with it to make sure you don't accidentally run commands that could disrupt or cripple the operating system.
Personally, I'd like to see a cross-platform sudo alternative that would work with Windows as well as Unix (including AIX) and Linux operating systems. It would be nice to have a small, simple program that would work for most multi-user operating systems available. I prefer the idea of a more compact program with very limited dependencies. A static build or no extra libraries would have avoided my shared library issue on AIX which caused sudo to fail.
I'd be very intrigued to hear about other sudo alternatives that are available. I'd also be interested in hearing about the pros and cons of security with regards to use of some of these programs. What do you regularly use on your system? What alternatives to root or sudo have you found? What works well on multi-user operating systems beyond Linux and Unix? What are your security concerns using sudo or some of these alternatives and how do you work around them? Feel free to share some of your comments on the topic on Mastodon. I'll be updating this article with more information if I find other lightweight, low dependency sudo alternatives that I like.