Com base nas descrições das man pages de su
e sudo
, presumo o seguinte.
- Como
sudo -iu <user>
significa um shell de login, isso seria equivalente a umsu - <user>
ousu -l <user>
. - Um
su
sem nenhum argumento altera seu ID de usuário efetivo, mas você ainda está usando seu ambiente<user>
original e umwho am i
relatará que você ainda está<user>
.
página do man sudo do excerto
-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.
Exemplo
Eu tenho uma conta de usuário, saml
com um UID de 500.
$ egrep "Uid|Gid" /proc/$$/task/$$/status
Uid: 500 500 500 500
Gid: 501 501 501 501
Na saída acima, a primeira coluna é meu UID real (uid) e o segundo é meu UID efetivo (euid).
Tornar-se root via (su)
$ su
Agora sou root, mas ainda mantenho meu ambiente e meu UID real ainda é 500
. Observe que meu euid agora é 0 (root).
$ egrep "Uid|Gid" /proc/$(pgrep su -n)/task/$(pgrep su -n)/status
Uid: 500 0 0 0
Gid: 501 501 501 501
No entanto, meu ambiente ainda é saml
. Aqui está uma das variáveis de ambiente, $LOGNAME
.
$ env | grep LOGNAME
LOGNAME=saml
Tornar-se root via (su -) ou (sudo -i)
$ su -
Com um su -
ou sudo -i
não apenas altero meu UID efetivo para um novo usuário, como também faço o upload de seus arquivos como se fosse um login, e meu ambiente agora se torna idêntico como se eu os identificasse diretamente fazer login.
$ egrep "Uid|Gid" /proc/$(pgrep su -n)/task/$(pgrep su -n)/status
Uid: 500 0 0 0
Gid: 501 501 501 501
No entanto, meu ambiente agora é root
. Mesma variável, $LOGNAME
, agora está definida com root
.
$ env | grep LOGNAME
LOGNAME=root
Então qual é a diferença?
Bem, vamos tentar o acima com sudo -i
e descobrir.
$ sudo -i
Agora vamos ver as mesmas informações:
$ egrep "Uid|Gid" /proc/$(pgrep su -n)/task/$(pgrep su -n)/status
Uid: 0 0 0 0
Gid: 501 501 501 501
Bem, uma coisa importante é que meu ID efetivo e ID real são ambos 0 ( root
) com essa abordagem. A variável de ambiente $LOGNAME
é como se tivéssemos efetuado login como root
.
$ env | grep LOGNAME
LOGNAME=root
Comparando ambientes
Se contarmos o número de linhas nos 3 métodos, talvez haja alguma informação adicional.
$ env > /tmp/<method used to become root>
Ficamos com esses três arquivos:
- -rw-r - r-- 1 raiz raiz 1999 2 de novembro 06:43 sudo_root.txt
- -rw-r - r-- 1 root raiz 1970 2 de novembro às 06:44 sudash_root.txt
- -rw-r - r-- 1 raiz raiz 4859 2 nov 06:44 su_root.txt
Já podemos ver que algo está acontecendo com apenas su
. O env. tem mais de 2x o tamanho dos outros.
Número de linhas em cada:
$ wc -l su*
28 sudash_root.txt
32 sudo_root.txt
92 su_root.txt
Não há necessidade de procurar mais no arquivo su_root.txt
. Este arquivo contém muito do ambiente do usuário que executou o comando su
. Então, vamos ver os outros 2 arquivos.
Eles são praticamente idênticos, exceto por algumas variáveis cosméticas, como $LANG
sendo ligeiramente diferentes. A arma de fumar na lista é o $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
Como você pode ver, sudo -i
nos oferece alguma proteção adicional removendo caminhos suspeitos, mas também mantém nossos $DISPLAY
e $TERM
intactos no caso de estarmos exibindo uma GUI para um local diferente.
Away?
- Portanto, a grande vantagem é que o método usado para se tornar root
sudo -i
é uma vantagem sobre os outros porque você usa sua própria senha para fazer isso, protegendo a senha do root de ser distribuída. - Há registro quando você se tornou
root
, e misteriosamente alguém se tornouroot
viasu
ousu -
. -
sudo -i
oferece uma melhor experiência do usuário em relação asu
, pois protege seus$DISPLAY
e$TERM
. -
sudo -i
fornece alguma proteção ao sistema quando o usuário se tornaroot
, limitando o ambiente ao qual é dado.
E quanto a sudo su
, você nem discutiu isso?
Eu intencionalmente evitei trazer isso para a discussão, mesmo que o OP tenha perguntado sobre isso, porque isso apenas confundiria a questão, IMO. Quando você executa sudo su
, o comando sudo
mascara os efeitos do su
e grande parte do ambiente que você obteria de um su
regular perdido. O Sudo está fazendo seu trabalho e fornecendo um ambiente limitado e protegido, independentemente de ser sudo su
ou sudo -i
.
Exemplo
Veja o resultado do ambiente sudo su
sendo descartado:
ls -l /tmp/sudosu_root.txt
-rw-r--r-- 1 root root 1933 Nov 2 14:48 /tmp/sudosu_root.txt
E o número de linhas:
$ wc -l /tmp/sudosu_root.txt
31 /tmp/sudosu_root.txt
Estas são as únicas variáveis que diferem entre sudo su -
e 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
Então, como você pode ver, não há muita diferença entre eles. Um pouco diferente de $PATH
, o $SUDO_COMMAND
e o $MAIL
e $USERNAME
são as únicas diferenças.