Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Topics - RamSense

#1
Hi,

I am running OPNsense:

OPNsense 26.7.2_2-amd64
FreeBSD 15.1-RELEASE-p2
OpenSSL 3.5.7

With Suricata IPS in Divert mode and Hyperscan.

There is currently an open OPNsense issue describing an intermittent deadlock during a live Suricata rule reload with SIGUSR2 in this configuration:
https://github.com/opnsense/core/issues/10416

The stock scheduled IDS rule update currently follows this path:


rule-updater.py
installRules.py
pkill -USR2 suricata

The workaround described in the issue is to update/install the rules and then perform a full Suricata restart instead of entering the problematic live-reload path.

I wanted to keep automatic rule updates, but add some safeguards around that workaround.

The wrapper below prevents concurrent runs with lockf, uses OPNsense's own rule updater and installer, backs up the active ruleset, skips an unnecessary restart when the active rules did not change, validates the new rules before restarting, performs a full restart without SIGUSR2, checks whether the Divert listeners return, and restores the previous active ruleset if validation/startup fails.

This is a temporary workaround, not an upstream fix.

1. Create the update wrapper

Create:
/usr/local/sbin/suricata-safe-update

contents:
#!/bin/sh

set -u

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
export PATH

TAG="suricata-safe-update"

UPDATER="/usr/local/opnsense/scripts/suricata/rule-updater.py"
INSTALLER="/usr/local/opnsense/scripts/suricata/installRules.py"
SURICATA="/usr/local/bin/suricata"
CONFIG="/usr/local/etc/suricata/suricata.yaml"
RC="/usr/local/etc/rc.d/suricata"

ACTIVE_DIR="/usr/local/etc/suricata/opnsense.rules"
ACTIVE_YAML="/usr/local/etc/suricata/installed_rules.yaml"

BACKUP_DIR=""

logmsg()
{
    logger -t "$TAG" "$*"
    echo "$TAG: $*"
}

active_hash()
{
    {
        if [ -d "$ACTIVE_DIR" ]; then
            find "$ACTIVE_DIR" -type f -name '*.rules' -print 2>/dev/null |
                sort |
                while IFS= read -r f; do
                    printf '%s ' "$f"
                    sha256 -q "$f"
                done
        fi

        if [ -f "$ACTIVE_YAML" ]; then
            printf '%s ' "$ACTIVE_YAML"
            sha256 -q "$ACTIVE_YAML"
        fi
    } | sha256 -q
}

divert_count()
{
    sockstat 2>/dev/null |
        awk '$2 == "suricata" && $5 == "div4" && $6 == "*:8000" { n++ }
             END { print n + 0 }'
}

restore_active()
{
    logmsg "restoring previous active ruleset"

    rm -rf "$ACTIVE_DIR"

    if [ -d "$BACKUP_DIR/opnsense.rules" ]; then
        cp -a "$BACKUP_DIR/opnsense.rules" "$ACTIVE_DIR"
    fi

    if [ -f "$BACKUP_DIR/installed_rules.yaml" ]; then
        cp -p "$BACKUP_DIR/installed_rules.yaml" "$ACTIVE_YAML"
    else
        rm -f "$ACTIVE_YAML"
    fi
}

cleanup()
{
    if [ -n "${BACKUP_DIR:-}" ] && [ -d "$BACKUP_DIR" ]; then
        rm -rf "$BACKUP_DIR"
    fi
}

trap cleanup EXIT HUP INT TERM

for f in "$UPDATER" "$INSTALLER" "$SURICATA" "$CONFIG" "$RC"; do
    if [ ! -e "$f" ]; then
        logmsg "ABORT: required file missing: $f"
        exit 10
    fi
done

if ! "$RC" status >/dev/null 2>&1; then
    logmsg "ABORT: Suricata is not running"
    exit 11
fi

OLD_DIVERT=$(divert_count)

if [ "$OLD_DIVERT" -lt 1 ]; then
    logmsg "ABORT: no active Suricata Divert listeners found"
    exit 12
fi

OLD_PID=$(cat /var/run/suricata.pid 2>/dev/null || true)
BEFORE=$(active_hash)

