Sobre o Software

Nome
SSH - Secure Shell

Descrição

O SSH é um programa e um protocolo de rede que permite administrar máquinas remotamente, executando inclusive apliativos gráficos, permite transferir arquivos de várias formas diferentes e permite também encapsular outros protocolos, possibilitando, por exemplo, acessar uma seção VNCatravés de um tunel seguro.

Autor/Empresa

O SSH foi desenvolvido pela empresa SSH Communications Security, criada em 1995 para desenvolver soluções seguras de comunicação.

Site
O site do SSH, onde é possível copiar o pacote, é http://www.ssh.fi.

Função Resumida

O SSH possibilita o acesso remoto via linha de comando por usuários que tenham o login e senha de uma das contas do sistema. Este é um acesso completo via terminal (rede ou internet), limitado aos privilégios do login do usuário.
Sua principal vantagem sobre outros protocolos, como por exemplo o telnet é a segurança, o SSH utiliza criptografia e protocolo de autenticação mais seguros. 

Funcionamento

Arquitetura

O pacote SSH consistem de vários programas que auxiliam na segurança do protocolo:

1.	SSHD

Servidor de conexões do protocolo SSH, deve ser executado como root e normalmente é instalado nos arquivos de inicialização das estações (rc files) mas é possível também iniciá-lo via o inetd. Como o servidor precisa calcular um par de chave publica/chave pivada de 1024 bits a cada inicialização, o método do inetd não é recomendado para máquinas de baixo desempenho. O servidor escuta a porta 22.

2.	SSH

Substituto do RSH com algumas melhorias. Por exemplo, se não houver uma entrada nos arquivos .rhosts, ou .shosts, para a máquina cliente, o servidor tenta autenticar pelo servidor de chavers RSA ou pela senha. Existe uma pequena mudança de sinaxe pra os comandos remotos trocando o nome do usuário.

3.	SLOGIN

Semelhante ao rlogin e assim como o rsh recai no rlogin quando nenhum comando é dado, o ssh também recai num shell criptografado quando executado sem um comando explícito para a máquina remota.

4.	SCP

Semelhante aos rpc, com a vantagem de não derrubar a conexão se a etação remota não possuir uma referência à máquina local nos seus arquivos hosts.equiv e .rhosts. Caso não obtenha autorização pelo .rhosts, a transferência  pode ser autorizada por RSA pessoal ou password transmitido codificado.

5.	SSH-KEYGEN

Gerador de chaves RSA. Cada usuário pode ter as suas próprias chaves RSA, que são geradas e colcadas no diretório .ssh. Estas chaves são utilizadas para a autenticação das conexões por chaves RSA. As chaves são geradas baseadas numa frase senha, o que aumenta a sua segurança em relação ao sistema de senha das estações ue em muitos casos é limitada a poucos caracteres. O arquivo de senha gerado, ssh/identity, deve terpermissão de leitura/escrita apena para o usuário.

6.	SSH-AGENT

Espécie de servidor de chaves RSA para uma seção, normalmente deve ser executado a partir do arquivo .login nas máquinas com login textual e .xsession nas máquinas com login controlado por xdm e seus equivalentes.

6.	SFTP

Cliente FTP com suporte a comunicação segura.

6.	SFTP-SERVER

Servidor FTP com suporte a comunicação segura.

6.	SSH-ADD

Adiciona chaves de autentificação DSA ou RSA ao programa de autentificação.

6.	SSH-COPY-ID

Usado para instalação do arquivo identity.pub em uma máquina remota.

Protocolo
SSH é um protocolo para login remoto seguro e outros serviços contextualizados em redes abertas. Esse protocolo é dividido em três componentes básicos:

· Camada de Transporte: Provê sigilo, integridade e autenticação do servidor. Opcionalmente, pode ser oferecido um serviço de compressão de dados. Essa camada geralmente é rodada em cima de uma conexão TCP/IP, mas é possivel que ela seja usada em cima de qualquer outro tipo de protocolo confiável e orientado a conexão.
· Protocolo de Autenticação: Autentica o usuário perante o servidor. Esse protocolo necessita da camada de transporte para o seu funcionamento.
· Protocolo de Conexão: Permite a multiplexação da conexão entre vários canais lógicos. Esse protocolo depende do protocolo de autenticação. Nessa camada encontramos recursos como shell interativo, tunelamento de portas TCP/IP e conexões X11.

