3 # Display current iptables firewall configuration from save file
5 require './firewall-lib.pl';
7 if ($iptables_save_file) {
8 $desc = &text('index_editing', "<tt>$iptables_save_file</tt>");
10 &ui_print_header(undef, $text{'index_title'}, undef, "intro", 1, 1, 0,
11 &help_search_link("iptables", "man", "doc"), undef, undef, $desc);
13 # Check for iptables and iptables-restore commands
14 if ($c = &missing_firewall_commands()) {
15 print "<p>",&text('index_ecommand', "<tt>$c</tt>"),"<p>\n";
16 &ui_print_footer("/", $text{'index'});
20 # Check if the kernel supports iptables
21 $out = `iptables -n -t filter -L OUTPUT 2>&1`;
23 print "<p>",&text('index_ekernel', "<pre>$out</pre>"),"<p>\n";
24 &ui_print_footer("/", $text{'index'});
28 # Check if the distro supports iptables
29 if (!$config{'direct'} && defined(&check_iptables) &&
30 ($err = &check_iptables())) {
31 print "<p>$err</p>\n";
32 &ui_print_footer("/", $text{'index'});
36 # Check if firewall is being started at boot
37 if (!$config{'direct'} && &foreign_check("init")) {
39 if (defined(&started_at_boot)) {
40 $atboot = &started_at_boot();
43 &foreign_require("init", "init-lib.pl");
44 $atboot = &init::action_status("webmin-iptables") == 2;
48 # Check if the save file exists. If not, check for any existing firewall
49 # rules, and offer to create a save file from them
50 @livetables = &get_iptables_save("iptables-save 2>/dev/null |");
51 &shorewall_message(\@livetables);
52 if (!$config{'direct'} &&
53 (!-s $iptables_save_file || $in{'reset'}) && $access{'setup'}) {
54 @tables = @livetables;
55 foreach $t (@tables) {
56 $rules++ if (@{$t->{'rules'}});
57 foreach $c (keys %{$t->{'defaults'}}) {
58 $chains++ if ($t->{'defaults'}->{$c} ne 'ACCEPT');
60 $hastable{$t->{'name'}}++;
62 foreach $t (@known_tables) {
63 system("iptables -t $t -n -L >/dev/null") if (!$hastable{$t});
65 if (!$in{'reset'} && ($rules || $chains)) {
66 # Offer to save the current rules
67 print &text('index_existing', $rules,
68 "<tt>$iptables_save_file</tt>"),"<p>\n";
69 print "<form action=convert.cgi>\n";
70 print "<center><input type=submit ",
71 "value='$text{'index_saveex'}'><p>\n";
72 if ($init_support && !$atboot) {
73 print "<input type=checkbox name=atboot value=1> ",
74 "$text{'index_atboot'}\n";
76 print "</center></form><p>\n";
78 print "<table border width=100%>\n";
79 print "<tr $tb><td><b>$text{'index_headerex'}</b></td></tr>\n";
80 print "<tr $cb> <td><pre>";
81 open(OUT, "iptables-save 2>/dev/null |");
83 print &html_escape($_);
86 print "</pre></td> </tr></table>\n";
89 # Offer to set up a firewall
90 print &text($in{'reset'} ? 'index_rsetup' : 'index_setup',
91 "<tt>$iptables_save_file</tt>"),"<p>\n";
92 print "<form action=setup.cgi>\n";
93 print &ui_hidden("reset", $in{'reset'});
94 print "<center><table><tr><td>\n";
95 print "<input type=radio name=auto value=0 checked> ",
96 "$text{'index_auto0'}<p>\n";
98 print "<input type=radio name=auto value=$a> ",
99 "$text{'index_auto'.$a} ",
100 &interface_choice("iface".$a),"<p>\n";
102 print "</td></tr></table>\n";
103 print "<input type=submit value='$text{'index_auto'}'><p>\n";
104 if ($init_support && !$atboot) {
105 print "<input type=checkbox name=atboot value=1> ",
106 "$text{'index_atboot'}\n";
108 print "</center></form>\n";
113 @tables = &get_iptables_save();
114 if (!$config{'direct'}) {
115 # Verify that all known tables exist, and if not add them to the
117 foreach $t (@tables) {
118 $hastable{$t->{'name'}}++;
120 foreach $t (@known_tables) {
121 if (!$hastable{$t}) {
122 local ($missing) = &get_iptables_save(
123 "iptables-save --table $t 2>/dev/null |");
125 delete($missing->{'line'});
126 &save_table($missing);
131 @tables = &get_iptables_save() if ($need_reload);
134 # Work out the default table
135 if (!defined($in{'table'})) {
136 foreach $t (@tables) {
137 if (@{$t->{'rules'}} && &can_edit_table($t->{'name'})) {
138 $in{'table'} = $t->{'index'};
143 if (!defined($in{'table'})) {
144 foreach $t (@tables) {
145 if (&can_edit_table($t->{'name'})) {
146 $in{'table'} = $t->{'index'};
151 $table = $tables[$in{'table'}];
153 # Allow selection of a table
154 print "<table width=100%><tr>\n";
155 print "<form action=index.cgi>\n";
156 print "<td><input type=submit value='$text{'index_change'}'>\n";
157 print "<select name=table onChange='form.submit()'>\n";
158 foreach $t (@tables) {
159 if (&can_edit_table($t->{'name'})) {
160 printf "<option value=%s %s>%s\n",
161 $t->{'index'}, $t eq $table ? "selected" : "",
162 &text('index_table_'.$t->{'name'}) || $t->{'name'};
165 print "</select></td></form>\n";
168 if ($access{'newchain'}) {
169 # Show form to create a chain
170 print "<form action=newchain.cgi>\n";
171 print "<td align=right>",&ui_hidden("table", $in{'table'});
172 print "<input type=submit value='$text{'index_cadd'}'>\n";
173 print "<input name=chain size=20></td></form>\n";
174 print "</tr></table>\n";
178 # Display a table of rules for each chain
179 foreach $c (sort by_string_for_iptables keys %{$table->{'defaults'}}) {
181 @rules = grep { lc($_->{'chain'}) eq lc($c) }
182 @{$table->{'rules'}};
183 print "<b>",$text{"index_chain_".lc($c)} ||
184 &text('index_chain', "<tt>$c</tt>"),"</b><br>\n";
185 print "<form action=save_policy.cgi>\n";
186 print &ui_hidden("table", $in{'table'});
187 print &ui_hidden("chain", $c);
189 @links = ( &select_all_link("d", $form),
190 &select_invert_link("d", $form) );
191 print &ui_links_row(\@links);
193 # Generate the header
194 local (@hcols, @tds);
195 push(@hcols, "", $text{'index_action'});
196 push(@tds, "width=5", "width=10% nowrap");
197 if ($config{'view_condition'}) {
198 push(@hcols, $text{'index_desc'});
201 if ($config{'view_comment'}) {
202 push(@hcols, $text{'index_comm'});
205 push(@hcols, $text{'index_move'}, $text{'index_add'});
206 push(@tds, "width=32", "width=32");
207 print &ui_columns_start(\@hcols, 100, 0, \@tds);
209 # Generate a row for each rule
210 foreach $r (@rules) {
211 $edit = &can_jump($r);
214 $text{"index_jump_".lc($r->{'j'}->[1])} ||
215 &text('index_jump', $r->{'j'}->[1]);
217 push(@cols, "<a href='edit_rule.cgi?table=".&urlize($in{'table'})."&idx=$r->{'index'}'>$act</a>");
222 if ($config{'view_condition'}) {
223 push(@cols, &describe_rule($r));
225 if ($config{'view_comment'}) {
226 $cmt = $config{'comment_mod'} ||
228 $r->{'comment'}->[1] : $r->{'cmt'};
234 if ($r eq $rules[@rules-1]) {
235 $mover .= "<img src=images/gap.gif>";
238 $mover .= "<a href='move.cgi?table=".
239 &urlize($in{'table'}).
240 "&idx=$r->{'index'}&".
242 "images/down.gif border=0></a>";
244 if ($r eq $rules[0]) {
245 $mover .= "<img src=images/gap.gif>";
248 $mover .= "<a href='move.cgi?table=".
249 &urlize($in{'table'}).
250 "&idx=$r->{'index'}&".
251 "up=1'><img src=images/up.gif ".
256 # Before / after adder
258 $adder .= "<a href='edit_rule.cgi?table=".
259 &urlize($in{'table'}).
260 "&chain=".&urlize($c)."&new=1&".
261 "after=$r->{'index'}'><img src=".
262 "images/after.gif border=0></a>";
263 $adder .= "<a href='edit_rule.cgi?table=".
264 &urlize($in{'table'}).
265 "&chain=".&urlize($c)."&new=1&".
266 "before=$r->{'index'}'><img src=".
267 "images/before.gif border=0></a>";
271 print &ui_checked_columns_row(
272 \@cols, \@tds, "d", $r->{'index'});
275 print &ui_columns_row(\@cols, \@tds);
278 print &ui_columns_end();
279 print &ui_links_row(\@links);
282 print "<b>$text{'index_none'}</b><br>\n";
285 # Show policy changing button for chains that support it,
286 # and rule-adding button
287 print "<table width=100%><tr>\n";
288 local $d = $table->{'defaults'}->{$c};
291 if ($access{'policy'}) {
292 # Change default button
293 print "<td width=33% nowrap>",
294 &ui_submit($text{'index_policy'}),"\n";
295 print "<select name=policy>\n";
296 foreach $t ('ACCEPT','DROP','QUEUE','RETURN') {
297 printf "<option value=%s %s>%s\n",
298 $t, $d eq $t ? "selected" : "",
299 $text{"index_policy_".lc($t)};
301 print "</select></td>\n";
304 print "<td width=33%></td>\n";
306 print "<td align=center width=33%>\n";
308 # Delete selected button
309 print &ui_submit($text{'index_cdeletesel'},
312 # Move selected button
313 print &ui_submit($text{'index_cmovesel'},
320 if ($access{'delchain'}) {
321 # Delete and rename chain buttons
322 print "<td width=33%>",
323 &ui_submit($text{'index_cdelete'}, "delete"),
325 &ui_submit($text{'index_crename'}, "rename"),
328 print "<td align=center width=33%>\n";
331 if ($access{'delchain'}) {
332 print &ui_submit($text{'index_cclear'},
336 # Delete rules button
337 print &ui_submit($text{'index_cdeletesel'},
340 # Move selected button
341 print &ui_submit($text{'index_cmovesel'},
346 print "<td align=right width=33%>",
347 &ui_submit($text{'index_radd'}, "add"),"</td>\n";
348 print "</tr></table></form>\n";
352 # Display buttons for applying and un-applying the configuration,
353 # and for creating an init script if possible
355 print "<table width=100%>\n";
357 if (!$config{'direct'}) {
358 if (&foreign_check("servers")) {
359 @servers = &list_cluster_servers();
361 if ($access{'apply'}) {
362 print "<tr><form action=apply.cgi>\n";
363 print &ui_hidden("table", $in{'table'});
364 print "<td><input type=submit ",
365 "value='$text{'index_apply'}'></td>\n";
367 print "<td>$text{'index_applydesc2'}</td>\n";
370 print "<td>$text{'index_applydesc'}</td>\n";
372 print "</form></tr>\n";
375 if ($access{'unapply'}) {
376 print "<tr><form action=unapply.cgi>\n";
377 print &ui_hidden("table", $in{'table'});
378 print "<td><input type=submit ",
379 "value='$text{'index_unapply'}'></td>\n";
380 print "<td>$text{'index_unapplydesc'}</td>\n";
381 print "</form></tr>\n";
384 if ($init_support && $access{'bootup'}) {
385 print "<tr><form action=bootup.cgi>\n";
386 print &ui_hidden("table", $in{'table'});
387 print "<td nowrap><input type=submit ",
388 "value='$text{'index_bootup'}'>\n";
389 printf "<input type=radio name=boot value=1 %s> %s\n",
390 $atboot ? "checked" : "", $text{'yes'};
391 printf "<input type=radio name=boot value=0 %s> %s\n",
392 $atboot ? "" : "checked", $text{'no'};
393 print "</td> <td>$text{'index_bootupdesc'}</td>\n";
394 print "</form></tr>\n";
397 if ($access{'setup'}) {
398 print "<tr><form action=index.cgi>\n";
399 print "<input type=hidden name=reset value=1>\n";
400 print "<td><input type=submit ",
401 "value='$text{'index_reset'}'></td>\n";
402 print "<td>$text{'index_resetdesc'}</td>\n";
403 print "</form></tr>\n";
407 # Show button for cluster page
408 if (&foreign_check("servers")) {
409 &foreign_require("servers", "servers-lib.pl");
410 @allservers = grep { $_->{'user'} }
411 &servers::list_servers();
413 if ($access{'cluster'} && @allservers) {
414 print "<tr><form action=cluster.cgi>\n";
415 print "<td><input type=submit ",
416 "value='$text{'index_cluster'}'></td>\n";
417 print "<td>$text{'index_clusterdesc'}</td>\n";
418 print "</form></tr>\n";
424 &ui_print_footer("/", $text{'index'});
426 sub shorewall_message
428 local ($filter) = grep { $_->{'name'} eq 'filter' } @{$_[0]};
429 if ($filter->{'defaults'}->{'shorewall'}) {
431 &text('index_shorewall', "$gconfig{'webprefix'}/shorewall/"),
432 "</b></center><p>\n";