Pesquisa de site

Como configurar um firewall usando Iptables no Ubuntu 14.04


Introdução

Configurar um bom firewall é uma etapa essencial para proteger qualquer sistema operacional moderno. A maioria das distribuições do Linux vem com algumas ferramentas de firewall diferentes que podemos usar para configurar nossos firewalls. Neste guia, abordaremos o firewall iptables.

Iptables é um firewall padrão incluído na maioria das distribuições Linux por padrão (uma variante moderna chamada nftables começará a substituí-lo). Na verdade, é um front-end para os ganchos do netfilter no nível do kernel que podem manipular a pilha de rede do Linux. Ele funciona comparando cada pacote que cruza a interface de rede com um conjunto de regras para decidir o que fazer.

No guia anterior, aprendemos como as regras do iptables funcionam para bloquear o tráfego indesejado. Neste guia, passaremos a um exemplo prático para demonstrar como criar um conjunto de regras básicas para um servidor Ubuntu 14.04. O firewall resultante permitirá o tráfego SSH e HTTP.

Observação: este tutorial aborda a segurança do IPv4. No Linux, a segurança do IPv6 é mantida separadamente do IPv4. Por exemplo, \iptables só mantém regras de firewall para endereços IPv4, mas tem uma contraparte IPv6 chamada \ip6tables, que pode ser usada para manter regras de firewall para endereços de rede IPv6.

Se o seu VPS estiver configurado para IPv6, lembre-se de proteger as interfaces de rede IPv4 e IPv6 com as ferramentas apropriadas. Para obter mais informações sobre ferramentas IPv6, consulte este guia: Como configurar ferramentas para usar IPv6 em um Linux VPS

Pré-requisitos

Antes de começar a usar este tutorial, você deve ter uma conta de superusuário separada e não raiz - um usuário com privilégios sudo - configurada em seu servidor. Se você precisar configurar isso, siga este guia: Configuração inicial do servidor com Ubuntu 14.04.

Comandos básicos do iptables

Agora que você tem um bom entendimento dos conceitos do iptables, devemos abordar os comandos básicos que serão usados para formar conjuntos de regras complexos e para gerenciar a interface do iptables em geral.

Primeiro, você deve estar ciente de que os comandos iptables devem ser executados com privilégios de root. Isso significa que você precisa fazer login como root, usar su ou sudo -i para obter um shell root ou preceder todos os comandos com sudo. Vamos usar sudo neste guia, pois esse é o método preferido em um sistema Ubuntu.

Um bom ponto de partida é listar as regras atuais configuradas para o iptables. Você pode fazer isso com o sinalizador -L:

  1. sudo iptables -L
Output:
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 nossas três cadeias padrão (INPUT, OUTPUT e FORWARD). Também podemos ver a política padrão de cada cadeia (cada cadeia tem ACCEPT como política padrão). Também vemos alguns cabeçalhos de coluna, mas não vemos nenhuma regra real. Isso ocorre porque o Ubuntu não vem com um conjunto de regras padrão.

Podemos ver a saída em um formato que reflete os comandos necessários para habilitar cada regra e política usando o sinalizador -S:

  1. sudo iptables -S
Output:
-P INPUT ACCEPT -P FORWARD ACCEPT -P OUTPUT ACCEPT

Para replicar a configuração, basta digitar sudo iptables seguido de cada uma das linhas na saída. (Dependendo da configuração, pode ser um pouco mais complicado se estivermos conectados remotamente para não instituir uma política de queda padrão antes que as regras estejam em vigor para capturar e permitir nossa conexão atual.)

Se você tem regras em vigor e deseja descartá-las e começar de novo, você pode liberar as regras atuais digitando:

  1. sudo iptables -F

Mais uma vez, a política padrão é importante aqui, porque, embora todas as regras sejam excluídas de suas cadeias, a política padrão não mudará com este comando. Isso significa que, se você estiver conectado remotamente, deverá garantir que a política padrão em suas cadeias INPUT e OUTPUT esteja definida como ACCEPT antes de liberar suas regras. Você pode fazer isso digitando:

  1. sudo iptables -P INPUT ACCEPT
  2. sudo iptables -P OUTPUT ACCEPT
  3. sudo iptables -F

