Firewall Transparente ou Uma Bridge Filtrada

Introdução

Nos *BSD’s a maioria dos quesitos de segurança e serviços auxiliares são NATIVOS, o que torna muito fácil sua utilização. Em nosso caso, estamos usando o FreeBSD 4.7, em máquina Pentium 166 com 48 mB de RAM (Itautec Infoway), e o IPFW :-)

Em primeiro lugar: pra que haveríamos de querer um treco dêsses aí? Será que um firewall convencional não atende nossas necessidades?

Bem, de fato a Bridge filtrada é medida adicional de segurança, algo que não vai pesar no orçamento (excessivamente, pelo menos) :-) e oferece um grau adicional de dificuldades ao eventual script-kid ou hacker, êsses monstros sempre dispostos a tirar nosso sono e (se acessarem nossos servidores), colocar em risco nosso caviar, festas anuais em Paris e viagens mensais ao Epicot Center, coisinhas que todos nós, Administradores de Rede, esforçamo-nos por oferecer às nossas familias. Lógico, não estou nêsse nível, mas vocês aí fora, seguramente, estão :-). Não se preocupem, não contarei ao Imposto de Renda, êsse esganado.

Embora a maioria dos colegas já saibam, de cor e salteado o que é uma bridge filtrada, permito-me repetir os conceitos:

Suponha que temos de um lado, um link que nos liga (via roteador/modem adsl/ cable modem) à internet, e de outro lado temos OU nossa máquina (o mais simples) OU um firewall fazendo NAT para um número qualquer de máquinas de nossa rede interna. Para efeitos de exposição, vou me limitar ao caso mais simples (minha casa), que dispunha de uma conexão ADSL (Speedy) de um lado e minha própria máquina de outro, ficando a bridge entre elas :-). Arte em ASCII:

|——> rl2 (192.168.10.10) /internet/——[bridge]—-/cliente/ ^ ^ |–rl0 | –rl1 rl2

É usada para contrôle, a partir de um notebook (por exemplo) ou outra máquina; O enderêço dessa placa deve ser DIFERENTE de qualquer outro eventualmente existente em nossa rede, ou seja, se estamos com uma rede em 192.168.1.0, podemos estabelecer essa placa como estando em rede 192.168.10.0 (ou 172.30.0.0, ou 10.0.0.0). Importa é que não seja acessível normalmente a partir de nossa própria rede, mesmo que no mesmo switch.

Não representado na ASCII-art, há um modem ADSL entre a internet e a bridge. Aqui é que vão começar as diferenças entre um firewall convencional e a bridge filtrada:

roteador: 200.204.151.65/26 –> é o modem ADSL cliente: 200.204.151.121/26 –> máquina interna

Tivéssemos um firewall convencional no lugar da bridge, e rl0 deveria ter um ip fixo, válido, enquanto em rl1 teríamos outro ip fixo, possívelmente um dos relacionados na RFC-1918, não roteável. A máquina cliente teria um ip dessa mesma classe/rede, ou seja (mais ASCII-art):

/internet/— oteador—–[firewall]—-/cliente/ ^ ^ ^ ^ 200.204.151.65——-| | | |—192.168.1.2..n 200.204.151.121–| |-192.168.1.1

Fazendo-se abstração completa do funcionamento disso, vamos ao que interessa: A bridge não tem enderêço em qualquer das placas. O conceito é de que tudo o que aparecer em uma delas é copiado para a outra. Contudo, antes de chegar à outra placa, vindo da Internet, o pacote de dados é analisado para saber se pode ou não atingir a máquina cliente. O pacote da máquina cliente poderá (ou não) sair para a Internet, sendo que, se houver expectativa de respostas, isso será inserido em uma tabela. Lógico, o processo é bem mais complexo, mas todos conhecem isso bem, não é mesmo? ;-)

Isso nos permite montar um sistema de defesa mais sofisticado, por exemplo: (e tome ASCII-art):

/internet/— oteador–{bridge}—[firewall]—-/cliente(ou LAN)/ ^ ^ ^ ^ 200.204.151.65——-| | | |—192.168.1.2..n 200.204.151.121–| |-192.168.1.1

