O protocolo SSH

  1. Autenticação
  2. Instruções de conexão básicas
  3. Rodando apenas um comando
  4. Chaves SSH
  5. Copiando a sua chave pública
  6. Desabilitando a autenticação por senha
  7. Mudando a porta do SSH Daemon
  8. Conexão em uma porta diferente
  9. Desabilitando o login do root
  10. Túneis SSH
    1. Local tunneling
    2. Remote tunneling

Quem trabalha com o shell em um sistema operacional baseado em UNIX vai ter facilidade para entender o que é SSH, se ainda não souber. SSH (Secure Shell) é um protocolo para se comunicar a um shell de um computador remoto de forma segura. A conexão é segura porque ela é criptografada, assim como a autenticação. É um meio muito comum de conexão a servidores, sejam físicos ou virtuais.

No shell de sistemas Unix você precisa ter uma conta, e no shell remoto não é diferente. E, para se conectar, você precisa especificar a qual conta você quer se conectar.

Uma vez que você se conectar usando SSH, os comandos que você digitar serão executados no seu shell remoto enquanto a sua sessão permanecer ativa, ou seja, enquanto você permanecer conectado ao shell remoto.

Para se conectar a um computador remoto usando SSH, o computador remoto precisa ter um programa chamado SSH Daemon, que é um servidor de SSH. Já o seu computador precisa ter um SSH Client, que é um programa que se conecta a um computador remoto usando SSH.

Autenticação

Os meios de autenticação do SSH que são mais usados são as senhas e as chaves SSH. Apesar das senhas serem mais fáceis de usar, elas não são recomendadas por serem muito inseguras. Servidores são alvos frequentes de atacantes que sabem que existem muitas pessoas que não seguem as boas práticas de segurança para protegê-los. Então, eles vão tentar se logar via senha repetidamente usando ataques de força bruta. Nesses ataques, um computador tenta diversas combinações de senha com o objetivo de se logar via SSH por tentativa e erro.

Usar chaves SSH é uma ótima prática de segurança, porque a autenticação é feita usando uma comunicação criptografada de forma assimétrica.

A autenticação funciona da seguinte forma: um par de chaves é gerado no cliente. A chave pública é enviada para o servidor, não a cada vez que ele se autentica, mas sim antes da autenticação, apenas uma vez. O servidor, de posse da chave pública, criptografa uma string aleatória usando a chave pública. Ele envia essa string criptografada para o cliente.

O cliente descriptografa a mensagem, pois ele tem a chave privada correspondente. Ele então gera um MD5 com uma string formada pela string original, que ele acabou de descobrir pela descriptografia, e o ID da sessão. Então, o cliente envia o MD5 para o servidor. O servidor também tem o ID da sessão e a mensagem original, então ele faz o mesmo processo e compara o MD5 que ele gerou com o MD5 que ele recebeu do cliente. Se eles forem iguais, o cliente acabou de provar que ele é quem ele diz que é, e a autenticação é sucedida.

Instruções de conexão básicas

Para se conectar a um servidor usando SSH, você pode usar o comando abaixo:

ssh nomeusuario@host_remoto

Se for a primeira vez que você tentar se conectar a um host, você vai ver uma mensagem informando que a autenticidade do host não pode ser estabelecida. Isso é uma mensagem normal, e aparece apenas na primeira vez em que você se conecta ao host. Basta se conectar assim mesmo, que a mensagem não aparecerá novamente.

Rodando apenas um comando

Às vezes, você não quer realmente abrir uma sessão shell para executar vários comandos. Você pode querer executar apenas um comando. Quando você quiser fazer isso, basta especificar o comando após o comando de autenticação:

ssh nomeusuario@host_remoto "comando"

Fazendo isso, você vai se autenticar, o comando será executado e sua sessão vai se tornar inativa após a execução do comando. Também dá pra rodar mais de um comando, se você quiser. Exemplo:

ssh nomeusuario@host_remoto "comando && comando2"

Chaves SSH

