Let us put the piggy (snort3 in jail. Grab a snack, this is a bit long...
First we create a folder where we keep the jails, and a folder for the new jail (or zfs volume if that is more your cup of tea)
Then we do a very basic install of FreeBSD in that jail.
$ doas mkdir -p /home/jails/snort3
$ doas bsdinstall jail /home/jails/snort3
After that we make some changes to the configs on the host
Add this to the /etc/rc.conf
jail_enable="YES"
jail_sysvipc_allow="YES"
jail_snort3_parameters="allow.raw_sockets=1"
ifconfig_re0_alias1="inet 192.168.0.66 netmask 255.255.255.255"
Add an entry like this, the part between 'snort3 {}', for each jail to your /etc/jail.conf
re0 is your network interface, and after the pipe is the ip of the jail (can ofcourse be a different network)
ip4=inherit;
exec.clean;
mount.devfs;
snort3 {
host.hostname = jailsnort3; # Hostname
ip4.addr = re0|192.168.0.66; # IP address of the jail
path = "/home/jails/snort3"; # Path to the jail
mount.devfs; # Mount devfs inside the jail
devfs_ruleset = 5;
exec.start = "/bin/sh /etc/rc"; # Start command
exec.stop = "/bin/sh /etc/rc.shutdown"; # Stop command
}
Then to allow the jail to communicate externally, we add these options in /etc/sysctl.conf
allow.raw_sockets=1
allow.sysvipc=1
security.jail.sysvipc_allowed=1
Lets start the jail (if you run into problems, first try to restart the host then the jail should start automaticly at boot):
$ doas service jail start # you can add your jail name after start if you have several and just want to start one
Upgrade the jail to a new release version:
$ doas freebsd-update -j snort3 -r 13.5-RELEASE upgrade
$ doas freebsd-update -j snort3 -r 13.5-RELEASE install
$ doas service jail restart snort3
$ doas freebsd-update -j snort3 -r 13.5-RELEASE install
Now lets enter the jail we created
$ doas jexec snort3 /bin/sh
Good to know for jail maintainance. There are jail wrappers, but i prefer the basic
Keep the jail updated (can be skipped if pkgbasified):
$ doas freebsd-update -j snort3 fetch install
Keep the jail packages updated:
$ doas pkg -j snort3 update && doas pkg -j snort3 upgrade
Restart a jail:
$ doas service jail restart snort3
If you from the host can't remove a old jail folder, first do:
$ doas chflags -R noschg jailfolder/ && doas rm -rf jailfolder
Now lets enter the jail if you are not there already:
$ doas jexec snort3 /bin/sh
Install snort3 and dependencies (followed this more or less: https://www.zenarmor.com/docs/linux-tutorials/how-to-install-and-configure-snort-on-freebsd)
# pkg install snort3 python3 py311-requests lzlib openssl pcre2 lzma libpcap
Get pulledpork3 to update rules automaticly:
# fetch https://github.com/shirkdog/pulledpork3/archive/refs/heads/main.zip
# unzip main.zip
Create folders and copy away pulled pork files:
# mkdir /usr/local/etc/pulledpork/
# cp pulledpork3-main/etc/pulledpork.conf /usr/local/etc/pulledpork/
# mkdir -p /usr/local/bin/pulledpork/lib
# cp pulledpork3-main/pulledpork.py /usr/local/bin/pulledpork/
# cp -r pulledpork3-main/lib/ /usr/local/bin/pulledpork/lib
Test pulledpork:
# python3 /usr/local/bin/pulledpork/pulledpork.py -V
PulledPork v3.0.0.5
https://github.com/shirkdog/pulledpork3
_____ ____
`----,\ ) PulledPork v3.0.0.5
`--==\\ / Lowcountry yellow mustard bbq sauce is the best bbq sauce. Fight me.
`--==\\/
.-~~~~-.Y|\\_ Copyright (C) 2021 Noah Dietrich, Colin Grady, Michael Shirk
@_/ / 66\_ and the PulledPork Team!
| \ \ _(")
\ /-| ||'--' Rules give me wings!
\_\ \_\\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Add this to the config /usr/local/etc/pulledpork/pulledpork.conf
--- edit ---
also add a line with like:
snort_version = 3.9.0.0
This version should replicate a version of snortrules-snapshot-VERSION.tar.gz from https://snort.org/downloads#rules
blocklist_path = /usr/local/lib/snort/intel/default.blocklist
rule_path = /usr/local/lib/snort/rules/pulledpork.rules
sorule_path = /usr/local/lib/snort/rules/
community_ruuleset = true
registered_ruleset = true # you can use the community_ruleset also if you dont want to register to snort.org, but registered gets more rules
oinkcode = 12345666 # your oinkcode from if you registered to snort.org, otherwise leave it as is.
snort_blocklist = true
et_blocklist = true
Add something like this maby once a week in cron:
# crontab -e
13 13 * * * python3 /usr/local/bin/pulledpork/pulledpork.py -c /usr/local/etc/pulledpork/pulledpork.conf
Verify that snort works (look how cute piggy)
# snort -V
,,_ -*> Snort++ <*-
o" )~ Version 3.8.1.0
'''' By Martin Roesch & The Snort Team
http://snort.org/contact#team
Copyright (C) 2014-2025 Cisco and/or its affiliates. All rights reserved.
Copyright (C) 1998-2013 Sourcefire, Inc., et al.
Using DAQ version 3.0.19
Using Hyperscan version 5.4.2 2025-08-12
Using libpcap version 1.10.5
Using LuaJIT version 2.1.1748459687
Using LZMA version 5.6.3
Using OpenSSL 1.1.1w-freebsd 11 Sep 2023
Using PCRE2 version 10.45 2025-02-05
Using ZLIB version 1.3.1
configuration of snort:
/usr/local/etc/snort/snort_defaults.lua (edit below)
RULE_PATH = '/usr/local/lib/snort/rules/'
BUILTIN_RULE_PATH = '/usr/local/lib/snort/builtin_rules/'
PLUGIN_RULE_PATH = '/usr/local/lib/snort/so_rules/'
-- If you are using reputation preprocessor set these
WHITE_LIST_PATH = '/usr/local/lib/snort/intel/'
BLACK_LIST_PATH = '/usr/local/lib/snort/intel/'
# tar zxf snortrules-snapshot-xxx.tar.gz (after downloaded latest snapshot or community rules from snort.org)
# mkdir /usr/local/lib/snort/rules
# mkdir /usr/local/lib/snort/so_rules
# mkdir /usr/local/lib/snort/builtins
# cp -r builtins/ /usr/local/lib/snort/builtins/
# cp -r so_rules/ /usr/local/lib/snort/so_rules/
# cp -r rules/ /usr/local/lib/snort/rules/
# cp etc/file_magic.lua /usr/local/etc/snort/
add a row after include in file /usr/local/etc/snort/snort.lua:
include 'file_magic.lua'
# tar zxf openappid-xxxx.tar.gz (after downloaded from snort.org)
# mkdir -p /usr/local/lib/snort/appid/odp
# cp -r odp/ /usr/local/lib/snort/appid/odp
# mkdir /usr/local/lib/snort/intel
# touch /usr/local/lib/snort/intel/ip-whitelist
# touch /usr/local/lib/snort/intel/ip-blacklist
Get a block list from snort https://snort.org/downloads/ip-block-list/terms (you need to use a webbrowser to accept terms)
# cp ip-filter /usr/local/lib/snort/intel/ip-blacklist
Add rules in the ips section in snort.lua, like all snort3*.rules from /usr/local/lib/snort/rules/
you have a line like: variables = default_variables
add a comma after that, then add:
rules = [[
inclue /usr/local/lib/snort/rules/snort3-app-detect.rules
... here you add all the other rules files as includes like the above line
]]
Now try to start snort:
# snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq -i re0 -l /var/log/snort -k none
you will see something like 46000 rules loaded
Create rc start script and chmod +x /usr/local/etc/rc.d/snort it after
#!/bin/sh
# Change the interface as necessary
interface="re0"
prog="snort"
pid=`ps ax | awk '{if (match($5, ".*/snort$") || $5 == "snort") print $1}'`
start() {
if test "$pid" != ""; then
echo "$prog is already running as pid $pid."
else
echo "Starting $prog..."
# This will run snort as root
/usr/local/bin/snort -c /usr/local/etc/snort/snort.lua --daq-dir /usr/local/lib/daq -D \
-i ${interface} -l /var/log/snort --lua "alert_csv = { file = true } -M"
# if you dont want snort to log to /var/log/messages when it starts for example, remove -M from above
# This will run snort as user 'snort' and group 'snort'
# /usr/local/bin/snort -c /usr/local/etc/snort.lua -D -u snort -g snort -i ${interface} -l /var/log/snort
fi
}
stop () {
if test "$pid" != ""; then
kill $pid
echo "$prog stopped."
else
echo "$prog is not running. Cannot stop."
fi
# This is a killall method, regardless of the variable 'pid'
# /usr/bin/killall snort && echo "$prog stopped."
}
status() {
if test "$pid" != ""; then
echo "$prog is running as pid $pid."
else
echo "$prog is not running."
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
# It seems that killing of snort requires some time
sleep 5
# The pid variable has not been cleared when snort is killed,
# but we don't know if snort is really killed, so check again
pid=""
pid=`ps ax | awk '{if (match($5, ".*/snort$") || $5 == "snort") print $1}'`
start
;;
status)
status
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
;;
esac
exit 0
# end
Verify that the pulledpork script works:
# python3 /usr/local/bin/pulledpork/pulledpork.py -c /usr/local/etc/pulledpork/pulledpork.conf
Running into this bug https://github.com/shirkdog/pulledpork3/issues/57
could it be related to if snort has moved stuff to AWS!?
Just saw that community_ruleset = true fetches things
if it would work for you, be happy. otherwise disable in crontab?
--- edit ---
this was all related to the version of snort that pulledpork uses, as of writing 3.8.1.0
which is not a snortrules-snapshot version on https://snort.org/downloads#rules.
By adding a snort_version = 3.9.0.0 to the pulledpork.conf it worked again.
You can verify that downloading the snortrules work, by running:
fetch 'https://snort.org/rules/snortrules-snapshot-3900.tar.gz?oinkcode=OINKCODE' -o snortrules-snapshot-3900.tar.gz
# mkdir /var/log/snort
# touch /var/log/snort/alert_csv.txt
then finally start the service:
# service snort start
it should write alot of output, then finally end with:
initializing daemon mode
child process is 53623
Commencing packet processing
++ [0] re0
Verify that the snort process is running : ps ax|grep snort
Wowie... this is a beast.
we did it. Oink oink!
Fly piggy flyyy