Nesse caso, o firewall está fazendo também NAT para a(s) máquina(s) cliente(s).

Resumo: alguém (na internet) já disse que a bridge filtrada é um fio inteligente. E é isso mesmo. Um fio, sem enderêços IP, que analisa os pacotes que por ela passam, bloqueando-os ou deixando-os passar, conforme as regras vigentes.

Optamos por um firewall do modêlo FECHADO, ou seja, tudo é bloqueado, salvo aquilo que é expressamente autorizado a trafegar. Pode ser que existam defensores do outro método (‘tudo aberto, fecho o que não quero’), mas prefiro o conceito de ‘tudo fechado, autorizo o que quero’. :-). Assim, com certeza, não deixo aberto algum furo que eu não queria, mas não lembrei de fechar :-)

Configurando o kernel

Será necessária a reconfiguração do kernel, habilitando a bridge, e os itens relativos ao firewall:

options IPFIREWALL #firewall
options IPFIREWALL_VERBOSE #print information about
#options IPFIREWALL_FORWARD #enable transparent proxy support
options IPFIREWALL_VERBOSE_LIMIT=250 #limit verbosity
options RANDOM_IP_ID #−−−> vide LINT ;−)

# TCP_DROP_SYNFIN adds support for ignoring TCP packets with SYN+FIN. This
# prevents nmap et al. from identifying the TCP/IP stack, but breaks support
# for RFC1644 extensions and is not recommended for web servers.

#
options TCP_DROP_SYNFIN #drop TCP packets with SYN+FIN
# ICMP_BANDLIM enables icmp error response bandwidth limiting. You
# typically want this option as it will help protect the machine from
# D.O.S. packet attacks.

#
options ICMP_BANDLIM
# BRIDGE enables bridging between ethernet cards −− see bridge(4).
# You can use IPFIREWALL and DUMMYNET together with bridging.
#
options BRIDGE

Configuração

O arquivo rc.conf também deve ter algumas opções acrescidas ou modificadas:

### Basic network and firewall/security options: ###
firewall_enable="yes" # Set to YES to enable firewall functionality
firewall_flags="" # Flags passed to ipfw when type is a file
firewall_logging="yes" # Set to YES to enable events logging

firewall_quiet="NO" # Set to YES to suppress rule display
firewall_script="/etc/rc.firewall.bridge" # Which script to run to set up the firewall
ifconfig_rl0="up"
ifconfig_rl1="up"

ifconfig_rl2="inet 192.168.10.10 netmask 255.255.255.0"
sshd_enable="YES"

O script de firewall (/etc/rc.firewall.bridge), que não é o padrão da instalação mas sim um script nosso (seguindo muitas sugestões de outros colegas); Note-se o fato de que as placas de rede rl0 e rl1 são ativadas, mas não recebem qualquer número ip, ao contrário de rl2, que recebe um ip-addr convencional, dos relationados na RFC-1918.

Ufa, estamos quase lá :-)) Crie um arquivo chamado “sysctl.conf” em “/etc”. Ou, caso o mesmo já exista, acrescente o seguinte conteúdo:

#enablesbridge
net.link.ether.bridge=1
#tells bridge togo through the firewall
net.link.ether.bridge_ipfw=1
#tells bridge what interfaces are bridged
net.link.ether.bridge_cfg=rl0:1,rl1:1
#−−−−−−finetunning −−−> recolhido da internet :)

net.inet.tcp.sendspace=32768
net.inet.tcp.recvspace=32768
kern.ipc.somaxconn=1024
net.inet.icmp.drop_redirect=1
net.inet.icmp.log_redirect=1
net.inet.ip.redirect=0
net.inet6.ip6.redirect=0
net.inet.ip.sourceroute=0

net.inet.ip.accept_sourceroute=0
net.link.ether.inet.max_age=1200
net.inet.icmp.bmcastecho=0

Agora, vamos às nossas regras para o IPFW :−)

