1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#!/bin/sh
# Copyright (c) 2023 Eric Fahlgren <eric.fahlgren@gmail.com>
# SPDX-License-Identifier: GPL-2.0
# shellcheck disable=SC2039 # "local" not defined in POSIX sh
alias log='logger -s -t "snort-rules[$$]" -p "info"'
[ "$1" = "-t" ] && testing=true || testing=false
download_rules() {
# Further information:
# https://www.snort.org/products#rule_subscriptions
# https://www.snort.org/oinkcodes
#
# Also, what to do about "subscription" vs Talos_LightSPD rules when subbed?
# Add a "use_rules" list or option or something?
oinkcode=$(uci -q get snort.snort.oinkcode)
local conf_dir=$(uci -q get snort.snort.config_dir || echo "/etc/snort")
local rules_file="$conf_dir/rules/snort.rules"
local data_dir=$(uci -q get snort.snort.temp_dir || echo "/var/snort.d")
local data_tar="$data_dir/rules.tar.gz"
# Make sure everything exists.
[ -d "$data_dir" ] || mkdir -p "$data_dir"
if $testing ; then
log "Generating testing rules..."
new_rules="$data_dir/testing.rules"
rm -f "$new_rules"
echo 'alert icmp any any <> any any (msg:"TEST ALERT ICMP v4"; icode:0; itype: 8; sid:10000010; rev:001;)' >> "$new_rules"
#echo 'alert icmp any any <> any any (msg:"TEST ALERT ICMP v6"; icode:0; itype:33; sid:10000011; rev:001;)' >> "$new_rules"
#echo 'alert icmp any any <> any any (msg:"TEST ALERT ICMP v6"; icode:0; itype:34; sid:10000012; rev:001;)' >> "$new_rules"
else
if [ -z "$oinkcode" ]; then
# If you do not have a subscription, then we use the community rules:
log "Downloading community rules..."
url="https://www.snort.org/downloads/community/snort3-community-rules.tar.gz"
else
# If you have a subscription and its corresponding oinkcode, use this:
#
# 'snortver' is the version number of the snort executable in use on your
# router.
#
# Ideally, the 'snort --version' output would work, but OpenWrt builds
# are often between (or, more likely, newer than) those listed on the
# snort.org downloads page.
#
# So instead, we define it manually to be the value just before the
# installed version. Look on https://www.snort.org/advisories/ and
# select the most recent date. On that page, find the closest version
# number preceding your installed version and modify the hard-coded
# value below (for example, installed is 31600 then use 31470):
#snortver=$(snort --version | awk '/Version/ {print gensub("\\.", "", "", $NF)}')
snortver=31470
log "Downloading subscription rules..."
url="https://www.snort.org/rules/snortrules-snapshot-$snortver.tar.gz?oinkcode=$oinkcode"
fi
wget "$url" -O "$data_tar" 2>&1 | log || exit 1
# ??? Does non-community tar contain just the one "*.rules" file, too???
new_rules=$(tar tzf "$data_tar" | grep '\.rules$')
new_rules="$data_dir/$new_rules"
old_rules="$data_dir/old.rules"
if [ -e "$new_rules" ]; then
# Before we overwrite with the new download.
log "Stashing old rules to $old_rules ..."
mv -f "$new_rules" "$old_rules"
fi
log "Unpacking $data_tar ..."
tar xzvf "$data_tar" -C "$data_dir" | log || exit 1
if [ -e "$old_rules" ] && ! cmp -s "$new_rules" "$old_rules" ; then
diff "$new_rules" "$old_rules" 2>&1 | log
fi
fi
rm -f "$rules_file"
ln -s "$new_rules" "$rules_file"
log "Snort rules loaded, restart snort now."
}
download_rules
|