What is the difference between sudo -i and sudo su?
- 1,283
-
To be fair, while answers to the linked question address "sudo su", it was not part of the original linked question. – Ian Robertson Nov 14 '16 at 18:20
3 Answers
Based on the descriptions from the man pages for su and sudo I would assume the following things:
- Since
sudo -iu <user>means a login shell this would be equivalent to ansu - <user>orsu -l <user>. - An
suwithout any arguments changes your effective user ID but you're still using your original<user>environment and awho am iwill report you're still<user>.
excerpt sudo man page
-i [command]
The -i (simulate initial login) option runs the shell specified in
the passwd(5) entry of the target user as a login shell. This means
that login-specific resource files such as .profile or .login will
be read by the shell. If a command is specified, it is passed to
the shell for execution. Otherwise, an interactive shell is
executed. sudo attempts to change to that user's home directory
before running the shell. It also initializes the environment,
leaving DISPLAY and TERM unchanged, setting HOME, MAIL, SHELL,
USER, LOGNAME, and PATH, as well as the contents of
/etc/environment on Linux and AIX systems. All other environment
variables are removed.
Example
I have a user account, saml with a UID of 500.
$ egrep "Uid|Gid" /proc/$$/task/$$/status
Uid: 500 500 500 500
Gid: 501 501 501 501
In the above output, the 1st column is my real UID (uid) and the 2nd is my effective UID (euid).
Becoming root via (su)
$ su
Now I'm root, but I still maintain my environment and my real UID is still 500. Notice that my euid is now 0 (root).
$ egrep "Uid|Gid" /proc/$(pgrep su -n)/task/$(pgrep su -n)/status
Uid: 500 0 0 0
Gid: 501 501 501 501
However my environment is still saml's. Here's one of he environment variables, $LOGNAME.
$ env | grep LOGNAME
LOGNAME=saml
Becoming root via (su -) or (sudo -i)
$ su -
With an su - or sudo -i not only do I change my effective UID to a new user, but I also source their files as if it was a login, and my environment now becomes identical as if I were them directly logging in.
$ egrep "Uid|Gid" /proc/$(pgrep su -n)/task/$(pgrep su -n)/status
Uid: 500 0 0 0
Gid: 501 501 501 501
However my environment is now root's. Same variable, $LOGNAME, now it's set with root.
$ env | grep LOGNAME
LOGNAME=root
So then what's the difference?
Well let's try the above with sudo -i and find out.
$ sudo -i
Now let's look at the same info:
$ egrep "Uid|Gid" /proc/$(pgrep su -n)/task/$(pgrep su -n)/status
Uid: 0 0 0 0
Gid: 501 501 501 501
Well one major thing is my effective ID and real ID are both 0 (root) with this approach. The environment variable $LOGNAME is as if we logged in as root.
$ env | grep LOGNAME
LOGNAME=root
Comparing environments
If we count the number of lines in say the 3 methods, perhaps there is some additional info to be had.
$ env > /tmp/<method used to become root>
We are left with these 3 files:
- -rw-r--r-- 1 root root 1999 Nov 2 06:43 sudo_root.txt
- -rw-r--r-- 1 root root 1970 Nov 2 06:44 sudash_root.txt
- -rw-r--r-- 1 root root 4859 Nov 2 06:44 su_root.txt
Already we can see that something is up with just a plain su. The env. is over 2x the size of the others.
Number of lines in each:
$ wc -l su*
28 sudash_root.txt
32 sudo_root.txt
92 su_root.txt
There's really no need to look further at the su_root.txt file. This file contains a much of user's environment that ran the su command. So let's look at the other 2 files.
They're virtually identical except for a few cosmetic variables, such as $LANG being slightly different. The one smoking gun in the list is the $PATH.
sudo
PATH=/usr/lib64/ccache:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/brlcad/bin:/root/bin
su -
PATH=/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/brlcad/bin:/root/bin
As you can see sudo -i gives us some additional protection by stripping out suspicious paths, but it also keeps our $DISPLAY and $TERM intact in case we were displaying a GUI to different location.
Takeaways?
- The big takeaway is that the method used to become root
sudo -ihas advantages over the others because you use your own password to do so, protecting root's password from needing to be given out. - There is logging when you became
root, vs. mysteriously someone becomingrootviasuorsu -. sudo -igives you a better user experience over eithersubecause it protects your$DISPLAYand$TERM.sudo -iprovides some protection to the system when users becomeroot, by limiting the environment which they are given.
What about sudo su - you didn't even discuss it?
I intentionally avoided bringing that into the discussion even though the OP asked about it because doing so would only have confused the issue, IMO. When you run sudo su the sudo command masks the effects of the su and so much of the environment that you'd get from a regular su is lost. Sudo is doing its job and providing a limited and protected environment regardless of whether it's sudo su or sudo -i.
Example
Here's the result of the sudo su environment being dumped:
ls -l /tmp/sudosu_root.txt
-rw-r--r-- 1 root root 1933 Nov 2 14:48 /tmp/sudosu_root.txt
And the number of lines:
$ wc -l /tmp/sudosu_root.txt
31 /tmp/sudosu_root.txt
These are the only variables that differ between a sudo su - and a sudo -i:
$ sdiff /tmp/sudosu_root.txt /tmp/sudo_root.txt | grep ' |'
USERNAME=saml | USERNAME=root
PATH=/usr/lib64/ccache:/sbin:/bin:/usr/sbin:/usr/bin:/usr/brl | PATH=/usr/lib64/ccache:/usr/local/sbin:/sbin:/bin:/usr/sbin:/
MAIL=/var/spool/mail/saml | MAIL=/var/spool/mail/root
PWD=/home/saml/tst | PWD=/root
SUDO_COMMAND=/bin/su | SUDO_COMMAND=/bin/bash
XAUTHORITY=/root/.xauthYFtlL3 | XAUTHORITY=/var/run/gdm/auth-for-saml-iZePuv/datab
So as you can see there really isn't much of a difference between them. Slightly different $PATH, the $SUDO_COMMAND, and the $MAIL and $USERNAME are the only differences.
References
- 8,678
- 369,824
-
2both
sudoandsugo through the PAM stack. If it logs under one, it should be logging under the other. Alsosudo suwill strip the environment just likesudo -iwill. In fact I don't see you mentionsudo suanywhere in your answer... – phemmer Nov 02 '13 at 17:42 -
@Patrick - figured it was long enough already. I figured touching on
sudo -iwas sufficient in giving insights into the advantages ofsudoover baresu -. Do you think it's necessary to mention it? I'll mention that I've been on Solaris systems that did not logsuattempts but did logsudo, so that distinction though a low possibility is possible. – slm Nov 02 '13 at 18:00 -
No, I was referring to you covering "bare
su". Op asked aboutsudo su, notsu:-) – phemmer Nov 02 '13 at 18:25 -
@Patrick - that was intentional not to discuss
sudo su. Since thesudothat prefixes would've masked the effects ofsu. Most ppl get lost in the.bashrc&.profilebusiness so I was attempting to shield the OP from that morass and cut to the effect, which is the resulting environment. – slm Nov 02 '13 at 18:44 -
1
I think @slm misread the question, so providing another answer.
He did hit on the main point, about one being a login shell and the other not.
When running sudo -i the shell will become a login shell, and so it will read things like ~/.profile where as a non-login shell will only read ~/.bashrc.
When chaining sudo with su (as in sudo su), neither the sudo nor the su invoke a login shell. The equivalent to sudo -i when using su would instead be sudo su -l.
I personally consider sudo su to be along the lines of "useless use of cat" examples. You can get the same behavior with sudo -s.
There are basically 5 common ways of invoking a root shell via sudo
sudo su- non-login shell
- sets
HOMEto/root - Prunes the environment
sudo -i- login shell
- sets
HOMEto/root - Prunes the environment
sudo su -l- login shell
- sets
HOMEto/root - Prunes the environment
When invoking a shell, this is equivalent to
sudo -isudo -s- non-login shell
- sets
HOMEto/root - Prunes the environment
When invoking a shell, this is equivalent to
sudo susudo -Es- non-login shell
- Leaves
HOMEalone - Leaves the environment alone (except for
$PATHand$LD_LIBRARY_PATHiirc)
Note, that these rules only apply when using them to gain a shell. There is a difference between sudo -s somecommand and sudo su -c somecommand.
- 71,831
The second one preserves the current directory (pwd) but the first command drops the user to the root's home directory.
- 12,884