#
# Setup system for firewall service.
#
# Suck in the configuration variables.
if [ −r /etc/defaults/rc.conf ]; then
. /etc/defaults/rc.conf
source_rc_confs
elif [ −r /etc/rc.conf ]; then
. /etc/rc.conf

fi
############
# Set quiet mode if requested
#
case ${firewall_quiet} in
[Yy][Ee][Ss])
fwcmd="/sbin/ipfw −q"
;;
*)
fwcmd="/sbin/ipfw"
;;
esac
############
# Flush out the list before we begin.

#
${fwcmd} −f flush
############
# Only in rare cases do you want to change these rules
#
${fwcmd} add 100 pass all from any to any via lo0
${fwcmd} add 200 deny all from any to 
127.0.0.0/8
${fwcmd} add 300 deny ip from 127.0.0.0/8 to any
# If you're using 'options BRIDGE', uncomment the following line to pass ARP
${fwcmd} add 400 pass udp from 
0.0.0.0 2054 to 0.0.0.0
#−−−−−−−−−−>
oif=rl0
iif=rl1
iic=rl2
${fwcmd} add check−state
${fwcmd} add deny log ip from 10.0.0.0/8 to any via ${oif}

${fwcmd} add deny log ip from 172.16.0.0/12 to any via ${oif}
${fwcmd} add deny log ip from 192.168.0.0/16 to any via ${oif}
${fwcmd} add pass udp from 
200.204.151.121 to any keep−state
${fwcmd} add reject log all from 200.221.6.0/32 to any in via rl0
${fwcmd} add pass udp from any to any in via ${iif} keep−state

${fwcmd} add pass ip from any to any in via ${iif}
${fwcmd} add pass icmp from any to any
${fwcmd} add pass tcp from any to any established
${fwcmd} add pass tcp from any to any 49152−65535 in via ${oif}
${fwcmd} add pass tcp from any to any 113 in via ${oif}

${fwcmd} add pass tcp from any to any 22 in via ${oif}
${fwcmd} add pass tcp from any to any 22 via ${iic}
${fwcmd} add pass tcp from any to any 53 in via ${oif}
${fwcmd} add pass log tcp from any to any 25 in via ${oif}

# ${fwcmd} add pass tcp from any to any 110 in via ${oif}
${fwcmd} add pass udp from any to any 49152−65535 in via ${oif}
# ${fwcmd} add pass udp from any to any 53 in via ${oif}
${fwcmd} add deny log ip from any to any

#−−−−−>

Os colegas podem notar que algumas dessas regras foram tomadas ‘emprestadas’ do rc.firewall original, existente em /etc :-). A idéia é KISS :-), sempre que for possível. As demais regras são bem simples, uma vez que o propósito desta bridge é ser uma plataforma de testes, para ampliarmos nosso conhecimento em filtragem de pacotes aplicadas à bridges. Lógico, essas regras devem ser revisadas e estabelecidas de acôrdo com o melhor conhecimento de cada um dos colegas quanto às suas próprias necessidades, caso venha a ser colocada em produção.

Uso: entre um roteador qualquer e um cliente qualquer. Em topologia mais sofisticada, ficaria entre o roteador e um firewall qualquer, ou ainda entre um firewall qualquer e uma rede qualquer :-). Bem, sugiro experimentarem :-), à vontade.

log /var/log/security

Dec 21 21:07:17 infoway /kernel: ipfw: 2300 Deny TCP 192.168.10.10:1024
192.168.10.1:22 out via rl2
Dec 22 08:07:05 infoway /kernel: ipfw: limit 250 reached on entry 2300

Dec 22 23:01:52 infoway /kernel: ipfw: limit 250 reached on entry 2300
Dec 23 08:14:30 infoway /kernel: ipfw: limit 250 reached on entry 2300
Dec 23 08:58:25 infoway /kernel: ipfw: 3100 Accept TCP 
192.168.10.1:619
192.168.10.10:22 in via rl2
Dec 23 08:59:00 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:718

