Turning off CP between certain times



  • Hello everyone,
    I'm currently using the voucher system to get my kids to finish their chores around the house in exchange for voucher tickets  ;D
    I would like to have specific times of the day where they have full access to the internet without using up a voucher code. I have been follow the guide at https://forum.pfsense.org/index.php?topic=80789.0 without luck.
    It's looking like when the captive portal service is stopped, it just shuts off access to the CP, and doesn't allow access to the internet, except to the addresses that are specified in the 'Allowed Hostnames'. Is the script in the forum link above still valid?

    Thanks!



  • Anyone have any ideas?

    To give more detail I'm running a subnet of 172.16.0.0/16 and I already set up certain IP ranges (ex. 172.16.1.0/24 and 172.16.2.0/24) to the 'Allowed IPs' list so it bypasses the CP. Technically you could just change your IP address to the allowed ranges to bypass the CP, but that shouldn't be a problem as of right now.

    After doing a bit of research entering the following shows me the zones that are in IPFW (In my case its Zone 2):

    ipfw zone list
    

    This shows me my tables, which appears to compile everything in my 'Allowed IPs' and 'Allowed Hostnames' lists:

    ipfw -x 2 table all list
    

    Then the following shows me the rules using the tables that were shown previously:

    ipfw -x 2 show
    

    So if I were to add a cron job to add/remove the subnet for the CP Zone (In this case to Tables 3 and 4), the whole zone should be allowed to bypass the captive portal?

    In theory I should be able to execute a script with this code to add the subnet to the table

    
    ipfw table 3 add 172.16.3.0/24
    ipfw table 4 add 172.16.3.0/24
    
    

    And to remove:

    
    ipfw table 3 delete 172.16.3.0/24
    ipfw table 4 delete 172.16.3.0/24
    
    

    Does that sound right, is there an easier way of doing this? Do I have to run any commands afterwards to reload any filters, or will it take effect instantly?

    I'm pretty new with PFSense, so bear with me  ;D

    EDIT: Thought I got it working, but even though the captive portal worked, I think it messed with the vouchers, because it allows me to authenticate by leaving the voucher code field blank.
    Below is my removed post of what I tried, in case somebody knows how to make it work:

    Tried the ipfw commands here:https://forum.pfsense.org/index.php?topic=65828.0
    It's a bit different in the latest pfsense version, now that you can set up multiple zones for CP.
    Use this command to turn off IPFW completely

    /sbin/kldunload ipfw.ko
    

    After doing this, network traffic was able to pass out to the internet without issues.

    To turn load ipfw and turn captive portal back on use these commands:

    /sbin/kldload ipfw.ko
    ipfw zone 2 create
    ipfw zone 2 madd <cpinterfacename>
    /sbin/ipfw -x 2 -q /tmp/ipfw_<zonename>.cp.rules</zonename></cpinterfacename>
    

    Replace CPInterfaceName with the actual interface, mine was hn1, and ZoneName as well, in my case it was vouchers, which left me with this:

    /sbin/kldload ipfw.ko
    ipfw zone 2 create
    ipfw zone 2 madd hn1
    /sbin/ipfw -x 2 -q /tmp/ipfw_vouchers.cp.rules
    

    Just throw these two scripts in a cron job, one to turn off the CP, and one to turn it back on

    It looks like its rebuilding the ipfw configuration from scratch each time



  • You could walk on two ways;

    • Use the Squid with user auth. and set time outs
    • Use a script that enables or disables the CP
      (Likes on a small Raspberry PI 2.0 & Raspbian)


  • Thanks for your help! So basically going the route of using a script would be pretty much like what I tried in my first post?
    Should that script still work, or there another script out there that can help me out?



  • Why not get a WiFi AP that allows scheduling, put the CP through one vlan/ssid and the free to use network on another vlan/ssid?



  • I managed to get it all working, I had to use a combination of the two solutions I had found. Following the post found at:https://forum.pfsense.org/index.php?topic=80789.15 I used the two scripts which left me with this:

    To disable the captive portal, I made a script called rc.captiveportal_disable:

    #!/usr/local/bin/php -f
    /* $Id$ */
    /*
        rc.captiveportal_disable
    
        copied and modified from rc.captiveportal_configure
    */
    
    require("config.inc");
    require("functions.inc");
    require_once("filter.inc");
    require("shaper.inc");
    require("captiveportal.inc");
    
    captiveportal_disable();
    
    function captiveportal_disable() {
    	global $config, $cpzone, $argv;
    
    	if (is_array($config['captiveportal'])) {
    		foreach ($config['captiveportal'] as $cpkey => $cp) {
    			$cpzone = $cpkey;
    			if (strpos($argv[1], $cpzone) !== false) {
    				if (isset($cp['enable'])) {
    					unset($cp['enable']);
    				}
    				captiveportal_configure_zone($cp);
    			}
    		}
    	} else
    		mwexec("/sbin/sysctl net.link.ether.ipfw=0");
    }
    
    ?>
    

    And another disable script that I made to call the above script and unload all IPFW tables(called that one rc.captiveportaloff):

    /etc/rc.captiveportal_disable vouchers
    /sbin/kldunload ipfw.ko
    

    After doing this the captive portal will be disabled and allowing internet traffic through

    To re-enable I used the script to reconfigure the captive portal for the particular zone, named rc.captiveportal_enable:

    #!/usr/local/bin/php -f
    /* $Id$ */
    /*
        rc.captiveportal_disable
    
        copied and modified from rc.captiveportal_configure
    */
    
    require("config.inc");
    require("functions.inc");
    require_once("filter.inc");
    require("shaper.inc");
    require("captiveportal.inc");
    
    captiveportal_enable();
    
    function captiveportal_enable() {
    	global $config, $cpzone, $argv;
    
    	if (is_array($config['captiveportal'])) {
    		foreach ($config['captiveportal'] as $cpkey => $cp) {
    			$cpzone = $cpkey;
    			if (strpos($argv[1], $cpzone) !== false) {
    				$cp['enable']=true;
    				captiveportal_configure_zone($cp);
    			}
    		}
    	} else
    		mwexec("/sbin/sysctl net.link.ether.ipfw=0");
    }
    
    ?>
    

    Then another script to call the above script and reload all the IPFW tables, named rc.captiveportalon:

    /sbin/kldload ipfw.ko
    ipfw zone 2 create
    /sbin/ipfw -x 2 -q /tmp/ipfw_vouchers.cp.rules
    ipfw zone 2 madd hn1
    /etc/rc.captiveportal_enable vouchers
    

    Then use a cron job to call rc.captiveportaloff and rc.captiveportalon whenever you like. Seems like a dirty way of getting this done, but it works for me. It would take a bit more code if your are dealing with multiple zones, but for a single zone this works.

    One other question, how does the tmp folder behave? I have my script using the ipfw rules found in /tmp/ipfw_vouchers.cp.rules, if I happen to reboot pfsense while CP is turned off, will it end up deleting that file thus breaking CP completely?