LPI-2 202-450 Topico 212.3
Shell seguro (SSH)
Índice
- 212.3 Shell seguro (SSH) - Objetivos
- 212.3 Shell Seguro (SSH) - Conteúdo
212.3 Shell seguro (SSH) - Objetivos
Peso 4
O candidato deve ser capaz de configurar e tornar seguro um daemon SSH. Este objetivo inclui administrar chaves e configurar o SSH para os usuários. Além disso, deve ser capaz de redirecionar um outro protocolo através do SSH e controlar o login SSH.
Conhecimentos-chave:
- Arquivos de configuração e ferramentas do OpenSSH;
- Restrições de login para o superusuário e para usuários normais;
- Controlar e usar chaves de cliente e servidor para realizar login com e sem senha;
- Uso de várias conexões de diversos hosts para garantir a manutenção da conexão em caso de perda de conexão com um host remoto.
Lista parcial dos arquivos, termos e ferramentas utilizados:
ssh
;sshd
;/etc/ssh/sshd_config
;/etc/ssh/
;- Arquivos de chaves públicas e privadas;
PermitRootLogin
,PubKeyAuthentication
,AllowUsers
,PasswordAuthentication
,Protocol
.
212.3 Shell Seguro (SSH) - Conteúdo
O protocolo SSH (também referenciado como Shell Seguro) é um metodo
seguro para login remoto de um computador ao outro. Ele provê várias
alternativas para uma autenticação forte protegendo a comunicação e
a integridade dos dados com uma criptogriafia forte. É uma
alternativa segura ante os protocolos de login não seguros tais como
o telnet
e o rlogin
.
Usos típicos do protocolo SSH:
- prover acesso seguro a usuários e processos automatizados;
- transferências de arquivos interativas ou automáticas;
- enviar comandos remotamente;
- gerenciamento de infraestrutura de redes e outros componentes de sistema de missão crítica.
Funcionamento do protocolo SSH
O modo de funcionamento do SSH é utilizando um modelo cliente-servidor para permitir a autenticação de dois sistemas remotos e a criptografia dos dados que passam entre eles.
O SSH opera na porta TCP 22 por padrão (embora isso possa ser alterado se necessário). O host (servidor) escuta na porta 22 (ou qualquer outra porta atribuída) para conexões de entrada.
O SSH fornece vários mecanismos para autenticar o servidor e o cliente. Dois dos mecanismos de autenticação comumente usados são o baseado em senha e a autenticação baseada em chave. Embora a autenticação baseada em senha também seja segura, é aconselhável usar a autenticação baseada em chave.
Figura 1: Diagrama da negociação de conexão do SSH
A conexão é estabelecida pelo cliente SSH conectando-se ao servidor SSH. O cliente SSH conduz o processo de configuração da conexão e usa criptografia de chave pública para verificar a identidade do servidor SSH. Após a fase de configuração, o protocolo SSH usa criptografia simétrica forte e algoritmos de hash para garantir a privacidade e integridade dos dados trocados entre o cliente e o servidor.
O que é o OpenSSH?
O OpenSSH é um conjunto de ferramentas de código aberto e gratuito usado par fornecer comunicação segura e criptografada em uma rede de computadores usando o protocolo SSH. Ele é desenvolvido pelo grupo Open BSD e licenciado em uma licença BSD simplificada.
Todas as comunicações e trocas de credenciais usando o OpenSSH são cifradas portanto protegidas de ataques do tipo man-in-the-middle. Se um terceiro tenta interceptar uma conexão ativa em OpenSSH, o OpenSSH irá detectar e irá nos informar sobre isso.
O diretório /etc/ssh
O OpenSSH possui dois conjuntos diferentes de arquivos de
configuração: um para programas clientes (ssh
, scp
e sftp
) e um
para o daemon do servidor (sshd
).
┌─[root@centos7lpi]──[19:14]──[~] └─[133]─># ls -l /etc/ssh/ total 604 -rw-r--r--. 1 root root 581843 Nov 24 13:35 moduli -rw-r--r--. 1 root root 2276 Nov 24 13:35 ssh_config -rw-------. 1 root root 3906 Mar 7 2021 sshd_config -rw-r-----. 1 root ssh_keys 227 Mar 7 2021 ssh_host_ecdsa_key -rw-r--r--. 1 root root 162 Mar 7 2021 ssh_host_ecdsa_key.pub -rw-r-----. 1 root ssh_keys 387 Mar 7 2021 ssh_host_ed25519_key -rw-r--r--. 1 root root 82 Mar 7 2021 ssh_host_ed25519_key.pub -rw-r-----. 1 root ssh_keys 1679 Mar 7 2021 ssh_host_rsa_key -rw-r--r--. 1 root root 382 Mar 7 2021 ssh_host_rsa_key.pub
O sshd_config
é o arquivo de configuração do daemon ssh
(ou
processo do servidor ssh
), enquanto o arquivo ssh_config
é o
arquivo de configuração do cliente ssh
. O arquivo de configuração
do cliente só tem influência quando você usa o comando ssh
para se
conectar a outro host por ssh
. Como você pode ver, existem chaves
públicas e chaves privadas aqui com algoritmos diferentes e podem
ser usadas pelo OpenSSH para criptografar a sessão.
A relação entre os arquivos de configuração
Na verdade, o servidor OpenSSH lê vários arquivos de configuração. O
arquivo sshd_config
especifica as localizações de um ou mais
arquivos de chave de host (obrigatório) e a localização de
arquivos authorized_keys
para usuários. Também pode referir-se a
vários outros arquivos.
Figura 2: Diagrama de carga de configurações do daemon sshd
O arquivo /etc/ssh_config
Este arquivo contém diretivas similares as encontradas em /etc/ssh/sshd_config
porém há ajustes específicos para os utilitários do SSH client
tais como scp e sftp.
Precedência das configurações
Importante dizer que o cliente SSH obedece uma ordem de precedência na hora de carregar as configurações:
- primeiramente o SSH client lê as opções que lhe foram passadas via linha de comando no momento da execução;
- depois ele lê as configurações que constam no arquivo de
configuração local do usuário
/.ssh/config
; - Por fim ele lê as configurações que contam no arquivo global
/etc/ssh/ssh_config
.
O arquivo /etc/ssh/sshd_config
É o arquivo que o servidor OpenSSH lê ao ser iniciado, é bastante extenso pois é vastamente documentado com comentários pois tem uma boa quantidade de diretivas que podem ser ajustadas.
Vamos listar aqui algumas importantes:
Port
- essa diretiva especifica a porta TCP que o serviço do SSH deve escutar, o padrão é na porta 22. Se for necessário mudar essa porta não esqueça de ajustar também no SELinux ou no Apparmor;
Protocol
- o OpenSSH pode trabalhar com o protocolo do tipo
1
, menos seguro, e o protocolo do tipo2
, mais seguro. Por isso, é bastante recomendável manter apenas o protocolo 2; SyslogFacility
por padrão o servidor OpenSSH envia os logs para a facility AUTH do
syslog
;auth
: destina-se a registrar comandos relacionados à autenticação e autorização;authpriv
: destina-se a mensagens de natureza sensível.
Todos os logs serão escritos em
/var/log/auth.log
para sistemas Debian-like ou em/var/log/secure
para sistemas RedHat-like.LogLevel
- por padrão o OpenSSH registra suas entradas de log no nível INFO. Se quisermos registrar mais detalhes (como tentativas de login malsucedidas) devemos aumentar o nível de registro para VERBOSE.
PermitRootLogin
- especifica se o usuário
root
pode efetuar login porssh
ou não. Essa diretiva pode ser setada como:yes
: o usuárioroot
poderá logar;no
: o usuárioroot
não poderá logar de forma alguma;without-password
: a autenticação utilizando senhas fica desligada para o usuárioroot
, assim permitindo login apenas utilizando chaves;forced-commands-only
: o login doroot
com autenticação de chaves será permitido, mas apenas se a opção de comando tiver sido especificada (o que pode ser útil para fazer backups remotos, mesmo se o login deroot
normalmente não for permitido). Todos os outros métodos de autenticação ficam desabilitados para oroot
.
PubkeyAuthentication
- permite aos usuários logarem usando chaves ssh sem precisarem entrar com senhas;
PermitEmptyPassword
- permite login para usuários sem senha definida;
PasswordAuthentication
- permite autenticações utilizando
senhas, porém para forçar autenticação por chaves para todos
essa diretiva deve ser setada como
no
; ChallengeResponseAuthentication
- devene se a autenticação
de "desafio-resposta" é permitida, para desabilitar a
autenticação por senha também deve ser definida para
no
em conjunto com a diretiva acima; IgnoreRhosts
- Ignora uma modalidade de liberação de acesso
legada, onde bastava que os endereços presentes nos arquivos
/.rhosts
e/.shosts
pudessem entrar sem fornecer senha. Banner
- define um arquivo de texto para exibir seu conteúdo como banner para ser exibido sempre que alguém logar no ssh;
PrintMotd
- exibe uma mensagem após o login;
MaxAuthTries
- especifica o número máximo de tentativas de autenticação permitidas por conexão. Quando o número de falhas atinge a metade desse valor, as falhas adicionais são registradas no log. Ele pode ser sobrescrito pelo PAM se algum módulo PAM estiver associado;
GatewayPorts
- permite a abertura de sockets no host
onde roda o serviço OpenSSH permitindo o uso do recurso de
encaminhamento de portas remotas, aceita os valores
no
(padrão),yes
eclientspecified
; X11Forwarding
- essa diretiva permite que janelas de
programas sejam abertas através da conexão SSH. É necessário
passar a opção
-X
para o comandossh
no cliente. Dessa forma, um programa sendo executado no servidor exibirá sua janela do ambiente gráfico do cliente.
Por padrão, todos os usuários com contas de usuário podem fazer
login por meio de ssh, mas existem duas opções que podem ser
adicionadas ao arquivo sshd_config
para alterar o comportamento
padrão:
AllowUsers
- especifica alguns usuários para fazer login (ninguém mais poderá logar);
DenyUsers
- proíbe alguns usuários de logar.
Túneis SSH e/ou encaminhamento de portas
O encapsulamento SSH é um método de transporte de dados arbitrários por meio de uma conexão SSH criptografada. Ele pode ser usado para adicionar criptografia a aplicativos legados. Ele também pode ser usado para implementar VPNs (Redes Privadas Virtuais) e acessar serviços de intranet através de firewalls.
Figura 3: Diagrama basico do encapsulamento SSH
O SSH é um padrão para logins remotos seguros e transferências de arquivos em redes não confiáveis. Ele também fornece uma maneira de proteger o tráfego de dados de qualquer aplicativo usando encaminhamento de porta, basicamente encapsulando qualquer porta TCP/IP sobre SSH. Isso significa que o tráfego de dados do aplicativo é direcionado para fluir dentro de uma conexão SSH criptografada para que não possa ser espionado ou interceptado enquanto estiver em trânsito. O encapsulamento SSH permite adicionar segurança de rede a aplicativos legados que não oferecem suporte nativo à criptografia.
Portanto, o encaminhamento de porta SSH é um mecanismo em SSH para encapsular portas de aplicativos da máquina cliente para a máquina servidor, ou vice-versa. Alguns administradores de sistema e profissionais de TI usam-no para abrir backdoors na rede interna de suas máquinas domésticas. Ele também pode ser usado por hackers e malware para abrir o acesso da Internet à rede interna.
Há três tipos de encaminhamentos de portas:
Encaminhamento de porta local
No Encaminhamento de porta local as conexões de um cliente SSH são encaminhadas, por meio do servidor SSH, para um servidor de destino.
Explicando com mais detalhes podemos abrir uma porta de conexção local e através de um túnel SSH alcançar alguma porta remota.
Esse recurso é muito útil quando precisamos alcançar algum serviço não seguro tais como HTTP e Telnet através da Internet sem precisar expor o serviço ou os dados, pois tudo isso estará protegido pela forte criptografia e autenticação do SSH.
Sintaxe para execução:
ssh -L host_local:porta_local:host_destino:porta_destino
usuario@servidor_ssh
Alcançando um serviço desprotegido através de um host com serviço SSHd
Este cenário é o mesmo mostrado na Figura 3 porém vamos detalha-lo mais.
Imagine uma rede contendo ativos de rede tais como switches ouvindo a porta de Telnet para administração. Por questões de segurança os switches estão protegidos por um Firewall de perímetro que não permite que o tráfego de Telnet seja alcançado de fora.
Um administrador de redes que estiver atuando remotamente poderia facilmente alcançar esses switches de forma muito segura utilizando um túnel ssh utilizando a sintaxe:
ssh -L localhost:2323:ip.do.switch:23 user@fw.exemplo
Como a opção -L
sempre aponta para portas do host onde o
comando de cliente SSH está sendo executado, podemos omitir o
termo localhost
do comando deixando-o um pouco mais prático:
ssh -L 2323:ip.do.switch:23 user@fw.exemplo
Existem mais duas opções úteis a agregar no comando ssh
no ato
da abertura do encaminhamento de porta, são elas:
-f
: que indica que o comando deve ser executado em segundo plano;-N
: determina que não deve ser aberta seção de shell no servidor OpenSSH.
Por fim o comando ficaria:
ssh -fNL 2323:ip.do.switch:23 user@fw.exemplo
Figura 4: Diagrama de encaminhamento de porta local
Por fim para poder conectar no switch você entrará com o comando:
telnet localhost 2323
Resumindo, no cenário aqui proposto você está encaminhando os dados que entrarem pela porta local 2121 através de um túnel SSH com criptografia forta para a porta 23 do switch remoto.
- Exemplo de uso, conexão através de um host com serviço SSHd
Em meu laboratório de LPI estou utilizando meu notebook que tem o hostname
tesla
(IP 10.152.240.41), nele subi uma VM com o hostnamecentos7lpi
(IP 10.152.240.45) e outra vm com o hostnamedebianlpi
(IP 10.152.240.47), como pode-se notar todos esses hosts estão no mesmo barramento de rede.Na VM
debianlpi
instalei o utilitárionetcat
(que falaremos mais dele no tópico 212.4), e com ele fiz a VMdebianlpi
ouvir a porta 4560/TCP com a seguinte sintaxe:netcat -n -l -vv -p 4560
No meu computador executei o comando:
ssh -fNL 1230:localhost:4560 root@centos7lpi.infralinux.net
┌─[root@debianlpi]──[13:38]──[~] └─[103]─># netcat -n -l -vv -p 4560 listening on [any] 4560 ... connect to [10.152.240.47] from (UNKNOWN) [10.152.240.45] 58214 teste sent 0, rcvd 7
Na saída do comando
netcat
no hostdebianlpi
podemos constatar que ele recebeu uma conexão provinda do IP 10.152.240.45 que é pertencente ao hostcentos7lpi
.┌─[jeremias@tesla]──[13:38]──[~] └─[1013]─>$ ssh -fNL 1230:10.152.240.47:4560 root@10.152.240.45 ┌─[jeremias@tesla]──[13:38]──[~] └─[1014]─>$ telnet localhost 1230 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. teste ^] telnet> quit Connection closed.
No meu computador o host
tesla
eu executei o comando para a abertura do túnel SSH com destino ao IP do hostcentos7lpi
e no conteúdo da opção-L
pedimos que no hosttesla
fosse aberta a porta 1230 e que todo o tráfego enviado a ela fosse encaminhado para a porta 4560 do hostdebianlpi
através do túnel criado no hostcentos7lpi
.Depois disso, no meu computador, abri uma seção de
telnet
com destino a localhost na porta 1230, como consta na listagem 3 a conexão foi aberta com sucesso. Logo pude escrever a palavra teste nessa seção de telnet que foi apresentada na saída do comandonetcat
que estava ativo no hostdebianlpi
, como consta na listagem 2. Por fim entrei com a combinação de teclas<ctrl+]>
para finalizar a seção detelnet
e também a seção do comandonetcat
que estava ativa no hostdebianlpi
.
Acessando um serviço desprotegido no host com serviço SSHd
E se o serviço desprotegido estiver localizado no próprio servidor onde está rodando o servidor SSH?
Este cenário é uma variação do anterior. Imagine que você tem um servidor do tipo VPS (Virtual Private Server ou servidor privado virtual em tradução nossa) em alguma cloud qualquer. Nele está instalada uma aplicação PHP que trabalha em conjunto com um banco de dados MySQL.
Por segurança o servidor MySQL não permite logins de usuários que não provenham de localhost, assim para podermos administrar o banco de dados de forma segura podemos usar túneis SSH. Segue sintaxe do comando:
ssh -L localhost:3306:localhost:3306 user@app.exemplo
O comando ficou bastante confuso, não? Bom a sintaxe da opção
-L
é composta de 4 elementos divididos por :
sendo os dois
primeiros elementos relativos ao socket que será criado no
cliente de SSH (até por isso que o primeiro elemento pode ser
omitido do comando) e os dois últimos elementos ao socket de
destino ao qual estamos tentando enviar os dados. Portanto no
exemplo o socket localhost:336
que vem após o segundo :
refere-se a algum socket existente no próprio host onde está
rodando o servidor SSH que estamos tentando conectar.
Como já exposto para ficar uma sintaxe menos confusa podemos
omitir a primeira porção do conteúdo de -L
:
ssh -L 3306:localhost:3306 user@app.exemplo
Figura 5: Diagrama de encaminhamento de porta local para serviço no próprio servidor onde está o SSHd
- Exemplo de uso, conexão em um serviço no host com serviço SSHd
O ambiente de laboratório para exemplificar esse caso é bem semelhante ao anterior, porém nesse caso não iremos utilizar o host
centos7lpi
em outras palavras não haverá host intermediário. A conexão SSH será aberta no próprio host onde está o serviço que queremos acessar de forma segura.Portanto da mesma forma que no cenário anterior no host
debianlpi
vou colocar onetcat
para ouvir a porta 4560.┌─[root@debianlpi]──[14:04]──[~] └─[106]─># netcat -n -l -vv -p 4560 listening on [any] 4560 ... connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 55928 teste 2 sent 0, rcvd 9
Já no meu computador vou executar o comando:
ssh -fNL 1230:localhost:4560 root@10.152.240.47
┌─[jeremias@tesla]──[14:05]──[~] └─[1024]─>$ ssh -fNL 1230:localhost:4560 root@10.152.240.47 ┌─[jeremias@tesla]──[14:05]──[~] └─[1025]─>$ telnet localhost 1230 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. teste 2 ^] telnet> quit Connection closed.
Na listagem 4 podemos notar que agora a conexão aparece como provinda de
127.0.0.1
provinda também de127.0.0.1
(localhost), bem diferente do que ocorre na listagem 2.
Encaminhamento de porta remota
No encaminhamento de porta remota as conexões de um servidor SSH são encaminhadas, por meio do cliente SSH, para um servidor de destino. Em outras palavras é o caminho inverso do tópico anterior.
No caso através do comando do cliente SSH iremos orientar ao servidor SSH a abrir no host que o sustenta uma porta especificada no comando e encaminhar o tráfego destinado a esta porta para o estino que também especificamos no comando.
A sintaxe de todo o processo é exatamente igual ao do tópico
anterior porém ao invés de usarmos a opção -L
(de local)
usaremos a opção -R
(de remoto).
A utilização desse recurso também é análoga ao do tópico anterior.
Permitindo acesso a um serviço rodando no próprio PC com o cliente SSH
Imagine o cenário de um desenvolvedor que tem em seu computador local um servidor MySQL com uma base de teste e ele se depara com o famoso problema de "no meu computador funciona".
A suposta base é relativamente grande e apenas para um teste não valeria a pena enviar a base para o servidor VPS. Seria prático se ele pudesse fazer sua aplicação poder ler na base de seu computador. Porém ele está em sua casa, com o IP público randômico atribuído pelo DHCP da operadora, atrás de firewall e outros complicadores.
Nesse cenário o tal desenvolvedor poderia abrir um túnel utilizando o encaminhamento de porta remota. O comando a utilizar seria o seguinte:
ssh -fNR 3306:localhost:3306 user@app.exemplo
Figura 6: Diagrama de encaminhamento de porta remota para o próprio cliente SSH
- Exemplo de uso, permitindo acesso a um serviço rodando no próprio PC com o cliente SSH
Para esse exemplo irei utilizar meu próprio computador hostname
tesla
IP10.152.240.42
e uma VM pública de teste com IP189.72.106.199
.No meu computador coloquei pra ouvir a porta 4560
┌─[jeremias@tesla]──[15:56]──[~] └─[1008]─>$ netcat -n -l -vv -p 4560 Listening on 0.0.0.0 4560 Connection received on 127.0.0.1 41776 teste
Também do meu computador abri um novo terminal e executei o comando
ssh
com a seguinte sintaxe:ssh -R 1230:localhost:4560 vpsuser@189.72.106.199
Com esse comando eu já caí na seção do Bash do servidor e pude executar o teste de telnet para
localhost:4560
[vpsuser@vps05754928]~# telnet localhost 1230 Trying ::1... Connected to localhost. Escape character is '^]'. teste ^] telnet> quit Connection closed.
Desse exemplo importa notar que na listagem 6 vemos que a conexão é originada de localhost e na listagem 7 (no host remoto) também mandamos o comando
telnet
com destino a localhost. No fim de tudo é estranho. Mas funciona.
Permitindo acesso a um serviço interno através do cliente SSH
Imaginemos o cenário em que precisa-se expor para algum usuário em uma rede remota algum serviço de rede que está em sua rede local, mas por algum motivo você não tem permissão de escrita no seu firewall para poder criar um encaminhamento de porta. Porém você tem acesso a um computador onde está a o usuário ao qual você quer apresentar o serviço de rede.
Esse exemplo pode até parecer algo que nunca vai acontecer, mas é muito comum em empresas de desenvolvimento algum desenvolvedor querer exemplificar uma tela nova para um site que está criando ou coisa semelhante.
Bom esse cenário é um pouco mais complexo do que os apresentados
até aqui, pois agora precisamos abrir uma porta no servidor SSH
para ouvir conexões de outros hosts na rede onde ele se
encontra. Esse comportamento é
bloqueado por padrão na configuração do OpenSSH. Porém pode ser
ajustado alterando o valor da diretiva GatewayPorts
no arquivo
de configuração /etc/ssh/sshd_config
. Essa diretiva aceita três
valores possíveis:
no
- é o valor padrão, não permitindo a abertura de portas no host onde roda o servidor OpenSSH;
yes
- permite que se abra quaisquer sockets possíveis no host onde roda o servidor OpenSSH;
clientspecified
também permite que se abra quaisquer sockets possíveis no host onde roda o servidor OpenSSH, mas com um porém, o cliente é obrigado a especificar o endereço de IP do socket a abrir.
Nessa opção fica bastante evidente a utilidade do formato de quatro elementos separados por
:
para as opções-L
e-R
. Pois para abrir um socket no servidor remoto que contenha o IP 192.168.30.18 o cliente precisaria especificar da seguinte forma:192.168.30.18:8080:localhost:80
Posto isso o tal desenvolvedor precisaria fazer os devidos
ajustes no serviço OpenSSH no servidor para permitir a criação de
/ sockets/ e depois usaria o comando ssh
com a seguinte
sintaxe:
ssh -R 8080:host.a.expor:80 usuario@host.remoto
Figura 7: Diagrama de encaminhamento de porta remota
Com o arranjo exposto acima o "Cliente remoto" conseguiria
alcançar a aplicação exposta na Intranet1 apontando seu navegador
para o endereço fictício http://servidor-ssh:8080
.
- Exemplo de uso, permitindo acesso a um serviço interno através do cliente SSH
Para esse exemplo irei utilizar 4 hosts sendo:
- meu notebook hostname
tesla
IP10.152.240.42
; - o host
centos7lpi
IP10.152.240.45
; - o host
debianlpi
IP10.152.240.47
; - o host
centos5
IP10.152.240.51
;
Nesse laboratório supomos que o host
tesla
e o hostdebianlpi
estão "lado a lado" no mesmo barramento. Já os hostscentos7lpi
ecentos5
estão "lado a lado" em barramentos diferentes.Execução do laboratório
- no host
debianlpi
coloco pra ouvir a porta 4560; - no host
centos7lpi
configuro a diretivaGatewayPorts
parayes
; no host
tesla
executo o comando:ssh -fNR 1230:10.152.240.47:4560 root@10.152.240.45
Que criará o túnel com o host
centos7lpi
e solicitará a abertura da porta 1230 para encaminhar conexões;- No host
centos5
executo o telnet com destino ao hostcentos7lpi
na porta 1230.
┌─[root@debianlpi]──[15:56]──[~] └─[126]─># netcat -n -l -vv -p 4560 listening on [any] 4560 ... connect to [10.152.240.47] from (UNKNOWN) [10.152.240.42] 47518 teste sent 0, rcvd 7
Note que na saída do comando
netcat
executado no hostdebianlpi
mostra que a conexão veio pelo IP10.152.240.42
que é o endereço do meu computador, o hosttesla
, que para efeitos do nosso laboratório devem ser considerados hosts que estão "lado a lado" no mesmo barramento.┌─[root@centos5]──[17:04]──[~] └─[258]─># telnet 10.152.240.45 1230 Trying 10.152.240.45... Connected to 10.152.240.45 (10.152.240.45). Escape character is '^]'. teste ^] telnet> quit Connection closed.
Note que partindo do host
centos5
estou enviando o comando Telnet para o IP10.152.240.45
que é o IP do hostcentos7lpi
na porta1230
.Resumindo utilizando o host
centos5
alcançamos o socket10.152.240.47:4560
ativo no hostdebianlpi
utilizando o socket10.152.240.45:1230
sustentado no hostcentos7lpi
através de um túnel SSH com o hosttesla
. - meu notebook hostname
Encaminhamento de portas dinâmico
Essa técinica consiste em criar uma conexão ssh com o objetivo de
utilizar a máquina remota como um gateway/proxy. E como nos casos
anteriores a opção em linha de comando a utilizar é
diferente. Aqui utilizaremos -D
(de Dinâmico).
Aqui, também diferente dos formatos anteriores, não precisaremos
apresentar ao opcional -D
todos aqueles detalhes sobre socket
que precisávamos especificar. Agora basta especificar a porta TCP
a qual iremos abrir em nosso cliente SSH para utilizar como
entrada para nossos dados. O socket de saída será atribuído
dinâmicamente pelo servidor OpenSSH funcionando análogo a um
proxy squid. Segue um comando de exemplo:
ssh -D 3028 user1@end.do.servidor.remoto
X remoto via SSH
É uma técnica semelhante aos túneis SSH, no caso essa técnica
permite abrir a janela de uma aplicação rodando no servidor onde
está rodando o sshd
por meio de uma conexão SSH.
Por exemplo, para exibir localmente o programa VirtualBox instalado em uma máquina remota:
Abra a conexão SSH com a máquina onde está o VirtualBox utilizando a opção
-X
:ssh -X usuario@virtualbox.exemplo.local
Na máquina remota basta chamar o programa:
$ VirtualBox
Pode-se simplificar isso tudo em um só comando:
ssh -X usuario@virtualbox.exemplo.local "VirtualBox"
O comando passado como argumento no final será executado na
máquina remota. Opcionalmente o comando ssh
também pode enviar
os dados recebidos pela entrada padrão para a entrada padrão do
comando remoto.
Autenticação baseada em chaves SSH
Até agora nós entendemos como o SSH funciona. Como mencionamos
quando a conexão SSH é iniciada, a chave pública do servidor SSH
é transferida para o cliente e armazenada em ./ssh/known_hosts
e
o cliente a usará para continuar a negociação com o servidor. Depois o
usuário deverá ser autenticado enviando nome de usuário e
senha.
Como já mostrado no /etc/ssh/
constam as chaves públicas e
privadas relativas ao computador.
Pois bem além das chaves do próprio computador, cada usuário também pode possuir sua chave pública e privada que podem ser utilizadas para garantir sua autenticidade.
Dessa form, é possível fazer com que o acess ovia SSH seja feito automaticamente, sem necessidade de fornecer a senha em todo login. Isso é especialemte útil quando um computador remoto é acessado frequentemente. Antes de conseguir fazer o login sem senha, é necessário que o usuário crie a chave pública e chave privada.
As chaves criptográficas podem utilizar diferentes tipos de formatos, sendo os mais populares o DSA e o RSA. Para gerar uma chave DSA de 1024 bits, utiliza-se:
ssh-keygen -t dsa -b 1024
Chaves RSA suportam um tamanho em bits maior, como 4096:
ssh-keygen -t rsa -b 4096
Um tamanho maior em bits torna ainda mais difícil a quebra da criptografia.
As chaves podem ser criadas com ou sem senha, as chamadas passphrases. Importa dizer que chaves protegidas com senhas são mais seguras, pois toda vez que forem utilizadas será necessário informar a senha respectiva.
O comando ssh-keygen
criará as chaves (pública e privada) no
diretório ~/.ssh/
na máquina de origem para o usuário atual.
O conteúdo do arquivo da chave pública do usuário deverá ser
incluída no arquivo authorized_keys
, criado no computador de
destino dentro do diretório .ssh/
na home do usuário a logar no
computador de destino. Esse arquivo pode conter uma ou mais chaves
que foram criadas em máquinas utilizadas como origem de acesso.
Enviando a chave pública para o computador de destino
Supondo que o computador de destino tenha o IP 192.168.1.1
e a
conta jeremias
, a chave pública do formato DSA pode ser copiada
com o comando:
cat ~/.ssh/id_dsa.pub | ssh jeremias@192.168.1.1 "cat >>
~/.ssh/authorized_keys"
Descrevendo: o conteúdo do arquivo ~/.ssh/id_dsa.pub
será
direcionado para o comando ssh
. Este, por sua vez, redirecionará o
conteúdo para o comando cat
na máquina remota que por fim
incluirá o conteúdo no final do arquivo /.ssh/authorized_keys
na ocnta na m[aquina remota.
Hoje o processo de cópia de chaves pode ser executado com um
comando específico o ssh-copy-id
:
ssh-copy-id -i ~/.ssh/id_dsa.pub jeremias@192.168.1.1
Se não for especificado o -i
o comando ssh-copy-id
irá
procurar automaticamente o arquivo ~/.ssh/id_rsa.pub
.
O uso de chaves públicas com passphrase
Se for informada uma passphrase durante a criação da chave,
será perdida toda a conveniência de realizar o login sem senha,
pois será necessário informar a pasphrase da chave todas vez
que ela for utilizada. Contud, é possível evitar a digitação da
passphrase a todo momento se for utilizado o comando
ssh-agent
.
O ssh-agent
atua como uma espécie de chaveiro. Ele armazena a
autorização e libera o usuário da necessidade de digitar a
passphrase novamente durante a mesma seção. Para utilizá-lo,
basta executar o comando ssh-agent
:
┌─[jeremias@tesla]──[18:01]──[~] └─[1003]─>$ ssh-agent SSH_AUTH_SOCK=/tmp/ssh-H4Fe0wcBpDjk/agent.1574038; export SSH_AUTH_SOCK; SSH_AGENT_PID=1574039; export SSH_AGENT_PID; echo Agent pid 1574039;
O ssh-agent
irá para o segundo plano e exibirá as variáveis de
ambiente que necessitam ser declaradas. Somente se essas
variáveis estiverem acessíveis na cessão é que a autorização
automática do ssh-agent
poderá ser utilizada. Essas variáveis
serão usadas pelos outros programas para fazer a autenticação via
ssh-agent
.
Com o ssh-agent
ativo e as variáveis de ambiente declaradas, é
utilizado o comando ssh-add
para incluir a chave do usuário no
ssh-agent
:
┌─[jeremias@tesla]──[18:12]──[~] └─[1004]─>$ ssh-add Enter passphrase for /home/jeremias/.ssh/id_rsa: Identity added: /home/jeremias/.ssh/id_rsa (/home/jeremias/.ssh/id_rsa)
A pasphrase será solicitada apenas no momento da execução do
comando ssh-add
, feito isso, não será necessário informar a
passphrase nas sessões onde as variáveis exportadas estiverem
acessíveis.
Manipulação das chaves SSH
Além de servir pssh formatos de chaveara criar chaves SSH o comando ssh-keygen
permite a manipulação das chaves SSH. Para entendermos isso
importa dizer que as chaves SSH são chaves assimétricas, em
outras palavras a chave privada é diferente da chave
pública. Posto isso deve-se entender que a partir da chave
privada podemos gerar a devida chave pública. Porém a partir da
chave pública nunca poderemos gerar a chave privada. E é esse o
segredo de toda a segurança quando se fala em assimetria dentro
do escopo de cryptografia.
Bom com o que colocamos acima fica fácil entender o porque a chave privada sempre deve ser guardada com muito cuidado. Pois se a perdermos não temos como recuperá-la sem operações de backup.
Sobre as chaves públicas há 4 formatos disponíveis para aplicações diferentes:
- o formato do próprio OpenSSH;
- o formato PEM;
- o formato PKCS8;
- o formato RFC4716.
A chave no formato do próprio OpenSSH é a que o comando
ssh-keygen
gera automaticamente quando criamos uma chave. Mas
no dia a dia é interessante saber alterar o formato da chave
pública quando necessário.
Usaremos duas opções no ssh-keygen
:
-e
- esta é a opção de "exportação" no caso ela lê o arquivo
de chave privada ou chave pública no formato OpenSSH que
especificaremos com a opção
-f
e permite exportá-lo nos formatosRFC4716
,PEM
ePKCS8
que devem ser especificados na opção-m
; -f
- especifica o arquivo de chave ao qual iremos trabalhar;
-i
- essa é a opção de "importação" com essa opção poderemos
apenas especificar arquivos de chave pública (não aceita
arquivos de chave privada) e nos formatos que não sejam o do
próprio OpenSSH (afinal estamos importando) usando essa opção
poderemos especificar na opção
-m
os formatosRFC4716
,PEM
ePKCS8
. -m
- é a opção que usamos para especificar os formatos de
chave
RFC4716
,PEM
ePKCS8
. Quando na execução de uma importação essa opção irá especificar o formato do arquivo de entrada, quando na execução de uma exportação essa opção irá especificar o arquivo de saída, nos dois casos o formato padrão (se a opção for omitida) será oRFC4716
.
Ao utilizar o comando ele sempre irá printar o resultado na
saída padrão. Portanto deveremos usar o pipe >
para direcionar
essa saída para um arquivo e podermos manipulá-lo.
Exemplos:
Exportar uma chave pública (formato RFC4716) a partir de uma chave privada:
ssh-keygen -e -m RFC4716 -f .ssh/chave > /tmp/chave.ppk
Exportar uma chave pública (formato PEM) a partir de uma chave pública:
ssh-keygen -e -m PEM -f .ssh/chave > /tmp/chave.pem
Importar uma chave pública para o formato do OpenSSH:
ssh-keygen -i -m PEM -f /tmp/chave.pem > /tmp/chave.pub
Clientes SSH
Nessa seção vamos dar uma olhada rápida nos clientes de SSH começando por algumas formas de chamar o próprio SSH:
Comando SSH | Descrição |
---|---|
ssh -V |
Mostra a versão do cliente SSH |
ssh -v user1@server1.exemplo.com |
Conecta no servidor no modo verboso |
ssh -lv user1 server1.exemplo.com |
O mesmo do comando anterior |
ssh user1@server1.exemplo.com <comando> |
Executa <comando> no host remoto |
ssh -X user@server1.exemplo.com |
Executa o ssh ativando o encaminhamento do X11 |
Comandos SCP
Podemos usar o comando SCP para copiar arquivos entre o host local e o host remoto usando a criptografia e autenticação do SSH.
Copiando um arquivo local para um servidor remoto:
scp localhostfile.txt user1@remotehost.example.com:/home/user1/
copiando um arquivo de um host remoto para a o host local:
scp user1@remotehost.example.com:/home/user1/remotehostfile.txt .
Comandos SFTP
O SFTP (SSH File Transfer Protoco ou protocolo de transferência de arquivo por SSH) é um protocolo de transferência de arquivos seguro. Ele tem pleno suporte as funcionalidades de segurança e autenticação do OpenSSH.
Comandos SFTP | Descrição |
---|---|
sftp user1@server1.example.com |
Conecta o SFTP com o user1 |
sftp> ? |
Apresenta a ajuda |
sftp> lpwd |
Mostra o diretório local |
sftp>ls |
Lista os diretórios remotos |
sftp>lls |
Lista os diretórios locais |
sftp> put local.profile |
Envia o arquivo local.profile |
sftp> mput *.txt |
Envia múltiplos arquivos |
sftp> get myfile.txt |
Baixa o arquivo myfile.txt |
sftp> mget *.txt |
Baixa múltiplos arquivos |
sftp> cd testdir |
Muda o diretório remoto |
sftp> lcd test |
Muda o diretório local |
sftp> mkdir mytestdir |
Cria um diretório remoto |
sftp> lmkdir mydownloads |
Cria um diretório local |
sftp > rm mytempfile.txt |
Apaga um arquivo remoto |
sftp > rm mytempfile.txt |
Apaga um diretório remoto |
sftp> ! |
Sai do shell sftp |