terça-feira, 18 de novembro de 2014

Configurando Shell In A Box no CentOS

Introdução


Shell In A Box (pronunciado shellinabox) é um emulador de terminal baseado na web criado por Markus Gutschke. Ele tem internamente um servidor web próprio que roda um cliente SSH baseado na web e em uma porta específica, disponibilizando para você um emulador de terminal para acessar e controlar remotamente seu servidor linux.

Shell In A Box utiliza somente AJAX/Javascript e CSS para funcionar, sem precisar instalar nenhum outro software adicional.

Nesse tutorial, iremos descrever como instalar o shellinabox para acessar remotamente o terminal SSH de um servidor linux usando apenas um browser moderno.

Clientes SSH baseado na web são bastante úteis quando você está protegido por um firewall/proxy e somente HTTP(s) podem passar por eles.

Instalando o Shellinabox no CentOS 6


Por padrão o shellinabox já vem incluído em várias distribuições através de seus repositórios padrões.

Mas no RHEL/CentOS você precisa primeiro instalar o repositório EPEL para conseguir instalá-lo via yum.
## RHEL/CentOS 6 64-Bit ##
sudo rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
Caso queira instalar o EPEL em outras versões do RHEL/CentOS pode consultar o artigo How to Enable EPEL Repository for RHEL/CentOS 7.x/6.x/5.x ou então ler um pouco mais em EPEL - FedoraProject.

Configurando o Shellinabox


Por padrão, shellinabox vem configurado para escutar na porta TCP/4200. Também, durante a instalação um novo certificado auto assinado é automaticamente criando dentro do diretório "/var/lib/shellinabox".

Para editar o arquivo de configuração:
sudo vi /etc/sysconfig/shellinaboxd
# Shell in a box daemon configuration
# For details see shellinaboxd man page

# Basic options
USER=shellinabox
GROUP=shellinabox
CERTDIR=/var/lib/shellinabox
PORT=4200
OPTS="--disable-ssl-menu -s /:LOGIN"


# Additional examples with custom options:

# Fancy configuration with right-click menu choice for black-on-white:
# OPTS="--user-css Normal:+black-on-white.css,Reverse:-white-on-black.css --disable-ssl-menu -s /:LOGIN"

# Simple configuration for running it as an SSH console with SSL disabled:
# OPTS="-t -s /:SSH:host.example.com"
Inicie o shellinabox:
service shellinaboxd start

ou

/etc/init.d/shellinaboxd start
Habilite o shellinabox para iniciar automaticamente toda vez o servidor linux for ligado:
chkconfig shellinaboxd on

Testando


Depois de tudo configurado é só testar, apontando seu navegador para http://server_ip_address:4200.

Aumentando a Segurança


Enquanto o shellinabox oferece uma grande conveniência para os administradores de sistema, ele pode oferecer um fácil ponto de entrada para hackers se não estiver apropriadamente seguro.

Li em alguns fóruns pessoas questionando e condenando a utilização do shellinabox. Mas, se você já tem liberado para a internet a porta SSH do seu servidor, de certa estamos apenas criando uma outra interface para acessar um serviço que já se encontra liberado.

Mas independentemente dessa discussão filosófica, vamos trazer um pouco mais de segurança para o nosso novo serviço.

1. Altere a porta padrão

Shellinabox por padrão vem configurado para escutar na porta 4200 e o problema é que hackers sabem dela. Entretanto, alterando a porta default para um outro número qualquer dificultará outras pessoas de encontrarem o serviço.
sudo vi /etc/sysconfig/shellinaboxd
# Altere a linha
PORT=5456
2. Ative SSL

Acessar o shellinabox sobre HTTP mandará todas as informações, inclusive usuário e senha, de forma não criptografada. Isto pode ser perigoso principalmente se você estiver acessando seu shellinabox remotamente na internet. A solução então é criptografar todos os dados durante a transferência, que dificultará a interceptação dos dados por pessoas maliciosas. Para ativar e forçar o acesso no linux via HTTPS, instale a seguinte lib:
sudo yum install openssl
Garanta que as opções '-t' ou '--disable-ssl' não esteja configurada no
OPTS="..."
Reinicie seu shellinabox. Ele agora deve estar acessível pelo endereço https://server_ip_address:5456

Note que você precisa ter um certificado SSL gerado. Como já dito, durante a instalação do shellinabox foi gerado um certificado auto assinado. Esse tipo de certificado fará com que o navegador abra uma janela de alerta quando tentar acessar o serviço.

3. Altere o SERVICE para SSH

Por padrão o shellinabox vem configurado para conectar ao sistema host através da chamada do /bin/login, pedindo o usuário e senha para então iniciar um login shell padrão.

