]> git.ipfire.org Git - ipfire-2.x.git/blob - config/suricata/convert-ids-backend-files
suricata: Change midstream policy to "pass-flow"
[ipfire-2.x.git] / config / suricata / convert-ids-backend-files
1 #!/usr/bin/perl
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2021 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 use File::Copy;
25
26 require '/var/ipfire/general-functions.pl';
27 require '/var/ipfire/ids-functions.pl';
28
29 # Exit if there is no main oinkmaster config file anymore.
30 exit 0 unless (-f "$IDS::settingsdir/oinkmaster.conf");
31
32 # Array of old files, which are safe to drop.
33 my @files_to_drop = (
34 # Old settings files of oinkmaster.
35 "$IDS::settingsdir/oinkmaster.conf",
36 "$IDS::settingsdir/oinkmaster-disabled-sids.conf",
37 "$IDS::settingsdir/oinkmaster-enabled-sids.conf",
38 "$IDS::settingsdir/oinkmaster-modify-sids.conf",
39 "$IDS::settingddir/oinkmaster-provider-includes.conf",
40
41 # Old settingsfiles for suricata.
42 "$IDS::settingsdir/suricata-default-rules.yaml",
43 "$IDS::settingsdir/suricata-static-included-rulefiles.yaml",
44 "$IDS::settingsdir/suricata-used-providers.yaml",
45 "$IDS::settingsdir/suricata-used-rulefiles.yaml"
46 );
47
48 #
49 ## Step 1: Stop suricata if it is running.
50 #
51 my $start_suricata;
52
53 # Check if the IDS is running.
54 if(&IDS::ids_is_running()) {
55 # Call suricatactrl to stop the IDS.
56 &IDS::call_suricatactrl("stop");
57
58 # Set start_suricata to true to start it
59 # at the end of the script again.
60 $start_suricata = "1";
61
62 # Wait until suricata has stopped.
63 sleep 1 while (-f $IDS::idspidfile);
64 }
65
66 #
67 ## Step 2: Move downloaded files to new location.
68 #
69
70 my $old_dl_rulesfiles_dir = "/var/tmp";
71
72 # Open old rules directory and do a directory listsing.
73 opendir(DIR, "$old_dl_rulesfiles_dir");
74
75 # Loop through the files of the directory.
76 while (my $file = readdir(DIR)) {
77 # Check if the file starts with an "idsrules-".
78 if ($file =~ /^idsrules-/) {
79 # Grab the mtime of the file.
80 my $mtime=(stat "$old_dl_rulesfiles_dir/$file")[9];
81
82 # Move the file to its new location.
83 move("$old_dl_rulesfiles_dir/$file", "$IDS::dl_rules_path/$file");
84
85 # Set correct ownership.
86 &IDS::set_ownership("$IDS::dl_rules_path/$file");
87
88 # Restore the mtime on the file.
89 utime(time(), "$mtime", "$IDS::dl_rules_path/$file");
90 }
91 }
92
93 # Close directory handle.
94 closedir(DIR);
95
96 # Get all supported providers.
97 my @providers = &IDS::get_ruleset_providers();
98
99 #
100 ## Step 3: Convert used rules files.
101 #
102
103 # Loop through the array of known providers.
104 foreach my $provider (@providers) {
105 my %used_rulesfiles = ();
106
107 # Generate old filename which contained the used rulesfile.
108 my $old_used_rulesfiles_file = "$IDS::settingsdir/suricata-$provider\-used-rulefiles.yaml";
109
110 # Skip the provider if there is no used rulesfiles file available.
111 next unless (-f $old_used_rulesfiles_file);
112
113 # Open the used rulesfiles file.
114 open(FILE, "$old_used_rulesfiles_file");
115
116 # Read-in the file content.
117 my @file = <FILE>;
118
119 # Close file handle.
120 close(FILE);
121
122 # Loop through the file content.
123 foreach my $line(@file) {
124 chomp($line);
125
126 # Grab the used rulesfile name from the line.
127 if ($line =~ /^\s-\s(.*)/) {
128 my $rulesfile = $1;
129
130 # Add the used rulesfile to the has of used rulesfile for this provider.
131 $used_rulesfiles{$rulesfile} = "enabled";
132 }
133 }
134
135 # Get the filename for the new used rulesfiles file.
136 my $used_rulesfiles_file = &IDS::get_provider_used_rulesfiles_file($provider);
137
138 # Write the file.
139 &General::writehash("$used_rulesfiles_file", \%used_rulesfiles);
140
141 # Set the correct ownership for the new file.
142 &IDS::set_ownership("$used_rulesfiles_file");
143
144 # Delete old used rulesfiles file.
145 unlink("$old_used_rulesfiles_file");
146 }
147
148 #
149 ## Step 4: Convert ruleset modifictaion files.
150 #
151
152 # Loop through the array of providers.
153 foreach my $provider (@providers) {
154 my %modifications = ();
155
156 # Generate old filename which hold the ruleset modifications.
157 my $old_modifications_file = "$IDS::settingsdir/oinkmaster\-$provider\-modified-sids.conf";
158
159 # Skip provider if there is no modifications file.
160 next unless (-f $old_modifications_file);
161
162 # Open modifications file.
163 open(FILE, "$old_modifications_file");
164
165 # Read-in file content.
166 my @file = <FILE>;
167
168 # Close file handle.
169 close(FILE);
170
171 # Loop through the file content.
172 foreach my $line (@file) {
173 chomp($line);
174
175 # Split line and assign to an temporary array.
176 my @tmp = split(/ /, $line);
177
178 # Assign nice human-readable variables.
179 my $action = $tmp[0];
180 my $sid = $tmp[1];
181
182 # Process stored rule action and assign to the modifications hash.
183 if ($action eq "enablesid") {
184 $modifications{$sid} = "enabled";
185
186 } elsif ($action eq "disablesid") {
187 $modifications{$sid} = "disabled";
188 }
189 }
190
191 # Get new filename which will hold the ruleset modifications for this provider.
192 my $new_modifications_file = &IDS::get_provider_ruleset_modifications_file($provider);
193
194 # Write new modifications file.
195 &General::writehash("$new_modifications_file", \%modifications);
196
197 # Set correct ownership for the new modifications file.
198 &IDS::set_ownership("$new_modifications_file");
199
200 # Delete old modifications file.
201 unlink("$old_modifications_file");
202 }
203
204 #
205 ## Step 5: Convert MONTIOR_TRAFFIC_ONLY setting.
206 #
207
208 my %ids_settings = ();
209 my %provider_settings = ();
210
211 &General::readhash("$IDS::ids_settings_file", \%ids_settings);
212 &General::readhasharray("$IDS::providers_settings_file", \%provider_settings);
213
214 # Default to IPS mode.
215 my $mode = "IPS";
216
217 # Check if MONTOR_TRAFFIC_ONLY has been activated.
218 if(($ids_settings{'MONITOR_TRAFFIC_ONLY'} && $ids_settings{'MONITOR_TRAFFIC_ONLY'} eq "on")) {
219 $mode = "IDS";
220 }
221
222 # Loop through the hash of providers.
223 foreach my $key (keys %provider_settings) {
224 # Get and dereference settings array from hash.
225 my @settings = @{ $provider_settings{$key} };
226
227 # Add the mode as last element to the settings array.
228 push(@settings, $mode);
229
230 # Assign the new settings to the hash.
231 $provider_settings{$key} = [ @settings ];
232 }
233
234 # Write back providers settings.
235 &General::writehasharray("$IDS::providers_settings_file", \%provider_settings);
236
237 #
238 ## Step 6: Regenerate the ruleset.
239 #
240 #
241
242 # Call oinkmaster wrapper function.
243 &IDS::oinkmaster();
244
245 #
246 ## Step 7: Write new config file for suricata which contains the used rulesfiles.
247 #
248
249 # Get enabled providers.
250 my @enabled_providers = &IDS::get_enabled_providers();
251
252 # Write used rulesfiles file.
253 &IDS::write_used_rulefiles_file(@enabled_providers);
254
255 # Set the correct ownership for the new file.
256 &IDS::set_ownership("$IDS::suricata_used_rulesfiles_file");
257
258 #
259 ## Step 8: Remove unneeded orphaned files.
260 #
261
262 # Loop through the array of files which are safe to drop.
263 foreach my $file (@files_to_drop) {
264 # Remove the file if it exists.
265 unlink("$file") if (-f "$file");
266 }
267
268 #
269 ## Step 9: Start the IDS again, if it was running.
270 #
271
272 # Check if the IDS is running.
273 if($start_suricata) {
274 # Call suricatactrl to perform the start of the IDS.
275 &IDS::call_suricatactrl("start");
276 }