2

What is the correct way to update the sudoers file programmatically? Specifically:

  • How can I add ,timestamp_timeout=600 to the end of the Defaults env_reset line in my sudoers files (to increase the sudo nag time to 10 hours), and doing this programmatically and without destroying the system (I tried this once and made my Linux system unbootable and had to reinstall). I have read that chmod 440 might be important for this.
  • I understand that this is dangerous, I understand why it is protected, but these are my home systems where I have a script that runs through dozens of simple configuration changes (and I rebuild those systems fairly regularly also, so it would be useful to me to be able to automate this).
  • I am most interested in how to do with this with standard Linux tools that I can put into a bash script, but I would be very interested to also see how this exact operation is done in Ansible so that I could roll out simple changes like this to all sudoers files on my home network.
  • On this page there is a discussion on the sudoers file, but I don't quite understand the references to visudo -c -f; I think what is being suggested there is: copy the sudoers file, then make changes to that copy, then visudo -c -f to check that the new file is valid, then overwrite sudoers, then chmod 440 on that new file, is that it? I'm not sure of the steps to implement this.
11
  • 2
    Changing the sudoers file will not make your system unbootable. The worst thing that will happen is that you can't use sudo any longer, but booting into single-user mode to fix that should be easy, or at least doable.
    – Kusalananda
    Commented Oct 14, 2021 at 10:27
  • My system because unbootable. It's possible that other things contributed to that, but it was more than a year ago, so I gave up attempting to do this, but I figure, surely there must be a clean and reliable way to automate this (or at least I am hoping so).
    – YorSubs
    Commented Oct 14, 2021 at 10:29
  • @YorSubs at least configuration files related, you can always boot a live linux and change the file there, no need to reinstall. Commented Oct 14, 2021 at 10:31
  • man visudo gives you detailed explanations on the use of the command and its options. Commented Oct 14, 2021 at 10:33
  • 1
    @YorSubs I was just pointing out that the -f option does somenthing different than checking syntax (at least that's what I interpret from your comment). I almost never change the sudoers file, but if I would, I'd follow the advice on the file # Please consider adding local content in /etc/sudoers.d/ instead of directly modifying this file.. Commented Oct 14, 2021 at 12:53

2 Answers 2

5

Programmatically, the best approach is to add files to /etc/sudoers.d with all the directives you need. These files need to be owned by root and have mode 0440. Adding files to /etc/sudoers.d brings three benefits: it reduces risk related to modifying /etc/sudoers for arbitrary changes; in most cases it means that the system’s default /etc/sudoers can be preserved, which simplifies future upgrades involving modifications to /etc/sudoers; and it makes it easy to see the changes that have been made to the default configuration.

Adding a file will work even for your timeout setting: Defaults lines can be repeated, so adding

Defaults timestamp_timeout=600

has the same effect as appending it to the existing Defaults env_reset line.

For this to work, you need to ensure that /etc/sudoers contains

@includedir /etc/sudoers.d

This is the default for recent installations of sudo, but you can ensure this programmatically as follows:

if ! sudo grep -q '^[@#]includedir /etc/sudoers.d$' /etc/sudoers; then
    sudo sed '$a\\n@includedir /etc/sudoers.d' /etc/sudoers > /etc/sudoers.new
    sudo visudo -c -f /etc/sudoers.new && sudo mv /etc/sudoers{.new,}
fi

(Don’t try using the SUDO_EDITOR trick here, because visudo will process /etc/sudoers.d/README too, resulting in an @include loop.)

2
  • Thanks, the SUDO_EDITOR trick that @cas gave me is really great (and he also answers a confusion that I had about why when I set EDITOR and VISUAL to vim, that visudo is still opening in nano, so I need to export SUDO_EDITOR=vim, good to know), but probably sudoers.d is the cleanest, most efficient approach. I forgot about the {.new,} syntax, great. However, what does the $a mean in the sed expression?
    – YorSubs
    Commented Oct 15, 2021 at 7:48
  • 1
    $a means “on the last line, append the following text”. Commented Oct 15, 2021 at 7:51
4

Warning: the following works. Whether it's a good idea to do this or not is debatable. But if you're going to do it, this is one of the less unsafe ways of doing it.

You can do this by setting and exporting the SUDO_EDITOR variable to invoke sed with a script that changes the file. e.g.

export SUDO_EDITOR='sed -i -e "s/^Defaults.*env_reset$/&,timestamp_timeout=600/"'
visudo
unset SUDO_EDITOR

This, of course, needs to be run as root. Normally SUDO_EDITOR is undefined....but it can be used to tell visudo to use vi or nano or joe or whatever you prefer (it has precedence with visudo over the more generic EDITOR and VISUAL env vars which are used by lots of programs. visudo will use them if they are defined but SUDO_EDITOR isn't). In this case, we're using a stream editor (sed) instead of an interactive editor.

If whatever changes you make are invalid, visudo will notice and ask you what to do. Your choices are:

What now?
Options are:
  (e)dit sudoers file again
  e(x)it without saving changes to sudoers file
  (Q)uit and save changes to sudoers file (DANGER!)

You will want to use option x. e will just run sed again, and Q will save your broken changes.

BTW, if you need to make other changes to /etc/sudoers and there's some reason why you can't just drop a file in /etc/sudoers.d/ then I very strongly recommend testing your changes on a copy of /etc/sudoers (e.g. to /tmp/sudoers) and using the -f option with visudo.

You can verify that the correct changes were made with diff. If it worked, great, you can run it without -f /tmp/sudoers. If it failed, run the cp command again to copy the original file again (i.e. revert whatever your SUDO_EDITOR command did), change SUDO_EDITOR and run visudo again. Repeat until it does what you want.

# cp -af /etc/sudoers /tmp/
# export SUDO_EDITOR='sed -i -e "s/^Defaults.*env_reset$/&,timestamp_timeout=600/"'
# visudo -f /tmp/sudoers 
# unset SUDO_EDITOR
# diff -u /etc/sudoers /tmp/sudoers
--- /etc/sudoers    2020-07-18 02:57:35.220317224 +1000
+++ /tmp/sudoers    2021-10-15 03:26:13.048804192 +1100
@@ -9,7 +9,7 @@
 
 Defaults exempt_group=sudo
 
-Defaults   env_reset
+Defaults   env_reset,timestamp_timeout=600
 Defaults   mail_badpass
 Defaults   secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

BTW, You can use anything that modifies a file here - if you prefer perl or python or even a shell script (e.g. a wrapper script around ed or ex or some other scriptable editor), there's no reason why you can't set SUDO_EDITOR to run that instead of sed. As long as it changes the file given it by visudo, it will work. Be careful about whitespace and nested quoting.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .