]>
Commit | Line | Data |
---|---|---|
5b0b4182 SS |
1 | #!/usr/bin/perl |
2 | ############################################################################### | |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
5 | # Copyright (C) 2019 IPFire Development 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 | ############################################################################### | |
21 | ||
22 | use strict; | |
23 | ||
24 | require '/var/ipfire/general-functions.pl'; | |
25 | require "${General::swroot}/ids-functions.pl"; | |
26 | ||
27 | # Snort settings file, which contains the settings from the WUI. | |
28 | my $snort_settings_file = "${General::swroot}/snort/settings"; | |
29 | ||
30 | # Main snort config file. | |
31 | my $snort_config_file = "/etc/snort/snort.conf"; | |
32 | ||
33 | # Snort rules tarball. | |
34 | my $snort_rules_tarball = "/var/tmp/snortrules.tar.gz"; | |
35 | ||
5b0b4182 SS |
36 | # |
37 | ## Step 1: Setup directory and file layout, if not present and set correct | |
38 | ## ownership. The converter runs as a privileged user, but the files | |
39 | ## needs to be full access-able by the WUI user and group (nobody:nobody). | |
40 | # | |
41 | ||
5b0b4182 SS |
42 | # Check if the settings directory exists. |
43 | unless (-d $IDS::settingsdir) { | |
44 | # Create the directory. | |
45 | mkdir($IDS::settingsdir); | |
46 | } | |
47 | ||
48 | # Check if the rules directory exists. | |
49 | unless (-d $IDS::rulespath) { | |
50 | # Create the directory. | |
51 | mkdir($IDS::rulespath); | |
52 | } | |
53 | ||
5b0b4182 SS |
54 | # Create file layout, if not exists yet. |
55 | &IDS::check_and_create_filelayout(); | |
56 | ||
36e69d34 SS |
57 | # Set correct ownership for settingsdir and rulespath. |
58 | &IDS::set_ownership("$IDS::settingsdir"); | |
59 | &IDS::set_ownership("$IDS::rulespath"); | |
5b0b4182 | 60 | |
78690361 SS |
61 | # Check if a snort settings file exists. |
62 | unless( -f "$snort_settings_file") { | |
63 | print "$snort_settings_file not found - Nothing to do. Exiting!\n"; | |
64 | exit(0); | |
65 | } | |
66 | ||
67 | # Check if the snort settings file is empty. | |
68 | if (-z "$snort_settings_file") { | |
69 | print "$snort_settings_file is empty - Nothing to do. Exiting!\n"; | |
70 | exit(0); | |
71 | } | |
72 | ||
5b0b4182 SS |
73 | # |
74 | ## Step 2: Import snort settings and convert to the required format for the new IDS | |
75 | ## (suricata). | |
76 | # | |
77 | ||
78 | # Hash which contains the "old" snort settings. | |
79 | my %snortsettings; | |
80 | ||
81 | # Hash which contains the IDS (suricata) settings. | |
82 | # | |
83 | # Add default value for MONITOR_TRAFFIC_ONLY which will be "on" | |
84 | # when migrating from snort to the new IDS. | |
85 | my %idssettings = ( | |
86 | "MONITOR_TRAFFIC_ONLY" => "on", | |
87 | ); | |
88 | ||
89 | # Hash which contains the RULES settings. | |
90 | # | |
91 | # Set default value for UPDATE_INTERVAL to weekly. | |
92 | my %rulessettings = ( | |
93 | "AUTOUPDATE_INTERVAL" => "weekly", | |
94 | ); | |
95 | ||
96 | # Get all available network zones. | |
97 | my @network_zones = &IDS::get_available_network_zones(); | |
98 | ||
99 | # Read-in snort settings file. | |
100 | &General::readhash("$snort_settings_file", \%snortsettings); | |
101 | ||
102 | # Loop through the array of network zones. | |
103 | foreach my $zone (@network_zones) { | |
104 | # Convert current zone into upper case. | |
105 | my $zone_upper = uc($zone); | |
106 | ||
107 | # Check if the current network zone is "red". | |
108 | if($zone eq "red") { | |
109 | # Check if snort was enabled and enabled on red. | |
110 | if ($snortsettings{"ENABLE_SNORT"} eq "on") { | |
111 | # Enable the IDS. | |
112 | $idssettings{"ENABLE_IDS"} = "on"; | |
113 | ||
114 | # Enable the IDS on RED. | |
115 | $idssettings{"ENABLE_IDS_$zone_upper"} = "on"; | |
116 | } | |
117 | } else { | |
118 | # Check if snort was enabled on the current zone. | |
119 | if ($snortsettings{"ENABLE_SNORT_$zone_upper"} eq "on") { | |
120 | # Enable the IDS on this zone too. | |
121 | $idssettings{"ENABLE_IDS_$zone_upper"} = "on"; | |
122 | } | |
123 | } | |
124 | } | |
125 | ||
126 | # Grab the choosen ruleset from snort settings hash and store it in the rules | |
127 | # settings hash. | |
128 | $rulessettings{"RULES"} = $snortsettings{"RULES"}; | |
129 | ||
130 | # Check if an oinkcode has been provided. | |
131 | if($snortsettings{"OINKCODE"}) { | |
132 | # Take the oinkcode from snort settings hash and store it in the rules | |
133 | # settings hash. | |
134 | $rulessettings{"OINKCODE"} = $snortsettings{"OINKCODE"}; | |
135 | } | |
136 | ||
137 | # | |
138 | ## Step 3: Import guardian settings and whitelist if the addon is installed. | |
139 | # | |
140 | ||
141 | # Pakfire meta file for owncloud. | |
142 | # (File exists when the addon is installed.) | |
143 | my $guardian_meta = "/opt/pakfire/db/installed/meta-guardian"; | |
144 | ||
145 | # Check if the guardian addon is installed. | |
146 | if (-f $guardian_meta) { | |
147 | # File which contains the taken setting for guardian. | |
148 | my $guardian_settings_file = "${General::swroot}/guardian/settings"; | |
149 | ||
150 | # File which contains the white-listed hosts. | |
151 | my $guardian_ignored_file = "${General::swroot}/guardian/ignored"; | |
152 | ||
153 | # Hash which will contain the settings of guardian. | |
154 | my %guardiansettings; | |
155 | ||
156 | # Check if the settings file of guardian is empty. | |
157 | unless (-z $guardian_settings_file) { | |
158 | # Read-in settings. | |
159 | &General::readhash("$guardian_settings_file", \%guardiansettings); | |
160 | } | |
161 | ||
162 | # Check if guardian is not configured to take actions on snort events. | |
163 | if ($guardiansettings{"GUARDIAN_MONITOR_SNORT"} eq "on") { | |
164 | # Change the IDS into MONITOR_TRAFFIC_ONLY mode. | |
165 | $idssettings{"MONITOR_TRAFFIC_ONLY"} = "off"; | |
166 | } | |
167 | ||
168 | # Check if guardian has any white-listed hosts configured. | |
169 | unless (-z $guardian_ignored_file) { | |
170 | # Temporary hash to store the ignored hosts. | |
171 | my %ignored_hosts; | |
172 | ||
173 | # Read-in white-listed hosts and store them in the hash. | |
174 | &General::readhasharray($guardian_ignored_file, \%ignored_hosts); | |
175 | ||
176 | # Write-out the white-listed hosts for the IDS system. | |
177 | &General::writehasharray($IDS::ignored_file, \%ignored_hosts); | |
178 | ||
179 | # Call subfunction to generate the file for white-listing the hosts. | |
180 | &IDS::generate_ignored_file(); | |
181 | } | |
182 | ||
183 | } | |
184 | ||
185 | # | |
186 | ## Step 4: Save IDS and rules settings. | |
187 | # | |
188 | ||
189 | # Write IDS settings. | |
190 | &General::writehash("$IDS::ids_settings_file", \%idssettings); | |
191 | ||
192 | # Write rules settings. | |
193 | &General::writehash("$IDS::rules_settings_file", \%rulessettings); | |
194 | ||
195 | # | |
196 | ## Step 5: Generate and write the file to modify the ruleset. | |
197 | # | |
198 | ||
199 | # Converters default is to only monitor the traffic, so set the IDS action to | |
200 | # "alert". | |
201 | my $IDS_action = "alert"; | |
202 | ||
203 | # Check if the traffic only should be monitored. | |
204 | if ($idssettings{"MONITOR_TRAFFIC_ONLY"} eq "off") { | |
205 | # Swith IDS action to alert only. | |
206 | $IDS_action = "drop"; | |
207 | } | |
208 | ||
209 | # Call subfunction and pass the desired IDS action. | |
210 | &IDS::write_modify_sids_file($IDS_action); | |
211 | ||
5d7d8749 SS |
212 | # Set correct ownership. |
213 | &IDS::set_ownership("$IDS::modify_sids_file"); | |
214 | ||
5b0b4182 SS |
215 | # |
216 | ## Step 6: Move rulestarball to its new location. | |
217 | # | |
218 | ||
219 | # Check if a rulestarball has been downloaded yet. | |
220 | if (-f $snort_rules_tarball) { | |
221 | # Load perl module which contains the move command. | |
222 | use File::Copy; | |
223 | ||
224 | # Move the rulestarball to the new location. | |
225 | move($snort_rules_tarball, $IDS::rulestarball); | |
226 | ||
227 | # Set correct ownership. | |
b09c13f1 | 228 | &IDS::set_ownership("$IDS::rulestarball"); |
cc636c47 SS |
229 | |
230 | # In case no tarball is present, try to download the ruleset. | |
231 | } else { | |
232 | # Check if enought disk space is available. | |
233 | if(&IDS::checkdiskspace()) { | |
e4bc9b8b SS |
234 | # Print error message. |
235 | print "Could not download ruleset - Not enough free diskspace available.\n"; | |
236 | } else { | |
cc636c47 SS |
237 | # Call the download function and grab the new ruleset. |
238 | &IDS::downloadruleset(); | |
239 | } | |
5b0b4182 SS |
240 | } |
241 | ||
242 | # | |
243 | ## Step 7: Call oinkmaster to extract and setup the rules structures. | |
244 | # | |
245 | ||
246 | # Check if a rulestarball is present. | |
247 | if (-f $IDS::rulestarball) { | |
248 | # Launch oinkmaster by calling the subfunction. | |
249 | &IDS::oinkmaster(); | |
cc636c47 SS |
250 | |
251 | # Set correct ownership for the rulesdir and files. | |
252 | &IDS::set_ownership("$IDS::rulespath"); | |
5b0b4182 SS |
253 | } |
254 | ||
255 | # | |
ee82349a SS |
256 | ## Step 8: Generate file for the HOME Net. |
257 | # | |
258 | ||
259 | # Call subfunction to generate the file. | |
260 | &IDS::generate_home_net_file(); | |
261 | ||
d4f31567 SS |
262 | # Set correct ownership for the homenet file. |
263 | &IDS::set_ownership("$IDS::homenet_file"); | |
264 | ||
ee82349a SS |
265 | # |
266 | ## Step 9: Setup automatic ruleset updates. | |
267 | # | |
268 | ||
269 | # Check if a ruleset is configured. | |
270 | if($rulessettings{"RULES"}) { | |
271 | # Call suricatactrl and setup the periodic update mechanism. | |
272 | &IDS::call_suricatactrl("cron", $rulessettings{'AUTOUPDATE_INTERVAL'}); | |
273 | } | |
274 | ||
275 | # | |
276 | ## Step 10: Grab used ruleset files from snort config file and convert | |
5b0b4182 SS |
277 | ## them into the new format. |
278 | # | |
279 | ||
280 | # Check if the snort config file exists. | |
281 | unless (-f $snort_config_file) { | |
282 | print "$snort_config_file does not exist - Nothing to do. Exiting!\n"; | |
283 | exit(0); | |
284 | } | |
285 | ||
286 | # Array to store the enabled rules files. | |
287 | my @enabled_rule_files; | |
288 | ||
289 | # Open snort config file. | |
290 | open(SNORTCONF, $snort_config_file) or die "Could not open $snort_config_file. $!\n"; | |
291 | ||
292 | # Loop through the file content. | |
293 | while (my $line = <SNORTCONF>) { | |
294 | # Skip comments. | |
295 | next if ($line =~ /\#/); | |
296 | ||
297 | # Skip blank lines. | |
298 | next if ($line =~ /^\s*$/); | |
299 | ||
300 | # Remove newlines. | |
301 | chomp($line); | |
302 | ||
303 | # Check for a line with .rules | |
304 | if ($line =~ /\.rules$/) { | |
305 | # Parse out rule file name | |
306 | my $rulefile = $line; | |
307 | $rulefile =~ s/\$RULE_PATH\///i; | |
308 | $rulefile =~ s/ ?include ?//i; | |
309 | ||
310 | # Add the enabled rulefile to the array of enabled rule files. | |
311 | push(@enabled_rule_files, $rulefile); | |
312 | } | |
313 | } | |
314 | ||
315 | # Close filehandle. | |
316 | close(SNORTCONF); | |
317 | ||
318 | # Pass the array of enabled rule files to the subfunction and write the file. | |
319 | &IDS::write_used_rulefiles_file(@enabled_rule_files); | |
320 | ||
5b0b4182 SS |
321 | # |
322 | ## Step 11: Start the IDS if enabled. | |
323 | # | |
324 | ||
325 | # Check if the IDS should be started. | |
326 | if($idssettings{"ENABLE_IDS"} eq "on") { | |
327 | # Call suricatactrl and launch the IDS. | |
328 | &IDS::call_suricatactrl("start"); | |
329 | } |