Todos, olá!
Estou tentando configurar o firewall do meu servidor usando o iptables (tenho que admitir que a última vez que usei o iptables foi há um ano), mas o iptables age ao contrário do que eu peço.
Aqui está o meu script de teste:
#!/bin/sh
IPT="/sbin/iptables"
echo -n "Loading iptables rules..."
# Flush old rules
$IPT --flush
$IPT --delete-chain
# Allow incoming and outgoing for loopback interfaces
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
# Allow incoming traffic for HTTP(S), SSH and SMTP
$IPT -A INPUT -p tcp --dport 80 -i eth0 -j ACCEPT
$IPT -A INPUT -p tcp --dport 443 -i eth0 -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp --dport 25 -i eth0 -j ACCEPT
# Allow ICMP requests
$IPT -A INPUT -p icmp -i eth0 -j ACCEPT
$IPT -A OUTPUT -p icmp -o eth0 -j ACCEPT
# Allow outgoing traffic for SMTP, DNS, NTP, PgSQL, SolR, and SSH
$IPT -A OUTPUT -p tcp --dport 25 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 53 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 53 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 123 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 5433 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 5433 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 8983 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p udp --dport 8983 -o eth0.2654 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 22 -o eth0 -j ACCEPT
$IPT -A OUTPUT -p tcp --dport 22 -o eth0.2654 -j ACCEPT
# Deny web server user outgoing connections
$IPT -A OUTPUT -o eth0 -m owner --uid-owner www-data -j DROP
# Drop everything else
$IPT -A INPUT -j DROP
$IPT -A OUTPUT -j DROP
$IPT -A FORWARD -j DROP
echo "rules loaded."
# Print rules as understood, then flush to avoid lockout
sleep 10
$IPT -L
# Flush old rules
$IPT --flush
$IPT --delete-chain
Com este script, o servidor não passa mais para nenhuma solicitação, mas faz ping (ICMP), depois de 10 segundos, imprime o texto a seguir e sai:
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
100 5920 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:www
0 0 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:https
1 52 ACCEPT tcp -- any any anywhere anywhere tcp dpt:ssh
0 0 ACCEPT tcp -- eth0 any anywhere anywhere tcp dpt:smtp
0 0 ACCEPT icmp -- eth0 any anywhere anywhere
0 0 DROP all -- any any anywhere anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any any anywhere anywhere
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
100 5920 ACCEPT all -- any lo anywhere anywhere
0 0 ACCEPT icmp -- any eth0 anywhere anywhere
0 0 ACCEPT tcp -- any eth0 anywhere anywhere tcp dpt:smtp
0 0 ACCEPT tcp -- any eth0 anywhere anywhere tcp dpt:domain
0 0 ACCEPT udp -- any eth0 anywhere anywhere udp dpt:domain
0 0 ACCEPT udp -- any eth0 anywhere anywhere udp dpt:ntp
0 0 ACCEPT tcp -- any eth0.2654 anywhere anywhere tcp dpt:5433
0 0 ACCEPT udp -- any eth0.2654 anywhere anywhere udp dpt:5433
0 0 ACCEPT tcp -- any eth0.2654 anywhere anywhere tcp dpt:8983
0 0 ACCEPT udp -- any eth0.2654 anywhere anywhere udp dpt:8983
0 0 ACCEPT tcp -- any eth0 anywhere anywhere tcp dpt:ssh
0 0 ACCEPT tcp -- any eth0.2654 anywhere anywhere tcp dpt:ssh
0 0 DROP all -- any eth0 anywhere anywhere owner UID match www-data
14 2061 DROP all -- any any anywhere anywhere
Primeiro elemento perturbador, notei que as primeiras regras INPUT e OUTPUT são ACEITAR todos os pacotes, enquanto eu não pedi para fazer isso. Além disso, tentei definir a política de INPUT e OUTPUT para DROP (usando $IPT -P INPUT DROP
e $IPT -P OUTPUT DROP
), mas isso definitivamente me bloqueou, mesmo após o tempo limite de dez segundos, e o servidor responde apenas ao ICMP, que me forçar a reiniciar o servidor. O mesmo efeito se eu definir as configurações de política no início do script.
Eu suspeito que meu erro seja óbvio para usuários regulares do iptables, mas eu procurei a solução por horas agora, e, como sempre neste tipo de situações, a resposta só será óbvia para mim quando alguém a apontar. Por favor, qualquer benfeitor para me ajudar?
eth0.2654
é uma VLAN usada para comunicações com nosso servidor PgSQL. Com relação às respostas HTTP, fiquei com a impressão de que eles usam a conexão que o cliente abriu, o que é permitido pela minha regra. Eu estava errado?