Diferença entre sudo -i e sudo su [duplicado]

16

Eu queria saber qual é a diferença entre sudo -i e sudo su ?

    
por Lucas Kauffman 02.11.2013 / 10:37

3 respostas

20

Com base nas descrições das man pages de su e sudo , presumo o seguinte.

  1. Como sudo -iu <user> significa um shell de login, isso seria equivalente a um su - <user> ou su -l <user> .
  2. Um su sem nenhum argumento altera seu ID de usuário efetivo, mas você ainda está usando seu ambiente <user> original e um who 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?

  1. 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.
  2. Há registro quando você se tornou root , e misteriosamente alguém se tornou root via su ou su - .
  3. sudo -i oferece uma melhor experiência do usuário em relação a su , pois protege seus $DISPLAY e $TERM .
  4. sudo -i fornece alguma proteção ao sistema quando o usuário se torna root , 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.

Referências

por 02.11.2013 / 10:54
3

Eu acho que o @slm leu mal a pergunta, fornecendo outra resposta.

Ele atingiu o ponto principal, cerca de um sendo um shell de login e o outro não.
Ao executar sudo -i , o shell se tornará um shell de login e, por isso, lerá coisas como ~/.profile , em que um shell que não seja de login só lerá ~/.bashrc .

Ao encadear sudo com su (como em sudo su ), nem o sudo nem o su invocarão um shell de login. O equivalente a sudo -i ao usar su seria, em vez disso, sudo su -l .

Pessoalmente, considero que sudo su está na linha dos exemplos de "uso inútil de gato". Você pode obter o mesmo comportamento com sudo -s .

Existem basicamente 5 maneiras comuns de invocar um shell de root via sudo

  • sudo su

    • shell de não login
    • define HOME para /root
    • Remove o ambiente
  • sudo -i

    • shell de login
    • define HOME para /root
    • Remove o ambiente
  • sudo su -l

    • shell de login
    • define HOME para /root
    • Remove o ambiente

    Ao invocar um shell, isso é equivalente a sudo -i

  • sudo -s

    • shell de não login
    • define HOME para /root
    • Remove o ambiente

    Ao invocar um shell, isso é equivalente a sudo su

  • sudo -Es

    • shell de não login
    • Deixa HOME sozinho
    • Deixa o ambiente em paz (exceto $PATH e $LD_LIBRARY_PATH iirc)

Observe que essas regras só se aplicam ao usá-las para ganhar um shell. Há uma diferença entre sudo -s somecommand e sudo su -c somecommand .

    
por 02.11.2013 / 19:22
1

O segundo preserva o diretório atual (pwd), mas o primeiro comando coloca o usuário no diretório inicial da raiz.

    
por 02.11.2013 / 10:52

Tags