O primeiro passo para que você possa usar chaves SSH é gerar um par de chaves no seu computador. Você pode fazer isso executando o comando abaixo na linha de comando:

ssh-keygen

Você pode escolher armazenar as chaves no caminho padrão, pressionando Enter, ou armazená-las em outro local. É recomendado manter o caminho padrão, pois assim o seu cliente SSH poderá encontrar as suas chaves sem que você precise informar onde elas estão. Você também pode definir uma senha. Se você fizer isso, precisará digitar a sua senha toda vez que for se autenticar. Isso é recomendado, pois é uma medida adicional de segurança, que pode ser útil caso a sua chave privada caia em mãos erradas.

Após a geração das suas chaves, assumindo que você optou por armazená-las no diretório padrão, a sua chave privada estará em ~/.ssh/id_rsa e a sua chave pública estará em ~/.ssh/id_rsa.pub.

Copiando a sua chave pública

Agora que você criou um par de chaves no seu computador, o próximo passo é enviar a chave pública para o servidor. Vou mostrar dois métodos para fazer isso: um que usa ssh-copy-id e um que não usa. O ssh-copy-id é um programa da linha de comando que copia a chave pública do seu computador para o computador remoto no qual você quer se autenticar usando chaves. Caso você tenha esse programa instalado, para enviar a sua chave pública para o servidor, basta rodar o comando abaixo:

ssh-copy-id nomeusuario@host_remoto

Obviamente, você precisa substituir nomeusuario e host_remoto pelo nome de usuário do computador remoto e pelo host dele.

Se você não tem o ssh-copy-id instalado no seu computador, você pode usar o cat, que é um utilitário da linha de comando e fazer o pipe da saída desse comando para o comando ssh. No comando ssh, você pode se autenticar e rodar dois comandos: um para garantir que o diretório onde a chave pública será inserida existe, e outro para inserir a saída do comando cat no arquivo onde ficam as chaves autorizadas a se autenticar no computador remoto. Veja abaixo o comando completo (perceba que ele considera que a chave pública foi armazenada no diretório padrão):

cat ~/.ssh/id_rsa.pub | ssh nomeusuario@host_remoto "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

O ssh-copy-id também envia a chave pública para o arquivo ~/.ssh/authorized_keys. Seja qual for o método que você escolheu, se tudo funcionou, agora você pode fazer login no seu servidor usando chaves SSH. Porém, é recomendável que você também desabilite a autenticação por senha, passo que veremos a seguir.

Desabilitando a autenticação por senha

Depois de habilitar a autenticação por chaves SSH, é uma boa ideia desabilitar a autenticação por senha, para que o seu servidor não fique mais suscetível a ataques de força bruta. Isso pode ser feito de uma forma bem simples:

  1. Abra o arquivo /etc/ssh/sshd_config com privilégios administrativos: sudo nano /etc/ssh/sshd_config
  2. Desabilite a diretiva PasswordAuthentication. Para isso, descomente-a, caso ela esteja comentada, e defina o valor dela como no
  3. Salve as suas alterações e reinicie o serviço SSH: sudo service ssh restart ou sudo service sshd restart (depende do SO do seu servidor).

Mudando a porta do SSH Daemon

Alguns administradores sugerem mudar a porta na qual o SSH Daemon roda, como uma medida de segurança, visto que existem aplicações maliciosas que assumem que o seu servidor SSH está rodando na porta padrão, o que realmente acontece na maioria dos casos, e ignora os servidores onde isso não acontece. Para mudar a porta padrão do SSH Daemon, siga os passos abaixo:

  1. Abra o arquivo /etc/ssh/sshd_config com privilégios de super usuário: sudo nano /etc/ssh/sshd_config
  2. Procure pela diretiva Port. Provavelmente, ela estará com o valor padrão (22). Mude para o valor desejado.
  3. Salve as suas alterações e reinicie o serviço SSH: sudo service ssh restart ou sudo service sshd restart (depende do SO do seu servidor).

Conexão em uma porta diferente

Se o servidor SSH ao qual você se quer se conectar rodar em uma porta diferente da padrão (22), você precisa especificar a porta dele ao fazer a conexão:

ssh -p porta nomeusuario@host_remoto

Desabilitando o login do root

Se você tem uma conta no seu servidor que tem privilégios administrativos (além da conta root, logicamente), é recomendado desabilitar o login do usuário root, visto que ele é um usuário muito visado por atacantes. Para desabilitar esse usuário, siga os passos abaixo:

  1. Abra o arquivo /etc/ssh/sshd_config com privilégios de super usuário: sudo nano /etc/ssh/sshd_config.
  2. Procure pela diretiva PermitRootLogin. Se ela estiver comentada, descomente-a. Mude seu valor para no.
  3. Salve as suas alterações e reinicie o serviço SSH: sudo service ssh restart ou sudo service sshd restart (depende do SO do seu servidor)

Túneis SSH

Túneis SSH são usados para encaminhar o tráfego de um host ao qual um computador remoto tem acesso para uma porta do seu computador local e também para fazer o contrário, ou seja, encaminhar o tráfego de um host ao qual o seu computador local tem acesso para uma porta do computador remoto. O primeiro caso, no qual é feito um túnel local, é chamado de local tunneling ou local port forwarding. Já o segundo caso, onde um túnel remoto é criado, é chamado de remote tunneling ou remote port forwarding.

Vamos ver os dois tipos de túneis em maiores detalhes. Mas, antes disso, não se preocupe se você tiver dificuldades para entender esse tema. Ele é um pouco confuso e pode ser difícil de entender de primeira, às vezes.

Local tunneling

Local tunneling é a criação de túneis locais de portas do seu computador local para receber o tráfego de uma porta acessada por um computador remoto. Veja o exemplo a seguir:

ssh -nNT -L 50000:example.com:80 nomeusuario@host_remoto

No exemplo acima, é feita uma conexão a um computador remoto usando SSH e o trecho -L 50000:example.com:80 é a parte do comando que indica que queremos criar um túnel local. A flag -L indica que queremos criar um túnel local. Depois dela, precisamos passar a porta local onde você deseja acessar o túnel, o host no qual você quer que o computador remoto se conecte e a porta que o computador remoto deve usar para se conectar.

No exemplo, o computador remoto vai simplesmente acessar o domínio example.com por HTTP (porta 80). O domínio poderá ser acessado localmente na porta 50000. O trecho -nNT foi colocado apenas para que seja o túnel seja feito sem que seja criada uma sessão SSH.

Local tunneling pode ser útil caso você queira acessar alguma coisa a qual você não tenha acesso, mas o seu servidor SSH tem acesso, podendo ser inclusive ser algo local para o computador remoto. Outro caso de uso é quando você quer se conectar a alguma coisa de forma segura, porque a conexão SSH é criptografada.

Remote tunneling

Agora que você já entendeu o que é local tunneling, é muito mais fácil entender o que é remote tunneling. É o inverso do local tunneling. É um túnel remoto no qual o seu computador local acessa um host e uma porta que você especificar e o tráfego dela é acessível pela porta remota que for especificada. Ou seja, se no túnel local, o computador remoto fazia o papel de ponte para o computador local, agora é o contrário. Exemplo:

ssh -nNT -R 50000:localhost:3306 nomeusuario@host_remoto

Note que uma das diferenças desse exemplo para o exemplo do túnel local é que foi usada a flag -R, para indicar que queremos fazer um túnel remoto. A sintaxe usada para especificar o túnel é a mesma sintaxe usada para definir o túnel local, com a diferença que a porta que especificamos primeiro (50000) é a porta do servidor remoto, e não a porta do computador local, e o host e a porta especificados em seguida são acessados pelo computador local. A porta especificada nesse exemplo é a porta padrão do MySQL. Assim, o seu banco de dados local poderá ser acessível remotamente na porta 50000.

Resumindo: local tunneling serve para criar túneis locais para que uma porta local tenha acesso a algo acessado por um computador remoto. Remote tunneling serve para criar túneis remotos para que uma porta remota tenha acesso a algo acessado por um computador local.