iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
👨

People who use 'sudo su' are mostly old-timers

に公開

https://twitter.com/tmtms/status/1395691473266372611

This random post I wrote got a "decent" reaction.

Come to think of it, I started using sudo over 20 years ago, and since my memory was a bit fuzzy, I decided to look it up.

Summary

Current Directory Inherited Environment Variables Shell Login Shell
su Unchanged Almost all Default shell No
su - User's home Only TERM Default shell Yes
sudo su Unchanged Some Default shell No
sudo su - User's home Only TERM Default shell Yes
sudo -s Unchanged Some $SHELL at execution No
sudo -i User's home Some Default shell Yes

sudo su and sudo -s are almost the same. The shell being executed may differ.

sudo su - and sudo -i are also almost the same. In terms of clearing environment variables, sudo su - is more thorough.

You don't necessarily need to read the rest.

su

A command to execute a shell as another user. I call it "su" or "S-U."
It seems it originally stood for "super user," "switch user," or "substitute user."

By default, it switches to root, but you can specify a username as an argument to switch to that user.
The shell configured as the default for the new user is executed.

The password to enter is the password of the new user.

~% su
Password: (root password)
root@hostname:/home/tmtms# id
uid=0(root) gid=0(root) groups=0(root)
root@hostname:/home/tmtms# 
~% su hoge
Password: (hoge's password)
hoge@hostname:/home/tmtms$ id
uid=1001(hoge) gid=1001(hoge) groups=1001(hoge)
hoge@hostname:/home/tmtms$ 

Arguments added after the username are passed to the shell.

~% su hoge -c id
Password: (hoge's password)
uid=1001(hoge) gid=1001(hoge) groups=1001(hoge)
~% 

The current directory does not change.

If the shell is bash, it executes /etc/bash.bashrc and ~/.bashrc. However, since it is not a login shell, /etc/profile and ~/.profile are not executed.

Environment variables HOME and SHELL are set. If switching to a user other than root, USER and LOGNAME are also set. Other environment variables are inherited.

When I actually tried su on Ubuntu, PATH and MAIL were also changed.

There are settings like the following for PATH in /etc/login.defs, but the values are different, so it doesn't seem to be this.

#
# *REQUIRED*  The default PATH settings, for superuser and normal users.
#
# (they are minimal, add the rest in the shell startup files)
ENV_SUPATH      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV_PATH        PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

It's written in /etc/pam.d/su and /etc/environment as follows, and this seems to be what's taking effect.

# This module parses environment configuration file(s)
# and also allows you to use an extended config
# file /etc/security/pam_env.conf.
# 
# parsing /etc/environment needs "readenv=1"
session       required   pam_env.so readenv=1
# locale variables are also kept into /etc/default/locale in etch
# reading this file *in addition to /etc/environment* does not hurt
session       required   pam_env.so readenv=1 envfile=/etc/default/locale
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"

MAIL is also affected by this in /etc/pam.d/su. Probably.

# Defines the MAIL environment variable
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
# in /etc/login.defs to make sure that removing a user 
# also removes the user's mail spool file.
# See comments in /etc/login.defs
#
# "nopen" stands to avoid reporting new mail when su'ing to another user
session    optional   pam_mail.so nopen

su -

Similar to su, a shell is executed as the new user, but it is executed as a login shell.

The current directory also becomes the new user's home directory.

If the shell is bash, files such as /etc/profile, ~/.bash_profile, ~/.bash_login, and ~/.profile are executed.

Environment variables are cleared, but there is one exception: the TERM environment variable is inherited. This is because if TERM were cleared, terminal control would break...

sudo

A command to execute commands as another user. I call it "su-doo" (sudo).
While su executes a shell, sudo allows you to specify the command to execute as an argument.

The password to enter is the password of the original user (the user who executed sudo).

~% sudo id
[sudo] password for tmtms: (original user's password)
uid=0(root) gid=0(root) groups=0(root)
~% 

By default, it switches to root, but you can specify a user with the -u option.

~% sudo -u hoge id
[sudo] password for tmtms: (original user's password)
uid=1001(hoge) gid=1001(hoge) groups=1001(hoge)
~% 

The current directory does not change.

Various environment variables are inherited (described later).

Since you only need to enter your own password, it is convenient to be able to execute commands as root without knowing the password of other users, especially root.

That said, we can't have just anyone executing commands as root, so the people who can use sudo are restricted in /etc/sudoers.
In Ubuntu, users belonging to the admin group or the sudo group can use sudo.

On Ubuntu, no password is set for root, so su cannot be used. If you need to perform tasks as root, you use sudo.

Once you enter your password for sudo, you can execute it without a password for a certain amount of time (15 minutes by default), so it's convenient not to be asked for a password every time when executing sudo consecutively. You can reset the timer with sudo -K.

Sometimes accidents happen where you preemptively type your password thinking you'll be asked, but since 15 minutes haven't passed since the last execution, the password string ends up being displayed in the terminal...

sudo -s

It's nice to be able to just prefix a command with sudo when you want to run it as root, but sometimes you want to use shell features (like wildcards or redirection) as root, so you want to run an interactive shell with sudo.

In those cases, the aforementioned sudo su is sometimes used.

sudo su executes su with root privileges, and su executes a shell as root, so as a result, you end up launching a shell as root using sudo.

~% sudo su
[sudo] password for tmtms: (original user's password)
root@hostname:/home/tmtms# 

Well, that's fine, but I feel like sudo bash would be simpler. Although it requires more typing.

~% sudo bash
[sudo] password for tmtms: (original user's password)
root@hostname:/home/tmtms# 

Now, sudo has an option called -s, which allows you to start a shell. This seems better than sudo su.

However, unlike su, the shell launched in this case uses the value of the SHELL environment variable at the time sudo was executed.

~% sudo -s
[sudo] password for tmtms: (original user's password)
hostname# 

sudo -i

sudo also has an -i option, which, like su -, starts the shell as a login shell.
The shell is properly the default shell of the new user, and the current directory also becomes the new user's home directory.

% sudo -i
[sudo] password for tmtms: (original user's password)
root@hostname:~# 

sudo Environment Variables

Running sudo -V as root displays various sudo settings. The environment variables that are inherited are also output here.

~% sudo -V
Sudo version 1.9.5p2
Sudoers policy plugin version 1.9.5p2
Sudoers file grammar version 48
Sudoers I/O plugin version 1.9.5p2
Sudoers audit plugin version 1.9.5p2
~% sudo sudo -V 
Sudo version 1.9.5p2
configure options: --build=x86_64-linux-gnu --prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-option-checking --disable-silent-rules --libdir=${prefix}/lib/x86_64-linux-gnu --libexecdir=${prefix}/lib/x86_64-linux-gnu --disable-maintainer-mode --disable-dependency-tracking -v --with-all-insults --with-pam --with-fqdn --with-logging=syslog --with-logfac=authpriv --with-env-editor --with-editor=/usr/bin/editor --with-exampledir=/usr/share/doc/sudo/examples --with-timeout=15 --with-password-timeout=0 --with-passprompt=[sudo] password for %p:  --without-lecture --with-tty-tickets --disable-root-mailer --enable-admin-flag --with-sendmail=/usr/sbin/sendmail --with-rundir=/run/sudo --libexecdir=/usr/lib --with-sssd --with-sssd-lib=/usr/lib/x86_64-linux-gnu --enable-zlib=system --with-selinux --with-linux-audit --enable-tmpfiles.d=yes MVPROG=/bin/mv
Sudoers policy plugin version 1.9.5p2
Sudoers file grammar version 48

Sudoers path: /etc/sudoers
Authentication methods: 'pam'
Syslog facility if syslog is used for logging: authpriv
Syslog priority if syslog is used for logging: notice
Syslog priority to use when user authentication fails: alert
Send mail if user authentication fails
Send mail if user is not in sudoers
Lecture user the first time they run sudo
Require user to be authenticated by default
Root may run sudo
Allow gathering of some information to display useful error messages
Require fully qualified hostnames in the sudoers file
visudo honors the EDITOR environment variable
Set the LOGNAME and USER environment variables
Length at which to wrap log file lines (0 for no wrap): 80
Authentication timestamp timeout: 15.0 minutes
Password prompt timeout: 0.0 minutes
Number of password attempts: 3
umask to use (0777 means use user's value): 022
Path to mail program: /usr/sbin/sendmail
Flags for mail program: -t
Address to send mail to: root
Subject line for mail: *** SECURITY information for %h ***
Incorrect password message: Sorry, try again.
Path to lecture status directory: /var/lib/sudo/lectured
Path to authentication timestamp directory: /run/sudo/ts
String to use for password prompt: [sudo] password for %p: 
Default user to run commands as: root
Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
Path to editor used by visudo: /usr/bin/editor
When to require a password for 'list' pseudo-command: any
When to require a password for 'verify' pseudo-command: all
Close file descriptors >= 3 before executing command
Set the collection of environment variables to default
Environment variables to check for safety:
	TZ
	TERM
	LINGUAS
	LC_*
	LANGUAGE
	LANG
	COLORTERM
Environment variables to remove:
	*=()*
	RUBYOPT
	RUBYLIB
	PYTHONUSERBASE
	PYTHONINSPECT
	PYTHONPATH
	PYTHONHOME
	TMPPREFIX
	ZDOTDIR
	READNULLCMD
	NULLCMD
	FPATH
	PERL5DB
	PERL5OPT
	PERL5LIB
	PERLLIB
	PERLIO_DEBUG
	JAVA_TOOL_OPTIONS
	SHELLOPTS
	BASHOPTS
	GLOBIGNORE
	PS4
	BASH_ENV
	ENV
	TERMCAP
	TERMPATH
	TERMINFO_DIRS
	TERMINFO
	_RLD*
	LD_*
	PATH_LOCALE
	NLSPATH
	HOSTALIASES
	RES_OPTIONS
	LOCALDOMAIN
	CDPATH
	IFS
Environment variables to preserve:
	XAUTHORIZATION
	XAUTHORITY
	PS2
	PS1
	PATH
	LS_COLORS
	KRB5CCNAME
	HOSTNAME
	DPKG_COLORS
	DISPLAY
	COLORS
Locale to use when parsing sudoers: C
Compress I/O logs using zlib
Directory in which to store input/output logs: /var/log/sudo-io
File in which to store input/output logs: %{seq}
Add records to utmp/utmpx file when a pty is allocated
PAM service name to use: sudo
PAM service name to use for login shells: sudo
Attempt to authenticate using PAM credentials for the target user
Create a new PAM session for the command to be run
Performing PAM account validation management
Enable sudoers netgroup support
Verify that the parent directory is writable when editing files with sudoedit
Allow command execution even if audit log file cannot be written to
Allow command execution even if log file cannot be written to
Log entries longer than this will be split into multiple syslog messages: 960
File mode for I/O logs: 0600
Use file descriptors instead of paths when executing commands: digest_only
Type of authentication timestamp: tty
Ignore case when looking up usernames
Ignore case when looking up group names
Log when a command is allowed by sudoers
Log when a command is denied by sudoers
Sudo log server timeout in seconds: 30
Enable SO_KEEPALIVE socket option on sockets connected to the log server
Verify that the log server's certificate is valid
Set PAM remote user to the user running sudo
Format of logs to generate: sudo
Enable SELinux RBAC support

Local IP address and netmask pairs:
	xxx.xxx.x.xxx/xxx.xxx.xxx.x
	xxx.xxx.x.xxx/xxx.xxx.xxx.x
	xxx.xx.x.x/xxx.xxx.x.x
	xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxx/xxxx:xxxx:xxxx:xxxx::
	xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
	xxxx::xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
	xxxx:xxxx:xxxx:xxxx:xxxx:xxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::
	xxxx::xxxx:xxxx:xxxx:xxxx/xxxx:xxxx:xxxx:xxxx::

Sudoers I/O plugin version 1.9.5p2
Sudoers audit plugin version 1.9.5p2

Discussion