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

    Package development - firewall rules

    Scheduled Pinned Locked Moved Development
    2 Posts 1 Posters 1.9k 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.
    • S
      Sander88
      last edited by

      I'm developing a pfSense package and I would like to generate one or more firewall rules from my package. I used the existing packages as an example and found the XML element '<filter_rules_needed>'. It looks like this is what is need (correct me when I'm wrong!). But this method is never being called (I think) by PFSense.

      My package config XML:

      
       <packagegui><description>My package</description>
      
          <name>MyPackage</name>
          <version>0.1</version>
          <title>My Package</title>
          <include_file>/usr/local/pkg/mypackage.inc</include_file>
          ...
          <filter_rules_needed>mypackage_generate_rules</filter_rules_needed></packagegui> 
      

      My package include file:

      
      require_once('util.inc');
      require_once('filter.inc');
      require_once('interfaces.inc');
      require_once('pfsense-utils.inc');
      require_once('service-utils.inc');
      
      function mypackage_generate_rules($sType)
      {
      	global $config;
      
      	log_error("mypackage_generate_rules: ".$sType);
      
      	$aInterfaces = explode(',', $config['installedpackages']['mypackage']['config'][0]['serverinterfaces']);
      	$aInterfaces = array_map('convert_friendly_interface_to_real_interface_name', $aInterfaces);
      	log_error("interfaces: ".print_r($aInterfaces, true));
      
      	$sRules = "";
      	switch($sType) 
      	{
      		case 'nat':
      			// Nothing here yet.
      			break;
      		case 'filter':
      		case 'rule':
      			foreach ($aInterfaces as $sInterface)
      			{
      				$sRules .= "pass quick on {$sInterface} proto upd to port 1234 flags S/SA keep state label \"MyPackage: Test\"\n";
      			}
      			break;
      		default:
      			break;
      	}
      
      	return $sRules;
      }
      
      

      PFSense doesn't create the rule as far as I can see. Also nothing in the logs; I would expect something like: 'mypackage_generate_rules' as I call log_error in this method.

      Anyone suggestions? Thanks!</filter_rules_needed>

      1 Reply Last reply Reply Quote 0
      • S
        Sander88
        last edited by

        I finally figured out what went wrong. There where 2 issues.

        1. The XML tag isn't used by PFSense at all, below a copy of the method PFSense uses to generate the rules (https://github.com/bsdperimeter/pfsense/blob/master/etc/inc/filter.inc).

        2. You should not use a subdirectory for your package; leave it in '/usr/local/pkg'. Otherwise the system won't find your 'generate_rules' function.

        function discover_pkg_rules($ruletype) {
        global $config, $g, $aliases;
        
        /* Bail if there is no pkg directory, or if the package files might be out of sync. */
        if(!is_dir("/usr/local/pkg") || file_exists('/conf/needs_package_sync'))
        return "";
        
        $rules = "";
        $files = glob("/usr/local/pkg/*.inc");
        foreach($files as $pkg_inc) {
        update_filter_reload_status(sprintf(gettext('Checking for %1$s PF hooks in package %2$s'), $ruletype, $pkg_inc));
        $pkg = basename($pkg_inc, ".inc");
        $pkg_generate_rules = "{$pkg}_generate_rules";
        if (!function_exists($pkg_generate_rules))
        require_once($pkg_inc);
        if(function_exists($pkg_generate_rules)) {
        update_filter_reload_status(sprintf(gettext('Processing early %1$s rules for package %2$s'), $ruletype, $pkg_inc));
        $tmprules = $pkg_generate_rules("$ruletype");
        file_put_contents("{$g['tmp_path']}/rules.test.packages", $aliases . $tmprules);
        $status = mwexec("/sbin/pfctl -nf {$g['tmp_path']}/rules.test.packages");
        if ($status <> 0) {
        $errorrules = sprintf(gettext("There was an error while parsing the package filter rules for %s."), $pkg_inc) . "\n";
        log_error($errorrules);
        file_put_contents("{$g['tmp_path']}/rules.packages.{$pkg}", "#{$errorrules}\n{$tmprules}\n");
        continue;
        }
        $rules .= $tmprules;
        }
        }
        return $rules;
        }
        

        I hope that this info will help someone figuring it out a lot faster than I did  ;)

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