Podemos alterar o SERVICE para SSH e dizer em qual servidor o shellinabox deverá conectar. Para isso edite o arquivo de configuração, localize a linha abaixo e faça a respectiva configuração:
sudo /etc/sysconfig/shellinaboxd
OPTS="--disable-ssl-menu -s /:SSH:127.0.0.1"
Caso quisesse que o shellinabox fizesse um SSH para um outro servidor que não fosse o mesmo onde o serviço está rodando, poderia alterar o endereço de localhost (127.0.0.1) para o endereço IP do outro servidor.
O serviço via SSH cria uma camada a mais de segurança entre o servidor shellinabox e o servidor ao qual está fazendo o acesso.

4. Restrinja o shellinabox apenas para localhost

Você pode restringir o acesso ao shellinabox apenas do localhost, ou seja, você terá acesso a ele somente do sistema onde o mesmo esta rodando.
sudo /etc/sysconfig/shellinaboxd
Encontre a linha abaixo e inclua a opção "--localhost-only"
OPTS="--localhost-only --disable-ssl-menu -s /:SSH:127.0.0.1"
Salve e reinicie o shellinabox. Enquanto essa configuração pode aumentar a segurança do serviço ela bloqueará o acesso de outros sistemas e acesso remoto pela internet, o que se torna um grande problema. Mas não se preocupe, essa configuração faz parte de um plano maior !!!

5.  Configure o acesso ao shellinabox via proxy reverso

Para adicionar uma camada de conveniência a segurança do shellinabox, vamos configurar o acesso via proxy reverso. Essa configuração pode ser feita via apache, mas nesse tutorial estaremos fazendo a configuração via nginx. Então vamos primeiramente instalar o nginx:
sudo yum install nginx
Particulamente, eu tive algumas dificuldades em utilizar o certificado digital auto assinado que foi gerado na instalação do shellinabox. Você pode inicialmente tentar utilizá-lo, mas caso tenha algum problema poderá gerar um outro com os seguintes comandos:
sudo mkdir /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/localhost.key -out /etc/nginx/ssl/localhost.crt
Por padrão o nginx já vem com algumas configurações do servidor WEB. Como minha instalação é exclusiva para acessar o shellinabox eu desativei essas configurações padrões.
sudo mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.orig
Agora vamos criar as configurações de acesso ao nosso shellinabox.
sudo vi /etc/nginx/conf.d/shellinabox-ssl.conf
E adicione ao arquivo a seguinte configuração abaixo.
server {

  listen 443 default_server;
  server_tokens off;
  ssl on;
  ssl_session_timeout 5m;
  ssl_certificate /etc/nginx/ssl/localhost.crt;
  ssl_certificate_key /etc/nginx/ssl/localhost.key;
  ssl_protocols SSLv3 TLSv1;
  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
  ssl_prefer_server_ciphers on;

  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  location ~* /shell/ {
    proxy_pass http://127.0.0.1:5456;                                           
    access_log /var/log/nginx/shellinabox.access.log;
    error_log /var/log/nginx/shellinabox.error.log;
  }

  location / {
    return 404;
  } 

  error_page 404 /404.html;
  location = /404.html {
    root /usr/share/nginx/html;
  } 

}
A configuração acima está basicamente dizendo:
  • Crie um novo servidor na porta 443 e habilite SSL;
  • Use o certificado que criamos um pouco mais acima;
  • Crie um 'location' chamado '/shell/' que fará um redirect para 'http://127.0.0.1:5456';
  • Se alguém tentar acessar a raiz do servidor web gere um ERROR 404;
  • ERROR 404 deverá exibir o arquivo 404.html.
Agora reinicie o nginx e o configure para subir sempre que reiniciar o servidor.
sudo /etc/init.d/nginx restart
sudo chkconfig nginx on 
Teste a nova configuração acessando:
https://IP_ADDRESS/shell/
Acessando o endereço acima, o nginx funcionará como uma ponte transparente entre o seu navegador e o shellinabox, o que aumenta a segurança do shellinabox não revelando a porta de acesso para o mundo externo.

6. Configure o firewall para bloquear a porta do shellinabox

Apesar de você ter o nginx como uma ponte entre o shellinabox e o seu navegado, alguém poderá rodar um 'port scanner' e ainda assim encontrar a porta aberta e tentar explorá-la.

Para evitar isso, basta configurar o iptables para bloquear qualquer tipo de acesso externo na porta  do shellinabox.

7. Ative a autenticação

Tanto no apache quanto no nginx você pode ativar uma tela de autenticação para acessar determinada URL. Então, cada vez que você acessar o shellinabox será solicitado a você um usuário e senha como mostrado na tela abaixo:



Para fazer isso, primeiro você precisa criar um arquivo .htpasswd. Você pode usar o programa htpasswd, que geralmente vem no pacote do apache ou então utilizar qualquer gerador online de htpasswd, como por exemplo o http://www.htpasswdgenerator.net/.