logmsg "starting rule update; current PID=$OLD_PID divert_listeners=$OLD_DIVERT"

"$UPDATER"
rc=$?

if [ "$rc" -ne 0 ]; then
    logmsg "FAILED: rule-updater.py rc=$rc"
    exit "$rc"
fi

BACKUP_DIR=$(mktemp -d /root/suricata-safe-update.XXXXXX)

if [ -d "$ACTIVE_DIR" ]; then
    cp -a "$ACTIVE_DIR" "$BACKUP_DIR/opnsense.rules"
fi

if [ -f "$ACTIVE_YAML" ]; then
    cp -p "$ACTIVE_YAML" "$BACKUP_DIR/installed_rules.yaml"
fi

logmsg "installing updated rules"

"$INSTALLER"
rc=$?

if [ "$rc" -ne 0 ]; then
    logmsg "FAILED: installRules.py rc=$rc"
    restore_active
    exit "$rc"
fi

AFTER=$(active_hash)

if [ "$BEFORE" = "$AFTER" ]; then
    logmsg "no active rule changes; restart skipped"
    exit 0
fi

logmsg "active rules changed; validating new ruleset"

"$SURICATA" -T --init-errors-fatal -c "$CONFIG"
rc=$?

if [ "$rc" -ne 0 ]; then
    logmsg "FAILED: Suricata validation rc=$rc; restart NOT performed"
    restore_active
    exit "$rc"
fi

logmsg "validation passed; performing full Suricata restart"

"$RC" restart
rc=$?

if [ "$rc" -ne 0 ]; then
    logmsg "FAILED: restart rc=$rc; restoring previous ruleset"
    restore_active
    "$RC" restart
    exit 30
fi

i=0
while [ "$i" -lt 36 ]; do
    sleep 5

    NEW_DIVERT=$(divert_count)

    if "$RC" status >/dev/null 2>&1 &&
       [ "$NEW_DIVERT" -eq "$OLD_DIVERT" ]; then
        NEW_PID=$(cat /var/run/suricata.pid 2>/dev/null || true)
        logmsg "SUCCESS: PID=$NEW_PID divert_listeners=$NEW_DIVERT"
        exit 0
    fi

    i=$((i + 1))
done

logmsg "FAILED: Divert listeners did not recover within 180 seconds"
logmsg "restoring previous ruleset and restarting"

restore_active
"$RC" restart
rc=$?

if [ "$rc" -ne 0 ]; then
    logmsg "CRITICAL: rollback restart failed rc=$rc"
    exit 40
fi

logmsg "ROLLBACK completed; manual verification required"
exit 41

Set ownership and permissions:
chown root:wheel /usr/local/sbin/suricata-safe-update
chmod 0700 /usr/local/sbin/suricata-safe-update

Check shell syntax:
/bin/sh -n /usr/local/sbin/suricata-safe-update
Optional check that the wrapper itself does not contain a SIGUSR2, pkill, or kill command:
grep -nEi 'USR2|pkill|kill ' /usr/local/sbin/suricata-safe-update
No output is expected.

2. Create a configd action

Create:
/usr/local/opnsense/service/conf/actions.d/actions_suricatasafe.conf

Contents:
[update]
command:/usr/bin/lockf -k -t 0 /var/run/suricata-safe-update.lock /usr/local/sbin/suricata-safe-update
parameters:
type:script
message:safely update Suricata rules with full restart when needed
description:Suricata safe rule update (full restart, no SIGUSR2)

Set permissions:
chown root:wheel /usr/local/opnsense/service/conf/actions.d/actions_suricatasafe.conf
chmod 0644 /usr/local/opnsense/service/conf/actions.d/actions_suricatasafe.conf

Reload configd:
service configd restart
Check that the action was registered:
configctl configd actions | grep -i suricatasafe
Expected:
suricatasafe update [ Suricata safe rule update (full restart, no SIGUSR2) ]

3. Test manually before changing Cron

Check the current Suricata PID:
cat /var/run/suricata.pid
Check the current Suricata sockets:
sockstat | grep '[s]uricata'
For the actual test I recommend using detached configctl:
/usr/local/sbin/configctl -d -- suricatasafe update
A synchronous call may exceed the configctl client timeout because Hyperscan validation and startup can take several minutes.

