Eu tenho uma alternativa: manter as chaves SSH de todos os seus clientes em um servidor e configurar seus servidores para solicitar a esse servidor chaves SSH autorizadas. Isso pode ser feito usando a diretiva AuthorizedKeysCommand
em sshd_config
.
Na página de manual:
AuthorizedKeysCommand
Specifies a program to be used to look up the user's public keys.
The program must be owned by root and not writable by group or
others. It will be invoked with a single argument of the
username being authenticated, and should produce on standard
output zero or more lines of authorized_keys output (see
AUTHORIZED_KEYS in sshd(8)). If a key supplied by
AuthorizedKeysCommand does not successfully authenticate and
authorize the user then public key authentication continues using
the usual AuthorizedKeysFile files. By default, no
AuthorizedKeysCommand is run.
AuthorizedKeysCommandUser
Specifies the user under whose account the AuthorizedKeysCommand
is run. It is recommended to use a dedicated user that has no
other role on the host than running authorized keys commands.
O comando pode ser simplesmente um script com:
#! /bin/bash
ssh bastion "cat $HOSTNAME/$1/authorized_keys"
Aqui, o AuthorizedKeysCommandUser
do servidor tem um login baseado em chave (sem senha) e simplesmente exibe o arquivo authorized_keys
para a combinação de nome do host / usuário do servidor de chaves. Outra maneira seria:
#! /bin/bash
wget --post-data="host=$HOSTNAME&user=$1" https://bastion
em que o servidor de chaves executa um servidor HTTP que retorna um conjunto de chaves autorizadas com base no nome do host e no usuário. Um script PHP ou Python de um arquivo seria suficiente para processar tal formulário. Uma vantagem seria que usar um servidor de banco de dados como o PostgreSQL ou o MySQL seria mais fácil. (Claro, você não precisa para usar o nome do host.)
Esse método é mais comumente usado com o LDAP, eu acho. Existem alguns scripts para o LDAP: link e link que você pode ver.
Para configurar isso, nos servidores, crie um usuário (chame-o de authkeys
) para executar o comando (ou você pode usar o nobody
usuário):
adduser --disabled-password --disabled-login --shell /usr/sbin/nologin authkeys
No servidor intermediário (chame-o de bastion
), um comando ligeiramente diferente: vamos configurar o shell para /bin/bash
por conveniência (mas você pode limitar isso):
adduser --disabled-password --disabled-login --shell /bin/bash authkeys
Este usuário muito desprivilegiado será usado com o único propósito de se conectar ao servidor intermediário e obter as chaves. Crie um script que este usuário execute:
sudo tee -a /usr/local/bin/get_keys.sh <<"EOF"
#! /bin/bash
ssh bastion "cat $HOSTNAME/$1/*.pub 2>/dev/null"
EOF
sudo chmod 0755 /usr/local/bin/get_keys.sh
Edite a configuração do servidor SSH /etc/ssh/sshd_config
nos servidores e adicione:
AuthorizedKeysCommand /usr/local/bin/get_keys.sh
AuthorizedKeysCommandUser authkeys
E reinicie os servidores SSH:
sudo service ssh restart
Em seguida, para simplificar, gere um par de chaves SSH e use o mesmo par de chaves em todos os servidores para authkeys
user:
# On one server
ssh-keygen -N '' -f id_rsa
Em todos os outros servidores, copie esses arquivos id_rsa
e id_rsa.pub
criados pelo comando acima e adicione-os à configuração SSH do usuário authkeys
:
cp id_rsa* ~authkeys/.ssh/
sudo chown authkeys:authkeys .ssh -R
sudo chmod 0700 .ssh
chmod 0600 .ssh/*
No servidor intermediário, adicione essa chave à lista authorized_keys
:
cat id_rsa.pub >> ~authkeys/.ssh/authorized_keys
Por fim, nos servidores intermediários, crie uma estrutura de diretórios seguindo o script usado acima:
mkdir -p ~authkeys/some_host/some_login
Em seguida, adicione as chaves autorizadas de seus administradores ao diretório:
echo "some_key" > ~authkeys/some_host/some_login/admin1.pub
echo "some_other_key" > ~authkeys/some_host/some_login/admin2.pub
Chore tudo para o usuário root (ou seu usuário - mas qualquer coisa que não seja authkeys
):
chown root:root ~authkeys/* -R
chmod o=rx ~authkeys/*/*
chmod o=r ~authkeys/*/*/*.pub -R
Use nomes de host ou IPs, mas lembre-se de alterar o script para usar o valor apropriado.