Você pode alterar a política de queda padrão de volta para DROP depois de estabelecer regras que permitem explicitamente sua conexão. Veremos como fazer isso em um momento.

Faça sua primeira regra

Vamos começar a construir nossas políticas de firewall. Como dissemos acima, vamos trabalhar com a cadeia INPUT, pois esse é o funil pelo qual o tráfego de entrada será enviado. Vamos começar com a regra da qual falamos um pouco acima: a regra que aceita explicitamente sua conexão SSH atual.

A regra completa de que precisamos é esta:

  1. sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Isso pode parecer incrivelmente complicado, mas a maior parte fará sentido quando analisarmos os componentes:

  • -A INPUT: O sinalizador -A anexa uma regra ao final de uma cadeia. Esta é a parte do comando que informa ao iptables que desejamos adicionar uma nova regra, que queremos essa regra adicionada ao final da cadeia e que a cadeia na qual queremos operar é a cadeia INPUT.
  • -m conntrack: o iptables possui um conjunto de funcionalidades principais, mas também possui um conjunto de extensões ou módulos que fornecem recursos extras. Nesta parte do comando, estamos declarando que desejamos 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 no relacionamento do pacote com conexões anteriores.
  • –ctstate: Este é um dos comandos disponibilizados chamando o módulo conntrack. Este comando nos permite combinar os pacotes com base em como eles estão relacionados aos pacotes que vimos antes. Passamos o valor de ESTABLISHED para permitir pacotes que fazem parte de uma conexão existente. Passamos o valor de RELATED para permitir pacotes associados a uma conexão estabelecida. Esta é a parte da regra que corresponde à nossa sessão SSH atual.
  • -j ACCEPT: especifica o destino dos pacotes correspondentes. Aqui, dizemos ao iptables que os pacotes que correspondem aos critérios anteriores devem ser aceitos e permitidos.

Colocamos essa regra no início porque queremos garantir que as conexões que já estamos usando sejam correspondidas, aceitas e retiradas da cadeia antes de atingir qualquer regra DROP.

Podemos ver as mudanças se listarmos as regras:

  1. sudo iptables -L
Output:
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ê conhece a sintaxe geral, vamos continuar adicionando mais alguns casos em que queremos aceitar a conexão.

Aceite outras conexões necessárias

Dissemos ao iptables para manter abertas quaisquer conexões que já estejam 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.

Queremos manter duas portas abertas especificamente. Queremos manter nossa porta SSH aberta (neste guia vamos assumir que este é o padrão 22. Se você mudou isso em sua configuração SSH, modifique seu valor aqui). Também vamos assumir que este computador está executando um servidor web na porta padrão 80. Se este não for o seu caso, você não precisa adicionar essa regra.

As duas linhas que vamos usar para adicionar essas regras são:

  1. sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
  2. sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Como você pode ver, elas são muito semelhantes à nossa primeira regra, mas talvez mais simples. As novas opções são:

  • -p tcp: Esta opção corresponde a pacotes se o protocolo usado for o TCP. Este é um protocolo baseado em conexão que será usado pela maioria dos aplicativos porque permite uma comunicação confiável.
  • –dport: Esta opção está disponível se o sinalizador -p tcp for fornecido. Ele fornece um requisito adicional de correspondência da porta de destino para o pacote correspondente. A primeira regra corresponde aos pacotes TCP destinados à porta 22, enquanto a segunda regra corresponde ao tráfego TCP apontado para a porta 80.

Há mais uma regra de aceitação que precisamos para garantir que nosso servidor funcione corretamente. Freqüentemente, os serviços no computador se comunicam enviando pacotes de rede entre si. Eles fazem isso utilizando uma pseudo interface de rede chamada dispositivo de loopback, que direciona o tráfego de volta para si mesmo em vez de para outros computadores.

