Posso descobrir qual chave ssh foi usada para acessar uma conta?

52

É possível descobrir qual chave ssh foi usada para acessar uma conta? Eu tenho uma conta em um servidor que eu deixo várias pessoas (confiáveis!) Têm acesso via ssh. Eu acharia útil saber quem logou e quando. Eu tenho acesso root para poder ver os logs, mas parece que não há nada lá. Existe algum interruptor de configuração que irá colocar alguma forma de identificar a chave nos logs?

    
por Loop Space 24.06.2011 / 18:53

7 respostas

37

Se você entrar no arquivo de configuração sshd (geralmente /etc/ssh/sshd_config ) e alterar a diretiva LogLevel para VERBOSE:

LogLevel VERBOSE

... você pode ver algo assim nos registros:

Jun 24 22:43:42 localhost sshd[29779]: Found matching RSA key: d8:d5:f3:5a:7e:27:42:91:e6:a5:e6:9e:f9:fd:d3:ce
Jun 24 22:43:42 localhost sshd[29779]: Accepted publickey for caleb from 127.0.0.1 port 59630 ssh2

De man sshd_config :

   LogLevel
          Gives  the  verbosity  level that is used when logging messages from
          sshd(8).  The possible values are: QUIET, FATAL, ERROR,  INFO,  VER-
          BOSE,  DEBUG,  DEBUG1,  DEBUG2,  and  DEBUG3.   The default is INFO.
          DEBUG and DEBUG1 are equivalent.  DEBUG2  and  DEBUG3  each  specify
          higher  levels of debugging output.  Logging with a DEBUG level vio-
          lates the privacy of users and is not recommended.
    
por 24.06.2011 / 21:40
14

Algo parecido com a resposta do @ user37161 . Se a conta compartilhada estiver executando um shell personalizado e o shell precisar saber qual usuário está lá, executar o script "wrapper" talvez não seja suficiente, já que as informações não são passadas para o shell personalizado, exceto por meio de métodos que podem causar problemas condições.

Em vez disso, você pode usar a opção environment= no arquivo authorized_keys para definir uma variável de ambiente, que o shell personalizado pode ler.

Dentro do seu arquivo .ssh/authorized_keys , prefixar cada linha com um conjunto de variáveis de ambiente, da seguinte forma:

environment="REMOTEUSER=jrhacker" ssh-rsa ....
environment="REMOTEUSER=jbloggs" ssh-rsa ....

Em seguida, o shell personalizado, ou qualquer um dos vários scripts rc, pode ler a variável $REMOTEUSER e tomar a ação apropriada.

No entanto, observe que, se você estiver usando um shell padrão, o usuário que efetuou login poderá modificar o arquivo para evitar várias coisas. Além disso, há alguns riscos em permitir que os usuários definam variáveis de ambiente, como LDPRELOAD . Veja a documentação de sshd_config sobre PermitUserEnvironment .

    
por 29.07.2014 / 23:09
12

Atualização 2016-10-31 sobre o formato de log

Alguns scripts para instalação adequada

Existe um método totalmente utilizável para rastrear / registrar conexões ssh por chave com expention para nome de usuário.

Introdução

Além do anwer do @Caleb, gostaria de compartilhar alguns pequenos truques:

Nota: Estou trabalhando no Debian 6.0 .

Instalação do servidor

Nível de log do SSHD

Primeiro, garantir que a configuração do servidor tenha um nível de registro suficiente:

como root, isso irá definir e ativar o loggin detalhado:

sed '/^[^#]*LogLevel.*\(QUIET\|FATAL\|ERROR\|INFO\)/{s/^/# /;h;s/$/\nLogLevel VERBOSE/};${p;g;/./!{iLogLevel VERBOSE'$'\n;};D}'  -i /etc/ssh/sshd_config

Poderia ser escrito:

sed '
     /^[^#]*LogLevel.*\(QUIET\|FATAL\|ERROR\|INFO\)/{
        s/^/# /;
        h;
        s/$/\nLogLevel VERBOSE/
    };
    ${
        p;
        g;
        /./!{
            iLogLevel VERBOSE
        };
        D
    }'  -i /etc/ssh/sshd_config

ou em um script sed :

#!/bin/sed -f
/^[^#]*LogLevel.*\(QUIET\|FATAL\|ERROR\|INFO\)/{
    s/^/# /;
    h;
    s/$/\nLogLevel VERBOSE/
};
${
    p;
    g;
    /./!{
        iLogLevel VERBOSE
    };
    D
}

Que pode ser executado como:

patchSshdConfigLogLevel.sed -i /etc/ssh/sshd_config

Do que ativando isso:

service ssh restart

Syslog: tornando as impressões digitais legíveis pelo usuário

Agora, tire impressões digitais em um arquivo legível pelo usuário:

echo ':msg, regex, "Found matching .* key:" -/var/log/sshdusers.log' \
    > /etc/rsyslog.d/ssh_key_user.conf 
echo ':msg, regex, "Accepted publickey for" -/var/log/sshdusers.log' \
    >> /etc/rsyslog.d/ssh_key_user.conf 

service rsyslog restart

Tente (re) fazer login a partir do ssh para garantir que o novo arquivo sshdusers.log seja criado (e contenha algo) e, em seguida,

chmod 644 /var/log/sshdusers.log

Uso

Isso imprimirá a impressão digital das sessões atuais:

sed -ne "/sshd.$PPID.:.*matching .SA key/{s/^.* //g;h};\${x;p}" /var/log/sshdusers.log

sed -ne "/sshd.\($(($(ps ho ppid $PPID)))\|$PPID\).:.*\(Accepted publickey\|matching .SA key\)/{s/^.* //g;h};\${x;p}" /var/log/sshdusers.log

Plug-in para .bashrc

E, finalmente, há um pequeno add-on para colocar no final do seu /etc/bash.bashrc ou usuário .bashrc :

ssh_oPwd=$OLDPWD
ssh_oUmask=$(umask)
umask 077
ssh_tempdir=$(mktemp -d /tmp/ssh-id-XXXXXXX)
cd $ssh_tempdir || exit 1

ssh_crtFp=$(
    sed -ne "/sshd.\($(($(ps ho ppid $PPID)))\|$PPID\).:.*\(Accepted publickey\|matching .SA key\)/{s/^.* //g;h};\${x;p}" /var/log/sshdusers.log
)
for ((ssh_i=1;ssh_i<=$(wc -l <$HOME/.ssh/authorized_keys);ssh_i++));do
    export ssh_line="$(sed -ne ${ssh_i}p <$HOME/.ssh/authorized_keys)"
    echo "$ssh_line" >tempKey
    export ssh_lFp=($(ssh-keygen -l -f tempKey))
    if [ "${ssh_lFp[1]}" == "$ssh_crtFp" ] ;then
        export SSH_KEY_USER=${ssh_line##* }
        break
      fi
  done

cd $OLDPWD
OLDPWD=$ssh_oPwd
rm -fR $ssh_tempdir
umask $ssh_oUmask
unset ssh_lFp ssh_line ssh_i ssh_crtFp ssh_tempdir ssh_oUmask ssh_oPwd

então, após o login do SSH, você verá:

set | grep ^SSH
SSH_CLIENT='192.168.1.31 43734 22'
SSH_CONNECTION='192.168.1.31 43734 192.168.1.2 22'
SSH_KEY_USER=user@mydesk
SSH_TTY=/dev/pts/2

Nota Em algumas instalações, o arquivo de chaves autorizado pode ter nomes diferentes, como $HOME/.ssh/authorized_keys2 ...

    
por 31.12.2012 / 15:08
8

Suponha que os usuários "joe" e "deb" tenham acesso à conta "x". Em seguida, na conta x .ssh_authorized_keys , adicione as linhas:

command='wrapper joe' joe public key
command='wrapper deb' deb public key

Também no script wrapper você pode fazer o que quiser, registrando a chave privada de joe usando ssh em uma data específica & hora com o comando $ORIGINAL_COMMAND .

    
por 14.04.2013 / 22:26
3

No fedora 20+, as tentativas e sucessos de login são salvos em /var/log/audit/audit.log. Esse log salva as tentativas de login (falhas e sucessos) e a impressão digital da chave usada para a tentativa de login é salva no campo denominado fp.

Você pode comparar a impressão digital da chave logada com as impressões digitais nas authorized_keys executando linha por linha através de ssh-keygen -l

Uma explicação detalhada com relação aos logins do ssh e sua segurança e detecção de invasões está aqui: link

    
por 12.06.2015 / 14:56
1

Você pode tentar isso:

ssh-add -L | awk '{ print $2 }' | xargs -i grep '{}' ~/.ssh/authorized_keys  | head -1
    
por 30.08.2011 / 18:26
0

Além de @F. Hauri responder, eu preparo útil "LoggedIn prompt".

Um arquivo adicional é opcional ($ HOME / .ssh / users):

kszumny@laptop kszumny
kszumny@comp2 kszumny
tom@laptop tom
pati@home
chris@workstation1 chris
chris@workstation2 chris

Esta parte deve ser colada em /etc/profile (para todos os usuários) ou em ~/.bashrc

other_users_prompt()
{
    pids='ps fx | grep "sshd:\s" | awk '{print $1}''
    users=""
    for uid in $pids
    do
        ssh_crtFp='sed -ne "/sshd.$uid.:.*matching .SA key/{s/^.* //g;p;q}" /var/log/sshdusers.log'
        for ((ssh_i=1;ssh_i<=$(wc -l <$HOME/.ssh/authorized_keys);ssh_i++));do
            export ssh_line="$(sed -ne ${ssh_i}p <$HOME/.ssh/authorized_keys)"
            echo "$ssh_line" >tempKey
            export ssh_lFp=($(ssh-keygen -l -f tempKey))
            if [ "${ssh_lFp[1]}" == "$ssh_crtFp" ] ;then
                export SSH_KEY_USER=${ssh_line##* }
                ST_USER='cat $HOME/.ssh/users | grep "${SSH_KEY_USER}" | awk '{print $2}''
                if [ -z "$ST_USER" ]; then
                    ST_USER=$SSH_KEY_USER
                fi
                if [ -z "$users" ]; then
                    users="$ST_USER"
                else
                    users="$users\n$ST_USER"
                fi
                break
            fi
        done
    done

    if [ 'echo -e "$users" | sort | uniq -c | wc -l' == 1  ]; then
       exit
    fi

    users='echo -e "$users" | sort | uniq -c | awk '{print $2"("$1")"}' | xargs echo -e'
    echo -e "[LoggedIn:$users] "

}

PS1='$(other_users_prompt)\u@\h:\w\$ '

Resultado

    
por 02.02.2014 / 07:02