From 345a92e04107617cb9c25fec93afee21d6b2ca13 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Tue, 11 Dec 2007 06:41:12 +0000 Subject: [PATCH] Better integration with FreeBSD rc.conf --- ipfw/CHANGELOG | 2 ++ ipfw/bootup.cgi | 5 ++- ipfw/config.info | 2 +- ipfw/index.cgi | 15 ++++----- ipfw/ipfw-lib.pl | 79 ++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 89 insertions(+), 14 deletions(-) diff --git a/ipfw/CHANGELOG b/ipfw/CHANGELOG index 70c5cf3c0..b63574065 100644 --- a/ipfw/CHANGELOG +++ b/ipfw/CHANGELOG @@ -6,3 +6,5 @@ Added button for deleting multiple rules from list. The firewall configuration can now be copied automatically to multiple hosts in a cluster, and will be applied on all hosts when the the Apply button is clicked. Like other cluster features in Webmin, this requires that the servers be first setup in the Webmin Servers Index module. ---- Changes since 1.260 ---- When creating a firewall rule, the rule number can be optionally manually entered. +---- Changes since 1.380 ---- +On FreeBSD systems, the firewall is now enabled at boot using /etc/rc.conf, and the IPFW config file specified in rc.conf is now used automatically. diff --git a/ipfw/bootup.cgi b/ipfw/bootup.cgi index 96d0443ce..cb92da5df 100755 --- a/ipfw/bootup.cgi +++ b/ipfw/bootup.cgi @@ -5,11 +5,10 @@ require './ipfw-lib.pl'; &ReadParse(); if ($in{'boot'}) { - &create_firewall_init(); + &enable_boot(); } else { - &foreign_require("init", "init-lib.pl"); - &init::disable_at_boot($module_name); + &disable_boot(); } &webmin_log($in{'boot'} ? "bootup" : "bootdown"); &redirect(""); diff --git a/ipfw/config.info b/ipfw/config.info index 525386241..ec35532b6 100644 --- a/ipfw/config.info +++ b/ipfw/config.info @@ -4,5 +4,5 @@ view_comment=Display comments?,1,1-Yes,0-No view_counters=Display counters?,1,1-Yes,0-No cluster_mode=Update cluster servers,1,0-Whenever a change is made,1-When applying the configuration line1=System configuration,11 -save_file=IPFW save file to edit,3,Webmin's default +save_file=IPFW save file to edit,3,Webmin's default or automatic ipfw=Full path to ipfw command,0 diff --git a/ipfw/index.cgi b/ipfw/index.cgi index 9bcfe1b1e..ae0b13fc8 100755 --- a/ipfw/index.cgi +++ b/ipfw/index.cgi @@ -152,8 +152,7 @@ elsif (@$rules && !$in{'reset'}) { # Show buttons to apply configuration and start at boot print "
\n"; - &foreign_require("init", "init-lib.pl"); - $atboot = &init::action_status($module_name); + $atboot = &check_boot(); print &ui_buttons_start(); if (&foreign_check("servers")) { @servers = &list_cluster_servers(); @@ -163,11 +162,13 @@ elsif (@$rules && !$in{'reset'}) { : $text{'index_applydesc'}); print &ui_buttons_row("unapply.cgi", $text{'index_unapply'}, $text{'index_unapplydesc'}); - print &ui_buttons_row("bootup.cgi", $text{'index_boot'}, - $text{'index_bootdesc'}, undef, - &ui_radio("boot", $atboot == 2 ? 1 : 0, - [ [ 1, $text{'yes'} ], - [ 0, $text{'no'} ] ])); + if ($atboot != -1) { + print &ui_buttons_row("bootup.cgi", $text{'index_boot'}, + $text{'index_bootdesc'}, undef, + &ui_radio("boot", $atboot ? 1 : 0, + [ [ 1, $text{'yes'} ], + [ 0, $text{'no'} ] ])); + } print &ui_buttons_row("index.cgi", $text{'index_reset'}, $text{'index_resetdesc'}, undef, &ui_hidden("reset", 1)); diff --git a/ipfw/ipfw-lib.pl b/ipfw/ipfw-lib.pl index 3987ba06f..aa7e09cb6 100644 --- a/ipfw/ipfw-lib.pl +++ b/ipfw/ipfw-lib.pl @@ -6,8 +6,23 @@ do '../web-lib.pl'; &init_config(); do '../ui-lib.pl'; +if (&foreign_check("net")) { + &foreign_require("net", "net-lib.pl"); + $has_net_lib = 1; + } -$ipfw_file = $config{'save_file'} || "$module_config_directory/ipfw.rules"; +# Work out save file +$ipfw_file = "$module_config_directory/ipfw.rules"; +if ($config{'save_file'}) { + $ipfw_file = $config{'save_file'}; + } +elsif ($has_net_lib) { + # Use entry in rc.conf, if set + local %rc = &net::get_rc_conf(); + if ($rc{'firewall_type'} =~ /^\//) { + $ipfw_file = $rc{'firewall_type'}; + } + } @actions = ( "allow", "deny", "reject", "reset", "skipto", "fwd", "check-state", "count", "divert", "pipe", "queue", "tee", "unreach" ); @@ -463,8 +478,7 @@ return undef; sub interface_choice { local @ifaces; -if (&foreign_check("net")) { - &foreign_require("net", "net-lib.pl"); +if ($has_net_lib) { return &net::interface_choice($_[0], $_[1], $_[2] ? undef : "<$text{'edit_ignored'}>"); } @@ -551,6 +565,65 @@ foreach $s (&list_cluster_servers()) { return undef; } +# check_boot() +# Returns 1 if enabled at boot via an init script, 2 if enabled via rc.conf, +# -1 if a different file is enabled at boot, 0 otherwise +sub check_boot +{ +&foreign_require("init", "init-lib.pl"); +local $atboot = &init::action_status($module_name); +if ($atboot == 2) { + return 1; + } +if ($has_net_lib && defined(&net::get_rc_conf)) { + local %rc = &net::get_rc_conf(); + if ($rc{'firewall_enable'} ne 'YES') { + # Disabled + return 0; + } + elsif ($rc{'firewall_type'} eq $ipfw_file) { + return 2; + } + elsif ($rc{'firewall_type'}) { + # A *different* file is enabled + return -1; + } + } +return 0; +} +# enable_boot() +# Make sure ipfw gets started at boot. Uses rc.conf if possible +sub enable_boot +{ +return 0 if (&check_boot()); # Already on +if ($has_net_lib && defined(&net::get_rc_conf) && -r "/etc/rc.conf") { + local %rc = &net::get_rc_conf(); + &lock_file("/etc/rc.conf"); + &net::save_rc_conf('firewall_type', $ipfw_file); + &net::save_rc_conf('firewall_enable', 'YES'); + &unlock_file("/etc/rc.conf"); + return 2; + } +&create_firewall_init(); +return 1; +} + +sub disable_boot +{ +local $mode = &check_boot(); +return 0 if ($mode <= 0); +if ($mode == 1) { + # Turn off init script + &init::disable_at_boot($module_name); + } +elsif ($mode == 2) { + # Take out rc.conf entry + &lock_file("/etc/rc.conf"); + &net::save_rc_conf('firewall_enable', 'NO'); + &unlock_file("/etc/rc.conf"); + } +return $mode; +} 1;