Suricata IPS/inline mode with NFTABLES

assuming you got NFTABLES up and running already

assuming you installed and setup Suricata already

tested on debian buster

Requirements

suricata --build-info | grep NFQ
zcat /proc/config.gz | grep CONFIG_NETFILTER_ADVANCED
zcat /proc/config.gz | grep CONFIG_NETFILTER_NETLINK_QUEUE

and since we’re doing it with NFTABLES

zcat /proc/config.gz | grep CONFIG_NF_TABLES
zcat /proc/config.gz | grep CONFIG_NFT_QUEUE

NFTABLES

Bypass allows to forward traffic even though the daemon might be down

    chain inline {
            type filter hook forward priority 10;
            iif eth0 oif eth1 queue bypass;
            iif eth1 oif eth0 queue bypass;
    }

Startup

Using default queue 0

/usr/local/bin/suricata --init-errors-fatal --af-packet -q 0 -D

Config

Defaults are fine in suricata.yaml but you need to enable dropping within the rules

cd /etc/suricata/
cp /usr/local/lib/python3.7/dist-packages/suricata/update/configs/drop.conf .
cp drop.conf drop.conf.dist
vi drop.conf

re:heartbleed
re:MS(0[7-9]|10)-\d+
re:classtype:trojan-activity

suricata-update
grep ^drop 2024366 /var/lib/suricata/rules/suricata.rules
grep ^drop /var/lib/suricata/rules/suricata.rules | wc -l
suricatasc -c reload-rules

Acceptance

Validate with e.g. https://github.com/jamesbarlow/icmptunnel

On the server

pkill icmptunnel
ps auxww | grep icmp
icmptunnel/icmptunnel -s &
sleep 1
ifconfig tun0 10.0.0.1 netmask 255.255.255.0
ifconfig tun0

On the client

pkill icmptunnel
ps auxww | grep icmp
icmptunnel/icmptunnel ssd.nethence.com &
sleep 1
ifconfig tun0 10.0.0.2 netmask 255.255.255.0
ifconfig tun0
nmap -Pn -p 2222 10.0.0.1
ssh root@10.0.0.1 -p 2222

Results

Before

04/10/2020-23:43:02.633117  [**] [1:2024366:1] ET MALWARE OpenSSH in ICMP Payload - Possible Covert Channel [**] [Classification: A Network Trojan was detected] [Priority: 1] {ICMP} 188.130.155.61:8 -> 51.15.190.74:0

After

04/11/2020-12:21:08.932307  [Drop] [**] [1:2024366:1] ET MALWARE OpenSSH in ICMP Payload - Possible Covert Channel [**] [Classification: A Network Trojan was detected] [Priority: 1] {ICMP} 10.1.1.250:8 -> 51.15.190.74:0

Troubleshooting

==> /var/log/suricata/suricata.log <==
[941] 11/4/2020 -- 12:17:55 - (respond-reject-libnet11.c:284) <Error> (RejectSendLibnet11L3IPv4ICMP) -- [ERRCODE: SC_ERR_LIBNET_WRITE_FAILED(147)] - libnet_write_raw_ipv4 failed: libnet_write_raw_ipv4(): -1 bytes written (Message too long)

==> TODO and in the meanwhile, use drop instead of reject

Resources

\12. Setting up IPS/inline for Linux https://suricata.readthedocs.io/en/suricata-5.0.0/setting-up-ipsinline-for-linux.html

Setting up IPS/inline for Linux https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Setting_up_IPSinline_for_Linux

Logging traffic https://wiki.nftables.org/wiki-nftables/index.php/Logging_traffic

Queueing to userspace https://wiki.nftables.org/wiki-nftables/index.php/Queueing_to_userspace

Suricata and Nftables https://home.regit.org/2014/02/suricata-and-nftables/

Using NFQUEUE and libnetfilter_queue https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/

How to Configure & Use Suricata for Threat Detection https://resources.infosecinstitute.com/configure-use-suricata-threat-detection/


HOME | GUIDES | BENCHMARKS | html