Salve o arquivo: "/etc/nginx/.htpasswd", e edite o arquivo de configuração do nginx.
sudo vi /etc/nginx/conf.d/shellinabox-ssl.conf
E insira as linhas abaixo em destaque no arquivo de configuração.
server {

  listen 443 default_server;
  server_tokens off;
  ssl on;
  ssl_session_timeout 5m;
  ssl_certificate /etc/nginx/ssl/localhost.crt;
  ssl_certificate_key /etc/nginx/ssl/localhost.key;
  ssl_protocols SSLv3 TLSv1;
  ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
  ssl_prefer_server_ciphers on;

  proxy_set_header Host $http_host;
  proxy_set_header X-Forwarded-Host $http_host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  location ~* /shell/ {
    proxy_pass http://127.0.0.1:5456; 
    auth_basic "Access Restricted";
    auth_basic_user_file "/etc/nginx/.htpasswd";                                          
    access_log /var/log/nginx/shellinabox.access.log;
    error_log /var/log/nginx/shellinabox.error.log;
  }

  location / {
    return 404;
  } 

  error_page 404 /404.html;
  location = /404.html {
    root /usr/share/nginx/html;
  } 

}
Pronto, agora é so reiniciar o nginx para ter uma tela de autenticação no acesso do shellinabox.

8. Configure autenticação em 2 passos no SSH

Quem não conhece autenticação em 2 passos ? Basicamente é aquele sistema onde além da sua senha você tem 'token' que gera um número aleatório a cada 30s, como utilizado para acesso aos bankline's da vida.

Para saber como habilitar autenticação em 2 passos no SSH leia o artigo Configurando Autenticação em 2 Passos no CentOS 6.

9. Notifique quando usuários logar via shellinabox

Apesar das várias camadas de segurança adicionadas, vamos ainda configurar um script que será executado toda vez que alguém logar via SSH no servidor através do shellinabox.

Nesse script você poderá enviar um email, mandar um SMS ou uma mensagem via WhatsApp para você alertando qua alguém logou no sistema e esse alguém não é você.

No nosso caso estamos utilizando os serviços prestados pela empresa Torpedo SMS Fácil que possui uma API de envio de SMS, para sempre que alguém logar no nosso sistema via shellinabox sejamos avisados ao mesmo tempo via SMS, permitindo tomar ação de forma rápida antes que algo mais crítico aconteça.

Para configurar a notificação crie o script a ser executado (como no exemplo abaixo).
sudo vi /etc/ssh/ssh_script.sh
#!/bin/bash
#Script file for ssh
#

# find IP address
ip=`echo $SSH_CONNECTION | cut -d " " -f 1`

#PUT YOUR COMMANDS HERE
echo "$USER just logged in from $ip" > /tmp/test.txt

#exit by calling a shell to open for the ssh session
/bin/bash 
Onde tem o comentário "#PUT YOUR COMMANDS HERE" é onde você deverá colocar o comando de enviar um SMS ou realizar alguma outra atividades. No exemplo acima, estamos simplesmente jogando as informações para dentro de um arquivo.

Vamos agora configurar o SSH para que execute o comando quando alguém fizer um logon.
sudo vi /etc/ssh/sshd_config
No final do arquivo inclua.
# Executar script quando a conexao for via shellinabox
Match Address 127.0.0.1
    ForceCommand /etc/ssh/ssh_script.sh 
Usamos o "Match Address" do SSH para dizer que o script deverá ser executando somente quando acontecer um logon que o IP de origem seja 127.0.0.1, pois quem está fazendo a conexão no SSH é o nginx que roda na mesma máquina.

Dessa forma conseguimos filtrar a execução do script apenas para logins via shellinabox.

Possíveis Erros


Caso esteja encontrando alguma dificuldade no funcionamento ou algum erro esteja sendo gerado nos logs do sistema, tente desativar o SELinux.

Eu tive algum problemas durante algumas configurações e só consegui resolver depois de ter desativado o SELinux do sistema.

Conclusão


Com todos esses passos conseguimos criar um cliente SSH web-based com a ajuda do Shell In A Box e do nginx, e ainda adicionar algumas camadas de segurança ao nosso serviço.

Referências


Sites que utilizei como referências para as respectivas configurações.

Shell in a Box - Remote to your Linux server via web browser
Shell In A Box – A Web-Based SSH Terminal to Access Remote Linux Servers
5 Easy steps to Increase Shellinabox Security
How to install Shell In a Box
Shellinabox With Apache Authentication Over HTTPS 443
How to get ssh access from almost anywhere in the world to your server with ssl encypted security!
How To Create a SSL Certificate on Apache for CentOS 6


Abraços.

Um comentário:

ddamaral disse...

Tutorial bem abrangente. Obrigado.