Will a single NIC work for snort3 in IPS mode if pure wireless?

My router/firewall only has wireless clients connecting. The WAN port is the only one occupied with a physical cable. My question is can an IPS work?

/etc/config/network
config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config globals 'globals'
	option ula_prefix 'fd99:97d2:a14e::/48'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'

config interface 'lan'
	option device 'br-lan.10'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'
	option ip6assign '60'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'lan4'
	list ports 'lan5'
	option ipv6 '0'

config bridge-vlan
	option device 'br-lan'
	option vlan '10'
	list ports 'lan1:u*'
	list ports 'lan2:u*'
	list ports 'lan3:u*'
	list ports 'lan4:u*'
	list ports 'lan5:u*'

config bridge-vlan
	option device 'br-lan'
	option vlan '3'

config bridge-vlan
	option device 'br-lan'
	option vlan '4'

config device
	option name 'br-lan.10'
	option type '8021q'
	option ifname 'br-lan'
	option vid '10'
	option ipv6 '0'

config device
	option name 'br-lan.3'
	option type '8021q'
	option ifname 'br-lan'
	option vid '3'
	option ipv6 '0'

config device
	option name 'br-lan.4'
	option type '8021q'
	option ifname 'br-lan'
	option vid '4'
	option ipv6 '0'

config device
	option name 'eth0'
	option ipv6 '0'

config device
	option name 'eth1'
	option ipv6 '0'

config device
	option name 'lan1'
	option ipv6 '0'

config device
	option name 'lan2'
	option ipv6 '0'

config device
	option name 'lan3'
	option ipv6 '0'

config device
	option name 'lan4'
	option ipv6 '0'

config device
	option name 'lan5'
	option ipv6 '0'

config device
	option type 'bridge'
	option name 'lxcbr0'
	option bridge_empty '1'
	option ipv6 '0'

config interface 'guest'
	option proto 'static'
	option device 'br-lan.3'
	option ipaddr '192.168.3.1'
	option netmask '255.255.255.0'

config interface 'iot'
	option proto 'static'
	option device 'br-lan.4'
	option ipaddr '192.168.4.1'
	option netmask '255.255.255.0'

config interface 'lxc'
	option device 'lxcbr0'
	option proto 'static'
	option netmask '255.255.255.0'
	option ipaddr '10.0.4.1'

@efahl @xxxx

Why not? The data from and to the Internet that goes from and to the WLAN devices must also go through the firewall of the Wan port and that is exactly where my script starts and the packets are sent to Snort. Everything behind the Wan port is protected by the Ips, regardless of whether they are wifi devices or wired devices. If you are worried about the wifi encryption, this is only done afterwards, i.e. snort sees the traffic as it leaves and arrives from the device. Even in afpacket mode this works, you would only have to specify the wifi interfaces as interfaces in Snort (this is the advantage of Nfq mode, you do not need to specify new interfaces on the protected side).

1 Like

Yeah, I concur. The actual PHY shouldn't matter, you just need packets to traverse then firewall then snort can intercept packets and provide a verdict on them.

1 Like

The verdict statement recently gave me an idea. So you could have Snort analyze Https traffic without breaking the encryption. Snort would have to decrypt a copy of the packet and if it is good tell the firewall that the original can continue.

Very cool. Device is GLiNET.MT6000. 4 threads but not super powerful.

I am getting errors trying to run it with your new config setup.

# snort-mgr check
/usr/bin/snort-mgr: eval: line 125: options: parameter not set

Manually as a test:

# snort -c /etc/config/snort
--------------------------------------------------
o")~   Snort++ 3.1.82.0
--------------------------------------------------
Loading /etc/config/snort:
ERROR: /etc/config/snort: can't load /etc/config/snort: /etc/config/snort:2: '=' expected near 'snort'

--------------------------------------------------
ERROR: /etc/config/snort: Could not find requested DAQ module: pcap

