Como proteger um firewall Linux com regras IPTables
A invasão de servidores e o acesso não autorizado são ameaças genuínas. Estas são as razões pelas quais você deve implementar um firewall como parte de sua estratégia geral de segurança de rede. Configurar um firewall com regras de iptables é uma forma de mitigar esses riscos em sistemas Linux.
Para sua sorte, este tutorial ensinará como implementar um firewall com configuração básica de regras de iptables que você pode personalizar com base em seus requisitos. Pronto para sujar as mãos? É hora de mergulhar!
Pré-requisitos
Este tutorial contém demonstrações práticas. Se desejar acompanhar, certifique-se de ter um servidor Linux ou um computador desktop. Este tutorial usa o Ubuntu 14.04 para os exemplos, mas deve funcionar com outras distribuições Linux e versões mais recentes do Ubuntu.
Instalando o serviço de firewall persistente Iptables
Como o nome indica, o IPTables Persistent Firewall é um serviço que salva seus conjuntos de regras e aplica automaticamente as regras do IPTables nas reinicializações do servidor. Mas primeiro você precisará instalar o pacote de firewall persistente.
Para instalar o Firewall Persistente IPTables, prossiga com as etapas a seguir.
1. Abra uma sessão de terminal em seu servidor localmente ou via SSH.
2. Em seguida, execute o comando abaixo para atualizar o cache de origem do pacote do seu servidor.
# Updating the package source cache
sudo apt update -y
3. Agora, execute o comando abaixo para instalar o IPTables Persistent Firewall.
# Installing the Persistent Firewall Package
sudo apt install iptables-persistent -y
4. Para salvar as regras IPv4 atuais, selecione Sim e pressione Enter no prompt. O instalador salva as regras IPv4 no arquivo /etc/iptables/rules.v4.
5. O próximo prompt solicita que você Salvar regras IPv6 atuais, selecione Sim e pressione Enter. O instalador salva as regras IPv6 no arquivo /etc/iptables/rules.v6.
Por último, confirme se netfilter-persistent.service
está ativo e habilitado.
sudo systemctl status netfilter-persistent
Configurando regras básicas do Iptables
Na configuração básica do firewall, você construirá uma estrutura extensível na qual poderá construir para configurar seu firewall. Geralmente, você configurará uma política “negar todos-aceitar todos”, o que significa que qualquer solicitação recebida de qualquer IP será negada, exceto seu IP e porta SSH 22 (para acesso de administrador).
Quaisquer conexões contínuas do IP do seu servidor com a Internet mais ampla serão permitidas; quaisquer conexões de entrada serão descartadas (exceto SSH). Posteriormente, você criará exceções para os serviços e tipos de tráfego específicos necessários, aprendendo gradualmente mais adiante neste tutorial.
1. Abra o arquivo /etc/iptables/rules.v4 em um editor de texto. Este exemplo usa nano
como editor.
sudo nano /etc/iptables/rules.v4
Em seguida, exclua todo o conteúdo do arquivo /etc/iptables/rules.v4 e substitua-o pelas linhas a seguir. Consulte os comentários embutidos para entender o que cada linha/seção faz.
Observação: a configuração do firewall abaixo é o que você pode descrever como estrita e serve apenas para criar uma regra básica de firewall, que você pode personalizar posteriormente.
*filter
# Setting up a "deny all-accept all" policy
# Allow all outgoing, but deny/drop all incoming and forwarding traffic
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Custom per-protocol chains
# Defining custom rules for UDP protocol.
:UDP - [0:0]
# Defining custom rules for TCP protocol.
:TCP - [0:0]
# Defining custom rules for ICMP protocol.
:ICMP - [0:0]
# Accept SSH UDP traffic
-A TCP -p udp --dport 22 -j ACCEPT
# Accept SSH TCP traffic
-A TCP -p tcp --dport 22 -j ACCEPT
# Acceptable ICMP traffic
# Boilerplate acceptance policy
# Allowing packets based on the CONNTRACK connection states of ESTABLISHED and RELATED
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# Allowing packets through the loopback interface, which is used for local connections
-A INPUT -i lo -j ACCEPT
# Packets that do not match any rules in the protocol-specific should be dropped.
-A INPUT -m conntrack --ctstate INVALID -j DROP
# Allowing new protocol-specific chains to process packets for UDP that have a NEW conntrack state.
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
# Allowing new protocol-specific chains to process packets for TCP that have a NEW conntrack state.
-A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
# Allowing new protocol-specific chains to process packets for ICMP that have a NEW conntrack state.
-A INPUT -p icmp -m conntrack --ctstate NEW -j ICMP
# Reject anything at this point. And print out rejection message with its specific protocol.
# Issuing an ICMP "port unreachable" message to any new incoming UDP packets, rejecting them.
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
# Issuing a "tcp-reset" message to any new incoming TCP packets, rejecting them.
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
# Issuing an "icmp-proto-unreachable" message to any new incoming TCP packets, dropping all other incoming packets.
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
# Commit the changes
COMMIT
*raw
# Allowing packets in the PREROUTING chain
:PREROUTING ACCEPT [0:0]
# Allows packets in the OUTPUT chain, which is used for locally generated packets
:OUTPUT ACCEPT [0:0]
# Commits the changes to the kernel
COMMIT
# NAT table is used to alter packets as they are routed through the system
*nat
:PREROUTING ACCEPT [0:0]
# Allowing packets in the INPUT chains for NAT
:INPUT ACCEPT [0:0]
# Allowing packets in the OUTPUT chains for NAT
:OUTPUT ACCEPT [0:0]
# Allowing packets in the POSTROUTING chains for NAT
:POSTROUTING ACCEPT [0:0]
# Commits the changes to the kernel
COMMIT
*security
# Allowing packets in the INPUT chains for security
:INPUT ACCEPT [0:0]
# Allowing packets in the FORWARD chains for security
:FORWARD ACCEPT [0:0]
# Allowing packets in the OUTPUT chains for security
:OUTPUT ACCEPT [0:0]
# Commits the changes to the kernel
COMMIT
*mangle
# Allowing packets in the PREROUTING chains for mangle
:PREROUTING ACCEPT [0:0]
# Allowing packets in the INPUT chains for mangle
:INPUT ACCEPT [0:0]
# Allowing packets in the FORWARD chains for mangle
:FORWARD ACCEPT [0:0]
# Allowing packets in the OUTPUT chains for mangle
:OUTPUT ACCEPT [0:0]
# Allowing packets in the POSTROUTING chains for mangle
:POSTROUTING ACCEPT [0:0]
# Commits the changes to the kernel
COMMIT
3. Salve o arquivo. Em nano
, pressione CTRL+X, Y, Enter.
4. Execute o comando iptables-restore
abaixo para validar ou encontrar quaisquer erros de sintaxe. Se não houver erros, o firewall será reiniciado com as regras definidas no arquivo. Se houver erros, o comando retornará uma lista dos erros e como corrigi-los.
sudo iptables-restore -t /etc/iptables/rules.v4
5. Em seguida, edite /etc/iptables/rules.v6 para implementar sua política e estrutura de firewall para IPv6.
sudo nano /etc/iptables/rules.v6
6. Substitua o arquivo /etc/iptables/rules.v6 pelas linhas a seguir. Salve e saia do /etc/iptables/rules.v6 pressionando CTRL+X, Y, Enter.
As regras de iptables abaixo eliminarão todo o tráfego IPv6 e assumirão que não há nenhum aplicativo ou serviço no servidor que dependa ou use IPv6.
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
COMMIT
7. Execute o comando abaixo para localizar e corrigir quaisquer erros de sintaxe.
sudo ip6tables-restore -t /etc/iptables/rules.v6
8. Agora, recarregue o serviço netfilter-persistent
para que as regras do iptables tenham efeito.
sudo service netfilter-persistent reload
9. Execute o comando abaixo para salvar as novas regras do iptables.
sudo service netfilter-persistent save
10. Execute o comando abaixo para listar todas as regras para IPv4 atualmente em uso.
sudo iptables -S
10. Por fim, liste as regras do iptables para IPv6.
sudo ip6tables -S
Alterando o endereço IP do servidor DNS do seu servidor (condicional)
O bloqueio de todo o tráfego IPv6 pode resultar em efeitos colaterais desfavoráveis, especialmente se o seu servidor depender do IPv6 para resolução de nomes.
Neste exemplo, a configuração de rede depende de servidores de nomes IPv6 (como 2001:4860:4860::8888 e 2001:4860:4860::8844). Como o firewall impõe apenas o tráfego IPv4, o sistema não pode procurar servidores de nomes para IPv6.
Por exemplo, alguns dos seus repositórios APT podem não funcionar se o firewall bloquear todo o tráfego IPv6. Se você tentar executar novamente o comando sudo apt update
, poderá receber o seguinte erro.
A solução é atualizar o arquivo de configuração da rede, preferindo usar servidores de nomes IPv4 (como 8.8.8.8 e 8.8.4.4).
1. Abra o arquivo /etc/network/interfaces em um editor de texto.
Os arquivos de configuração da interface de rede podem diferir dependendo da distribuição ou versão do Linux. O exemplo abaixo é especificamente para Ubuntu 14.04 LTS.
sudo nano /etc/network/interfaces
2. Procure a diretiva dns-nameservers
. Altere esta diretiva para dns-nameservers 8.8.8.8 8.8.4.4
.
Os 8.8.8.8 e 8.8.4.4 são servidores DNS públicos administrados pelo Google. Esses servidores DNS públicos são confiáveis e rápidos. Sinta-se à vontade para usar outros servidores DNS, como OpenDNS ou DNS IPv4 interno em sua organização.
3. Execute o comando abaixo para alternar a interface de rede do seu servidor e usar os novos servidores de nomes.
sudo ifdown eth0 && sudo ifup eth0
4. Em seguida, abra /etc/apt/apt.conf.d/99force-ipv4 em um editor de texto. Esta configuração padrão arquiva o que o APT
usa para configurações persistentes.
sudo nano /etc/apt/apt.conf.d/99force-ipv4
5. Preencha o arquivo 99force-ipv4 com a seguinte linha. Este valor forçará o APT a usar IPv4 para resolução de nomes. Salve e saia do 99force-ipv4.
Acquire::ForceIPv4 "true";
6. Efetue logout e login novamente em sua sessão SSH e execute novamente o comando sudo apt update
. Você não deverá mais ver os erros de resolução de nomes.
Adicionando isenções para serviços específicos
Agora que você tem as regras de iptables “permitir tudo-negar tudo” em funcionamento, você pode abrir portas específicas para determinados serviços, conforme necessário. Por exemplo, se o seu servidor hospeda ou irá hospedar um site, você precisará permitir o tráfego da porta HTTP 80 ou da porta HTTPS 443. Para fazer isso, proceda da seguinte forma.
1. No terminal, execute o seguinte comando para abrir a porta TCP 80 para tráfego HTTP e a porta 443 para tráfego HTTPS.
- O parâmetro
-A
aceita qual cadeia anexar a regra. - O parâmetro
-p
especifica o tipo de protocolo que a regra aplica. - O valor do parâmetro
--dport
é o número da porta de destino. - O parâmetro
-j
direciona qual ação tomar quando a regra corresponder.
sudo iptables -A TCP -p tcp --dport 80 -j ACCEPT
sudo iptables -A TCP -p tcp --dport 443 -j ACCEPT
2. Execute o comando abaixo para verificar se as novas regras agora estão em vigor.
sudo iptables -L -v
Você verá suas duas entradas para HTTP e HTTPS, respectivamente.
3. Por fim, execute o comando abaixo para salvar suas alterações nas regras do iptables.
sudo service netfilter-persistent save
Permitindo conexões com base na fonte
O Iptables também permite criar regras para permitir tráfego de fontes específicas, como de um ou mais endereços IP. Por exemplo, sua empresa pode ter três sites, cada um com seu endereço IP (por exemplo, 192.168.1.20, 192.168.1.30 e 192.168.1.40).
Você provavelmente deseja permitir conexões ao seu servidor de cada site. Para fazer isso, você criará três regras separadas com -s
para especificar a fonte específica.
1. Execute os seguintes comandos para permitir conexões de três endereços IP específicos.
Os endereços IP abaixo são apenas para fins de exemplo e podem não refletir um cenário do mundo real. Os endereços IP dos seus sites serão diferentes.
# Allowing connection from 192.168.1.20
sudo iptables -A TCP -s 192.168.1.20 -j ACCEPT
# Allowing connection from 192.168.1.30
sudo iptables -A TCP -s 192.168.1.30 -j ACCEPT
# Allowing connection from 192.168.1.40
sudo iptables -A TCP -s 192.168.1.40 -j ACCEPT
2. Execute novamente o comando abaixo para verificar se as novas regras foram adicionadas.
sudo iptables -L -v
Você verá três entradas para suas três fontes específicas, permitindo que elas se conectem ao seu servidor.
3. Por fim, não se esqueça de salvar suas regras de iptables executando o comando abaixo.
sudo service netfilter-persistent save
Redefinindo regras do Iptables
Agora você configurou com sucesso um firewall com regras de iptables. Mas nem tudo corre conforme o planejado o tempo todo. Mas e se você errasse e quisesse começar do zero?
Uma opção é redefinir todas as regras do iptables. Para fazer isso, siga as etapas abaixo.
1. Primeiro, faça uma cópia de backup das regras existentes do iptables. O comando abaixo copia os arquivos rules.v4 e rules.v6 para seu diretório inicial.
sudo cp /etc/iptables/* ~/
2. Em seguida, elimine todas as regras existentes do iptables executando o comando abaixo.
sudo service netfilter-persistent flush
3. Confirme se as regras não existem mais.
sudo iptables -S
Como você pode ver abaixo, apenas as regras padrão do iptables permanecem, permitindo tudo. Esse comportamento garante que a redefinição das regras não causará um cenário de bloqueio de acesso de administrador.
Conclusão
Ao longo deste tutorial, você aprendeu como proteger seu firewall Linux com regras de iptables e como configurar isenções.
Alguns administradores Linux podem argumentar que o iptables está desatualizado para configurar o firewall Linux. Mas muitas aplicações ainda dependem do iptables, o que pode significar que ele continuará sendo um pilar por muitos anos.
O que você acha de usar regras persistentes de iptables? Você considerará implementá-lo ou adotará opções mais recentes, como o firewall descomplicado (UFW)?