O SSH é bastante flexível no sentido de que os algoritmos usados em uma conexão são negociados entre o cliente e o servidor. Isso permite que algoritmos fracos sejam removidos ou novos algoritmos sejam testados sem que haja uma mudança no protocolo.

Camada de Transporte

A camada de tranporte do SSH é um protocolo seguro de baixo nivel que fornece encriptação, integridade e autenticação do servidor. Observe que aqui somente é feita a autenticação do servidor, sendo que a autenticação do usuario é responsabilidade do protocolo de autenticação.
Os pacotes que são recebidos e enviados por essa camada possuem o seguinte formato:
 
Tamanho (4 bytes)	
Tamanho do preenchimento (1 byte)	
Conteúdo (n1 bytes)	
Preenchimento (n2 bytes)	
MAC (m bytes)	

Tamanho: Indica o comprimento do pacote sem incluir o MAC e o próprio campo Tamanho. Tamanho = 1 + n1 + n2.
Tamanho do preenchimento = “n2”: Número de bytes que serão colocados no pacote para que o tamanho total (sem o MAC) seja múltiplo de 8 (ou do tamanho do bloco usado na encriptacao). n2 não pode ser menor que 4.
Conteúdo: Conteúdo útil do pacote. Se algum algoritmo de compressão estiver sendo usado, esse campo é compactado.
Preenchimento: “n2” bytes aleatórios.
MAC: Código de autenticação de mensagem. O número “m” de bytes varia de acordo com o algoritmo que está sendo utilizado. O cálculo do MAC é: mac = MAC(key, no_do_pacote || pacote_não_encriptado), onde no_do_pacote é um contador de pacotes enviados (ou recebidos).

Protocolo de Troca de Chaves

0- Troca de strings de versão: Após a conexão ser estabelecida, cliente e servidor trocam strings no formato: "SSH-protoversion-softwareversion comentários\r\n". Essa string é chamada V_S para a string enviada pelo servidor e V_C para a do cliente. A partir de então, todos os dados são transmitidos no formato do pacote citado no item anterior.
1- Negociação dos algoritmos usados: Ambos os lados enviam o pacote SSH_MSG_KEXINIT a seguir:

byte 	SSH_MSG_KEXINIT	
byte[16]	cookie (bytes aleatórios)	
string *	Algoritmos de troca de chaves	
string *	Algoritmos de chave pública	
string *	Algoritmos de encriptação cliente-servidor	
string *	Algoritmos de encriptação servidor-cliente	
string *	Algoritmos MAC cliente-servidor	
string *	Algoritmos MAC servidor-cliente	
string *	Algoritmos compressão cliente-servidor	
string *	Algoritmos compressão servidor-cliente	
string 	Linguagens cliente-servidor	
string 	Linguagens servidor-cliente	
boolean	first_kex_packet_follows	
uint32 	0 (reservado)	

Os campos em destaque (*) são as strings com os nomes dos algoritmos em ordem de preferência. Após os dois lados enviarem esse pacote, a camada de transporte decide qual o algoritmo que será usado no protocolo em cada um dos campos. O algoritmo usado é o primeiro que o cliente possuir que o servidor suporte.
2. Protocolo de troca de chaves. A saída dessa etapa é um segredo compartilhado K e o resultado H de um hash. Esse hash é usado como identificador de secao e como parte dos dados assinados pelo servidor para ele se autenticar perante o cliente.
O protocolo de troca de chaves padrão do SSH é o diffie-hellman-group1-sha1 explicado a seguir:
2.1 Cliente:
2.1.1 gera X randômico
2.1.2 envia
byte	SSH_MSG_KEXDH_INIT	
mpint	e = (g^x mod p)	
Onde g=2 e p o seguinte primo(120 bits):
FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1
29024E088A67CC74020BBEA63B139B22514A08798E3404DD
EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245
E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED
EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381
2.2. Servidor:
2.2.1 gera Y randômico
2.2.2 calcula:
· f = g y mod p
· K = e y mod p
· H = SHA-1(V_C || V_S || I_C || I_S || K_S || e || f || K)
Onde V_C, V_S são as strings de versão; I_C e I_S os conteúdos dos pacotes SSH_MSG_KEXINIT; e K_S a chave pública do servidor.
2.2.3 gera S = assinatura sobre H usando a chave privada
2.2.4 envia:
byte 	SSH_MSG_KEXDH_REPLY	
string 	K_S (chave publica)	
mpint 	f	
string 	S – Assinatura sobre H	