FATAL: see prior 2 errors (0 warnings)
Fatal Error, Quitting..
/etc/config/snort
config snort 'snort'
	option enabled         '1'              # one of [0, 1]
	option manual          '0'              # one of [0, 1]
	option oinkcode        ''               # a string
	option home_net        '192.168.1.0/24 192.168.3.0/24' # a string
	option external_net    '!$HOME_NET'            # a string
	option config_dir      '/etc/snort'     # a path string
	option temp_dir        '/var/snort.d'   # a path string
	option log_dir         '/var/log'       # a path string
	option logging         '1'              # one of [0, 1]
	option openappid       '0'              # one of [0, 1]
	option mode            'ips'            # one of [ids, ips]
	option method          'nfq'           # one of [pcap, afpacket, nfq]
	option action          'drop'        # one of [default, alert, block, drop, reject]
	option interface       'eth1'           # a string
	option snaplen         '1518'           # 1518 <= x <= 65535
	option include         '/etc/snort/include.snort'               # a path string

config nfq 'nfq'
	option queue_count     '4'              # 1 <= x <= 16
	option queue_start     '4'              # 1 <= x <= 32768
	option queue_maxlen    '8192'           # 1024 <= x <= 65536
	option fanout_type     'lb'           # one of [hash, lb, cpu, rollover, rnd, qm]
	option thread_count    '4'              # 0 <= x <= 32
	option chain_type      'postrouting'          # one of [prerouting, input, forward, output, postrouting]
	option chain_priority  '300'         # one of [raw, filter, 300]
	option include         '/etc/snort/include.nfq'               # a path string
/etc/snort/include.snort
-- Disable output to syslog
alert_syslog = nil
alert_json = nil

-- Enable output to alert_fast.txt
alert_fast = {
  file = true,
  packet = false,
}

network = {
  checksum_eval = 'none',
}
/etc/snort/include.nfq
    ct state invalid drop;
    oifname "{{ snort.interface }}" tcp flags ack ct state established counter accept
1 Like

Please post the snort.lua it looks like a syntax error in it. I say it was not a good idea to do everything via the snort.lua. Apart from that the code of efahl is outdated the Nfq script which integrates Snort into the firewall has undergone important updates.

//edit/ I see your problem you are trying to pass the config file from efahls script to snort this does not work of course you have to specify the snort.lua as config file snort -c /etc/config/snort.lua

Ah! I did not modify /etc/snort/snort.lua at all. Why does snort-mgr check fail? @efahl

# snort -c /etc/snort/snort.lua 
--------------------------------------------------
o")~   Snort++ 3.1.82.0
--------------------------------------------------
Loading /etc/snort/snort.lua:
Loading snort_defaults.lua:
Finished snort_defaults.lua:
	ssh
	hosts
	host_cache
	pop
	so_proxy
	stream_tcp
	mms
	smtp
	ftp_data
	gtp_inspect
	packets
	dce_http_proxy
	stream_icmp
	normalizer
	ips
	process
	binder
	stream_udp
	wizard
	appid
	js_norm
	alerts
	file_id
	http2_inspect
	http_inspect
	dce_smb
	ftp_server
	port_scan
	dce_http_server
	dce_tcp
	telnet
	iec104
	cip
	modbus
	ssl
	sip
	host_tracker
	rpc_decode
	netflow
	stream_user
	back_orifice
	stream_ip
	classifications
	dnp3
	active
	ftp_client
	decode
	search_engine
	stream
	network
	references
	arp_spoof
	output
	trace
	dns
	dce_udp
	imap
	file_policy
	s7commplus
	daq
	stream_file
Finished /etc/snort/snort.lua:
Loading file_id.rules_file:
Loading file_magic.rules:
Finished file_magic.rules:
Finished file_id.rules_file:
--------------------------------------------------
ips policies rule stats
              id  loaded  shared enabled    file
               0     208       0     208    /etc/snort/snort.lua
--------------------------------------------------
rule counts
       total rules loaded: 208
               text rules: 208
            option chains: 208
            chain headers: 1
--------------------------------------------------
service rule counts          to-srv  to-cli
                  file_id:      208     208
                    total:      208     208
--------------------------------------------------
fast pattern groups
                to_server: 1
                to_client: 1
--------------------------------------------------
search engine (ac_bnfa)
                instances: 2
                 patterns: 416
            pattern chars: 2508
               num states: 1778
         num match states: 370
             memory scale: KB
             total memory: 68.5879
           pattern memory: 18.6973
        match list memory: 27.3281
        transition memory: 22.3125