Portanto, se um serviço deseja se comunicar com outro serviço que está aguardando conexões na porta 4555, ele pode enviar um pacote para a porta 4555 do dispositivo de loopback. Queremos que esse tipo de comportamento seja permitido, pois é essencial para o correto funcionamento de muitos programas.

A regra que precisamos adicionar é esta:

  1. sudo iptables -I INPUT 1 -i lo -j ACCEPT

Isso parece um pouco diferente dos nossos outros comandos. Vamos ver o que ele está fazendo:

  • -I INPUT 1: O sinalizador -I diz ao iptables para inserir uma regra. Isso é diferente do sinalizador -A que anexa uma regra ao final. O sinalizador -I leva uma cadeia e a posição da regra onde você deseja inserir a nova regra. Neste caso, estamos adicionando esta regra como a primeira regra da cadeia INPUT. Isso derrubará o restante das regras. Queremos isso no topo porque é fundamental e não deve ser afetado por regras posteriores.
  • -i lo: Este componente da regra corresponde se a interface que o pacote está usando for a interface \lo A interface \lo é outro nome para o dispositivo de loopback. Isso significa que qualquer pacote que use essa interface para se comunicar (pacotes gerados em nosso servidor, para nosso servidor) deve ser aceito.

Para ver nossas regras atuais, devemos usar o sinalizador -S. Isso ocorre porque o sinalizador -L não inclui algumas informações, como a interface à qual uma regra está vinculada, que é uma parte importante da regra que acabamos de adicionar:

  1. sudo iptables -S
Output:
-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

Implementando uma regra de descarte

Agora temos quatro regras separadas que aceitam pacotes explicitamente com base em determinados critérios. No entanto, nosso firewall atualmente não está bloqueando nada.

Se um pacote entrar na cadeia INPUT e não corresponder a uma das quatro regras que fizemos, ele está sendo passado para nossa política padrão, que é aceitar o pacote de qualquer maneira. Precisamos mudar isso.

Existem duas maneiras diferentes de fazer isso, com algumas diferenças bastante importantes.

A primeira maneira de fazer isso é modificar a política padrão de nossa cadeia INPUT. Podemos fazer isso digitando:

  1. sudo iptables -P INPUT DROP

Isso capturará todos os pacotes que caírem em nossa cadeia INPUT e os descartará. Isso é o que chamamos de política de queda padrão. Uma das implicações desse tipo de design é que ele recai sobre a eliminação de pacotes se as regras forem liberadas.

Isso pode ser mais seguro, mas também pode ter sérias consequências se você não tiver outra forma de acessar seu servidor. Com a DigitalOcean, você pode fazer login por meio de nosso console da web para obter acesso ao seu servidor, caso isso aconteça. O console da web atua como uma conexão local virtual, portanto, as regras do iptables não o afetarão.

Você pode querer que seu servidor descarte automaticamente todas as conexões caso as regras sejam descartadas. Isso impediria que seu servidor fosse deixado totalmente aberto. Isso também significa que você pode facilmente anexar regras à parte inferior da cadeia e, ao mesmo tempo, descartar os pacotes como desejar.

A abordagem alternativa é manter a política padrão para a cadeia como aceitar e adicionar uma regra que descarta todos os pacotes restantes na parte inferior da própria cadeia.

Se você alterou a política padrão para a cadeia INPUT acima, pode defini-la novamente para seguir digitando:

  1. sudo iptables -P INPUT ACCEPT

Agora, você pode adicionar uma regra ao final da cadeia que eliminará todos os pacotes restantes:

  1. sudo iptables -A INPUT -j DROP

O resultado em condições normais de operação é exatamente o mesmo que uma política de queda padrão. Esta regra funciona combinando cada pacote restante que a alcança. Isso evita que um pacote nunca caia por toda a cadeia para alcançar a política padrão.

Basicamente, isso é usado para manter a política padrão para aceitar tráfego. Dessa forma, se houver algum problema e as regras forem liberadas, você ainda poderá acessar a máquina pela rede. Esta é uma forma de implementar uma ação padrão sem alterar a política que será aplicada a uma cadeia vazia.

