ipfirewall tricks

Giorgos Keramidas keramida at ceid.upatras.gr
Wed May 3 00:12:46 UTC 2006


On 2006-05-02 17:35, Bryan Curl <bc3910 at gmail.com> wrote:
> I want to limit time my kids spend on the internet.  The way I am
> doing it is to make varying, seperate ipf.rules files and install them
> from cron at the appropriate time.

Sounds like a good plan.

> Problem is, if I make a change to one file, I generally have to update
> all the others accordingly.

Which files?  You can use symlinks to your advantage.  For example, if
you have two sets of rules, named `ipf.conf.allow' and `ipf.conf.block',
you can set your `/etc/rc.conf' to reference `/etc/ipf.conf' and then
use a cron job or two to symlink to one of the two :-)

    00 08 * * *         /root/scripts/ipf-allow.sh
    00 20 * * *         /root/scripts/ipf-block.sh

The scripts could be something as simple as:

|   #!/bin/sh
|   #
|   # ipf-allow.sh      - Reload IP Filter from /etc/ipf.conf.allow
|   #
|
|   # If anything goes wrong, fall back to a slightly paranoid ruleset
|   # that disallows almost *ALL* network access, letting only ICMP, DNS
|   # and SSH through.
|   paranoid_rules() {
|       { echo 'pass in  quick on lo0 all' ;
|         echo 'pass out quick on lo0 all' ;
|         echo 'pass in  quick proto icmp all' ;
|         echo 'pass out quick proto icmp all' ;
|         echo 'pass out quick proto udp from any to any port = 53 keep state' ;
|         echo 'pass out quick proto tcp from any to any port = 53 keep state' ;
|         echo 'pass in  quick proto tcp from any to any port = 22 keep state' ;
|         echo 'pass out quick proto tcp from any to any port = 22 keep state' ;
|         echo 'block in all' ;
|         echo 'block out all' ;
|       } | ipf -Fa -f -
|   }
|
|   ipf_allow_rules='/etc/ipf.conf.allow'
|   ipf_rules='/etc/ipf.conf'
|
|   if test ! -f "${ipf_allow_rules}" ; then
|       echo >&2 "${ipf_allow_rules}: ruleset missing, blocking (almost) all network access."
|       paranoid_rules
|       exit 1
|   fi
|
|   /bin/rm -f "${ipf_rules}" && \
|   ln -s "${ipf_allow_rules}" "${ipf_rules}" && \
|   ipf -Fa -f "${ipf_allow_rules}"
|
|   if test $? -ne 0 ; then
|       echo >&2 "${ipf_load_rules}: ruleset failed to load, blocking (almost) all network access."
|       paranoid_rules
|       exit 1
|   fi

A similar script for ipf_deny_rules, and you're set.  You can even join
the two scripts in one and pass the ruleset file to load in the cronjob:

    00 08 * * *         /root/scripts/ipf-load.sh /etc/ipf.conf.allow
    00 20 * * *         /root/scripts/ipf-load.sh /etc/ipf.conf.block

and then write your script as:

|   #!/bin/sh
|   #
|   # ipf-load.sh       - Reload IP Filter from $1
|   #
|
|   # If anything goes wrong, fall back to a slightly paranoid ruleset
|   # that disallows almost *ALL* network access, letting only ICMP, DNS
|   # and SSH through.
|   paranoid_rules() {
|       { echo 'pass in  quick on lo0 all' ;
|         echo 'pass out quick on lo0 all' ;
|         echo 'pass in  quick proto icmp all' ;
|         echo 'pass out quick proto icmp all' ;
|         echo 'pass out quick proto udp from any to any port = 53 keep state' ;
|         echo 'pass out quick proto tcp from any to any port = 53 keep state' ;
|         echo 'pass in  quick proto tcp from any to any port = 22 keep state' ;
|         echo 'pass out quick proto tcp from any to any port = 22 keep state' ;
|         echo 'block in all' ;
|         echo 'block out all' ;
|       } | ipf -Fa -f -
|   }
|
|   if test $# -ne 1 ; then
|       echo >&2 "usage: ipf-load.sh ruleset-path"
|       paranoid_rules
|       exit 1
|   fi
|
|   ipf_load_rules="$1"
|   ipf_rules='/etc/ipf.rules'
|
|   if test ! -f "${ipf_load_rules}" ; then
|       echo >&2 "${ipf_load_rules}: ruleset missing, blocking (almost) all network access."
|       paranoid_rules
|       exit 1
|   fi
|
|   /bin/rm -f "${ipf_rules}" && \
|   ln -s "${ipf_load_rules}" "${ipf_rules}" && \
|   ipf -Fa -f "${ipf_load_rules}"
|
|   if test $? -ne 0 ; then
|       echo >&2 "${ipf_load_rules}: ruleset failed to load, blocking (almost) all network access."
|       paranoid_rules
|       exit 1
|   fi

> Is there a better way? I have read man ipf but didnt come out with any
> ideas.

Well, the 'best' way is the one you like the most, I guess :)



More information about the freebsd-questions mailing list