Linux security - SUDO

mail

What's the difference between sudo -i and sudo su - ?

For reference or reminder :

The size of the environment returned by env :

kevin@myComputer:~$ sudo -i
[sudo] password for kevin:
root@myComputer:~# env | wc -l
34
root@myComputer:~# exit
logout

kevin@myComputer:~$ sudo su -
root@myComputer:~# env | wc -l
26
root@myComputer:~# exit
logout

Let's have a deeper look at the environment :

kevin@myComputer:~$ sudo -i
root@myComputer:~# env > ~kevin/sudo_-i.txt && logout

kevin@myComputer:~$ sudo su -
root@myComputer:~# env > ~kevin/sudo_su_-.txt

root@myComputer:~# diff ~kevin/sudo_-i.txt ~kevin/sudo_su_-.txt
2,4c2
< COLORTERM=truecolor
< SUDO_GID=1000
< LANGUAGE=en_EN.UTF-8
---
> LANGUAGE=en

7d4
< SUDO_COMMAND=/bin/bash
9d5
< SUDO_USER=kevin
12d7
< XAUTHORITY=/home/kevin/.Xauthority
14d8
< LANG=en_US.UTF-8
15a10
> LANG=en_US.UTF-8
17d11
< XDG_CURRENT_DESKTOP=XFCE
23d16
< DISPLAY=:0.0

30,31c23
< PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin                            :/snap/bin	spaces added to compare with the line below
< SUDO_UID=1000
---
> PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
  • sudo -i provides some protection to the system when users become root by limiting the environment which they are given : suspicious paths (like /usr/*games) are stripped from $PATH.
  • More about su -
mail

Is it mandatory that /etc/sudoers.d/filename matches username ?

Let's !

man sudoers + searching sudoers.d says that the /etc/sudoers.d/* configuration files will be included by /etc/sudoers if their name :
  • do not end with ~ : these are often editor backup files
  • have no . : these are often editor temporary files
Apart from these rules, no restrictions on file names.

Let's check it :

Run this as root :
username='bob'; sudoersFile='/etc/sudoers.d/sudoersFileWithGenericName'; useradd -m "$username"; echo "$username ALL=(root) NOPASSWD:$(which whoami)" > "$sudoersFile"; su - "$username" -c "whoami; sudo whoami"; [ -f "$sudoersFile" ] && rm "$sudoersFile"; userdel -r "$username"
bob
root
  • It works : we can grant sudo privileges to bob using a file which name has nothing to do with "bob".
  • However, based on the principle of least astonishment —and as a "lazy" admin— sounds like a fair practice that anything related with bob actually mentions "bob" .
mail

sudo vs ssh root

According to this article, there are several solutions when it comes to get elevated privileges (i.e. root) on a GNU/linux box. The most popular one is to use sudo, but this _may_ not be the safest solution, an alternative being using SSH with some localhost-specific settings.

SSHd settings

Common settings

# disable password logins
PasswordAuthentication no
ChallengeResponseAuthentication no	# OpenSSH <8.7 (Debian)
KbdInteractiveAuthentication no	# OpenSSH 8.7+
PubkeyAuthentication yes

Let root log in with a key :

from everywhere :
PermitRootLogin prohibit-password
from localhost only :
PermitRootLogin no

Match Address 127.0.0.1
PermitRootLogin prohibit-password
As a good practice, Match directives should be found at the bottom of the file.

Other SSHd settings worth considering in this context

AllowUsers root
only root can log in
LoginGraceTime 30s
SSHd will close the connection if you fail to log in within 30s
MaxAuthTries 4
up to 4 attempts to log in, starting to log halfway
PerSourceMaxStartups 1
MaxStartups 4096
limit the number of concurrent unauthenticated connections to SSHd
TODO:
 * check if it's possible to specify both :
	from="12.34.56.78" command="cmd" ssh-ed25519 key
 * some docs mention "PermitRootLogin forced-commands-only" as a prerequisite...
mail

How to open a shell as an other user whose login shell is disabled ?

Situation

Solution

Alternate solution

  1. become root :
    sudo -i
  2. as root, become stuart :
    su -s /bin/bash - stuart
mail

How to login as root via sudo only ?

On modern (decent !) Linux distributions, you can not log in as root anymore. Instead, users can be allowed to get elevated privileges with sudo. This is a good thing : To do so :
  1. Open a terminal as root (in the CTRL-ALT-Fn screens) just in case something goes wrong in the process. Leave it as is, and continue the procedure in another terminal.
  2. Become a sudoer. This implies adding
    bob	ALL=(root)	/bin/su
    to /etc/sudoers.d/bob.
  3. Try it, as bob :
    sudo su -
    After typing your password, you should have become root.
  4. Now, as root, disable the root password : passwd -l root
  5. Check this with : grep root /etc/shadow
    root:!$6$fRTcws15$d7doaLc.WNnUK/4l4mHTnA......
    Read more about ! and * in the password field of /etc/shadow
  6. Try opening a shell as root, it should fail now.
  7. Enjoy
mail

How to become a sudoer ?

The bare minimum of sudoing : let Bob become a sudoer, while using local authentication :

This is potentially granting too many rights !

As root :
  1. Make Bob a member of the sudo group : adduser bob sudo
  2. touch /etc/sudoers.d/bob
    At this step, Bob can already run sudo commands because :
    • he belongs to the sudo group
    • and thanks to this directive in /etc/sudoers :
      # Allow members of group sudo to execute any command
      %sudo ALL=(ALL:ALL) ALL
    • syntax of the sudoers rules
  3. Edit it with your favorite text editor :
    bob ALL=(root) NOPASSWD:/usr/sbin/service
    • There must be a LF after the last directive, otherwise trying to use these new permissions will fail :
      >>> /etc/sudoers.d/bob: syntax error near line 1 <<<
      sudo: parse error in /etc/sudoers.d/bob near line 1
      sudo: no valid sudoers sources found, quitting
      sudo: unable to initialize policy plugin
    • Both [space] and [TAB] indentation are supported
  4. Save, exit, then chmod 440 /etc/sudoers.d/bob

Syntax of sudoers rules :

%sudo ALL=(ALL:ALL) ALL
stands for :
who where = (as_whom) what
  • who :
    • name of user or group (specified as %groupName) receiving extra privileges
    • full details : man -P 'less -p "User ::="' sudoers
  • where :
    • hostname or IP address (if any) or ALL
    • full details : man -P 'less -p "Host ::="' sudoers
  • as_whom :
    • specified with runAsUser:runAsGroup
    • full details : man -P 'less -p "Runas_Member ::="' sudoers
  • what :
    • the command for which we're doing all this
    • full details : man -P 'less -p "Cmnd_List ::="' sudoers

Notes about sudo passwords (source) :

When launching a sudo command :
  1. sudo prompts for the user password
  2. IF the password is correct AND IF the command is allowed :
    • sudo saves the elevated permission into a dedicated cache
    • looks like the default cache duration has been decreased from 15 minutes to 5 minutes (set to 5 minutes in sudo 1.8.31, not checked previous versions)
    OTHERWISE (wrong password OR forbidden command) :
    • nothing is cached
  3. The next time a sudo command is launched, the permission is checked from the cache (if available)
To purge the cache : sudo -k

Using LDAP authentication

Contents of /etc/sudoers :
bob ALL=(ALL) ALL
becomes (literally) :
sudoUser sudoHost=(sudoRunAs) sudoCommand sudoOption
in the LDAP rules. (details)