Obviamente, isso também significa que qualquer regra adicional que você deseja adicionar ao final da cadeia terá que ser adicionada antes da regra de eliminação. Você pode fazer isso removendo temporariamente a regra de descarte:

  1. sudo iptables -D INPUT -j DROP
  2. sudo iptables -A INPUT new_rule_here
  3. sudo iptables -A INPUT -j DROP

Ou você pode inserir as regras necessárias no final da cadeia (mas antes da queda) especificando o número da linha. Para inserir uma regra na linha número 4, você pode digitar:

  1. sudo iptables -I INPUT 4 new_rule_here

Se você está tendo problemas para saber qual é o número da linha de cada regra, você pode dizer ao iptables para numerar as regras digitando:

  1. sudo iptables -L --line-numbers
Output:
Chain INPUT (policy DROP) num target prot opt source destination 1 ACCEPT all -- anywhere anywhere 2 ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED 3 ACCEPT tcp -- anywhere anywhere tcp dpt:ssh 4 ACCEPT tcp -- anywhere anywhere tcp dpt:http Chain FORWARD (policy ACCEPT) num target prot opt source destination Chain OUTPUT (policy ACCEPT) num target prot opt source destination

Isso pode ser útil para garantir que você esteja adicionando sua regra na posição apropriada.

Listando e excluindo regras do Iptables

Se você quiser saber os detalhes sobre como listar e excluir regras do iptables, confira este tutorial: Como listar e excluir regras de firewall do Iptables.

Salvando sua configuração do Iptables

Por padrão, as regras que você adiciona ao iptables são efêmeras. Isso significa que, quando você reiniciar o servidor, as regras do iptables desaparecerão.

Na verdade, esse é um recurso para alguns usuários, porque oferece a eles um caminho para voltar se eles acidentalmente se bloquearam fora do servidor. No entanto, a maioria dos usuários desejará uma maneira de salvar automaticamente as regras que você criou e carregá-las quando o servidor iniciar.

Existem algumas maneiras de fazer isso, mas a maneira mais fácil é com o pacote iptables-persistent. Você pode baixá-lo dos repositórios padrão do Ubuntu:

  1. sudo apt-get update
  2. sudo apt-get install iptables-persistent

Durante a instalação, você será perguntado se deseja salvar suas regras atuais para serem carregadas automaticamente. Se você estiver satisfeito com sua configuração atual (e tiver testado sua capacidade de criar conexões SSH independentes, poderá optar por salvar suas regras atuais.

Ele também perguntará se você deseja salvar as regras IPv6 que você configurou. Estes são configurados através de um utilitário separado chamado ip6tables que controla o fluxo de pacotes IPv6 quase da mesma maneira.

Quando a instalação estiver concluída, você terá um novo serviço chamado iptables-persistent que está configurado para ser executado na inicialização. Este serviço carregará suas regras e as aplicará quando o servidor for iniciado.

Salvando atualizações

Se você atualizar seu firewall e quiser preservar as alterações, você deve salvar suas regras do iptables para que elas sejam persistentes.

Salve suas regras de firewall com este comando:

  1. sudo invoke-rc.d iptables-persistent save

Conclusão

Agora você deve ter um bom ponto de partida para desenvolver um firewall que atenda às suas necessidades. Existem muitos outros utilitários de firewall e alguns que podem ser mais fáceis, mas iptables é uma boa ferramenta de aprendizado, apenas porque expõe parte da estrutura subjacente do netfilter e porque está presente em muitos sistemas.

Para saber mais sobre como proteger sua rede com iptables, confira estes tutoriais:

  • Como implementar um modelo básico de firewall com Iptables no Ubuntu 14.04
  • Iptables Essentials: regras e comandos comuns de firewall
  • Como configurar um firewall Iptables para proteger o tráfego entre seus servidores
  • Um mergulho profundo na arquitetura Iptables e Netfilter
  • Como testar sua configuração de firewall com Nmap e Tcpdump