appid: MaxRss diff: 2844
appid: patterns loaded: 300
--------------------------------------------------
ERROR: Could not find requested DAQ module: pcap

FATAL: see prior 1 errors (0 warnings)
Fatal Error, Quitting..

It doesn't find the daq, it's best to remove everything again and set everything up manually without the efahls script. Something is going very wrong because the daq mode should be nfq and not pcap. You could of course force the correct daq mode with --daq-dir /usr/lib/daq --daq nfq but I'm afraid there are more problems.

Let’s allow Eric to weigh in… he script is front and center now and should work.

You are right but the script would have to be revised in general because some things are no longer correct and it is generally better to control snort with parameters because they have priority and only use a general snort.lua.

Blah, that's a bug I've been sitting on for a couple months waiting for https://github.com/openwrt/packages/pull/23412 to get merged.

Edit /usr/bin/snort-mgr at 57 and 121, change

        local options
to
        local options=''

Otherwise your config looks good to me!

2 Likes

Can't wait forever, so I pushed the PR: https://github.com/openwrt/packages/pull/23859

Thanks @efahl. I have it working on the device. I have a RPi4B connected via an ethernet cable and my test rule dropping pings is enforced so 1 NIC works.

Do I need /etc/snort/include.nfq? I have the option for it commented out in /etc/config/snort and IPS mode works.

Excellent! :+1:t3:

What you posted above is pretty much just an optimization, it bypasses already-known flows directly, so it should work just fine with or without it. You might want to measure throughput and see if there's any detectable difference, but it looks like it shouldn't impact things very much if at all (and ct invalid packets are so rare that the first line is probably never fired anyhow).

Thanks! I am CPU-bound on downloads. Bandwidth is capped to approx 100 Mbps due to 100% CPU load on a single core. This device is using VLANs/subsets. When I define only my guest IP range, I still see CPU saturation due to snort on the RPi4B which is assigned 192.168.1.101 ... why?

  option home_net        '192.168.3.0/24' # a string

EDIT: I did see this in the logread output:

Tue Apr  9 16:06:41 2024 kern.warn kernel: [346767.429488] net_ratelimit: 2020 callbacks suppressed
Tue Apr  9 16:06:41 2024 kern.warn kernel: [346767.429502] nfnetlink_queue: nf_queue: full at 1024 entries, dropping packets(s)
Tue Apr  9 16:06:41 2024 kern.warn kernel: [346767.442197] nfnetlink_queue: nf_queue: full at 1024 entries, dropping packets(s)
Tue Apr  9 16:06:41 2024 kern.warn kernel: [346767.449737] nfnetlink_queue: nf_queue: full at 1024 entries, dropping packets(s)
Tue Apr  9 16:06:41 2024 kern.warn kernel: [346767.457268] nfnetlink_queue: nf_queue: full at 1024 entries, dropping packets(s)
...

Is that to blame? Can I increase the value from 1024 to something larger?

Actually this shouldn't be the case because in your /etc/config/snort the option maxlen is already '8192' , see if it has copied it into the snort.lua. By the way, you also have to increase the value of snaplen '1518' to 65531 otherwise snort will only process the beginning of the packets.

@efahl could you please update the firewall integration of the queue to the latest version, the old code does not protect the data input to the router itself.

I’d like to snort. Should I?

Why is CPU usage so high?

SNORT is popular today!

I think asking the threads be merged is a bit much so I just linked them.

@xxxx any idea why the CPU hits 100% for the subnet I have not defined? I would expect those packets to not go through snort at all.

I have not read the whole thread:
have you enabled packet steering?

And how are you determining 100% cpu usage?

You have also defined external net correctly with EXTERNAL_NET = "!$HOME_NET" ? Otherwise I would need more information. But there is also the possibility that the thread scheduler lets snort switch too much over the cpu threads, which had the effect that the core 0 regularly went to 100% under load because it had other tasks, I have eliminated this by pinning snort with maximum priority via nice and taskset to the cpus 1 to 3.

/edit// oh yes, you should also activate the Hyperscan search engine if you have not already done so.