]>
Commit | Line | Data |
---|---|---|
d72b3e64 | 1 | #!/bin/sh |
66c36198 PM |
2 | ############################################################################### |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
5 | # Copyright (C) 2007-2022 IPFire Team <info@ipfire.org> # | |
6 | # # | |
7 | # This program is free software: you can redistribute it and/or modify # | |
8 | # it under the terms of the GNU General Public License as published by # | |
9 | # the Free Software Foundation, either version 3 of the License, or # | |
10 | # (at your option) any later version. # | |
11 | # # | |
12 | # This program is distributed in the hope that it will be useful, # | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
15 | # GNU General Public License for more details. # | |
16 | # # | |
17 | # You should have received a copy of the GNU General Public License # | |
18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
19 | # # | |
20 | ############################################################################### | |
d72b3e64 SS |
21 | |
22 | . /etc/sysconfig/rc | |
23 | . ${rc_functions} | |
24 | ||
25 | PATH=/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin; export PATH | |
26 | ||
d72b3e64 | 27 | eval $(/usr/local/bin/readhash /var/ipfire/suricata/settings) |
e8a28edb | 28 | eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings) |
d72b3e64 | 29 | |
9cf253e1 SS |
30 | # Name of the firewall chains. |
31 | IPS_INPUT_CHAIN="IPS_INPUT" | |
32 | IPS_FORWARD_CHAIN="IPS_FORWARD" | |
33 | IPS_OUTPUT_CHAIN="IPS_OUTPUT" | |
3c2c5483 SS |
34 | |
35 | # Optional options for the Netfilter queue. | |
36 | NFQ_OPTS="--queue-bypass " | |
37 | ||
38 | # Array containing the 4 possible network zones. | |
51b63b41 | 39 | network_zones=( red green blue orange ovpn ) |
3c2c5483 | 40 | |
9cf253e1 SS |
41 | # Array to store the network zones weather the IPS is enabled for. |
42 | enabled_ips_zones=() | |
43 | ||
00a03114 SS |
44 | # PID file of suricata. |
45 | PID_FILE="/var/run/suricata.pid" | |
46 | ||
c9b07d6a SS |
47 | # Function to get the amount of CPU cores of the system. |
48 | function get_cpu_count { | |
49 | CPUCOUNT=0 | |
50 | ||
51 | # Loop through "/proc/cpuinfo" and count the amount of CPU cores. | |
52 | while read line; do | |
53 | [ "$line" ] && [ -z "${line%processor*}" ] && ((CPUCOUNT++)) | |
54 | done </proc/cpuinfo | |
55 | ||
a8387f8d SS |
56 | # Limit to a maximum of 16 cores, because suricata does not support more than |
57 | # 16 netfilter queues at the moment. | |
58 | if [ $CPUCOUNT -gt "16" ]; then | |
59 | echo "16" | |
60 | else | |
61 | echo $CPUCOUNT | |
62 | fi | |
c9b07d6a SS |
63 | } |
64 | ||
9cf253e1 | 65 | # Function to flush the firewall chains. |
5e3067cb | 66 | function flush_fw_chain { |
9cf253e1 | 67 | # Call iptables and flush the chains |
f78eb45c MT |
68 | iptables -w -F "$IPS_INPUT_CHAIN" |
69 | iptables -w -F "$IPS_FORWARD_CHAIN" | |
70 | iptables -w -F "$IPS_OUTPUT_CHAIN" | |
5e3067cb SS |
71 | } |
72 | ||
c9b07d6a SS |
73 | # Function to create the firewall rules to pass the traffic to suricata. |
74 | function generate_fw_rules { | |
75 | cpu_count=$(get_cpu_count) | |
76 | ||
c9b07d6a SS |
77 | # Loop through the array of network zones. |
78 | for zone in "${network_zones[@]}"; do | |
79 | # Convert zone into upper case. | |
80 | zone_upper=${zone^^} | |
81 | ||
82 | # Generate variable name for checking if the IDS is | |
83 | # enabled on the zone. | |
84 | enable_ids_zone="ENABLE_IDS_$zone_upper" | |
85 | ||
86 | # Check if the IDS is enabled for this network zone. | |
87 | if [ "${!enable_ids_zone}" == "on" ]; then | |
e8a28edb SS |
88 | # Check if the current processed zone is "red" and the configured type is PPPoE dialin. |
89 | if [ "$zone" == "red" ] && [ "$RED_TYPE" == "PPPOE" ]; then | |
90 | # Set device name to ppp0. | |
91 | network_device="ppp0" | |
51b63b41 SS |
92 | elif [ "$zone" == "ovpn" ]; then |
93 | # Get all virtual net devices because the RW server and each | |
94 | # N2N connection creates it's own tun device. | |
95 | for virt_dev in /sys/devices/virtual/net/*; do | |
96 | # Cut-off the directory. | |
97 | dev="${virt_dev##*/}" | |
98 | ||
99 | # Only process tun devices. | |
100 | if [[ $dev =~ "tun" ]]; then | |
101 | # Add the network device to the array of enabled zones. | |
102 | enabled_ips_zones+=( "$dev" ) | |
103 | fi | |
104 | done | |
105 | ||
106 | # Process next zone. | |
107 | continue | |
e8a28edb SS |
108 | else |
109 | # Generate variable name which contains the device name. | |
110 | zone_name="$zone_upper" | |
111 | zone_name+="_DEV" | |
112 | ||
113 | # Grab device name. | |
114 | network_device=${!zone_name} | |
115 | fi | |
c9b07d6a | 116 | |
9cf253e1 SS |
117 | # Add the network device to the array of enabled zones. |
118 | enabled_ips_zones+=( "$network_device" ) | |
c9b07d6a SS |
119 | fi |
120 | done | |
5d04cfe7 | 121 | |
9cf253e1 SS |
122 | # Assign NFQ_OPTS |
123 | NFQ_OPTIONS=$NFQ_OPTS | |
124 | ||
125 | # Check if there are multiple cpu cores available. | |
126 | if [ "$cpu_count" -gt "1" ]; then | |
127 | # Balance beetween all queues. | |
128 | NFQ_OPTIONS+="--queue-balance 0:$(($cpu_count-1))" | |
129 | NFQ_OPTIONS+=" --queue-cpu-fanout" | |
130 | else | |
131 | # Send all packets to queue 0. | |
132 | NFQ_OPTIONS+="--queue-num 0" | |
133 | fi | |
134 | ||
135 | # Flush the firewall chains. | |
136 | flush_fw_chain | |
137 | ||
138 | # Check if the array of enabled_ips_zones contains any elements. | |
139 | if [[ ${enabled_ips_zones[@]} ]]; then | |
140 | # Loop through the array and create firewall rules. | |
141 | for enabled_ips_zone in "${enabled_ips_zones[@]}"; do | |
142 | # Create rules queue input and output related traffic and pass it to the IPS. | |
3fa8300e MT |
143 | iptables -w -A "$IPS_INPUT_CHAIN" -i "$enabled_ips_zone" -j NFQUEUE $NFQ_OPTIONS |
144 | iptables -w -A "$IPS_OUTPUT_CHAIN" -o "$enabled_ips_zone" -j NFQUEUE $NFQ_OPTIONS | |
9cf253e1 SS |
145 | |
146 | # Create rules which are required to handle forwarded traffic. | |
147 | for enabled_ips_zone_forward in "${enabled_ips_zones[@]}"; do | |
3fa8300e | 148 | iptables -w -A "$IPS_FORWARD_CHAIN" -i "$enabled_ips_zone" -o "$enabled_ips_zone_forward" -j NFQUEUE $NFQ_OPTIONS |
9cf253e1 SS |
149 | done |
150 | done | |
9cf253e1 | 151 | fi |
c9b07d6a SS |
152 | } |
153 | ||
d72b3e64 SS |
154 | case "$1" in |
155 | start) | |
156 | # Get amount of CPU cores. | |
c9b07d6a SS |
157 | cpu_count=$(get_cpu_count) |
158 | ||
159 | # Numer of NFQUES. | |
1a65ea1b | 160 | NFQUEUES="-q 0" |
c9b07d6a | 161 | |
1a65ea1b SS |
162 | if [ $cpu_count -gt "1" ]; then |
163 | NFQUEUES+=":$(($cpu_count-1))" | |
164 | fi | |
d72b3e64 | 165 | |
3c2c5483 SS |
166 | # Check if the IDS should be started. |
167 | if [ "$ENABLE_IDS" == "on" ]; then | |
3c2c5483 SS |
168 | # Start the IDS. |
169 | boot_mesg "Starting Intrusion Detection System..." | |
af006569 | 170 | /usr/bin/suricata -c /etc/suricata/suricata.yaml -D $NFQUEUES >/dev/null 2>/dev/null |
3c2c5483 | 171 | evaluate_retval |
00a03114 SS |
172 | |
173 | # Allow reading the pidfile. | |
174 | chmod 644 $PID_FILE | |
c9b07d6a SS |
175 | |
176 | # Flush the firewall chain | |
177 | flush_fw_chain | |
178 | ||
179 | # Generate firewall rules | |
180 | generate_fw_rules | |
3c2c5483 | 181 | fi |
d72b3e64 SS |
182 | ;; |
183 | ||
184 | stop) | |
185 | boot_mesg "Stopping Intrusion Detection System..." | |
00a03114 | 186 | killproc -p $PID_FILE /var/run |
d72b3e64 | 187 | |
3c2c5483 | 188 | # Flush firewall chain. |
c9b07d6a | 189 | flush_fw_chain |
3c2c5483 | 190 | |
57fda8c8 AF |
191 | # Sometimes suricata not correct shutdown. So killall. |
192 | killall -KILL /usr/bin/suricata 2>/dev/null | |
193 | ||
194 | # Remove suricata control socket. | |
d72b3e64 SS |
195 | rm /var/run/suricata/* >/dev/null 2>/dev/null |
196 | ||
62910a28 SS |
197 | # Trash remain pid file if still exists. |
198 | rm -f $PID_FILE >/dev/null 2>/dev/null | |
199 | ||
d72b3e64 SS |
200 | # Don't report returncode of rm if suricata was not started |
201 | exit 0 | |
202 | ;; | |
66c36198 | 203 | |
d72b3e64 SS |
204 | status) |
205 | statusproc /usr/bin/suricata | |
206 | ;; | |
66c36198 | 207 | |
d72b3e64 SS |
208 | restart) |
209 | $0 stop | |
210 | $0 start | |
211 | ;; | |
6187da50 SS |
212 | reload) |
213 | # Send SIGUSR2 to the suricata process to perform a reload | |
214 | # of the ruleset. | |
215 | kill -USR2 $(pidof suricata) | |
c9b07d6a SS |
216 | |
217 | # Flush the firewall chain. | |
218 | flush_fw_chain | |
219 | ||
220 | # Generate firewall rules. | |
221 | generate_fw_rules | |
6187da50 | 222 | ;; |
66c36198 | 223 | |
d72b3e64 | 224 | *) |
6187da50 | 225 | echo "Usage: $0 {start|stop|restart|reload|status}" |
d72b3e64 SS |
226 | exit 1 |
227 | ;; | |
228 | esac | |
229 | ||
230 | chmod 644 /var/log/suricata/* 2>/dev/null |