Ubuntu – Make sudo not ask for password for n minutes after login

passwordsshsudo

I regularly log in to boxen via SSH, and run update and so forth as root, using sudo.

I appreciate that sudo asks for password after a certain time, in case I walk away from terminals or such. But as I already have entered either login password, or SSH key phrase, I would prefer sudo not to ask for a password for the first n minutes after a login, but behave as if sudo had been executed successfully immediately after login.

Is this possible to configure so that no password is required for first invocation after login?

To make an example of the desired behaviour

ssh foo@example.org
[~]$ sudo somecommand
[~]$ #no password asked.
[~]$ sudo somecommand #n minutes later
[sudo] password for foo: 

Best Answer

Here's an idea for how it could be done. NOTE: this is a hack; use only if the words passwordless sudo make your eyebrows want to crawl all the way up your skull.

The premise is: we cannot pass login credentials to sudo. So the question is how to have a NOPASSWD sudo for only the first few minutes of a login. We can do that by starting the login shell in NOPASSWD mode, and spawning a background process in .bashrc which after some minutes undoes the NOPASSWD.

# somewhere near the bottom of ~/.bashrc
sudo -n /bin/bash -c "$HOME/nopasswd-sudo 60s 12h <&- >&- &"

Of course the script itself must be started with NOPASSWD sudo, or we would be still be prompted for a password. And the script must reinstate the NOPASSWD rule when the bash session ends, so that NOPASSWD is set for the next login.

Here is the script $HOME/nopasswd-sudo that will do that:

#!/bin/bash

SUDO_FILE="/etc/sudoers.d/$(basename "$0")-${SUDO_USER}"
SUDO_RULE="${SUDO_USER} ALL=(ALL:ALL) NOPASSWD: ALL"

[ -z "$SUDO_USER" ] &&
     echo "$(basename "$0"): must be invoked with sudo" >&2 &&
     exit 1

# Trap exit to recreate SUDO_FILE for next login
trap "echo '$SUDO_RULE' > '$SUDO_FILE'; exit 0" EXIT

# First time around just exit, creating the SUDO_FILE
[ -f "$SUDO_FILE" ] || exit 0

# After $1 (default 5m) remove SUDO_FILE to end NOPASSWD sudo
sleep ${1:-5m} && rm -f "$SUDO_FILE"

# Wait until our parent exits, and we will exit via the trap
# If after $2 (default 12h) still alive, we assume we missed the HUP
sleep ${2:-12h}

On its first run (which must done from the command-line, not from .bashrc), the script creates the file /etc/sudoers.d/nopasswd-sudo-$USER containing a NOPASSWD wildcard for the logged in $USER:

{username} ALL=(ALL:ALL) NOPASSWD: ALL

Then on every login it starts and waits in the background until the passwordless time is up, after which it removes the file, and the next sudo will require a password.

After that it waits indefinitely (actually, up to 12h, to prevent lingering orphans that missed their parent's HUP signal), or until its parent, the login shell, ends. Just before it exits, its EXIT trap recreates the NOPASSWD file.


Tip for the adventurous: remember to always keep a separate root shell open while you mess with login scripts or sudo rules. You wouldn't be the first to lock yourself out.

Related Question