[FUG-BR] RES: Filtro L7

Patrick Tracanelli eksffa em freebsdbrasil.com.br
Segunda Novembro 26 12:33:59 BRST 2007


Vou tentar resumir o ambiente que eu uso pra filtrar L7, aja que a 
thread esta bem grande.

Instale via ports o snort_inline, e entao configure o snort_inline.conf 
com algo proximo a isso (pode comecar com isso e depois customizar):

### Network variables
var HOME_NET [192.168.0.0/16,10.0.0.0/8,200.X.Y.0/22]
#var HOME_NET any
var HONEYNET any
var EXTERNAL_NET any
var SMTP_SERVERS any
var TELNET_SERVERS any
var HTTP_SERVERS any
var SQL_SERVERS any
var HTTP_PORTS 80
var SHELLCODE_PORTS !80
var ORACLE_PORTS 1521
var DNS_SERVERS any
var SSH_PORTS 22 2222 2022

#config checksum_mode: all
config ipfw_reinject_rule: 65500

var RULE_PATH /usr/local/share/snort_inline/rules

preprocessor flow: stats_interval 0 hash 2
output alert_fast: inline_fast

include /usr/local/share/snort_inline/classification.config
include /usr/local/share/snort_inline/reference.config
#include /usr/local/share/snort_inline/rules/classification.config

include $RULE_PATH/FBSDBR/patrick.rules
include $RULE_PATH/FBSDBR/patrick-p2p-drop.rules

include $RULE_PATH/p2p.rules
include $RULE_PATH/bleeding-p2p.rules

Na regra 65500 u tenho um "add count tag 30 all from any to any keep-state"

E logo abaixo faco queue (Wf2Q+) de tudo "tagged 30". Um pipe obviamente 
também serve.

No comeco de tudo, faca um "skipto 65500 all from any to any tagged 30".

As dicas são:

- resuma seu firewall a regras antes da 65500, de forma que nada que nao 
for desviado/reinjetado para 65500 jamais chegue nela (ou seja: "add 
65499 deny all from any to any" pra ter a politica antes desse pool 
final de regras. Desvie para a 65500 apenas pelo snort_inline - o .conf 
acima ja esta configurado pra isso);

- desvie para o snort_inline o trafego desejado, NO MOMENTO que voce 
jugar necessario: comece com "divert 8000 all from any to any" pra 
testes, depois seja seletivo: "divert 8000 all from $minharede to any 
out", "divert 8000 all from any to $minharede in"

- lembre-se que apos o desvio 2 coisas acontecem: se o snort_inline nao 
classificar o pacote com as regras carregadas, o pacote volta pra 
proxima regra do firewall, se bater com as regras, o pacote sera 
reinjetado para a ipfw_reinject_rule configurada;

- porque usar "tag" e "count" e "keep-state"? porque voce nao quer 
permitir, nem negar, nem ja jogar pro controle de banda, apenas aquele 
pacote; voce quer com base no pacote conhecer a sessao toda 
(keep-state), e taggear *todos* os pacotes da sessao, e depois manipula-los

Por ultimo, eleve o net.inet.ip.fw.dyn_udp_lifetime, eu uso-o em 300 sem 
  dó (sim, 5 minutos).

Agora algumas considerações:

- SANS Security recomenda que toda analise de payload nao seja feita 
pelo firewall, e preferencialmente seja feita por aplicacoes de 
userlevel pois se comprometidas nao desestabiliza o sistema (ao 
contrario de analise me kernel);

- O custo de desviar pra uma aplicacao de userland com divert em relacao 
ao processamento que seria feito se fosse em kernel, é de 2 syscall para 
os pacotes nao classificados (praticamente todos) e 3 syscall para os 
classificados; isso realmente gera impacto no seu ambiente?

- O custo de processamento do snort_inline, que atua de forma pró-ativa 
(veja bem: snort convencional: passivo, snort com flexresp: responsivo, 
snort com snortsam ou OSSEC evocando rotinas externas: resposta ativa, 
snort_inline = pró-ativo pois se o snort não reinjetar, não volta pro 
firewall e consequentemente não volta pra pilha IP) é no máximo 5% 
superior ao snort atuando em modo passivo. Você não tem CPU suficiente 
para o snort com meia duzia de rules seletivas?

Por último, algumas considerações adicionais:

- Impacto negativo: você está desviando um dado fluxo para o 
snort_inline, isso quer dizer que se não tive nada ouvindo na porta 8000 
  protocolo div4, aquele fluxo vai pra /dev/null (ou seja, tudo para); 
mas o snort_inline nunca morre sozinho; se mesmo assim você tem medo: 
daemontools pra que te quero.

- Você pode anular o ponto negativo anterior trocando "divert" por "tee" 
na regra de firewall. Nesse caso uma cópia vai para o snort_inline e 
outra, do pacote, fica no firewall. Portanto voce vai querer repensar 
seu firewall pra copia q fica nao cair num "allow" antes de cair no seu 
controle de banda. Dica: skipto vai resolver.

- Funciona 100%? Não! Digamos, uns 70%. Porque? Porque tem alguns P2P 
que detectamos via TCP mas o tráfego vai por UDP. Nesse caso precisaria 
de um tipo de "keep-state" no firewall que mantesse a sessão apenas por 
IP, sem se ligar em porta ou protocolo. Ai sim funcionaria 
perfeitamente. Tai algo q mereceria ser investigado e feito no ipfw.

- Eu amenizei todas as situações onde os "30%" q nao funcionava era um 
problema analisando com tcpdump os trafegos e criando minhas proprias 
regras. Ai que mora outra vantagem: regras snort, nada mais facil de fazer.

Finalmente, consideracoes de experiencia propria:

- Nessa mauqina:

# dmesg | grep "CPU:\|memory"
CPU: Intel(R) Core(TM)2 CPU         T7200  @ 2.00GHz (2010.15-MHz 
686-class CPU)
real memory  = 1072103424 (1022 MB)
avail memory = 1031237632 (983 MB)

Eu filtro 34Mbit/s, load avg dela nesse momento:

load averages: 0,98 1,23 1,22

Latencia maxima percebida com divert pro snort_inline, comparado com sem 
o divert, foi de 83ms. Não é pouco. Mas para internet não é 
significativo. Essa é a máxima, a latencia média é inferior a 20ms.

Ultima consideração: H323 não funciona!! Não descobri o porque, o pacote 
é reinjetado numa boa, mas não passa nada H323 depois do divert. Ta 
certo que H323 é um lixo, mas as vezes esse lixo na sua rede não pode 
ser substituído por RTP. Foi o meu caso. A solução foi permitir o 
tráfego H.323 pro meu gatekeeper antes do divert.

Bom, essa é a melhor abordagem que eu conheço, funcional, e a que eu uso 
- portanto a que eu recomendo. Espero que lhes seja útil.

-- 
Patrick Tracanelli

FreeBSD Brasil LTDA.
Tel.: (31) 3516-0800
316601 em sip.freebsdbrasil.com.br
http://www.freebsdbrasil.com.br
"Long live Hanin Elias, Kim Deal!"



Mais detalhes sobre a lista de discussão freebsd