Monitor the updater and Suricata:
ps -axww -o pid,ppid,state,etime,%cpu,%mem,rss,vsz,command | grep -E 'suricata-safe-update|suricata -T|/usr/local/bin/suricata' | grep -v grep
Check the sockets:
sockstat | grep '[s]uricata'
After the update has finished, check the PID again:
cat /var/run/suricata.pid
Check whether the new engine completed startup:
/bin/sh -c 'PID=$(cat /var/run/suricata.pid); grep "suricata $PID" /var/log/suricata/suricata_*.log | grep -E "Engine started|<Error>|<Warning>" | tail -30'
A successful start should contain something similar to:
Threads created -> W: 8 FM: 1 FR: 1  Engine started.

The number of workers/listeners depends on the system configuration.

4. Replace the normal scheduled IDS update

Go to:

System → Settings → Cron

Disable the existing:
ids rule updates

I kept the original job present but disabled, rather than deleting it, so reverting is easy.

Then create a new Cron job using:
Suricata safe rule update (full restart, no SIGUSR2)
For example, daily at 02:00:


Minutes:  0
Hours:    2
Days:      *
Months:    *
Weekdays:  *

OPNsense should generate an effective cron entry similar to:
0 2 * * * /usr/local/sbin/configctl -d -- suricatasafe update
Verify the effective cron:
grep -nE 'ids update|suricatasafe update' /var/cron/tabs/nobody
The old active command:
/usr/local/sbin/configctl -d -- ids update
should be gone.

The new active command should be:
/usr/local/sbin/configctl -d -- suricatasafe update
5. Why detached configctl -d?

On my system a real rule update plus Hyperscan validation and full Suricata restart takes longer than a synchronous configctl client waits.

During testing, a synchronous invocation produced:


error in configd communication
TimeoutError: timed out

The configd action itself continued running and completed successfully.

For scheduled execution I therefore use:
/usr/local/sbin/configctl -d -- suricatasafe update
The lockf around the wrapper prevents two update jobs from running concurrently.

6. Tested result

Tested on:


OPNsense:        26.7.2_2
Suricata:        8.0.6
IPS mode:        Divert
Pattern matcher: Hyperscan

A real rule update resulted in a full Suricata restart.

During startup the new Suricata process spent roughly two minutes at high CPU while compiling/initializing the rules.

Afterwards all eight Divert listeners on my system returned:


div4 *:8000
div4 *:8000
div4 *:8000
div4 *:8000
div4 *:8000
div4 *:8000
div4 *:8000
div4 *:8000

The log then reported:
Threads created -> W: 8 FM: 1 FR: 1  Engine started.

SHA256 of the exact wrapper version I tested:


93d4235d5c79a3ce2aba22bbc80e049601ca0d5ca88a845f24afb67ed928231f

7. Important note

This is specifically a workaround for the current Divert + Hyperscan live-reload problem described in:

OPNsense core issue #10416

The automatic path deliberately avoids:
pkill -USR2 suricata
and performs a full restart when the active ruleset changes.

A full restart introduces a short inspection interruption while Suricata starts again, so anyone using this should evaluate that behavior for their own inline setup.

The wrapper above also checks OPNsense Divert listeners on:
*:8000

because that is the Divert configuration used on my system. Anyone with a substantially different setup should review the listener detection before copying it unchanged.

This is not intended to replace Suricata's normal live-reload mechanism permanently. Once the upstream Divert/Hyperscan issue is fixed and that fix is available in OPNsense, I intend to remove this workaround and return to the stock OPNsense rule-update path.

I hope this helps somebody else also.

This applies specifically to OPNsense Suricata IPS using Divert mode + Hyperscan. Do not use this workaround for normal Netmap/IDS installations unless you understand why you need it.
#2
I just made the jump with the outbound NAT to SNAT conversion using the NAT migration tool.

This is working as expected! Thanks for that. One minor human error occurred here. When I imported the CSV file, there was a validation error with one of the (non-activated) old outbound NAT rules.
I ignored this warning because it is no longer in use.