2.3 Cliente:
2.3.1 Verifica se K_S é realmente a chave pública do servidor, podendo ser feito uma busca em um histórico de conexões. Caso esse passo não seja executado corretamente, o protocolo está sujeito ao ataque man-in-the-middle.
2.3.2 Calcula:
· K = f k mod p
· H = SHA-1(V_C || V_S || I_C || I_S || K_S || e || f || K)
2.3.2 Verifica S com K_S
3. Efetivação do uso de novas chaves com os algoritmos negociados.
Cada lado da conexão envia a seguinte mensagem

byte 	SSH_MSG_NEWKEYS	

A partir de então, todos os pacotes enviados são encriptados de acordo com o algoritmo negociado.

Reexecução da Troca de Chaves

É recomendável que as chaves de sessão sejam trocadas a cada 1Gb de dados transmitidos ou de hora em hora. Para efetuar essa troca basta que um dos lados mande um pacote do tipo SSH_MSG_KEXINIT. Isso força a execução dos passos 1 ao 3 da troca de chaves. O Identificador da sessão é o “H” da primeira troca de chave, e ele mantêm o seu valor até o término da conexão.

Vetores de Inicialização e Chaves de Seção

Os vetores de inicializacao e chaves de sessao para os algoritmos de encriptação e MACs são criados da seguinte forma:

	cliente - servidor	servidor - cliente 	
VI	HASH(K || H || "A" || ID)	HASH(K || H || "B" || ID)	
Chave de Encriptação	HASH(K || H || "C" || ID)	HASH(K || H || "D" || ID)	
Chave do MAC	HASH(K || H || "E" || ID)	HASH(K || H || "F" || ID)	

“HASH” aqui é o algoritmo utilizado na troca de chaves negociada. No caso do diffie-hellman-group1-sha1 por exemplo, HASH é o SHA1.

Requisição de Serviços

Após o protocolo terminar a troca de chaves e receber o pacote SSH_MSG_NEWKEYS, o sistema pode tomar vários rumos, onde o caso mais comum é a autenticação do usuário. Para isso, deve-se requisitar um serviço através do seguinte pacote:

byte 	SSH_MSG_SERVICE_REQUEST	
string 	Nome do serviço	

Se o servidor reconhecer esse serviço, ele deve retornar o próximo pacote:

byte 	SSH_MSG_SERVICE_ACCEPT	
string 	Nome do serviço	

Se o servidor recusar o pedido, o cliente deve receber SSH_MSG_DISCONNECT e em seguida ser desconectado.
Obs.: Para o caso da autenticação, nome do serviço é “ssh-userauth”.

Algoritmos

A seguir temos a tabela com os algoritmos padronizados que foram definidos no protocolo de transporte do SSH. Como citado anteriormente, outros algoritmos podem ser acrescentados nessa lista. Basta utilizar nomes diferente dos citados a seguir, pois estes são reservados para o protocolo.

Compressão	none, zlib 	
Encriptação	3des-cbc,blowfish-cbc, twofish256-cbc,twofish-, twofish192-cbc, twofish128-cbc, aes256-cbc, aes192-cbc, aes128-cbc, serpent256-cbc, serpent192-cbc, serpent128-cbc, arcfour, idea-cbc, cast128-cbc, none	
MAC	hmac-sha1, hmac-sha1-96, hmac-md5, hmac-md5-96, none	
Troca de Chaves	diffie-hellman-group1-sha1	
Algoritmos de chave pública	ssh-dss, ssh-rsa, x509v3-sign-rsa, x509v3-sign-dss, spki-sign-rsa, spki-sign-dss, pgp-sign-rsa, pgp-sign-dss	

Protocolo de Autenticação

Aqui são executados os procedimentos relativos a autenticação do usuário. É assumido que a camada de transporte já está provendo integridade e sigilo na comunicação.
Para ocorrer a autenticação, o cliente deve enviar a seguinte mensagem:

