Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login
    Introducing Netgate Nexus: Multi-Instance Management at Your Fingertips.

    Snort (pfSense 2.8.1 / package 4.1.6_28) – DNP3 rules not triggering but working in standalone Snort 2.9.20_8

    Scheduled Pinned Locked Moved IDS/IPS
    12 Posts 3 Posters 3.8k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      honeybadger101
      last edited by honeybadger101

      I’m currently testing Snort integration on pfSense 2.8.1-RELEASE using the Snort package version 4.1.6_28, which depends on Snort 2.9.20_8.
      I’ve run into an issue where DNP3 rules (with dnp3_func) are not triggering in pfSense, even though the exact same rules and PCAPs work correctly when I run Snort standalone.

      What I tested (standalone Snort)

      In a separate Ubuntu environment, I built Snort 2.9.20 from source, and configured the following:

      • stream5 enabled
      • dnp3 preprocessor enabled
      • modbus preprocessor enabled
      • custom local.rules

      Example rule:

      alert tcp any any -> any 20000 \
      (msg:"OT DNP3 DIRECT OPERATE observed"; \
      dnp3_func:direct_operate; \
      sid:6100005; rev:1;)
      

      Running command:

      snort -r dnp3_cut.pcap -c snort.conf -A console -k none
      

      Results:
      ✅ Alerts are generated correctly
      ✅ DNP3 parser works
      ✅Modbus parser works
      ✅Different dnp3_func values match depending on PCAP

      Same test in pfSense

      On pfSense:

      • Same PCAPs
      • Same rules (via custom rules / local.rules equivalent)
      • Snort enabled on the appropriate interface
      • Didn't tweak with any advanced settings apart from enabling SCADA preprocessors

      Observations:
      ✅ Broad rule on port 20000 works (see below):

      alert tcp any any -> any 20000 \
      (msg:"ANY DNP3 TRAFFIC"; sid:1000001; rev:1;)
      

      ✅ Modbus rules (modbus_func) work correctly
      ❌ DNP3 rules with dnp3_func do NOT trigger (e.g. below):

      alert tcp any any -> any 20000 \
      (msg:"DNP3 READ"; dnp3_func:read; sid:1000002; rev:1;)
      

      Hence, DNP3 preprocessor does not appear to be active or parsing the traffic.

      What I’m trying to confirm
      • Does Snort package 4.1.6_28 include full DNP3 preprocessor support?
      • Is there any additional GUI setting required to enable DNP3 (similar to other preprocessors)?
      • Has anyone successfully used dnp3_func rules in pfSense Snort recently?
      1 Reply Last reply Reply Quote 0
      • bmeeksB Offline
        bmeeks
        last edited by bmeeks

        Your path to the snort.conf file is incorrect when running against your PCAP file.

        I maintained the Snort package and created and maintained the Suricata package on pfSense for many years, but I recently retired from that role at the start of this year.

        Snort on pfSense does NOT use any of the files in /usr/local/etc/snort/ directly. Instead, each time you save the config in the GUI or start/stop the service from the GUI, the PHP code creates a new snort.conf file in the /usr/local/etc/snort/snort_xxxx/ subdirectory where the "xxxx" is replaced by a UUID and the physical interface device name the Snort instance is using. When Snort is started within the GUI or automatically by pfSense during a reboot, the Snort binary is passed the proper custom path where it can find the snort.conf file appropriate for the interface.

        So, the configuration you make in the GUI is only respected when run against the correct snort.conf file in that subdirectory.

        TL/DR answer is: "Snort in pfSense does NOT behave at all like a standalone Snort install on Linux or even FreeBSD does." It uses custom paths for the configuration file, for the rules, and for logging. Those custom paths are named with a UUID and the physical interface name. This is so you can run multiple instances of Snort on different interfaces with each having its own unique configuration and logging settings.

        Your command line execution should look like this:

        snort -r dnp3_cut.pcap -c /usr/local/etc/snort/snort_xxxx/snort.conf -A console -k none
        

        where you replace "xxxx" with the proper UUID and physical interface name.

        When you run Snort with the command line parameter you are using for the snort.conf file, it will use the default snort.conf file in /usr/local/etc/snort/ which will not have the necessary preprocessors enabled nor will it be pointing to the directory where the correct rules are located. That's why you are not seeing any alerts. The DNP3 preprocessor is not enabled in the default snort.conf file. But it will be enabled if you enable it in the GUI and then point Snort to the proper conf file in the appropriate subdirectory as I indicated above.

        H S 2 Replies Last reply Reply Quote 1
        • H Offline
          honeybadger101 @bmeeks
          last edited by

          Hi @bmeeks, thanks for the detailed explanation.
          Just to clarify, I’m not running Snort from the CLI on pfSense, and I’m not using any snort.conf. I should have explained better my setup, sorry for misleading you.

          My setup is:

          • Snort configured via pfSense GUI
          • Snort running on a specific interface
          • Traffic generated by replaying a PCAP from a separate VM to another VM (pfSense sits in between)
          • pfSense Snort inspecting that traffic live on the interface

          So Snort is operating within pfSense exactly as intended (via the GUI), not via manual command-line execution.

          I will edit the post to make it more clear.

          bmeeksB 1 Reply Last reply Reply Quote 0
          • bmeeksB Offline
            bmeeks @honeybadger101
            last edited by bmeeks

            @honeybadger101 said in Snort (pfSense 2.8.1 / package 4.1.6_28) – DNP3 rules not triggering but working in standalone Snort 2.9.20_8:

            Hi @bmeeks, thanks for the detailed explanation.
            Just to clarify, I’m not running Snort from the CLI on pfSense, and I’m not using any snort.conf. I should have explained better my setup, sorry for misleading you.

            My setup is:

            • Snort configured via pfSense GUI
            • Snort running on a specific interface
            • Traffic generated by replaying a PCAP from a separate VM to another VM (pfSense sits in between)
            • pfSense Snort inspecting that traffic live on the interface

            So Snort is operating within pfSense exactly as intended (via the GUI), not via manual command-line execution.

            I will edit the post to make it more clear.

            Sorry, I did misunderstand your initial post with regards to how you were running Snort.

            With the DNP3 preprocessor enabled under the PREPROCESSORS tab in the GUI, Snort should behave the same on pfSense as on the Ubuntu machine. The specific configuration for each preprocessor is generated based on the GUI settings for it and then written to the snort.conf file. I would start by comparing the DNP3 preprocessor sections in the two snort.conf files to see if anything is different. Also wouldn't be a bad idea to run a packet capture on the pfSense interface to be 100% the traffic you expect to be there is actually there.

            H 2 Replies Last reply Reply Quote 0
            • H Offline
              honeybadger101 @bmeeks
              last edited by

              This post is deleted!
              H 1 Reply Last reply Reply Quote 0
              • S Offline
                slu @bmeeks
                last edited by

                @bmeeks said in Snort (pfSense 2.8.1 / package 4.1.6_28) – DNP3 rules not triggering but working in standalone Snort 2.9.20_8:

                I maintained the Snort package and created and maintained the Suricata package on pfSense for many years, but I recently retired from that role at the start of this year.

                @bmeeks nice to hear from you!

                Do you know if the package is still supported by Negate?
                There was no notification or I missed it.

                @honeybadger101 sorry for the off topic post.

                pfSense Gold subscription

                1 Reply Last reply Reply Quote 0
                • H Offline
                  honeybadger101 @honeybadger101
                  last edited by

                  This post is deleted!
                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    honeybadger101 @bmeeks
                    last edited by

                    @bmeeks
                    So yes, traffic is 100% there. I compared the two snort.conf files as suggested and they look pretty much the same. I uploaded both configs, could you please take a look at them as I don't see anything outstanding?

                    pfsense.snort.conf.txt
                    ubuntu.snort.conf.txt

                    H 1 Reply Last reply Reply Quote 0
                    • bmeeksB Offline
                      bmeeks
                      last edited by bmeeks

                      Sorry to be late on the reply. Was away from home for several hours today.

                      I don't see any immediate differences in the two snort.conf files for the DNP3 preprocessor, but the Ubuntu one is very "bare bones".

                      I assume you have reviewed the official Snort 2.9.x documentation here: http://manual-snort-org.s3-website-us-east-1.amazonaws.com/node17.html#SECTION003223000000000000000 ??

                      Two possibilities stand out to me from reviewing the Dependency Requirements and Configuration sections of the above link. First, I would ensure that all the items under "Dependency Requirements" are met. Second, I see that if check_crc is specified and there is any CRC frame error, the packet will be ignored. It's possible there is some difference in how CRC checks are performed and bubbled up in Linux versus FreeBSD. Don't know for sure, but worth investigating. Maybe try removing the check_crc argument for testing. Removing that parameter will require editing one of the PHP source files as follows:

                      In file /usr/local/pkg/snort/snort_generate_conf.php find the section beginning at line #878 as shown below.

                      # DNP3 preprocessor #
                      preprocessor dnp3: \
                      	ports { {$dnp3_ports} } \
                      	memcap 262144 \
                      	check_crc
                      

                      Modify it to appear as follows and save the change. Notice the check_crc line is removed as is the trailing backslash on the memcap line above it.

                      # DNP3 preprocessor #
                      preprocessor dnp3: \
                      	ports { {$dnp3_ports} } \
                      	memcap 262144
                      

                      After editing and saving the file, stop and start Snort on the interface to force a rebuild of the snort.conf file with the new information.

                      H 1 Reply Last reply Reply Quote 0
                      • H Offline
                        honeybadger101 @bmeeks
                        last edited by

                        @bmeeks Thanks. Due to a couple of reasons I had to step out of the office this week, so apologies for not getting back to it earlier. I hope to try what you suggested when I am back end of the week.

                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          honeybadger101 @honeybadger101
                          last edited by

                          Hi @bmeeks, sorry for the late reply. I had some vacation weeks and couldn't follow-up.
                          Unfortunately I haven't solved this issue even with your great support.
                          I doubled checked the dependency requirements and changed the configuration as suggested to disable CRC checks but still, rules don't fire.
                          I have attached some screenshots that show the requirements both in pfsense GUI and conf file. Could you please double-check, just to be sure I'm not missing anything?
                          Thanks again for your help on this.

                          dnp3_conf.png

                          frag3_conf.png

                          IP_defragmentation_dependency.png

                          paf_config.png

                          PAF_dependency.png

                          stream5_conf.png

                          stream5_dependency.png

                          1 Reply Last reply Reply Quote 0
                          • bmeeksB Offline
                            bmeeks
                            last edited by bmeeks

                            I don't immediately see any misconfiguration. In some additional web research I did find this post from 2012 on the Snort blog about SCADA capabilities in Snort 2.9.x: https://blog.snort.org/2012/01/snort-292-scada-preprocessors.html. I also found some discussion of the new SCADA capability in Snort 2.9.x at SANS here: https://isc.sans.edu/diary/12346.

                            I am not really familiar with using either of these SCADA protocols. Although I did work early in my career as an Instrumentation and Controls Technician and understood the basics of SCADA, that area was not my primary job focus. Later as a cyber security analyst working to secure industrial controls systems I again was not specifically tasked with the SCADA side of things. I specialized more in firewalls and L3 stuff instead of deep diving into SCADA.

                            With DNP3 in particular, I would double-check to be sure your PCAP matches the possibly more primitive protocol decoding present in Snort 2.9.20 as compared to Snort3.

                            It's been a while since I've visited this thread, but I seem to recall that you tested your PCAP on a standalone Linux install of Snort 2.9.20. If possible, I would repeat that test on a standalone install of Snort 2.9.20 on a FreeBSD installation. This would rule out any potential network stack differences between Linux and FreeBSD that might be at play (not saying there are any, but it is certainly possible).

                            Running Snort in IDS mode (not IPS) on pfSense uses the libpcap library to obtain a copy of all packets traversing the targeted interface. The default mode of Snort on pfSense also enables Promiscuous Mode packet capture so that every packet seen by the interface is captured for Snort.

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post
                            Copyright 2026 Rubicon Communications LLC (Netgate). All rights reserved.