I clicked the [green checkmark] and the window with this validation error stayed open. I clicked the green checkmark two more times and then decided to click the [ x ]to close it.

I noticed that my SNAT has now been populated with three times the same rules ;-). Maybe a control function can be added to the migration tool to prevent importing the same rules repeatedly if someone accidentally clicks the green checkmark more than once?


#3
another false positive. you seem to block https://internet.nl/ their ip.
As soon when I disable Q-feeds it is working.
#4
I just noticed on https://pentest-tools.com/network-vulnerability-scanning/port-scanner-online-nmap
that the auto generated Anti-Lockout Rules (Destination NAT) for port 22 and port 444 (my opnsense gui) are both opened on WAN and can be reached.

Is this my fault and should those 2 Anti-Lockout rules be deleted after installing 26.1 or is this something to look at? I cant see a delete option in the Destination NAT list.
#5
Hi,
I noticed (while watching the logs more closely since updating to OpnSense 26.1 and now on 26.1_4) I saw those below notification errors:
(connection is fiber PPPoE)

Notice kernel [158] [fib_algo] inet.0 (radix4_lockless#948) rebuild_fd_flm: table rebuild failed
Notice kernel 158] [fib_algo] inet.0 setup_fd_instance: radix4_lockless algo instance setup failed, failures=22

Not sure if it is only 26.1x related. Systems runs, but others seeing this also and how to mitigate?
#6
I just took the jump also,
Upgraded and after reboot i have internet connection for a little while. And that stops,
I am not able to get it back up.

After another reboot the same.
I noticed the wan interface was down.

In the log I noticed this:

[357] pf_test: kif == NULL, if_xname pppoe0

Is this the reason?
What can i do?

Thanks for the help in advance!
#7
Q-Feeds (Threat intelligence) / automatic upgrade api
November 20, 2025, 07:28:16 AM
I just ordered a plus upgrade. I was already using the free api key.
I noticed that after paying for the upgrade, and received confirmation, it stays free.
Than i read that i have to go into the tip-qfeeds account and edit my free api key to change it to plus.

I think it will be very convenient for the user to have this api altered to this paid version automatically, instead of now manually.
Why would a user want its api to stay free when he/she just ordered an upgrade?

p.s. is there a way to check if my qfeeds plugin is getting the plus feed instead of the free? And should i alter my url in Adguard Home for this plus package? or is there another url only for plus to use in adguard home?
#8
Hi,

