Linux / Security: Sudo ‘sudo su -’ vs ‘sudo -s’
I always use ‘sudo su -’ when I need to get to a root shell. I have seen a few people before, and a new co-worker recently use ‘sudo -s’. Since I could not remember off hand the actual differences between the two, I had to check. The following will run through the actual limitations.
The big difference when using ‘-s’ are listed below
-s The -s (shell) option runs the shell specified by the SHELL environment variable if it is set or the shell as specified inpasswd(5).
Below is the typical sudo command when going to root
$ sudo su -
Now that we are root, check the current environment variables. Here we see that we are in the bash shell, which is different from the Korn (ksh) shell that the user was in. Also note, the home directory is ‘/root’, and the ‘PATH’ locations.
[root@testServ01 ~]# printenv HOSTNAME=testServ01.testDomain.com SHELL=/bin/bash TERM=xterm HISTSIZE=1000 USER=root PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin INPUTRC=/etc/inputrc PWD=/root LANG=en_US.UTF-8 SHLVL=1 HOME=/root LOGNAME=root CVS_RSH=ssh LESSOPEN=|/usr/bin/lesspipe.sh %s DISPLAY=localhost:10.0 G_BROKEN_FILENAMES=1 _=/usr/bin/printenv
When ‘sudo su -’ was executed, we were in the testuser01 home directory (/home/testuser01). After execution, we are now in the root user home directory (/root)
[root@testServ01 ~]# pwd
/root
Now that we have seen what ‘sudo su -’ does, lets check out ‘sudo -s’.
$ sudo -s
Time to check the current environment variables again. Main things to note here are the home directory, PATH definition, and the SUDO_* variables. This is definitely different then what was listed before.
# printenv
_=/usr/bin/printenv
DISPLAY=localhost:10.0 HISTSIZE=1000 HOME=/home/testuser01 HOSTNAME=testServ01.testDomain.com INPUTRC=/etc/inputrc LANG=en_US.UTF-8 LOGNAME=root MAIL=/var/spool/mail/testuser01 PATH=/usr/bin:/bin PWD=/home/testuser01 SHELL=/bin/ksh SUDO_COMMAND=/bin/ksh SUDO_GID=500 SUDO_UID=500 SUDO_USER=testuser01 TERM=xterm USER=root USERNAME=root
When ‘sudo -s’ was executed, we were in the testuser01 home directory (/home/testuser01). After execution, you can see that we are still in the same directory.
# pwd
/home/testact
Since the ‘PATH’ variable was passed from the testuers01 shell to the sudo environment, the administrative tools directories (/sbin, /usr/sbin) are not listed. This is not a huge issue, just more of a hassle if there were not passed from the user account.
Since this was the case for the test, I tried to issue ‘iptables’ without the absolute path. Per below, it failed.
# iptables -L /bin/ksh: iptables: not found [No such file or directory]
Since I do actually have root level access, when I issue the command with the absolute path it works fine
# /sbin/iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination RH-Firewall-1-INPUT all -- anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination RH-Firewall-1-INPUT all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination
To conclude ‘sudo -s’:
Notes: So to be safe, I will still use ‘sudo su -’ when needing root level access. Seems that the ‘sudo -s’ option would be a little more safe for some users. Mainly due to the sbin locations not being in the ‘PATH’. This would make the user execute most administrative commands using the full path to the executable, unless sbin(s) were exported.
The big difference when using ‘-s’ are listed below
<li>This option reads the environment or password file for the shell to be executed. Does not execute root shell!
<li>All environment variables are passed over from the current account to the root account
Per the Linux man page for sudo
<pre>-s The -s (shell) option runs the shell specified by the SHELL environment variable if it is set or the shell as specified in
passwd(5).</pre>
Below is the typical sudo command when going to root
<pre>$ sudo su -</pre>
Now that we are root, check the current environment variables. Here we see that we are in the bash shell, which is different from the Korn (ksh) shell that the user was in. Also note, the home directory is ‘/root’, and the ‘PATH’ locations.
<pre>[root@testServ01 ~]# printenv
HOSTNAME=testServ01.testDomain.com
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
USER=root
PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
INPUTRC=/etc/inputrc
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
CVS_RSH=ssh
LESSOPEN=|/usr/bin/lesspipe.sh %s
DISPLAY=localhost:10.0
G_BROKEN_FILENAMES=1
_=/usr/bin/printenv</pre>
When ‘sudo su -’ was executed, we were in the testuser01 home directory (/home/testuser01). After execution, we are now in the root user home directory (/root)
<pre>[root@testServ01 ~]# pwd
/root</pre>
Now that we have seen what ‘sudo su -’ does, lets check out ‘sudo -s’.
<pre>$ sudo -s</pre>
Time to check the current environment variables again. Main things to note here are the home directory, PATH definition, and the SUDO_* variables. This is definitely different then what was listed before.
<pre># printenv
_=/usr/bin/printenv
DISPLAY=localhost:10.0
HISTSIZE=1000
HOME=/home/testuser01
HOSTNAME=testServ01.testDomain.com
INPUTRC=/etc/inputrc
LANG=en_US.UTF-8
LOGNAME=root
MAIL=/var/spool/mail/testuser01
PATH=/usr/bin:/bin
PWD=/home/testuser01
SHELL=/bin/ksh
SUDO_COMMAND=/bin/ksh
SUDO_GID=500
SUDO_UID=500
SUDO_USER=testuser01
TERM=xterm
USER=root
USERNAME=root</pre>
When ‘sudo -s’ was executed, we were in the testuser01 home directory (/home/testuser01). After execution, you can see that we are still in the same directory.
<pre># pwd
/home/testact</pre>
Since the ‘PATH’ variable was passed from the testuers01 shell to the sudo environment, the administrative tools directories (/sbin, /usr/sbin) are not listed. This is not a huge issue, just more of a hassle if there were not passed from the user account.
Since this was the case for the test, I tried to issue ‘iptables’ without the absolute path. Per below, it failed.
<pre># iptables -L
/bin/ksh: iptables: not found [No such file or directory]</pre>
Since I do actually have root level access, when I issue the command with the absolute path it works fine
<pre># /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
RH-Firewall-1-INPUT all – anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
RH-Firewall-1-INPUT all – anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination</pre>
To conclude ‘sudo -s’:
<li>does NOT change the shell
<li>’PATH’ does not change since root shell is not executed
<li>carries over all environment variables from the non-privileged user
Notes: So to be safe, I will still use ‘sudo su -’ when needing root level access. Seems that the ‘sudo -s’ option would be a little more safe for some users. Mainly due to the sbin locations not being in the ‘PATH’. This would make the user execute most administrative commands using the full path to the executable, unless sbin(s) were exported.

