Instituto Superior Técnico, Universidade de Lisboa
Segurança Informática em Redes e Sistemas
O objetivo deste laboratório é configurar um servidor web, usando Apache, e uma firewall simples, usando iptables. A topologia da rede encontra-se abaixo.
Este guião está estruturado em três partes. Em primeiro lugar, vamos configurar um servidor web Apache com o objetivo de servir uma página web simples. Em segundo lugar, vamos adicionar um servidor de base de dados SQL, que será usado pelo servidor web. Por fim, vamos configurar uma firewall para controlar o acesso à página web.
Sugestão: os comandos que fazem alterações e que queira tornar permanentes podem ser colocados no fim dos ficheiros de arranque (startup).
Isto permite reproduzir rapidamente o trabalho efetuado.
Para testar alterações, pode criar pequenos scripts de Python/Bash, colocá-los na pasta /shared e chamá-los a partir dos ficheiros de startup.
O servidor Apache serve documentos, por exemplo, páginas HTML, para a world wide web. Este servidor foi desenvolvido como um projeto de código aberto e é, desde 1996, o mais usado a nível mundial.
O exercício consiste em lançar o servidor Apache e configurá-lo, de modo a que, ao nível da aplicação, sejam colocadas algumas restrições sobre os documentos que estão acessíveis.
Vamos agora executar alguns passos para configurar o Apache.
- Inicie o laboratório:
kathara lstart- Verifique que no
webservero serviçoapache2está a correr.
/etc/init.d/apache2 statusA pasta /etc/init.d contém os serviços duma máquina Linux no modo SysVInit.
Atualmente será mais comum encontrar o comando systemctl do modo systemd em vez do SysVInit.
Ambos são alternativas para gerir a inicialização do sistema operativo e respetivos serviços.
- No debian10, os URLs disponibilizados pelo Apache, mapeiam para ficheiros dentro da pasta
/var/www/htmlpor omissão. Dentro dowebserverexecute o comandocurlpara tentar pedir o ficheiropublic/index.html.
curl -v 'http://127.0.0.1/public/index.html'
curl -v 'http://127.0.0.1/notpublic/onlymine.jpg'- Após fazer este pedido, observe como o Apache guarda no ficheiro
/var/log/apache2/access.loginformação relativa ao pedido que foi feito.
tail -n 10 /var/log/apache2/access.log - O Apache contém diferentes módulos que podem ser opcionalmente ativados para implementar funcionalidades.
Um desses módulos é
cgi(common gateway interface), que permite executar scripts quando um determinado documento é pedido.
Para ativar o módulo:
a2enmod cgi
/etc/init.d/apache2 restartPodemos verificar que o módulo foi ativado verificando que na pasta /etc/apache2/mods-enabled se encontra um ficheiro com o nome do módulo (no caso, cgi).
- É possível executar scripts dentro da pasta
/usr/lib/cgi-bin/como resposta a pedidos HTTP, por exemplopublic/past_exam_answers.py:
curl -v 'http://127.1.2.3/cgi-bin/public/past_exam_answers.py'- Usando o
curl, observe como, a partir dopc1, consegue obter as página webhttp://<ip do webserver>/public/index.htmlecgi-bin/public/past_exam_answers.pycomo esperado. Observar também que no ficheiroaccess.logfoi registado o acesso pelo IP dopc1.
Nota: ao tentar aceder a past_exam_answers.py, obterá um erro por não estar ligado ao serviço da base de dados.
Este erro será corrigido no exercício 2.
-
Observe como, a partir do
pc1, consegue obterhttp://<ip do webserver>/notpublic/onlymine.jpgecgi-bin/notpublic/future_exam_answers.py, o que não deveria acontecer. Pelo menos conseguimos verificar que estes documentos foram acedidos indevidamente noaccess.log. É necessário corrigir a configuração de modo a que os documentos não estejam acessíveis. -
Vamos então desativar o acesso a esses documentos. Para o fazer, o Apache permite definir permissões por pasta, criando um ficheiro
.htaccessna raiz da pasta na qual queremos definir permissões. Coloque um ficheiro.htaccesscom este conteúdo na pastanotpublicna directoria do laboratório e reinicie o laboratório:
deny from all- Para os ficheiros na pasta
/var/lib/cgi-bin, o apache por definição não executa os ficheiros.htaccess. Para corrigir isso, podemos pôr no ficheiro/etc/apache2/apache2.confuma regra equivalente a um ficheiro.htaccess. Podemos observar no ficheiro/etc/apache2/apache2.confregras equivalentes e adicionar esta nova regra:
<Directory /usr/lib/cgi-bin/notpublic/>
deny from all
</Directory>
Alternativamente, podemos apenas ativar ficheiros .htaccess para o diretório em questão:
<Directory /usr/lib/cgi-bin/notpublic/>
AllowOverride All
</Directory>
-
Reinicie o apache2 e volte a executar os pedidos com o
curle confirme que a resposta do servidor é403 Forbidden. -
Como estamos a usar uma simulação, quando o laboratório é reiniciado o ficheiro
/etc/apache2/apache2.confé limpo. De forma a persistir esta alteração é possivel adicionar as seguintes linhas no ficheirowebserver.startup(antes de iniciar o apache):
# Add these 3 lines
echo '<Directory /usr/lib/cgi-bin/notpublic/>' >> /etc/apache2/apache2.conf
echo ' deny from all' >> /etc/apache2/apache2.conf
echo '</Directory>' >> /etc/apache2/apache2.conf
Se escolheu usar AllowOverride All mude de acordo.
Agora que temos o servidor Apache configurado, vamos adicionar um novo servidor à nossa rede que terá um serviço SQL (MariaDB), à escuta de pedidos na porta 3306.
Este serviço será usado pelo webserver na página http://<ip do webserver>/cgi-bin/public/past_exam_answers.py.
A máquina sqlserver já está pré-configurada com um servidor de SQL.
Agora é necessário ligá-la à rede de modo a que esteja acessível pelo servidor.
Depois, é preciso modificar a segunda linha nos ficheiros past_exam_answers.py e future_exam_answers.py para ter o IP e porta de acesso ao sqlserver.
Siga os seguintes passos:
-
Observe a topologia de rede da figura, vamos modificá-la de modo a que o servidor SQL fique ligado também à firewall.
-
Modifique o ficheiro
lab.confde modo a ligar a máquinasqlservera um novo collision domain ligado à firewall. -
Configure o ficheiro
firewall.startuppara configurar a ligação à nova interface criada. Poderá ser necessário mudar a subrede configurada para a interface ligada ao webserver. -
Confirme que o seguinte comando mostra resultados:
curl 'http://<ip do webserver>/cgi-bin/public/past_exam_answers.py'- Confirme que o seguinte comando não mostra resultados:
curl 'http://<ip do webserver>/cgi-bin/notpublic/future_exam_answers.py'Mas, se for executado localmente no webserver, já deve funcionar:
python /usr/lib/cgi-bin/notpublic/future_exam_answers.pyAgora que temos a nossa aplicação web de perguntas de exames a correr no servidor, de forma correta, vamos observar o comportamento do ponto de vista de um utilizador.
Recorde a topologia de rede que utilizou no exercício 2 e vamos observar o comportamento a partir do pc1.
- No
pc1, verifique que consegue aceder aos exames passados e não aos futuros, tal como se podia observar no servidor:
curl 'http://<ip do webserver>/cgi-bin/public/past_exam_answers.py'
curl 'http://<ip do webserver>/cgi-bin/notpublic/future_exam_answers.py'- Infelizmente, ainda temos problemas na nossa configuração de rede. Observe o que acontece se executar o seguinte comando no cliente:
nmap <ip do sqlserver>- A porta do MariaDB (
3306) está acessível ao mundo exterior. Isto tem dois problemas. Em primeiro lugar é possível a um atacante tentar descobrir a nossa senha (especialmente dado que a senha épassword, substitua o IP 5.5.5.3 pelo correspondente do sqlserver):
# a partir do pc1:
mysql -u root -D sirs -e "SELECT * from exams;" -h 5.5.5.3 -ppasswordEm segundo lugar, mesmo sem saber a senha, é possível que o atacante "bombardeie" a porta com pedidos de tentativas de estabelecimento de ligação que consumam recursos no servidor e impeçam ligações legítimas de serem estabelecidas.
-
Vamos utilizar a firewall para criar regras que forcem a só expormos os serviços da rede
5.5.5.0/24que queremos explicitamente expor para o mundo exterior. Para isso vamos utilizar o comandoiptables(no debian10 temos de usar o comandoiptables-legacy, porque atualmente o comandoiptablesnão funciona corretamente). -
Na máquina
firewall, execute seguinte comando para listar as regras atuais da firewall:
iptables -L
Verá que existem 3 tipos de regras (INPUT, FORWARD, OUTPUT), denominadas chains, e que não existem regras configuradas na firewall atualmente.
- Caso queira apagar a firewall, pode apagar todas as regras existentes executando:
iptables -F
- Vamos começar por adicionar uma regra simples que bloqueia todos os pacotes ICMP (pings) que tenham como destino a firewall:
iptables –A INPUT –p icmp –j DROP
Se o comando falhar, relembra-se que deve usar o comando iptables-legacy em vez de iptables.
- Observe o resultado na
firewall(iptables -L) e verifique o resultado de tentar "pingar" afirewalle owebservera partir dopc1e de estabelecer uma ligação TCP (obter uma página alojada nowebserver).
ping 5.5.5.1
ping 5.5.5.2
curl 'http://5.5.5.2/public/index.html'- Apague a regra de input que adicionou:
iptables –D INPUT –p icmp –j DROP-
Repita os passos 7 a 9, trocando
INPUTcomFORWARDeOUTPUT, de modo a observar o que acontece em cada caso. Certifique-se que entende o que faz cada regra. Porque é que numa firewall se usa sobretudo a chainFORWARD? -
Se quisermos, também podemos criar regras mais específicas, por exemplo, a seguinte regra bloqueia ligações TCP com destino à porta 23 de qualquer endereço na rede
42.42.0.0/16provenientes da rede192.168.2.0/24(ou aceitaria ligações com essas características se trocássemos DROP por ACCEPT).
iptables –A INPUT –p tcp –s 192.168.2.0/24 -d 42.42.0.0/16 –-dport 23 –j DROP- Vamos agora proteger a rede. Comece por apagar todas as regras que criou na firewall:
iptables -F-
Crie uma ou mais regras para permitir que seja possível aceder ao servidor web, nomeadamente ao porto
80desse servidor usando o protocoloTCP, sobre o qual o protocoloHTTPé encapsulado. -
Crie uma ou mais regras para bloquear todo o restante tráfego que vem de fora da rede, ou seja, que passa pela firewall.
-
Teste que noutras portas não é possível criar ligações pondo um serviço à espera de ligações numa porta. Por exemplo, pode usar o comando
nc -l 1314para colocar um processo à espera de ligações na porta indicada como argumento. -
Teste que não é possível acesso de qualquer pacote do mundo exterior ao
sqlserver. -
Teste que não é possível enviar pacotes ICMP do
sqlserverpara o mundo exterior. -
Liste as regras da firewall.
-
Observe que continua a fazer conseguir pedidos HTTP do
pc1para owebserver, mas que não consegue ligar-se aosqlservera partir dopc1.
Os objetivos de isolamento na configuração de rede foram alcançados!
-
Oskar Andreasson, Iptables Tutorial, version 1.2.2, http://www.frozentux.net/iptables-tutorial/iptables-tutorial.html, 2006