byte 	SSH_MSG_USERAUTH_REQUEST	
string 	user name	
string 	Nome do serviço	
string 	Nome do método	
… extra …		

O nome do serviço especifica qual o serviço que será iniciado após a autenticaçao. Se o serviço não estiver disponível, o servidor irá desconectar o cliente.
O método é o nome do procedimento usado para a autenticação.
O servidor pode responder de duas formas:

Autenticação confirmada:
byte 	SSH_MSG_USERAUTH_SUCCESS	
Autenticação falhou:
byte 	SSH_MSG_USERAUTH_FAILURE	
string 	Métodos disponíveis	
boolean 	Sucesso parcial	

Onde sucesso parcial indica que o método de autenticação aceitou o usuário, mas o servidor não aceitou essa autenticação.
Um exemplo de método de autenticação é o que utiliza senha. O pacote SSH_MSG_USERAUTH_REQUEST relative a ele é o seguinte:

byte 	SSH_MSG_USERAUTH_REQUEST	
string 	user name	
string 	Nome do serviço	
string 	“password”	
boolean	FALSE	
string	senha	

Embora a senha é informada “às claras”, o pacote todo é criptografado (ao contrário do telnet, por exemplo), impedindo assim o vazamento da senha se alguém estiver ouvindo o tráfego.
O servidor também pode responder com SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, informando que a senha do usuário expirou e que ela deve ser trocada. Para isso, o cliente deve enviadar o seguinte pacote:

byte 	SSH_MSG_USERAUTH_REQUEST	
string 	user name	
string 	Nome do serviço	
string 	“password”	
boolean	TRUE	
string	Senha antiga	
string	Senha nova	

Protocolo de Comunicação

Esta é aparte que provê execução de commandos remotos, abertura de shells, tunelamento de conexões TCP/IP e de conexões X11. Todos esses canais são multiplexados em um único tunel encriptado.
O protocolo de comunicação tem o seu funcionamento baseado em canais. Cada canal é identificado por um número em cada uma das pontas. Esse número pode ser diferente em cada um dos lados.
Canais possuem fluxo controlado. Os dados são transmitidos através deles até quando o espaço disponível em suas janelas se esgotar. Quando isso ocorrer, o tamanho das janelas deve ser incrementado com o envio de uma mensagem adequada.
Para abrir um canal na conexão, a próxima mensagem deve ser transmitida por um dos lados.

byte 	SSH_MSG_CHANNEL_OPEN	
string 	Tipo do canal	
uint32 	no do canal remetente	
uint32 	Tamanho inicial da janela	
uint32	Tamanho máximo dos pacotes	
… extra …		

O outro lado deve responder o pedido com um dos dois pacotes a seguir:

byte 	SSH_MSG_CHANNEL_OPEN_CONFIRMATION	
uint32 	no do canal destinatário	
uint32 	no do canal remetente	
uint32 	Tamanho inicial da janela	
uint32	Tamanho máximo dos pacotes	
… extra …		

byte 	SSH_MSG_CHANNEL_OPEN_FAILURE	
uint32 	no do canal destinatário	
uint32 	código do motivo	
string 	Informaçao adicional	
string	Tag de lingugagem	

Observe que o no do canal destinatário dessas duas ultimas mensagens é o número do canal remetente de quem requisitou a abertura do canal (SSH_MSG_CHANNEL_OPEN).
Para transferir dados pelo canal, utiliza-se a seguinte mensagem:

byte 	SSH_MSG_CHANNEL_DATA	
uint32 	no do canal destinatário	
string 	Dados	
ou
byte 	SSH_MSG_CHANNEL_EXTENDED_DATA	
uint32	no do canal destinatário	
uint32 	Tipo dos dados	
string 	Dados	

O tamanho disponível da janela de quem receber os dados deve ser decrementada pelo número de bytes do campo dados, e ao se esgotar a janela a mensagem a seguir deve ser enviada pelo destinatário:

byte 	SSH_MSG_CHANNEL_WINDOW_ADJUST	
uint32 	no do canal destinatário	
uint32 	no de bytes incremental	

Com isso a janela disponibiliza o número de bytes solicitado.

Implementação do Cliente

