Allowing a less trusted user to run apt-get update
is ok. They worst they can do is consume a lot of bandwidth and fill up some disk space, and they have plenty of other means to do this unless you've taken stringent measures to prevent this.
Allowing a user to run apt-get upgrade
is likely to give them root access. Some packages query the user and might allow a shell escape; for example the user who has access to the terminal that apt-get upgrade
(or any dpkg -i
call) is running on might get prompted for what to do if a configuration file has been updated, and one of the options there is to run a shell to examine the situation.
You need to restrict the command some more:
#!/bin/sh
set -ex
exec </dev/null >"/var/log/automatic-apt-upgrade-$(date +%Y%m%d-%H%M%S)-$SUDO_USER.log" 2>&1
apt-get --assume-no upgrade
This shouldn't give the user a way to become root, since they can't interact with the package manager. As upgrades can sometimes break a system, and a user with only these permissions wouldn't be able to repair anything, this should only be done with a stable release, with only security updates pending. If it's a kernel update, let a user with full root access decide when to trigger a reboot.
By the way, the user wouldn't be able to inject package content — to do that, they'd need to be in control of the server distributing the package, and in addition to the server signing the package if the package is signed (which is the case for all official sources). It's irrelevant for this attack vector who's in command of the machine at the time of the upgrade.
All this being said… use unattended-upgrades, if that's what you want.
Solution
- Create a new Group:
groupadd -r updaters
The -r
option reserves a system group, i.e. 0 - 100.
- Add Users to Above Group:
useradd -G updaters john
, useradd -G updaters sally
. You can also use the user alias section to acheive this. See Sudoer File Examples for a fully functioning User Alias Section. In my opinion, doing it the way I've done adds security, as the group actually exists in the system.
- Create your command list for updaters: Note: Apt-get uses argument passing. See Problem Section
Cmnd_Alias UPDATE_CMDS = /usr/bin/aptitude, /usr/bin/dpkg, /usr/bin/apt-get up*, /usr/bin/apt-get install
- Note that
dpkg
is needed for apt-get
. See AskUbuntu: Adding apt-get to sudoers file.
- Note that
apt-get update
and apt-get upgrade
are both needed. Using a glob pattern achieves both.
- Note that
aptitude
may be used to replace apt-get
if the dpkg
behavior noted above is undesired. If you don't want users in the updaters
group to install off the internet with a mouse click...
Now we must add our updates into our sudoers file. Issue: visudo
,and:
The default sudoers file from Ubuntu (with adds from above):
# /etc/sudoers
#
# This file MUST be edited with the 'visudo' command as root.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
# Uncomment to allow members of group sudo to not need a password
# %sudo ALL=NOPASSWD: ALL
# Host alias specification
# User alias specification
# Cmnd alias specification
Cmnd_Alias UPDATE_CMDS = /usr/bin/aptitude, /usr/bin/dpkg, /usr/bin/apt-get up*, /usr/bin/apt-get install
# User privilege specification
root ALL=(ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Members of the upgraders group may perform certain upgrade commands.
# If No Password is desired, comment the line below, and see the next option.
%upgraders ALL=UPDATE_CMDS
# Members of the upgraders group may perform certain upgrade commands,
# WITHOUT A PASSWORD DANGEROUS (uncomment if desired):
#%upgraders ALL=NOPASSWD:UPDATE_CMDS
If you decide to add unattended-upgrade
, read the Debian Documentation on it. and use which unattended-upgrade
to determine the path to add it to UPDATE_CMDS
. See Problem Section.
Update
After even more research, I ran across a Blogpost: Everything you need to know about conffiles: configuration files managed by dpkg. The problem is not in apt variants, the problem is in the underlying dpkg
implementation. Quoting:
Avoiding the conffile prompt
Every time that dpkg must install a new conffile that you have
modified (and a removed file is only a particular case of a modified
file in dpkg’s eyes), it will stop the upgrade and wait your answer.
This can be particularly annoying for major upgrades. That’s why you
can give predefined answers to dpkg with the help of multiple
--force-conf* options:
- --force-confold: do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix. With this
option alone, even configuration files that you have not modified are
left untouched. You need to combine it with --force-confdef to let
dpkg overwrite configuration files that you have not modified.
- --force-confnew: always install the new version of the configuration file, the current version is kept in a file with the
.dpkg-old suffix.
- --force-confdef: ask dpkg to decide alone when it can and prompt otherwise. This is the default behavior of dpkg and this option
is mainly useful in combination with --force-confold.
- --force-confmiss: ask dpkg to install the configuration file if it’s currently missing (for example because you have removed the
file by mistake).
Knowing this, as the blog points out, we can create /etc/apt/apt.conf.d/local
, and add (example):
Dpkg::Options {
"--force-confdef";
"--force-confold";
}
This should then bypass the Z
option all together.
Problem
Unattended Upgrades are usually a bad idea, because the OS may install items that were unexpected, for example new kernels, or updated drivers that will break a functioning driver, added to the idea that you're giving the option to a user. The other issue here is that since apt-get
uses argument passing to decide which option to perform, one must pass each desired option in the Command Alias created. By adding each argument separately, we remove the ability to use the dist-upgrade
argument. Like you, I assumed one could not pass an argument in the sudoers file, and while researching I too, learned something new.
References
nixCraft - Howto: Linux Add User To Group
Aptitude - Ubuntu Documentation
Ubuntu Forums - Thread: HowTO: Sudoers Configuration
Ubuntu Documentation - Installing Software
AskUbuntu - What is the difference between apt-get update and upgrade?
Best Answer
For basic operation — running commands as root — the most visible difference between sudo and su is that sudo requires the password of the calling user (i.e. your password) whereas su requires the password of the target user (i.e. the root password). The security implications have been discussed extensively in a previous question: Which is the safest way to get root privileges: sudo, su or login?.
Sudo has additional features beyond su's. In particular, once you have a user's password, you can run any command as that user. On the other hand, sudo can be configured so that the user invoking it can only run specific commands as some other user. This is possible because sudo doesn't require any authentication (other than perhaps confirming that you are you by typing your password — but that's subtly different from authenticating your user for a task).
You change the sudo configuration by running the
visudo
command as root (never edit the configuration directly). Make sure the environment variableEDITOR
orVISUAL
is set to your favorite editor or you may get an unfamiliar editor. Thesudoers
man page is a bit terse but has examples. To allow the userbob
to run/bin/foo
(with any number of arguments) and/bin/bar --safe
(but not with any other argument) asroot
, use the following lines: