Score:0

sudo to allow apt-get install of remote packages, but forbidding arbitrary commands

cn flag

I'm looking for a way to allow a user to install (only remote) packages via apt-get (or another mechanism?) but not allow them to run arbitrary commands as root.

I can get some of the way there via /etc/sudoers. Say I have this in my /etc/sudoers file

root ALL=(ALL:ALL) ALL
john ALL=NOPASSWD:/usr/bin/apt,/usr/bin/apt-get

Then John appears limited to run apt and apt-get via sudo. But... there do seem to be ways to escape apt-get to a shell as root (https://blog.ikuamike.io/posts/2021/package_managers_privesc/):

  • Type sudo apt-get changelog apt and hit enter
  • Type an exclamation mark ! and hit enter
  • You’re now in the shell as root and can do anything

Or run the below:

sudo apt update -o APT::Update::Pre-Invoke::="/bin/bash"

If it makes any difference, this is in Docker


Was posted at https://superuser.com/q/1698692/315568, but I think that was the wrong site, since this isn't (just) for my machine, but for others

cn flag
Bob
If you don't trust user john he should not get any sudo rights. You're attempting to close a single avenue of abuse, but the fact is that john can for example still create a custom package that installs whatever tools he needs to circumvent your access controls with `sudo apt install ./my-rootkit.deb`
Score:1
cn flag
Bob

The sudoers manual also has a whole section how a proper policy in the /etc/sudoers configuration file (or of course the included drop-in policy files) can offer limited protection against shell escapes with the RESRICTand NOEXEC options.

That might be more generic than creating a wrapper script for a particular utility.

restrict Avoid giving users access to commands that allow the user to run arbitrary commands. Many editors have a restricted mode where shell escapes are disabled, though sudoedit is a better solution to running editors via sudo. Due to the large number of programs that offer shell escapes, restricting users to the set of programs that do not is often unworkable.

and

noexec
Many systems that support shared libraries have the ability to override default library functions by pointing an environment variable (usually LD_PRELOAD) to an alternate shared library. On such systems, sudo's noexec functionality can be used to prevent a program run by sudo from executing any other programs. Note, ... ...
To enable noexec for a command, use the NOEXEC tag as documented in the User Specification section above. Here is that example again:
aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi
This allows user aaron to run /usr/bin/more and /usr/bin/vi with noexec enabled. This will prevent those two commands from executing other commands (such as a shell).

So in your example:

john ALL=NOEXEC:NOPASSWD: /usr/bin/apt,/usr/bin/apt-get

should be enough to still allow user john to run apt and apt-get with elevated privileges, without being prompted for his password and without having the ability to use a shell escape or other trick exceeds the limits of his authority.

Note that doing so may have unintended results as well. For example after installing a new service apt may not be able to start the associated service.

Score:0
cn flag

This is my attempt, so the user would be use sudo to run this script, but no others.

#!/bin/bash

# This script wraps `apt update` and `apt install`, but attempts to forbid
# arbitrary commands being able to be run by the user as root. It exists
# because allowing the user to `sudo apt` would allow
# `sudo apt changelog apt`, which runs `less` which then would allows the
# user to escape into the shell.

# But, full access to `apt update` and `apt install` still cannot be given,
# since there are 3 ways they can be used to run arbitrary commands
#
# 1. Via options in the APT_CONFIG environment variable
# 2. Via command line options, such as '-o' to specify scripts to run
# 3. Via a local package that contains custom install script(s)
#
# So this script attempts to forbid the 3 above possibilities

# 1. Clear any options in the APT_CONFIG environment variable
export APT_CONFIG=''

# 2. and 3. Forbid command line options or local packages
for var in $*
do
   if [[ ${var::1} == "/" || ${var::1} == "." || ${var::1} == "-" ]]
   then
     echo "E: It's forbidden to install a local package or pass an option"
     exit 1
   fi
done

# Update, and install requested packages
apt update
apt install -y $*
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.