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

56

É possível descobrir qual chave ssh foi usada para acessar uma conta? Eu tenho uma conta em um servidor ao qual permito que várias pessoas (confiáveis!) Tenham acesso via ssh. Acharia útil saber quem fez login e quando. Eu tenho acesso root para poder ver os logs, mas não parece haver nada lá. Existe alguma opção de configuração que colocará alguma maneira de identificar a chave nos logs?

Espaço em loop
fonte
Você já tentou brincar com o LogLevel no sshd_config?
precisa
Seria incrivelmente útil poder descobrir qual chave foi usada para autorizar a sessão atual - no meu caso, para controle de acesso em um repositório Mercurial acessado por meio de um login compartilhado. Todas as técnicas existentes envolvem a segmentação da identidade por meio de uma opção de comando, que é um pouco desajeitada.
Tom Anderson
5
Há um pedido de recurso OpenSSH sobre isso: Por favor, adicione pubkey impressão digital na mensagem de log de autenticação
Steffen
Mecanismo Centos: unix.stackexchange.com/questions/147295/...
jhfrontz

Respostas:

38

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

LogLevel VERBOSE

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

24 jun 22:43:42 localhost sshd [29779]: Encontrado chave RSA correspondentes: D8: d5: F3: 5a: 7e: 27: 42: 91: e6: A5: e6: 9e: f9: fd: D3: ce
junho 24 22:43:42 localhost sshd [29779]: chave pública aceita para caleb da porta 127.0.0.1 porta 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.
Caleb
fonte
Isso parece promissor. A impressão digital me diz qual chave é usada. Ótimo, obrigado.
Loop Space
Para impressão digital da sessão atual:sed -ne "/sshd.$PPID.:.*matching DSA key/{s/^.* //g;p;q}" /var/log/auth.log
F. Hauri
Eu gosto do GNU sed !
F. Hauri
3
@ F.Hauri, A menos que esteja faltando alguma coisa, isso não retornaria a coisa errada se um PID fosse reutilizado para uma segunda sessão SSH? Parece que sempre retornará a impressão digital mais antiga para o PID fornecido no auth.log, em vez da mais recente.
21814 godlygeek
@godlygeek Oh sim! Eu tenho melhor whipe qdirectiva, linha loja até o final do arquivo ... linha sed tornar-se: sed -ne "/sshd.$PPID.:.*matching DSA key/{s/^.* //g;h};\${x;p}" /var/log/auth.log. Definitivamente: Eu amo sed!
31714
15

Um pouco semelhante à resposta de @ user37161 . Se a conta compartilhada estiver executando um shell personalizado e o shell precisar saber qual usuário existe, a execução do script "wrapper" poderá não ser suficiente, pois as informações não são passadas para o shell personalizado, exceto por métodos que podem causar problemas de execução. condições.

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

Dentro do seu .ssh/authorized_keysarquivo, acrescente cada linha com um conjunto de variáveis ​​de ambiente, como o seguinte:

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 $REMOTEUSERvariável e executar a ação apropriada.

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

Chris Cogdon
fonte
13

Atualize 31/10/2016 sobre o formato do log

Alguns scripts para instalação adequada

Existe um método utilizável completo para rastrear / registrar conexões ssh por chave, com exceção do nome de usuário.

Introdução

Além da resposta de @Caleb, eu gostaria de compartilhar alguns truques aqui:

Nota: Estou trabalhando no Debian 6.0 .

Instalação do servidor

Nível de log SSHD

Primeiro, assegurando que a configuração do servidor tenha nível de log suficiente:

como root, isso definirá um loggin detalhado e ativo:

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

Pode 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
}

O que poderia ser executado como:

patchSshdConfigLogLevel.sed -i /etc/ssh/sshd_config

Do que para ativar isso:

service ssh restart

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

Agora tire impressões digitais no 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 no ssh para garantir que um novo arquivo sshdusers.logseja 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 complemento para colocar no final do seu /etc/bash.bashrcusuá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 novamente 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 chave autorizado pode ter um nome diferente, como $HOME/.ssh/authorized_keys2...

F. Hauri
fonte
Quando isso foi publicado, eu estava no Debian 6 do GNU / Linux , mas esse trabalho era o mesmo no Debian 7 ...
F. Hauri
Atualizado devido a alterações no formato do log #
F. Hauri 31/10
Agradável. Seu patchSshdConfigLogLevel.sed não deve ter o ".sed" no final, pois exporia detalhes de implementação desnecessariamente. O #! linha é inteiramente suficiente.
Alex-North-Keys
As extensões do @ AlexNorth-Keys no UN * X geralmente são tecnicamente desnecessárias, pois preferimos usar o mime e fileconhecer os tipos de arquivo. Mas, como para humano que navegar sistemas de arquivos, tendo extensões como .pl, .py, .sh, .awk, .sed, .tar.gz, ou mesmo .png.b64.gzé útil!
F. Hauri
8

Suponha que os usuários "joe" e "deb" tenham acesso à conta "x". Em seguida, na conta x, .ssh_authorized_keysvocê adiciona 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 que a chave privada de joe tem vindo a utilizar sshnuma determinada data e hora com o comando $ORIGINAL_COMMAND.

user37161
fonte
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 chave usada para a tentativa de login é salva no campo denominado fp.

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

Uma explicação detalhada sobre os logins ssh e sua segurança e detecção de intrusão está aqui: http://vpathak.tumblr.com/post/121343814158/fedora-audit-log-with-love-from-russia

vpathak
fonte
2

Você pode tentar isso:

ssh-add -L | awk '{ print $2 }' | xargs -i grep '{}' ~/.ssh/authorized_keys  | head -1
pci
fonte
Indiscutivelmente mais preciso e menos intensivo de CPU:ssh-add -L | awk 'NR==FNR { k=$2;next } /^#/{next} $2==k { print $3;exit} $3==k {print $4;exit} ' - ~/.ssh/authorized_keys
Otheus
0

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

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 para /etc/profile(para todos os usuários) ou para~/.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

insira a descrição da imagem aqui

barulhento
fonte