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.