A seguir, foi implementado um protótipo de um cliente que se comunica com um servidor SSH. Este cliente possui os seguintes recursos:
· Algoritmo de encriptação: 3des-cbc, none
· Algoritmos MAC: hmac-md5, hmac-sha1
· Algoritmo de troca de chaves: diffie-hellman-group1-sha1
· Algoritmo de chave pública: ssh-dss
· Protocolo de autenticação: password
· Tipo de serviço suportado: shell remoto
· Visualização de pacotes
· Botão de reexecutar troca de chaves

Interface Principal
O 1º botão conecta ou disconecta em um servidor.
O 2º botão (reexecutar troca de chaves) funciona da seguinte forma: Ao clicá-lo, novas chaves são estabelecidas. Como uma funcionalidade didática, os algoritmos de encriptação (3des-cbc e none) são alternados em cada nova troca, assim como os algoritmos de MAC (hmac-md5, hmac-sha1). Se o servidor não suportar o hmac-md5 ou o none, o cliente não funcionará. Logo, não use o botão de reexecutar troca de chaves se nao se conhecer os algoritmos suportados pelo servidor.
A listagem que aparece no lado direito são os pacotes que entram e saem do aplicativo. Ao dar um duplo clique é possível visualizar o conteúdo de cada pacote.
Alguns exemplos de pacotes (decriptados):

pacote SSH_MSG_USERAUTH_REQUEST para autenticação

pacote SSH_MSG_CHANNEL_DATA enviando o commando “date” para o shell

resultado de “date” enviado para o shell:”Tue Dec 16 23:52:26 BRST 2003”

Na barra de status são mostrados os algoritmos utilizados para encriptar e para gerar os MAC’s. Nessa barra existe um botão (“KEX Status”) que mostra um janela com os dados da sessão (H, K, Pub.Key do Server). O MD5 fingerprint da chave pública é mostrada diretamente na barra de status.

barra de status com os dados da conexão

janela informando K, H e a Chave Pública do servidor

Recursos

O SSH necessita 6 MB de RAM mais o kernel do linux. Este limite deve ser redimensionado para servidores de acesso dedicao, 64MB de RAM deve ser suficiente para algumas centenas de conexões simultâneas.
O protocolo é aberto, o que dá a liberdade de implementações específicas dele de proverem novos recursos, através da utilização de outros protocolos paralelamente. 

Prós e Contras

Prós	Contras	
Protocolo aberto	Não recomendao para PCs lentos	
Excelente velocidade do console	Necessidade de se digitar a senha toda vez que uma conexão com um servidor remoto for solicitada	
Multi-Plataforma		
Conexão de dados criptografada entre cliente/servidor		
Cópia de arquivos usando conexão criptografada		
Suporte FTP criptografado.		
Suporte a compactação de dados entre cliente/servidor		
Controle de acesso das interfaces servidas pelo servidor SSH		
Suporte a controle de acesso TCP wrappers 		
Autenticação usando um par de chaves pública/privada RSA ou DSA		
Algoritmo de criptografia livre de patentes		
Suporte a PAM		
Suporte as caracteres ANSI		

Referências Bibliográficas

SSH Home Page. Disponível em: http://www.ssh.fi/. Acessado em: 10 out. 2006.

Criando tuneis criptografados com SSH. Disponível em: http://www.dicas-l.com.br/dicas-l/20061017.php. Acessado em: 10 out. 2006.

Getting started with SSH. Disponível em: http://kimmo.suominen.com/docs/ssh/. Acessado em: 15 out. 2006.

Wikipédia. Disponível em: http://pt.wikipedia.org/wiki/SSH. Acessado em: 15 out. 2006.

O que é SSH. Disponível em: http://www.rnp.br/newsgen/9708/n3-3.html. Acessado em: 22 out. 2006.

Ylonen, T., "SSH Protocol Architecture", Disponível em: http://draft-ietf-architecture-15.txt, Acessado em: 30 out. 2006.

Ylonen, T., "SSH Connection Protocol", Disponível em: http://draft-ietf-connect-18.txt, Acessado em: 30 out. 2006.

Ylonen, T., "SSH Transport Layer Protocol", Disponível em: http://draft-ietf-transport-17.txt, Acessado em: 30 out. 2006.