Como configurar um firewall com Iptables no Ubuntu 14.04
A criação de um bom firewall é um requisito de segurança essencial em qualquer sistema operacional. A maioria das distribuições Linux vem com algumas ferramentas de firewall diferentes que podemos usar para configurar nossos firewalls. Neste guia, vamos fazer a cobertura do firewall iptables.
Iptables é um firewall incluído na maioria das distribuições Linux por padrão (o novo firewall nftables está chegando com tudo e provavelmente começará a substituí-lo). Na verdade, o Iptables é um front-end para utilizar os recursos do netfilter que roda a nível do kernel e que podem manipular as pilhas de redes Linux. O Iptables é utilizado para controlar quais pacotes podem entrar ou sair pela rede interna ou externa, assim ele poderá bloquear o tráfego indesejado de pacotes.
Neste guia, vamos passar para um exemplo prático para demonstrar como criar uma regra básica definida para um servidor Ubuntu 14.04.
Nota: Este tutorial aborda segurança IPv4. No Linux, segurança IPv6 é mantida separadamente das IPv4. Por exemplo, “Iptables” só mantém as regras de firewall para endereços IPv4, mas em contrapartida, para IPv6 temos o comando “ip6tables”, que pode ser usado para manter as regras de firewall para endereços de rede IPv6.
Iptables – Comandos Básicos
Agora que você já viu alguns conceitos sobre como o Iptables trabalha, vamos abordar comandos básicos que serão utilizados para formar conjuntos de regras complexas e para gerir a interface do Iptables em geral.
Primeiro, você deve estar ciente de que os comandos Iptables devem ser executados com privilégios de root. Isto significa que você precisa estar logado como root, use su
ou sudo -i
para acessar o shell como root, ou execute todos os comandos precedidos do comando sudo
. Vamos usar o sudo
neste guia uma vez que é o método preferido em um sistema Ubuntu.
Um bom ponto de partida é listar as regras atuais que estão configurados para iptables. Você pode fazer isso com o parâmetro -L
:
sudo iptables -L
Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Como você pode ver, temos três cadeias padrão (INPUT, OUTPUT, e FORWARD). Nós também podemos ver a política padrão de cada regra (cada uma dessas cadeias tem ACCEPT como política padrão), sendo assim, sua missão é bloquear todo tráfego indesejado. Vemos também alguns cabeçalhos de coluna, mas não vemos quaisquer regras aplicadas. Isto é porque o Ubuntu não vem com um conjunto de regras padrão, ou seja, está tudo liberado.
Podemos ver a saída abaixo de como seria os comandos para modificar as cadeias:
sudo iptables -S
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT
Se você já criou algumas regras em seu firewall e deseja desfazer-se delas e começar de novo, digite o comando:
sudo iptables -F
Cuidado: a política padrão é muito importante, o comando acima excluirá todas as regras do seu firewall, mas a politica padrão permanecerá, ou seja, se a política padrão estiver configurada para bloquear todas as entradas e você entrar com o comando acima estando conectado remotamente via SSH, certamente você perderá o acesso remoto ao servidor imediatamente.
Para evitar problemas, sempre que precisar limpar as regras do seu firewall com o Iptables, antes de qualquer coisa, altere a política padrão e em seguida você poderá limpar as regras já existentes, para isso, você poderá utilizar os seguintes comandos:
sudo iptables -P INPUT ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -F
Crie sua primeira regra
Nós vamos começar a construir as nossas políticas de firewall. Vamos começar trabalhando com a cadeia INPUT, responsável por todo tráfego de entrada no servidor. Vamos começar com uma regra que permite sua conexão SSH.
A regra completa que precisamos é a seguinte:
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Isto pode parecer incrivelmente complicado, mas a maior parte dele vai fazer sentido quando vamos ao longo dos componentes:
- -A INPUT: O parâmetro
-A
acrescenta uma regra para a extremidade de uma cadeia. Este é o parâmetro do comando que diz ao Iptables para adicionar uma nova regra, e que queremos que regra adicionada fique no final da cadeia, e queremos operar na cadeia INPUT. - -m conntrack: o Iptables tem um conjunto de funcionalidades básicas, mas também tem um conjunto de extensões ou módulos que oferecem recursos extras.
Nesta parte do comando, nós estamos dizendo que queremos ter acesso à funcionalidade fornecida pelo módulo conntrack
. Este módulo dá acesso a comandos que podem ser usados para tomar decisões com base na relação dos pacotes para ligações anteriores.
* –ctstate: Este é um dos comandos disponibilizados chamando o módulo conntrack
. Este comando permite-nos corresponder pacotes com base em como eles estão relacionados com os pacotes que já vimos antes.
Passamos o valor ESTABLISHED
para permitir que os pacotes que fazem parte de uma conexão existente. Passamos o valor RELATED
para permitir pacotes que estão associados com uma conexão estabelecida. Esta é a parte da regra que corresponde a nossa sessão SSH atual.
* -j ACCEPT: Isso especifica o alvo de pacotes que combinem. Aqui, nós dizemos iptables que os pacotes que correspondem aos critérios anteriores devem ser aceites e permitido passar.
Colocamos essa regra no início, porque queremos garantir que as conexões que já estão em uso são correspondidas, aceitas, e tiradas da cadeia antes de chegar a qualquer regra de bloqueio (DROP).
Podemos ver as mudanças no Iptables utilizando o comando para listar regras:
sudo iptables -L
Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
Agora que você sabe a sintaxe geral de Iptables, vamos continuar adicionando mais algumas regras para aceitar outros tipos de conexão.
Aceitar outras conexões necessárias
Temos dito ao Iptables para manter aberto quaisquer conexões que já estão abertas e permitir novas conexões relacionadas a essas conexões. No entanto, precisamos criar algumas regras para estabelecer quando queremos aceitar novas conexões que não atendam a esses critérios.
Vamos adicionar algumas regras para permitir conexões em duas portas especificamente. Nós queremos manter a nossa porta SSH aberta (neste guia estamos trabalhando com a porta 22). Se você mudou isso em sua configuração SSH, modifique este valor aqui). Também vamos supor que este computador está executando um servidor web na porta padrão 80. Se este não é o seu caso, você não precisa adicionar essa regra.
As duas linhas que vamos usar para adicionar essas regras são:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Como você pode ver, esses comandos são muito semelhantes à nossa primeira regra, porém um pouco mais simples. As novas opções são:
- -p tcp: Esta opção corresponde pacotes se o protocolo a ser utilizado é TCP. Este é um protocolo com base na ligação que irá ser utilizada por maior parte das aplicações, pois permite uma comunicação confiável.
- –dport: Esta opção está disponível se o parâmetro
-p tcp
estiver presente. Este requisito corresponde a porta de destino para o pacote correspondente. A primeira regra corresponde aos pacotes TCP com destino a porta 22, enquanto que a segunda regra corresponde ao tráfego TCP apontado para a porta 80.
Existe mais uma regra que precisamos adicionar para garantir que o nosso servidor funcione corretamente. Muitas vezes, temos alguns serviços instalados em nosso computador que precisam se comunicar com outros serviços dentro da rede, e eles fazem isso através da utilização de uma interface de rede chamada loopback device
, que direciona o tráfego de volta para si mesmo e não para outros computadores.
Portanto, se um serviço quer comunicar com outro serviço que está atendendo as conexões através da porta 4555, ele poderá enviar um pacote para a porta 4555 do dispositivo de auto-retorno. Queremos que este tipo de comportamento seja permitido, porque é essencial para o bom funcionamento de muitos programas.
A regra que você precisa adicionar é esta:
sudo iptables -I INPUT 1 -i lo -j ACCEPT
Isso parece um pouco diferente do que os nossos outros comandos. Vamos ver o que ele está fazendo:
- -I INPUT 1: A parâmetro
-I
diz para o Iptables inserir uma regra. Mas, é diferente do parâmetro-A
, que acrescenta uma regra no final. O parâmetro-I
insere uma nova regra na posição que você quer dentro da cadeia de regras. - * -i Lo: A interface “lo” é outro nome para o dispositivo de auto-retorno. Isto significa que qualquer pacote que esteja usando essa interface para se comunicar (pacotes gerados do nosso servidor, para o nosso servidor) deve ser aceito.
Para ver nossas regras atuais, devemos usar o parâmetro -S
. Isso ocorre porque o parâmetro -L
não inclui algumas informações, como a interface que a regra está vinculada, e isso é uma parte importante que precisamos ver, para isso use o comando:
sudo iptables -S
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
A implementação da regra DROP
Agora temos quatro regras distintas que aceitam explicitamente pacotes com base em determinados critérios. No entanto, o nosso firewall atualmente não está bloqueando nada.
Conforme vimos anteriormente, o objetivo do Iptables é configurar um firewall que permita somente o tráfego de pacotes confiáveis e em portas que estão sendo utilizadas por serviços que precisamos, por exemplo, se você quer rodar servidor web, como Apache ou Nginx, provavelmente você precisará da porta 80, então você precisará adicionar ao seu firewall uma regra que permita isso. Até o momento, a política padrão de nosso firewall é aceitar tudo, e isso não é legal, temos que mudar isso.
Há duas maneiras diferentes que podemos fazer isso, com algumas diferenças muito importantes.
A primeira maneira que nós poderíamos fazer isso é modificar a política padrão da nossa cadeia INPUT. Nós podemos fazer isso digitando:
sudo iptables -P INPUT DROP
Pronto, agora nós estamos bloqueando todos os pacotes de entrada, exceto aqueles que permitimos nas regras que adicionamos no tópico anterior.
Cuidado: Esse método pode ser o mais seguro, mas também pode ter consequências graves, se você estiver conectado via SSH através da porta 22 e aplicar esta regra sem antes ter adicionado as regras que liberam o serviço de acesso remoto, você perderá o acesso remoto imediatamente e não conseguirá mais acessar o servidor remotamente.
Utilizando atribuir o DROP como política padrão, você precisará adicionar regras que liberem as portas que você precisá utilizar. Se não fizer isso, o serviço não poderá ser acessado externamente, por exemplo, se você tem o Apache rodando na porta 80 e não adicionou as regras para liberá-la, quando você tentar acessar o seu site, o navegador não conseguirá acessá-lo.
Modelo de firewall com Iptables
Para auxiliá-lo na configuração do seu firewall, quero deixar um modelo básico, porém eficiente para você seguir, só não esqueça de remover as regras dos serviços que não estão rodando no seu servidor.
### Exclui todas as regras ### iptables -t nat -F iptables -t mangle -F iptables -t filter -F ### Exclui cadeias customizadas ### iptables -X ### Zera os contadores das cadeias ### iptables -t nat -Z iptables -t mangle -Z iptables -t filter -Z ### Define a política padrão do firewall ### iptables -P INPUT DROP iptables -P OUTPUT DROP iptables -P FORWARD DROP ### Regras INPUT ### ### informa os estados que devem ser checados (Conexão estabelecida # ou Relacionada). Caso o estado da conexão seja uma dessas 2, então # ele vai aceitar. iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Libera o INPUT para a interface loopback, ou seja, a própria máquina iptables -A INPUT -i lo -j ACCEPT # Permite icmp 0 (resposta de Echo) iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT # Permite icmp 8 (Pedido de Echo) iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT # Permite o acesso ao servidor usando SSH iptables -A INPUT -p tcp --dport 22 -j ACCEPT # Permite acesso do Apache na porta 80 iptables -A INPUT -p tcp --dport 80 -j ACCEPT # Permite acesso do Apache na porta 443 (https) iptables -A INPUT -p tcp --dport 443 -j ACCEPT # Permite o acesso ao servidor usando FTP iptables -A INPUT -p tcp --dport 21 -j ACCEPT # Permitir acesso externo ao MySQL Server iptables -A INPUT -p tcp --dport 3306 -j ACCEPT # PassivePorts Proftpd iptables -A INPUT -p tcp --dport 49152:65534 -j ACCEPT # Permitir listagem de diretorios FTP com Proftpd /sbin/modprobe ip_nat_ftp # Permitir acesso ao servidor de envio de email iptables -A INPUT -p tcp --dport 110 -j ACCEPT ### Regras OUTPUT ### iptables -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
Se você chegou a este tópico do tutorial sem lê-lo inteiro, somente para copiar este modelo e você não sabe nada sobre firewall, cuidado, “esse modelo não vai blindar o seu servidor”, você precisa adaptá-lo a sua necessidade, recomendo ler este tutorial inteiro.
Salvando sua configuração iptables
Por padrão, as regras que você adicionar ao Iptables são efêmeros. Isto significa que quando você reiniciar o servidor, suas regras de Iptables serão perdidas.
Isso é bom, porque quando estiver criando seu firewall e, acidentalmente aplicar alguma regra que bloqueie seu acesso, você poderá reiniciar seu servidor e tudo voltará ao normal. Mas assim que você terminar suas configurações, com certeza desejará que suas configurações de firewall inicie no start do servidor.
Para isso, existem algumas maneiras de fazer isso, mas a maneira mais fácil é com o pacote iptables-persistent
. Você pode baixá-lo nos repositórios padrão do Ubuntu:
sudo apt-get update sudo apt-get install iptables-persistent
Durante a instalação, você deverá informar se gostaria de salvar as regras atuais para que sejam carregadas automaticamente. Ele também irá perguntar se você deseja salvar as regras IPv6 que você configurou. Essas regras são configuradas através de um utilitário chamado ip6tables de forma separadas para controlar o fluxo de pacotes IPv6.
Quando a instalação estiver concluída, você terá um novo serviço chamado iptables-persistent
que está configurado para executar na inicialização. Este serviço irá carregar suas regras e aplicá-las quando o servidor é iniciado.
Conclusão
Agora você deve ter um bom ponto de partida para o desenvolvimento de um firewall que atenda às suas necessidades. Há muitos outros utilitários de firewall e alguns que podem ser mais fácil, mas o Iptables é uma boa ferramenta de aprendizagem, mesmo porque ele expõe parte da estrutura Netfilter e porque ele está presente em muitos outros sistemas.
Digital Ocean – Servidores / VPS a partir de 5$
Para você que pretende ter um servidor estável e com baixo custo, recomendamos você utilizar os serviços da Digital Ocean, eles oferecem VPS a partir de 5$, no Brasil não tem nada perto desse valor, muito bom, vale a pena testar, e o atendimento do suporte técnico é incrível. No primeiro mês você ganha 10$ para testar.