Project

General

Profile

Actions

Bug #13920

closed

23.01RC - Suricata stops working after Wireguard installed

Added by Greger Blennerud almost 2 years ago. Updated almost 2 years ago.

Status:
Resolved
Priority:
Normal
Assignee:
-
Category:
Suricata
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Plus Target Version:
Affected Version:
Affected Plus Version:
Affected Architecture:
amd64

Description

Upgraded to 23.01RC from 22.05 without any packages installed. Current base system shown as 23.01.r.20230202.0019

Installed Suricata (from scratch) and set it up exactly as I have had it before.
When installing Wireguard, Suricata stops working.

The error it show in the suricata.log file is:

<Info> -- alert-pf > Added IPv4 address 1.0.0.3/32 from assigned Pass List.
<Info> -
alert-pf > Added IPv4 address 1.1.1.1/32 from assigned Pass List.
<Error> -
[ERRCODE: SC_ERR_FATAL(171)] - prefix or user NULL

The next IP in the passlist file (/usr/local/etc/suricata/suricata_18023_igb1/passlist) is the Tunnel IP's for the peers in Wireguard.
10.6.210.0/31
10.6.250.0/31

Removing Wireguard package allows Suricata to go through with the passlist and it starts up again...

Actions #1

Updated by Jim Pingle almost 2 years ago

  • Project changed from pfSense to pfSense Packages
  • Category changed from Configuration Upgrade to Suricata
  • Priority changed from High to Normal
  • Release Notes deleted (Default)
Actions #2

Updated by Bill Meeks almost 2 years ago

I might need some assistance from the Netgate wireguard guru on this one. I don't have a functioning wireguard package setup in my test environment.

The problem is likely coming at line 4299 in the file /usr/local/pkg/suricata/suricata.inc. Here is the code area:

    /* WireGuard */
    if (function_exists('wg_get_tunnel_networks')) {
        foreach (wg_get_tunnel_networks() as $wgn) {
            $vpns_arr[] = $wgn;
        }
    }

The Suricata code is expecting a valid IP subnet or IP address to add to its array of VPN addresses that are to be added to the default Pass List (so they will not be blocked). This code is part of a function contributed by Viktor Gurov before he left. The same function was added to both the Suricata and Snort packages.

Actions #3

Updated by Christian McDonald almost 2 years ago

Hi,

I'll have a look. Might not be this week, but definitely next week.

Actions #4

Updated by Bill Meeks almost 2 years ago

Christian McDonald wrote in #note-3:

Hi,

I'll have a look. Might not be this week, but definitely next week.

Thanks Christian. If you have some questions just let me know. I can tell you what Suricata is expecting.

Actions #5

Updated by Bill Meeks almost 2 years ago

Looking into this deeper, I suspect there is potentially an issue with the custom blocking plugin used with the Suricata binary on pfSense. That plugin inserts IP addresses from the Pass List into an internal Radix Tree maintained by Suricata. With certain IP address and subnet combinations, the Radix Tree insertion is not being handled correctly. This is likely due to changes in both the Suricata binary and the custom blocking plugin between Suricata 6.0.4 which is used in current pfSense RELEASE branches and Suricata 6.0.8 which is used in the new DEVEL and RC snapshots.

I will continue to investigate.

Actions #6

Updated by Greger Blennerud almost 2 years ago

I decided to do some more testing and discovered some wierd issues with the passlist.

First of all, I get a discrepancy between what Suricata reports to be doing, like adding an IP to the passlist, and what it then shows when "Loading and parsing passlist."

Going to Interfaces > myVPN (tun_wg0) and changing the IP to e.g. 192.n.n.n or 172.n.n.n the log shows the following:

adding firewall interface tun_wg0 IPv4 address 172.6.210.0 to automatic interface IP Pass List.
adding firewall interface tun_wg1 IPv4 address 192.168.250.0 to automatic interface IP Pass List.
output device (regular) initialized: block.log
Loading and parsing Pass List from: /usr/local/etc/suricata/suricata_28603_vtnet1/passlist.
Added IPv4 address 8.8.8.8/32 from assigned Pass List.

This is where it stopped earlier

Added IPv4 address 10.6.210.0/31 from assigned Pass List.
Added IPv4 address 10.6.250.0/31 from assigned Pass List.
Added IPv4 address 127.0.0.1/32 from assigned Pass List.

Suricata now works it's way through and actually starts. However it does throw the same PHP error as before.

The actual list found in /usr/local/etc/suricata/suricata_28603_vtnet1 never changes, no matter what changes I make in Interfaces or inside Wireguard.

Manually removing it and restarting Suricata results in a crash, it does not seem to be created or changed? Rebooting makes no difference...

Manually editing the list and setting the same IP's as the interface has, AND using mask /31 in the passlist, will result in Suricata not starting with the same fault reported as before during parsing:
<Error> -- [ERRCODE: SC_ERR_FATAL(171)] - prefix or user NULL

Using mask /32 in the passlist allows it to continue through, regardless of the interface having the mask /31.
Then making a change in the Interface and clicking Save Changes gives the following in suricata.log

Received notification of IP address change on firewall interface tun_wg1.
deleted address 10.6.250.0 from automatic firewall interface IP Pass List.
Received notification of IP address change on firewall interface tun_wg1.
added address 10.6.250.0 to automatic firewall interface IP Pass List.

