Vários serviços no mesmo porto com o SSLH

sslh2

Existem vezes em que precisamos executar determinados serviços que estão bloqueados pela firewall da empresa ou entidade. Quase todas as empresas e entidades bloqueiam tráfego desnecessário para as tarefas laborais. Isto acontece por várias razões. Quer sejam elas financeiras para controlar melhor os custos das comunicações, quer seja por razões de segurança ou ambas. A realidade é que bloqueiam determinados portos, deixando normalmente abertos portos HTTPS/HTTP. Numa situação destas como é que acedo ao SSH que se encontra em minha casa?

Por outro lado, temos um servidor que disponibiliza conteúdo HTTPS/HTTP, mas precisamos acede-lo para configura-lo, actualiza-lo entre outras tarefas que são normais na administração de um sistema. Mas não queremos mostrar directamente ao mundo que temos o SSH a correr. Visto que este protocolo é alvo de ataques a toda a hora. Como posso disponibilizar o SSH de forma mais discreta?

Neste artigo vou mostrar como configurar o SSLH no Ubuntu 14.04.1, de forma a resolver estes dois problemas de uma só vez.

O SSLH actua como um serviço que corre num determinado porto, normalmente no porto 443. Ele fica a escutar os pacotes que chegam nesse porto e analisando o seu conteúdo a fim de perceber a que tipo de protocolo pertence. O SSLH pode passar esses pacotes para determinados serviços como o ssh, openvpn, https. Desta forma é possível apenas com um porto servir vários serviços.

É interessante que se fizermos uma busca por portos num determinado servidor que use esta técnica vamos ver apenas o porto 443/https aberto, o que nos leva a pensar que aquele determinado servidor apenas serve conteúdo web. A verdade é que o mesmo porto pode servir vários serviços.

Normalmente esta técnica é usada para esconder serviços sensíveis como o ssh e o openvpn.

Neste artigo vou mostrar como compilar este software, visto que o pacote que está nos repositórios do Ubuntu está a dar problemas. Mas vamos instalar o pacote na mesma para aproveitar os ficheiros de configuração. Vou configurar para que disponibilize o serviço ssh no mesmo porto que o https.

Para começar temos que ter uma máquina com Ubuntu 14.04 instalado. Vamos precisar do serviço http o apache como webserver e do serviço ssh o openssh.

Para já começamos por instalar o software que precisamos para compilar o sslh, bem como instalar os serviços que vão ser utilizados para configurar esta solução. Ora vamos lá instalar.

# apt-get install gcc libconfig-dev apache2 openssh-server sslh unzip

Agora que temos tudo o que precisamos instalado vamos lá configurar esta solução. Neste artigo vou utilizar o IP 192.168.1.60 para o servidor.

Configurar o Apache

Como o sslh irá escutar no porto 443, temos de configurar o apache para escutar no porto 4443. Mais tarde o sslh como veremos será configurado para passar os pacotes que são direccionados ao serviço https ao apache no porto 4443.

Temos de configurar dois ficheiros do apache para mudar os portos que ele escuta de 443 para 4443. O ficheiro ports.conf e o ficheiro default-ssl.conf

O ficheiro /etc/apache2/ports.conf como podemos ver abaixo foi configurado os portos das ligações SSL com 192.168.1.60:4443. É assim que precisa de ser configurado.

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80

<IfModule ssl_module>
Listen 192.168.1.60:4443
</IfModule>

<IfModule mod_gnutls.c>
Listen 192.168.1.60:4443
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

O ficheiro /etc/apache2/sites-available/default-ssl.conf como podemos ver abaixo foi subsistido o porto 443 por 4443.

<IfModule mod_ssl.c>
<VirtualHost _default_:4443>
ServerAdmin webmaster@localhost

DocumentRoot /var/www/html

Agora que já configuramos o necessário no apache temos de configurar o apache para usar SSL para isso lançamos a seguinte comando:

# a2enmod ssl

Agora que o apache está pronto a usar SSL, activamos o virtual host com o seguinte comando:

# a2ensite default-ssl

Agora recarregamos as configurações, executamos o seguinte comando:

# service apache2 reload

O apache está configurado para o mínimo necessário para que esta solução funcione.

Compilar o SSLH

Fiz alguns testes com sslh dos repositórios e reparei que se fize-se um scan por portos ele rebentava. Bastava executar o seguinte comando para ele rebentar.

# nmap -PN 192.168.1.60

Então decidi compilar o software e ver se o problema se mantinha. Felizmente esse problema desapareceu. Por essa razão vou compilar o sslh.