192.168.10.10:22 in via rl2
Dec 23 09:03:20 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:654
192.168.10.10:22 in via rl2
Dec 23 09:07:48 infoway /kernel: ipfw: 3100 Accept TCP 
192.168.10.1:1012
192.168.10.10:22 in via rl2
Dec 23 10:07:37 infoway /kernel: ipfw: limit 250 reached on entry 2300
Dec 23 14:11:21 infoway /kernel: ipfw: Accounting cleared.

Dec 23 15:07:30 infoway /kernel: ipfw: limit 250 reached on entry 2100
Dec 23 18:18:57 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:744

192.168.10.10:22 in via rl2
Dec 23 18:23:54 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:952
192.168.10.10:22 in via rl2
Dec 23 18:28:14 infoway /kernel: ipfw: 3100 Accept TCP 
192.168.10.1:736
192.168.10.10:22 in via rl2
Dec 23 19:28:07 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:758

192.168.10.10:22 in via rl2
Dec 23 19:36:24 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:665

192.168.10.10:22 in via rl2
Dec 23 19:37:25 infoway /kernel: ipfw: Accounting cleared.
Dec 23 19:40:26 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:982

192.168.10.10:22 in via rl2
Dec 23 19:49:19 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:686
192.168.10.10:22 in via rl2
Dec 23 20:48:00 infoway /kernel: ipfw: limit 250 reached on entry 2100

Dec 23 21:59:21 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:944
192.168.10.10:22 in via rl2
Dec 23 22:00:54 infoway /kernel: ipfw: 3100 Accept TCP 
192.168.10.1:734
192.168.10.10:22 in via rl2
Dec 23 22:01:06 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:905

192.168.10.10:22 in via rl2
Dec 23 22:07:30 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:928

192.168.10.10:22 in via rl2
Dec 23 22:07:49 infoway /kernel: ipfw: 3100 Accept TCP 192.168.10.1:985
192.168.10.10:22 in via rl2
Dec 23 22:12:21 infoway /kernel: ipfw: 3100 Accept TCP 
192.168.10.1:854
192.168.10.10:22 in via rl2
Dec 24 08:59:53 infoway /kernel: ipfw: limit 250 reached on entry 2100
Dec 24 11:57:56 infoway /kernel: ipfw: 3100 Accept TCP 
192.168.10.1:944
192.168.10.10:22 in via rl2
Dec 24 13:00:23 infoway /kernel: ipfw: limit 250 reached on entry 2200
Jan 6 10:08:25 infoway /kernel: ipfw: limit 250 reached on entry 2200

Jan 7 15:58:50 infoway /kernel: ipfw: limit 250 reached on entry 2200
Jan 7 20:12:50 infoway /kernel: ipfw: limit 250 reached on entry 2200

Ah sim, para acessar a máquina, basta estabelecer um ‘alias’ para sua placa convencional de rede, para a mesma rede 192.168.10.0 de rl2.

Exemplo: ifconfig eth0:0 192.168.10.1 up (sintaxe Linux)

Depois de terminado quaisquer trabalhos que tenha tornado isso necessário, basta remover o aliases e.. pronto, novamente invisível :-)

Lógico, todos já puderam perceber que a bridge é completamente inacessível (ou não?) a partir das rl0 e rl1, uma vez que não há um ip agregado às mesmas. Isso torna bastante difícil que haja uma ‘invasão’ da mesma :-). Contudo, o impossível é apenas algo que ainda não descobrimos como fazer, portanto.. Não existe nada seguro sob o sol, exceto a Morte :-)

Notas (quase) importantes

1 – Supôe-se que o leitor já tem instalado o FreeBSD em condições funcionais, ou que saiba fazê-lo sem problemas, ou seja, não se imagina que o usuário seja um completo leigo em FreeBSD. 2 – Não sou responsável por quaisquer danos ou perda de dados decorrentes das instruções contidas nêste artigo. O usuário deve usar estas instruções por sua conta e risco. 3 – Funciona aqui. Deverá funcionar aí. Se não funcionar aí, o problema é local, portanto, NÃO OFEREÇO SUPORTE a qualquer instalação que tenha estas instruções como base. Divirtam-se :-)

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: