Por: @jonasc
Publicado em: 2021-06-06
Snort IDS/IPS com DAQ NFQUEUE
O Snort usa o LibDAQ como uma camada de abstração para interação com fontes de dados diferentes, como por exemplo, uma interface de rede, uma arquivo pcap, entre outros. Esta é a bibioteca responsável por intermediar a intercepção de tráfego e fornecimento dos dados necessários para o Snort. O DAQ possui alguns módulos disponíveis com diferentes comportamentos.
O LAB Snort IPS implementou a forma mais simples de aplicar o IPS usando o módulo afpacket
em modo inline
. Este é um formato mais simples, que não requer conhecimento aprofundado de roteamento ou regras de firewall (iptables), basta apenas informar um par de interfaces LAN e WAN (entrada e saída) que o snort cria uma bridge entre os devices e faz todo o controle necessário. Desvantagem do modo inline: Em um ambiente com 2 links é necessário configurar 2 processos do snort (LAN+WAN1 e LAN+WAN2). Outro problema é que o Snort intercepta e analisa todo o tráfego de rede, não sendo possível ativar em regras de firewall específicas, somente em interfaces de rede selecionadas.
Este laboratório irá focar na implementação do Snort 3 como IPS usando o DAQ com módulo nfq
em modo inline
. O NFQUEUE é um recurso do iptables que permite direcionar um tráfego específico para uma fila, até que alguma ação seja executada e o tráfego possa ser liberado/roteado ou descartado. Ou seja, é possível que regras de firewall iptables específicas sejam direcionadas para análise do Snort.
Topologia
Topologia de rede padrão com FWFLEX sobre CentOS 8 e IDS funcional, seguindo o labratório Snort IDS.
Instalação
Para funcionamento do NFQ no Snort 3, no momento da compilação é necessário fornecer algumas dependências. Em adição aos pacotes de dependência já instalados no LAB de IDS, é necessário instalar o libmnl-devel
:
yum install libmnl libmnl-devel libnfnetlink libnfnetlink-devel libnetfilter_queue libnetfilter_queue-devel
OBS: Os demais pacotes acima também são dependência, mas já estavam instalados devido ao LAB de IDS e também ao firewall iptables básico já estar configurado.
Após suprir a dependência, é necessário recompilar o LibDAQ:
cd /usr/src/sources/libdaq/
./bootstrap
./configure
make
make install
ldconfig
Após executar ./configure
é possível validar se foi possível realizar o build do NFQ:
Build AFPacket DAQ module.. : yes
Build BPF DAQ module....... : yes
Build Divert DAQ module.... : no
Build Dump DAQ module...... : yes
Build FST DAQ module....... : yes
Build NFQ DAQ module....... : yes
Build PCAP DAQ module...... : yes
Build netmap DAQ module.... : no
Build Trace DAQ module..... : yes
Com NFQ suportado, basta seguir para as configurações.
Configuração do IPS com NFQ
Configurando mode inline
para ativar o IPS na seção ips
em /usr/local/snort/etc/snort/snort.lua
:
ips =
{
mode = inline,
-- use this to enable decoder and inspector alerts
--enable_builtin_rules = true,
-- use include for rules files; be sure to set your path
-- note that rules files can include other rules files
--include = 'snort3-community.rules',
variables = default_variables,
rules = [[
include $RULE_PATH/snort3-community.rules
include $RULE_PATH/itflex-custom.rules
]]
}
OBS: A configuração acima é igual tanto usando o afpacket
quanto o daq
.
Configurando a biblioteca DAQ para usar IPS na seção daq
em /usr/local/snort/etc/snort/inline.lua
:
daq =
{
inputs = { '4' },
module_dirs =
{
'/usr/local/lib/daq/',
},
modules =
{
{
name = 'nfq',
mode = 'inline'
}
}
}
Na configuração acima foi especificado como INPUT a QUEUE número 4 do iptables e também especificado o módulo nfq
em modo inline
.
Somente usando esta configuração, o Snort trabalha o DAQ com NFQ em modo passivo, ou seja, funciona apenas como IDS. Para ativar o modo ativo, é necessário editar a unit do systemd em /etc/systemd/system/snort.service
adicionar o parâmetro -Q
:
[Unit]
Description=Snort 3 Intrusion Detection and Prevention service
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/local/snort/bin/snort -c /usr/local/snort/etc/snort/snort.lua --plugin-path /usr/local/snort/extra -l /var/log/snort -D -u snort -g snort --create-pidfile -k none -Q
ExecReload=/bin/kill -SIGHUP $MAINPID
User=snort
Group=snort
Restart=on-failure
RestartSec=5s
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_IPC_LOCK
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_IPC_LOCK
[Install]
WantedBy=multi-user.target
Ativando o IPS:
systemctl daemon-reload
systemctl restart snort
Para analisar mais de uma QUEUE, é necessário mudar a linha inputs
em /usr/local/snort/etc/snort/inline.lua
:
inputs = { '4', '5' },
Também é necessário configurar para o Snort ativar 2 threads. Necessário adicionar -z 2
no parâmetro de comando da unit em /etc/systemd/system/snort.service
:
ExecStart=/usr/local/snort/bin/snort -c /usr/local/snort/etc/snort/snort.lua --plugin-path /usr/local/snort/extra -l /var/log/snort -D -u snort -g snort --create-pidfile -k none -Q -z 2
Atualizando novamente as configurações:
systemctl daemon-reload
systemctl restart snort
Neste ponto, o Snort está analisando como INPUT todo tráfego que o iptables está direcionando para as QUEUEs 4 e 5.
Configuração de Regras do iptables
Basta configurar para que uma regra de encaminhamento comum seja direcionada para uma QUEUE do iptables:
iptables -I FORWARD -j NFQUEUE --queue-num=4
iptables -I FORWARD -d 8.8.8.8 -j NFQUEUE --queue-num=5
Com os parâmetros acima, caso ocorra erro ou snort esteja parado, o tráfego será descartado, pois o QUEUE não faz return. É possível ativar bypass:
iptables -I FORWARD -j NFQUEUE --queue-num=4 --queue-bypass
OBS: Bypass não é o mesmo que return. Significa aceitar imediatamente o tráfego. Por exemplo, mesmo tendo um DROP imediatamente abaixo do bypass, este não tem efeito algum:
[root@lab-snort-ips.itflex.local snort]# iptables -nvL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 360 NFQUEUE all -- * * 0.0.0.0/0 0.0.0.0/0 NFQUEUE num 4 bypass
1 60 DROP all -- * * 0.0.0.0/0 0.0.0.0/0
Testes
Regras usadas para simulação em itflex-custom.rules
:
drop icmp any any -> 8.8.8.8 any (
msg:”TESTE ICMP”;
sid:1000001;
rev:1;
classtype:icmp-event;
)
alert icmp any any -> any any (
msg:”TESTE ICMP”;
sid:1000002;
rev:1;
classtype:icmp-event;
)
pass icmp any any -> 1.1.1.1 any (
msg:”TESTE ICMP”;
sid:1000003;
rev:1;
classtype:icmp-event;
)
Testes executados:
$ ping 1.1.1.1
$ ping 8.8.8.8
$ ping 8.8.4.4
Host 1.1.1.1 liberado sem gerar log, 8.8.4.4 liberado gerando alerta e 8.8.8.8 bloqueado gerando alerta.
Resultados
Ponto positivo: Mostrou que atende bem a necessidade de ativar IPS em regra de firewall específica e permitiu configuração de múltiplos threads. Ponto preocupante: Qualquer problema com Snort, a QUEUE descarta o tráfego ou faz bypass (libera). Não possui return.