Note that “sudo -i” generally achieves the same thing as “sudo su -”. It will “simulate initial login” of the runas_default user in sudoers, which is usually “root”. In short, it is like “sudo -s” except that it does process the normal login settings files. It is what I tend to use when I need to get to a root shell as it is fewer keystrokes, and I am lazy.
qhartman said this on August 18, 2009 at 5:57 pm
Good information. Will check it out tomorrow. I am the same way, the less keystrokes the better! FYI, that wood burning stove in your flickr album is awesome.
Kevin Goodman said this on August 18, 2009 at 6:27 pm
[...] is the original post: Linux / Security: Sudo 'sudo su -' vs 'sudo -s' « Colocation to … Posted in: [...]
Linux / Security: Sudo 'sudo su -' vs 'sudo -s' « Colocation to … | Linux Affinity said this on August 18, 2009 at 8:32 pm
Good information. Will check it out tomorrow. I am the same way, the less keystrokes the better! FYI, that wood burning stove in your flickr album is awesome.
Sorry, forgot to add great post! Can’t wait to see your next post!
Kevin Goodman said this on August 19, 2009 at 5:03 am
Very nice article! The problem I have is how to find out who is who in /var/log/secure. If there are 2 users on the system and both are working in a root shell it is impossible to find out what they did after switching to root. Any idea how to solve that?
nice blog! keep up the good work!
cheers
mod said this on September 12, 2009 at 1:08 am
Enable process accounting. This will at least get you the ability to follow an audit trail using timestamps. Can track what user was accessing the root account and the commands issued.
Kevin Goodman said this on September 14, 2009 at 10:55 am
the dash in “su -” brings in the environment of the user you’re switching to, in this case since no user is specified the default is the root user.
If you su (no dash) you will become root without executing the switched user’s environment.
So I guess the question in my mind is what’s the difference between “sudo -s” and “sudo su”
Anonymous said this on August 18, 2010 at 7:57 am