5. Configurando o Firewall

Agora é hora de criar seu próprio arquivo com regras de firewall personalizadas, a fim de proteger a rede interna. Haverá alguma complicação em fazer isso porque nem todas as funcionalidades do firewall estão disponíveis em pacotes em ponte. Além disso, há uma diferença entre os pacotes que estão sendo encaminhados e os pacotes que estão sendo recebidos pela máquina local. Em geral, os pacotes de entrada passam pelo firewall apenas uma vez, não duas vezes, como é normalmente o caso; na verdade eles são filtrados somente após o recebimento, portanto, as regras que usam out ou xmit nunca darão match. Pessoalmente, eu uso in via que é uma sintaxe antiga, mas uma que tem sentido quando você a lê. Outra limitação é que você está restrito a usar somente comandos pass ou drop para os pacotes filtrados por uma ponte. Coisas sofisticadas como divert, forwar ou reject não estão disponíveis. Essas opções ainda podem ser usadas, mas apenas no tráfego para ou a partir da própria máquina ponte (se ela tiver um endereço IP).

O conceito de filtragem stateful é novo no FreeBSD 4.0. Esta é uma grande melhoria para o tráfego UDP, que normalmente é um pedido que sai, seguido pouco depois por uma resposta com exatamente o mesmo conjunto de endereços IP e números de porta (mas com origem e destino invertidos, é claro). Para firewalls que não possuem manutenção de estado, quase não há como lidar com esse tipo de tráfego como uma sessão única. Mas com um firewall que pode lembrar de um pacote UDP de saída e, nos próximos minutos, permitir uma resposta, o manuseio de serviços UDP é trivial. O exemplo a seguir mostra como fazer isso. É possível fazer a mesma coisa com pacotes TCP. Isso permite que você evite alguns ataques de negação de serviço e outros truques desagradáveis, mas também faz com que sua tabela de estado cresça rapidamente em tamanho.

Vamos ver um exemplo de configuração. Note primeiro que no topo do /etc/rc.firewall já existem regras padrão para a interface de loopback lo0, então não devemos mais precisar delas. Regras customizadas devem ser colocadas em um arquivo separado (digamos, /etc/rc.firewall.local) e carregadas na inicialização do sistema, modificando a linha de /etc/rc.conf onde definimos o firewall open:

firewall_type="/etc/rc.firewall.local"

Importante:

Você tem que especificar o caminho completo, caso contrário ele não será carregado com o risco de permanecer isolado da rede.

Para nosso exemplo, imagine ter a interface fxp0 conectada para o exterior (Internet) e a xl0 para o interior (LAN). A máquina ponte tem o IP 1.2.3.4 (não é possível que o seu ISP possa lhe dar um endereço assim, mas para nosso exemplo ele é bom).

# Things that we have kept state on before get to go through in a hurry
add check-state

# Throw away RFC 1918 networks
add drop all from 10.0.0.0/8 to any in via fxp0
add drop all from 172.16.0.0/12 to any in via fxp0
add drop all from 192.168.0.0/16 to any in via fxp0

# Allow the bridge machine to say anything it wants
# (if the machine is IP-less do not include these rows)
add pass tcp from 1.2.3.4 to any setup keep-state
add pass udp from 1.2.3.4 to any keep-state
add pass ip from 1.2.3.4 to any

# Allow the inside hosts to say anything they want
add pass tcp from any to any in via xl0 setup keep-state
add pass udp from any to any in via xl0 keep-state
add pass ip from any to any in via xl0

# TCP section
# Allow SSH
add pass tcp from any to any 22 in via fxp0 setup keep-state
# Allow SMTP only towards the mail server
add pass tcp from any to relay 25 in via fxp0 setup keep-state
# Allow zone transfers only by the slave name server [dns2.nic.it]
add pass tcp from 193.205.245.8 to ns 53 in via fxp0 setup keep-state
# Pass ident probes.  It is better than waiting for them to timeout
add pass tcp from any to any 113 in via fxp0 setup keep-state
# Pass the "quarantine" range
add pass tcp from any to any 49152-65535 in via fxp0 setup keep-state

# UDP section
# Allow DNS only towards the name server
add pass udp from any to ns 53 in via fxp0 keep-state
# Pass the "quarantine" range
add pass udp from any to any 49152-65535 in via fxp0 keep-state

# ICMP section
# Pass 'ping'
add pass icmp from any to any icmptypes 8 keep-state
# Pass error messages generated by 'traceroute'
add pass icmp from any to any icmptypes 3
add pass icmp from any to any icmptypes 11

# Everything else is suspect
add drop log all from any to any

Aqueles de vocês que já configuraram firewalls antes podem notar algumas coisas que estão faltando. Em particular, não há regras anti-spoofing, na verdade nós não adicionamos:

add deny all from 1.2.3.4/8 to any in via fxp0

Ou seja, dropar os pacotes que estão vindo do lado de fora dizendo ser da nossa rede. Isso é algo que você normalmente faria para ter certeza de que alguém não tentaria escapar do filtro de pacotes, gerando pacotes nefastos que parecem ser de dentro. O problema é que existe pelo menos um host na interface externa que você não deseja ignorar: o roteador. Mas geralmente ISP tem anti-spoofs em seu roteador, então não precisamos nos incomodar muito.

A última regra parece ser uma duplicata exata da regra padrão, ou seja, não deixa passar nada que não seja especificamente permitido. Mas há uma diferença: todo tráfego suspeito será registrado.

Existem duas regras para passar o tráfego SMTP e o do DNS para o servidor de e-mail e o servidor de nomes, se você os tiver. Obviamente, todo o conjunto de regras deve ser definido de acordo com as suas preferências pessoais, isso é apenas um exemplo específico (o formato da regra é descrito com precisão na página de manual do ipfw(8)). Note que, para que o relay e o ns funcionem, as pesquisas de serviço de nomes devem funcionar antes da ponte ser ativada. Este é um exemplo de quando você precisa ter certeza de que definiu o IP na placa de rede correta. Como alternativa, é possível especificar o endereço IP em vez do nome do host (necessário se a máquina não tiver IP).

As pessoas que estão acostumadas a configurar firewalls provavelmente também estão acostumadas a ter uma regra reset ou forward para pacotes ident (TCP porta 113). Infelizmente, esta não é uma opção aplicável com a ponte, então o melhor é simplesmente passá-las ao seu destino. Enquanto essa máquina de destino não estiver executando um daemon ident, isso é relativamente inofensivo. A alternativa é descartar as conexões na porta 113, o que criará alguns problemas com serviços como por exemplo o IRC (o probe do ident irá dar timeout).

A única outra coisa que é um pouco estranha e que você pode ter notado é que existe uma regra para deixar a máquina ponte falar, e outra para os hosts internos. Lembre-se que isso ocorre porque os dois conjuntos de tráfego terão caminhos diferentes através do kernel e do filtro de pacotes. A rede interna passará pela ponte, enquanto a máquina local usará a pilha IP normal para falar. Assim, as duas regras lidam com casos diferentes. As regras in via fxp0 funcionam nos dois caminhos. Em geral, se você usar as regras in via em todo o filtro, precisará abrir uma exceção para pacotes gerados localmente, porque eles não vieram em nenhuma de nossas interfaces.

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.