Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Multiple interfaces sharing a filter config: a script

    Scheduled Pinned Locked Moved Firewalling
    1 Posts 1 Posters 1.0k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Z
      zcarlson
      last edited by

      Hello, everyone!

      We manage a pfSense box running 1.2.3 for stability reasons, and had run into a problem where we needed the rules for two interfaces to be exactly the same at all times. I've since heard that there's a feature in pfSense 2.x that will allow one set of rules to apply to multiple interfaces, but upgrading is not an option; therefore, I wrote this script with some guidance from the IRC channel. Hopefully it will be of use to someone.

      In the configuration section, $iface1 is the "master" interface that you want to propagate to the other interface; $iface2 is the interface to compare and POTENTIALLY OVERWRITE. They use the internal names pfSense uses: you can usually figure out the internal names of the interfaces you want to use by looking at their firewall rules pages and taking the "if=" parameter from the URL. For example, in the URL https://your.pfsense.firewall.com/firewall_rules.php?if=opt1 , 'opt1' is your interface name.

      Be sure to take a full backup of your configuration before running this script. Of course, I am not responsible for any damage done to your firewall as a result of running this script; it is provided free of charge with no warranty and all of that.

      
      // Configuration section
      $iface1 = "wan";
      $iface2 = "opt1";
      // End configuration section
      
      require_once("globals.inc");
      require_once("functions.inc");
      require_once("config.inc");
      require_once("util.inc");
      // ^ preamble
      
      $lock_fh = fopen("/tmp/propagator.lock", "w+");
      $blocked_lock = FALSE;
      $test_lock = flock($lock_fh, LOCK_EX|LOCK_NB, $blocked_lock);
      if (!$test_lock && $blocked_lock) exit(0);
      if (!$test_lock) exit(1);
      
      $iface1_rules = array();
      $iface2_rules = array();
      
      $sorted_out_rules = array();
      
      foreach ($config['filter']['rule'] as $index => $rule) {
      	if ($rule['interface'] != $iface2) {
      		if (!isset($sorted_out_rules[$rule['interface']])) $sorted_out_rules[$rule['interface']] = array();
      		$sorted_out_rules[$rule['interface']][] = $rule; 
      	}
      
      	if ($rule['interface'] == $iface1) {
      		unset($rule['interface']);
      		$iface1_rules[] = $rule;
      		continue;
      	}
      
      	if ($rule['interface'] == $iface2) {
      		unset($rule['interface']);
      		$iface2_rules[] = $rule;
      		continue;
      	}
      }
      
      $filter_applied = (file_exists($g['varrun_path'] . "/filter.conf.dirty") ? 0 : 1);
      
      if ($iface1_rules != $iface2_rules) {
      	/* Our iface2 is different from our iface1 :( */
      	$new_rules = array(); 
      	foreach ($sorted_out_rules as $iface => $rule_array) {
      		$new_rules = array_merge($new_rules, $rule_array);
      	}
      
      	foreach ($sorted_out_rules[$iface1] as $rule) {
      		$rule['interface'] = $iface2;
      		$new_rules[] = $rule;
      	}
      
      	$config['filter']['rule'] = $new_rules;
      
      	write_config("Syncing out-of-date firewall rules in {$iface2}...");
      	if ($filter_applied) filter_configure();
      }
      
      flock($lock_fh, LOCK_UN|LOCK_NB);
      fclose($lock_fh);
      unlink("/tmp/propagator.lock");
      
      ?>
      

      You should be able to use it in a cron as well; it should prevent itself from running twice at the same time.

      Enjoy! :)

      1 Reply Last reply Reply Quote 0
      • First post
        Last post
      Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.