+++ date = '2024-10-20T14:22:33-03:00' title = 'Dominando o iptables: Configurações básicas de firewall para um servidor GNU/Linux recém-implantado' description = "O uso básico do iptables para um novo servidor web GNU/Linux" tags = [ "webserver", "GNU/Linux", "Basics Series", ] canonical = "/posts/iptables-basics" +++ Ao configurar um novo servidor Linux, uma das primeiras coisas que você deve fazer é protegê-lo configurando um firewall. O iptables, uma poderosa ferramenta de firewall disponível na maioria das distribuições Linux, é uma excelente opção para gerenciar regras de tráfego. Nesta publicação, vou mostrar algumas configurações básicas do iptables para um servidor recém-implantado. No final, você terá um firewall sólido para proteger seus serviços e, ao mesmo tempo, manter as coisas simples. ## Oque é iptables? iptables é um utilitario de firewall por linha de comando que utiliza "chains" para gerenciar o tráfego. As "chains" são basicamente uma lista de regras que aplicam para pacotes de entrada ou saida. Voce pode fazer as regras baseadas em IPs de origem, portas e protocolos, por exemplo. Tornar um servidor seguro é a primeira prioridade para qualquer sysadmin, e firewalls são uma das camadas mais importantes de defesa. Com iptables voce pode: - [ ] Bloquear trafego indesejado - [ ] Permitir conexões confiáveis (como SSH, HTTP/HTTPS) - [ ] Proteger contra ataques DoS e port scanning - [ ] Gerar logs de atividades suspeitas para analise futura ## Como funciona o fluxo de pacotes no iptables Eu recomendo fortemente que voce leia mais sobre o fluxo de pacotes do iptables antes de aplicar qualquer regra. Recomendo que voce inicie por esses diagramas muito bem feitos nesse gist do [nerdalert no GitHub](https://gist.github.com/nerdalert/a1687ae4da1cc44a437d) ## Comandos basicos do iptables Vamos começar com uma overview dos comandos essenciais do iptables: ### Mostrar regras atuais ```bash iptables -L ``` ### Deletar regras atuais ```bash iptables -F ``` ### Salvar regras atuais Se voce está rodando Debian, voce precisa primeiro instalar o pacote `iptables-persistent`, depois disso voce pode usar os seguintes comandos: ```bash iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6 ``` Restaurar regras: ```bash iptables-restore < /etc/iptables/rules.v4 ip6tables-restore < /etc/iptables/rules.v6 ``` ## Configurar iptables em um servidor novo Agora, vamos passar por algumas regras basicas que voce pode aplicar no seu servidor logo de inicio. Vamos permitir trafego essencial como SSH e HTTP/HTTPs e bloquear todo o resto. ### Passo 1: Limpar regras existentes Antes de começar a definir regras, é uma boa ideia limpar as regras existentes para começar do zero: ```bash iptables -F ``` Isso nos garante que estamos iniciando em um estado limpo. Tome cuidado com os proximos comandos, para voce não se trancar para fora do seu proprio servidor! Isso já aconteceu com todos sysadmins mais cedo ou mais tarde. A forma mais simples de garantir que isso não ocorra é fazendo tudo isso fisicamente, ou através de uma conexão por KVM por exemplo. ### Passo 2: Definir as politicas default Agora, vamos definir o comportamento padrão para conexões de entrada (INPUT), saida (OUTPUT) e encaminhadas (FORWARD). Por padrão, é uma boa ideia bloquear toda a entrada e permitir toda a saida. ```bash iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT ``` Isso faz com que todas as conexões sejam dropadas a menos que uma regra as permita. O trafego de saida por sua vez, é liberado por padrão. ### Passo 3: Permitir trafego SSH (Porta 22) Voce vai precisar de SSH para acessar o seu servidor, então vamos permitir trafego na porta 22. É importante que voce proteja esse acesso permitindo que somente seus IPs confiaveis possam acessar, por simplicitade vamos iniciar permitindo todas as conexões SSH: ```bash iptables -A INPUT -p tcp --dport 22 -j ACCEPT ``` O "-A" significa "Append", isso insere a regra no final da lista, para colocar no topo use a flag "-I". É uma boa ideia sempre adicionar comentarios nas regras, para no futuro facilitar o nosso troubleshooting. No iptables, podemos adicionar comentarios com a seguinte sintaxe: ```bash iptables -m comment --comment "Seu comentario aqui" ``` Se voce quiser restringir seu acesso SSH para apenas um IP de origem (por exemplo, o IP da sua casa), faça assim: ```bash iptables -A INPUT -p tcp -s -m comment --comment "Permite SSH de casa" --dport 22 -j ACCEPT ``` ### Passo 4: Permitir HTTP e HTTPs (portas 80 e 443) Se voce estiver rodando um webserver, voce vai querer liberar o trafego nessas portas: ```bash iptables -A INPUT -m comment --comment "Permite HTTP" -p tcp --dport 80 -j ACCEPT iptables -A INPUT -m comment --comment "Permite HTTPS" -p tcp --dport 443 -j ACCEPT iptables -A INPUT -m comment --comment "Permite QUIC" -p udp --dport 443 -j ACCEPT ``` Isso permite o trafego ao seu servidor via HTTP (porta 80) e HTTPS (porta 443). Note que eu adicionei a porta 443/udp, que é para o protocolo QUIC, QUIC é um protocolo de camada de transporte desenvolvido pelo Google, feito para ser mais rapido, e mais seguro combinando features do TCP, TLS e HTTP/2 para melhorar a latencia e performance. Eu recomendo que voce pesquise mais sobre esse assunto, talvez eu faça um artigo sobre ele no futuro. ### Passo 5: Permitir trafego loopback O seu servidor precisa se comunicar com ele mesmo pela interface loopback. Garanta que esse trafego seja permitido: ```bash iptables -A INPUT -m comment --comment "Permite trafego loopback" -i lo -j ACCEPT ``` ### Passo 6: Dropar pacotes invalidos Pacotes invalidos podem ser erros de configuração ou até mesmo ataques, então é uma boa pratica sempre dropar: ```bash iptables -A INPUT -m conntrack --ctstate INVALID -j DROP ``` ### Passo 7: Permitir conexões estabelecidas e relacionadas Para permitir respostar a conexões de saida (como quando o seu servidor solicita algum update), voce vai precisar aplicar essa regra: ```bash iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ``` Isso garante que o servidor aceite respostas para requisições que ele mesmo fez. ### Passo 8: Não esqueça o IPv6! Para IPv6, a sintaxe é a mesma, voce apenas precisa mudar o comando de `iptables` para `ip6tables` A maior diferença é no protocolo ICMP, voce deve sempre permitir ICMPv6 para que o seu servidor funcione corretamente. Essas são algumas regras iniciais, onde permitimos explicitamente pacotes de controle ICMPv6 e dropamos o resto. ```bash ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT ip6tables -A OUTPUT -p icmpv6 --icmpv6-type echo-reply -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type time-exceeded -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type destination-unreachable -j ACCEPT ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT ip6tables -A INPUT -p icmpv6 -j DROP ``` ### Passo 9: Salve suas regras Quando voce terminou de aplicar as suas regras, não se esqueça de salvar elas. Isso garante que elas sejam aplicadas novamente no proximo reboot: ```bash iptables-save > /etc/iptables/rules.v4 ip6tables-save > /etc/iptables/rules.v6 ``` ### Passo 10: Testar tudo Depois de configurar todas as suas regras, é bom sempre valida-las conectando em seu servidor. Nesse exemplo voce deve conseguir se comunicar via SSH, HTTP e HTTPS, todo o resto deve estar bloqueado. ## Sumario Em sumario, essas são algumas regras basicas para iniciar, sempre revise e altere conforme a sua necessidade! ### IPv4 ```bash iptables -P INPUT DROP iptables -P FORWARD DROP iptables -P OUTPUT ACCEPT iptables -A INPUT -p tcp -s -m comment --comment "Permite SSH de casa" --dport 22 -j ACCEPT iptables -A INPUT -m comment --comment "Permite HTTP" -p tcp --dport 80 -j ACCEPT iptables -A INPUT -m comment --comment "Permite HTTPS" -p tcp --dport 443 -j ACCEPT iptables -A INPUT -m comment --comment "Permite QUIC" -p udp --dport 443 -j ACCEPT iptables -A INPUT -m comment --comment "Permite trafego loopback" -i lo -j ACCEPT iptables -A INPUT -m conntrack --ctstate INVALID -j DROP iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables-save > /etc/iptables/rules.v4 ``` ### IPv6 ```bash ip6tables -P INPUT DROP ip6tables -P FORWARD DROP ip6tables -P OUTPUT ACCEPT ip6tables -A INPUT -p tcp -s -m comment --comment "Permite SSH de casa" --dport 22 -j ACCEPT ip6tables -A INPUT -m comment --comment "Permite HTTP" -p tcp --dport 80 -j ACCEPT ip6tables -A INPUT -m comment --comment "Permite HTTPS" -p tcp --dport 443 -j ACCEPT ip6tables -A INPUT -m comment --comment "Permite QUIC" -p udp --dport 443 -j ACCEPT ip6tables -A INPUT -m comment --comment "Permite trafego loopback" -i lo -j ACCEPT ip6tables -A INPUT -m conntrack --ctstate INVALID -j DROP ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ip6tables-save > /etc/iptables/rules.v6 ``` ## Conclusão Parabens! Voce acabou de configurar o iptables em seu novo servidor GNU/Linux. Por bloquear todo o trafego exceto o que é confiavel voce adicionou uma camada de segurança a seu servidor.