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