Para compilar o software temos de descarrega-lo do git-hub do projecto oficial. Para isso executamos o seguinte comando:

# wget https://github.com/yrutschle/sslh/archive/master.zip

Agora vamos ter de descomprimir o software, para isso executamos o seguinte comando:

# unzip master.zip

Agora entramos para dentro de directório do software  e compilamos o source o que é coisa simples, vejamos:

# cd sslh-master
# make

Não vamos instalar pois não queremos todo o software apenas o binário, os ficheiros de configuração vamos utilizar os do Ubuntu pois funcionam perfeitamente bem. Vamos copiar apenas o binário, para isso executamos o comando:

# cp sslh-select /usr/sbin

Neste momento já temos o software todo, podemos agora configurar o sslh.

Configurar o SSLH

Eu vou configurar para que ele trabalhe de forma transparente, pois desta forma os logos do apache terá o IP da máquina que fez o pedido. Bem como é possível utilizar por exemplo o fail2ban para bloquear o acesso ao SSH. Quando o sslh não funciona em modo transparente isto não é possível, pois o ssh e o apache recebem sempre o IP do servidor que neste caso é 192.168.1.60. Em modo transparente é um pouco mais complicado de configurar, pois necessita de algumas regras de firewall bem como rotas, mas a meu ver não faz sentido de outra forma pois perdíamos a informação de quem nos acede ou teríamos que arranjar outra forma de saber. Portanto será de todo a melhor solução.

Para configurarmos o sslh temos de configurar o ficheiro /etc/default/sslh desta forma.

# Default options for sslh initscript
# sourced by /etc/init.d/sslh

# Disabled by default, to force yourself
# to read the configuration:
# - /usr/share/doc/sslh/README.Debian (quick start)
# - /usr/share/doc/sslh/README, at "Configuration" section
# - sslh(8) via "man sslh" for more configuration details.
# Once configuration ready, you *must* set RUN to yes here
# and try to start sslh (standalone mode only)

RUN=yes

# binary to use: forked (sslh) or single-thread (sslh-select) version
DAEMON=/usr/sbin/sslh-select

DAEMON_OPTS="--transparent -p 192.168.1.60:443 --ssh 192.168.1.60:22 \
--ssl 192.168.1.60:4443 --pidfile /var/run/sslh/sslh.pid"

Agora já temos o SSLH configurado, falta-nos as regras de firewall e rota.

Configurar a firewall e Rotas

Todos os sistemas Linux já trazem a firewall integrada e o Ubuntu não foge à regra. A firewall iptables do Linux é super poderosa, mas precisa-se de muito estudo para podermos percebe-la razoavelmente. Neste caso vou utilizar algumas regras que já foram testadas para o SSLH trabalhar em modo transparente. Estas regras serão inseridas no ficheiro /etc/rc.local para que sejam lidas sempre que o servidor for iniciado.

O ficheiro /etc/rc.local tem o seguinte conteúdo:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Permite que um serviço corra com um utilizador sem privilégios de
# administrador na porta 443 ou qualquer uma
setcap cap_net_bind_service,cap_net_admin+pe /usr/sbin/sslh-select

# Regras de firewall que permite marcar os pacotes recebidos pelo sslh no porto 443
# aos serviços corretos HTTPS e SSH
iptables -t mangle -N SSLH
iptables -t mangle -A  OUTPUT --protocol tcp --out-interface eth0 --sport 22 --jump SSLH
iptables -t mangle -A OUTPUT --protocol tcp --out-interface eth0 --sport 4443 --jump SSLH
iptables -t mangle -A SSLH --jump MARK --set-mark 0x1
iptables -t mangle -A SSLH --jump ACCEPT

# Estas rotas também são necessárias
ip rule add fwmark 0x1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

exit 0

E já configuramos o necessário para a solução funcionar. Agora basta-nos testar a solução.

Podemos testar o serviço HTTPS a partir do FireFox ou qualquer outro browser. Bastando para isso inserirmos a URL https://192.168.1.60.

Para testarmos o SSH utilizamos um terminal e executamos o seguinte comando:

$ ssh -p 443 utilizador@192.168.1.69

Se tudo correu bem e eu não me esqueci de nada, esta solução deve funcionar muito bem.

Espero que este artigo seja útil para alguém, aconselho a lerem a manual se realmente tiverem interessados a utilizar este software, pois isto é só um exemplo. O software está preparado para outras situações.

Comentem, partilhem, experimentem!

Artigos Relacionados:

Deixe uma resposta