And then the error shows up:
PHP ERROR: Type: 1, File: /usr/local/pkg/suricata/suricata.inc, Line: 4310, Message: Uncaught TypeError: Cannot access offset of type string on string in /usr/local/pkg/suricata/suricata.inc:4310
Stack trace:
#0 /usr/local/pkg/suricata/suricata.inc(599): suricata_get_vpns_list()
#1 /usr/local/pkg/suricata/suricata_generate_yaml.php(46): suricata_build_list(Array, 'default')
#2 /usr/local/pkg/suricata/suricata.inc(3800): include('/usr/local/pkg/...')
#3 /usr/local/pkg/suricata/suricata.inc(933): suricata_generate_yaml(Array)
#4 /etc/inc/pkg-utils.inc(715) : eval()'d code(1): sync_suricata_package_config()
#5 /etc/inc/pkg-utils.inc(715): eval()
#6 /etc/rc.start_packages(66): sync_package('suricata')
#7 {main}
thrown @ 2023-02-04 14:09:51

Actions #7

Updated by Bill Meeks almost 2 years ago

Greger Blennerud wrote in #note-6:

The actual list found in /usr/local/etc/suricata/suricata_28603_vtnet1 never changes, no matter what changes I make in Interfaces or inside Wireguard.

The Pass List file you see in the interface subdirectory is recreated each time you save a change within the Suricata GUI or start/restart Suricata from within the GUI. Suricata only reads that file once during startup. The file is not dynamically processed.

Manually removing it and restarting Suricata results in a crash, it does not seem to be created or changed? Rebooting makes no difference...

Suricata can also be started by the shell script in /usr/local/etc/rc.d/suricata.sh . That script simply starts the daemon using the "existing" configuration found in the interface's subdirectory under /usr/local/etc/suricata/xxx . The shell script is called to start Suricata following a firewall reboot.

Manually editing the list and setting the same IP's as the interface has, AND using mask /31 in the passlist, will result in Suricata not starting with the same fault reported as before during parsing:
<Error> -- [ERRCODE: SC_ERR_FATAL(171)] - prefix or user NULL

Using mask /32 in the passlist allows it to continue through, regardless of the interface having the mask /31.
Then making a change in the Interface and clicking Save Changes gives the following in suricata.log

Received notification of IP address change on firewall interface tun_wg1.
deleted address 10.6.250.0 from automatic firewall interface IP Pass List.
Received notification of IP address change on firewall interface tun_wg1.
added address 10.6.250.0 to automatic firewall interface IP Pass List.

The root problem is an issue within the Suricata binary, and more specifically, within the custom blocking plugin created for use on pfSense. That plugin uses the built-in Radix Tree API within the Suricata binary to store Pass List IP addresses and/or subnets. That code is not properly handling a /31 subnet mask resulting in the SC_ERR_FATAL error from Suricata when it fails to start. If you can reconfigure your WG tunnels to use a /30 subnet mask instead of /31, that should work around the issue until the Suricata binary can be patched.

And then the error shows up:
PHP ERROR: Type: 1, File: /usr/local/pkg/suricata/suricata.inc, Line: 4310, Message: Uncaught TypeError: Cannot access offset of type string on string in /usr/local/pkg/suricata/suricata.inc:4310
Stack trace:
#0 /usr/local/pkg/suricata/suricata.inc(599): suricata_get_vpns_list()
#1 /usr/local/pkg/suricata/suricata_generate_yaml.php(46): suricata_build_list(Array, 'default')
#2 /usr/local/pkg/suricata/suricata.inc(3800): include('/usr/local/pkg/...')
#3 /usr/local/pkg/suricata/suricata.inc(933): suricata_generate_yaml(Array)
#4 /etc/inc/pkg-utils.inc(715) : eval()'d code(1): sync_suricata_package_config()
#5 /etc/inc/pkg-utils.inc(715): eval()
#6 /etc/rc.start_packages(66): sync_package('suricata')
#7 {main}
thrown @ 2023-02-04 14:09:51

Just to be clear on this PHP error. I think you are getting that because you made an edit I suggested to one of the PHP source files ( /usr/local/etc/suricata/suricata.inc ). You need to revert that edit to get rid of the PHP error. The code I provided is incorrect. I mentioned this in one of my replies to you in the Netgate Forum thread about this issue.

Actions #8

Updated by Greger Blennerud almost 2 years ago

Bill Meeks wrote in #note-7:

Just to be clear on this PHP error. I think you are getting that because you made an edit I suggested to one of the PHP source files ( /usr/local/etc/suricata/suricata.inc ). You need to revert that edit to get rid of the PHP error. The code I provided is incorrect. I mentioned this in one of my replies to you in the Netgate Forum thread about this issue.

I actually thought I changed it back but perhaps not... Anyway, changing the subnet mask to /30 works so now I have 23.01 up an running with Suricata as well.

Actions #9

Updated by Bill Meeks almost 2 years ago

The fix for this issue requires an update to the custom blocking plugin compiled into the Suricata binary on pfSense. That fix is ready but will not be deployed until after pfSense Plus 23.01 goes to RELEASE. This is to minimize changes during the final testing phase of the 23.01 RC branch.

In the interim, the issue can easily be worked around by choosing a /30 subnet mask as the minimum size. The OP was using a /31 on the Wireguard tunnels.

Actions #10

Updated by Bill Meeks almost 2 years ago

The final fix for this issue is contained in pull request #1226 posted for review and merge. The request may be viewed here: https://github.com/pfsense/FreeBSD-ports/pull/1226. Some changes were made in how the custom blocking plugin used for Legacy Mode Blocking processes a user-supplied Pass List. The plugin now handles IP address and IP subnets differently, and tests before attempting to insert a new entry into the Radix Tree to see if the new entry is covered by an already existing Radix Tree network.

After the pull request is merged, this issue can be marked "resolved".

Actions #11

Updated by Jim Pingle almost 2 years ago

  • Status changed from New to Resolved

PR merged. Will be in builds soon.

Actions

Also available in: Atom PDF