I have my WireGuard not working after a reboot of opnsense ( looks a lot like this post: https://forum.opnsense.org/index.php?topic=41081.0 and this one https://forum.opnsense.org/index.php?topic=36688.0). When I just hit [apply] on the SYSTEM: GATEWAYS: CONFIGURATION page (without making changes) all starts working with WireGuard.

I'm trying to "fix" this by cloning the Monit alert settings [gateway alert] and in service test settings, execute and something like path:
/bin/sh -c '/usr/local/sbin/configctl interface routes alarm'

What is the cli command for "apply settings gateway, without changing configuration?"

Or is there another way to automate this after an Opnsense reboot?

Thank you for your help with this.
#9
Since a version of 3 back, I have the update to run twice. The first time OPNsense 25.1.6-amd64 completes, it restarts the opnsense box but I have to run update again to have the missing:
os-bind  installed

and with this time the update os-postfix was also missing and installed the second run.

Others having this also?
(n.b. I only use BIND for dns, no unbound or dnsmasq etc)
#10
I'm running the latest OPNsense and Nginx plugin:

OPNsense 25.1-amd64
FreeBSD 14.2-RELEASE
OpenSSL 3.0.15

Nginx log shows this warning:
nginx: [warn] could not build optimal variables_hash, you should increase either variables_hash_max_size: 1024 or variables_hash_bucket_size: 64; ignoring variables_hash_bucket_size

I tried changing the setting, Nginx - configuration - general settings - global HTTP settings:
Hash Bucket Size : 128 and 256
Server Names Hash Max Size : 1024, 2048 and 4096

But all did not seem to work, and the warning remains the same. It looks like this gui setting does not work (anymore?) or am I changing the wrong settings?

Others having this warning also? How to fix?

#11
Hi, I am wondering if this is possible:
I am running Opnsense with Adguard Home (plugin) and Bind (plugin). So that every DNS/port 53 goes to Adguard home. Adguard Home has 127.0.0.1:5354 as upstream (Bind), bind has no DNS Forwarders. This way every lookup will go to the dns root servers, if not yet unknown/cache. As I have learned in the past from this forum, this gives more privacy while no root dns "has it all" and better than trusting the 1.1.1.1 server or your ISP encrypted dns server who "has it all". This is working great.

However, every local/LAN dns lookup is plain dns / unencrypted. Is there a way to make LAN also DoT? e.g. Adguard Home DoT to Bind? Maybe plain dns is a small risk on LAN, but if it can be secured, why not doing so.

I am eager to learn your solution(s) for this.
#12
I have just updated to OPNsense 24.7.5-amd64
FreeBSD 14.1-RELEASE-p5
OpenSSL 3.0.15

Now WireGuard does not work/does not get an ipv4 address, only showing ipv6 when https://www.whatismyip.com/

Others having this issue also? Is there a Quick fix?

#13
I just updated my box to opnsense 24.7.4. Reboot hung so I did a manual power off and on,
Opnsense won't start. Connected a monitor to it and I see: failed to load kernel.
What should I do to get it back ?

Thank you very much for the help!
#14
Hi,
I have my own email server running and I use postfix on opnsense as a mail gateway as described here:
https://docs.opnsense.org/manual/how-tos/mailgateway.html
This works great for port 25 SMTP to enable communication between the sending and receiving servers to my local hosted email server.

Now I wonder if opnsense-postfix can (and should?) also be used for port 587 (SMTP-STARTTLS), so that all email clients (pc, iphone, laptop, etc) can sent email by first going to port 587/postfix and sending emails from our local email server.

Currently I have port 25 pointing to and using postfix, while for port 587 and IMAP i use a port forward to the local email server. Can this be postfix also for the same reason of using port 25? And if so, how can I configure that using the postfix-GUI?

Thanks for explaining and help in advantage
#15
Hi, I have just updated my applience to OPNsense 24.7.2 and noticed the red square / not running of APCUPSD. pressing the start or doing start in the plugin menu using - Enabled check, does not help.

in the log I see this error:

Quote2024-08-21T18:22:47   Error   apcupsd   apcupsd error shutdown completed   
2024-08-21T18:22:47   Error   apcupsd   Lock file data error:   
           please stop it and run this program again.   
           If apcupsd or apctest is already running,   
           Unable to create UPS lock file.   
2024-08-21T18:22:47   Error   apcupsd   apcupsd FATAL ERROR in apcupsd.c at line 221   
2024-08-21T18:22:47   Error   apcupsd   Lock file data error: 

Others having this issue also?
#16
23.7 Legacy Series / BIND error checkhints
December 22, 2023, 03:20:39 PM
Hi, I am using Bind plugin and noticed this error in the log:

Quote2023-12-22T14:58:37.242000   general   Warning   checkhints: b.root-servers.net/AAAA (2001:500:200::b) extra record in hints
2023-12-22T14:58:37.241000   general   Warning   checkhints: b.root-servers.net/AAAA (2801:1b8:10::b) missing from hints
2023-12-22T14:58:37.241000   general   Warning   checkhints: b.root-servers.net/A (199.9.14.201) extra record in hints
2023-12-22T14:58:37.241000   general   Warning   checkhints: b.root-servers.net/A (170.247.170.2) missing from hints

I updated the /usr/local/etc/namedb/named.root file with this latest one:
https://www.internic.net/domain/named.root

and got the error fixed. Others using Bind experienced the same error? seems that our default 2017 named.root file in opnsense needed an update?
#17
General Discussion / Solved - Bind DNSSEC localdomain
December 16, 2023, 06:54:42 PM
I have Bind running and Adguard home. In Adguard I get a green-lock when an external domain of mine is validated with dnssec.
Is there an how to, on thow to do this with localdomain in bind? for localdomain.com ?
I would like this to avoid dns sniffing on local connections, has someone experience with this?

thanks for the help!
#18
I just noticed that on the interfaces-overview page - wan the virtual ip's of IPv4 are not showing there under the main wan IP (under IPv4 address), where the virtual ip's of IPv6 are still all mentioned as used to be (IPv6 address).
It looks like the virtual ipv4 virtual ip's are gone on this overview. The virtual ip's are working perfect, so it is a cosmetic bug. Others have this issue also?

p.s. I used this https://forum.opnsense.org/index.php?topic=21207.0 as my interface setup PPPoE
#19
I have, for some weeks now, running Postfix on opnsense. It was working perfectly with IPv4 and IPv6.
Now after the update to OPNsense 23.7.4, postfix IPv6 is not working. IPv4 is still good
I checked with https://www.hardenize.com

And there I saw the error with TLS. See attached picture.
Others using Postfix and ipv6 have the same errors? Or is there something changed with the update to 23.7.4 or something that broke my config wat was working perfectly before 23.7.4?

When I do the port forward to my mailsever directly instead of postfix, the mail is working. So it has something to do with postfix or opnsense(?)

Solved it: somehow my trusted network ipv6 was missing.
#20
Hi,

I have a weird DHCP and BIND problem running on:
OPNsense 23.7.3-amd64
FreeBSD 13.2-RELEASE-p2
OpenSSL 1.1.1v 1 Aug 2023

I see on the main GUI screen of OPNsense about every minute that DHCPv6 Server turns RED and than restarts and is back up to green. After that BIND Daemon turns RED and than restarts.

In the DHCP log i see this every time:
Informational   dhcpd   Server starting service.   
Informational   dhcpd   Sending on Socket/8/igb1/2a10:xxxx:xxxx:1::/64   
Informational   dhcpd   Listening on Socket/8/igb1/2a10:xxxx:xxxx:1::/64   
Informational   dhcpd   Bound to *:547   
Informational   dhcpd   Wrote 0 NA, 0 TA, 0 PD leases to lease file.   
Informational   dhcpd   Wrote 0 new dynamic host decls to leases file.   
Informational   dhcpd   Wrote 0 deleted host decls to leases file.   
Informational   dhcpd   For info, please visit https://www.isc.org/software/dhcp/   
Informational   dhcpd   All rights reserved.   
nformational   dhcpd   Copyright 2004-2022 Internet Systems Consortium.   
Informational   dhcpd   Internet Systems Consortium DHCP Server 4.4.3-P1   
Informational   dhcpd   PID file: /var/run/dhcpdv6.pid   
Informational   dhcpd   Database file: /var/db/dhcpd6.leases   
Informational   dhcpd   Config file: /etc/dhcpdv6.conf

In the BIND log i see this:

general   Notice   running
general   Notice   all zones loaded
zoneload   Informational   zone x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.2.ip6.arpa/IN: loaded serial 2308140935
zoneload   Informational   zone 0.ip6.arpa/IN: loaded serial 42
zoneload   Informational   zone localhost/IN: loaded serial 42
zoneload   Informational   zone mydomain.com/IN: loaded serial 2308182130
zoneload   Informational   zone 1.168.192.in-addr.arpa/IN: loaded serial 2308182144
zoneload   Informational   zone x.x.x.x.x.x.x.x.x.x.x.x.x.x.2.ip6.arpa/IN: loaded serial 2308151502
zoneload   Informational   zone 127.in-addr.arpa/IN: loaded serial 42
zoneload   Informational   zone 10.x.xin-addr.arpa/IN: loaded serial 2308140934
zoneload   Informational   managed-keys-zone: loaded serial 6493
general   Notice   exiting
network   Error   automatic interface scanning terminated: end of file
general   Notice   stopping command channel on 127.0.0.1#9530
general   Informational   shutting down: flushing changes
network   Informational   no longer listening on 127.0.0.1#5354
network   Informational   no longer listening on 2a10:xxxx:xxxx:1::#5354
general   Informational   received control channel command 'stop'

Others having this issue also? Any clues on how to fix this?