pf and name resolving

Hi,

I have a server acting as a firewall.
Some of the rules in my /etc/pf.conf had dns names.

For example :
Code:
...
pass in quick on $int_if to smtp.isp.com port smtp
pass in quick on $int_if to pop3.isp.com port pop3
...

The problem is when the server reboots, the rules are not loaded because pf can't resolv names at startup. As a consequence, all the traffic is blocked because of nat rules in the rules file. I have to manually reload pf rules to let people acces the net.

I've searched the net and forums for a solution to fix this and found a discussion that suggests to use tables and put my dns names in the tables created.

I tried this but the problem is still here.

Does anyone have a solution/fix/workaround to let pf rules load at startup with dns names in the rules file ?

I read that pf is loading before named that's why it can't do the resolving step. Changing this order may be the solution. Is it feasable ?

Thanks,
P.S. Sorry for my poor english.
 
Code:
# cat /etc/rc.d/pf
#!/bin/sh                               
#                                       
# $FreeBSD: src/etc/rc.d/pf,v 1.19.2.2.2.1 2009/10/25 01:10:29 kensmith Exp $
#                                                                            

# PROVIDE: pf
# REQUIRE: FILESYSTEMS netif pflog pfsync
# BEFORE:  routing                       
# KEYWORD: nojail
It loads even before routing xD
About problem: i think its right thing to start before server gets network.
But, problem is still persist... You can use IPs instead, or hosts file.

I got same thing when i needed nat after mpd gets his ng0 interface. So i put `/etc/rc.d/pf reload` into mpd-up script. You can make an rc script to start after named, doing same. ("reload" does not clear states, so it should be painless for users)
 
ips ? numerical adresses you mean ?

I know it is working this way, my rules had only numerical destinations before i started adding domain names, but i'm not totally satisfied with this solution. :\

I'll continue my investigations ;)
 
kisscool-fr said:
ips ? numerical adresses you mean ?

I know it is working this way, my rules had only numerical destinations before i started adding domain names, but i'm not totally satisfied with this solution. :\

I'll continue my investigations ;)
It is a general practice to use IPs instead of host names when it comes to firewalls. It is easier to spoof a host rather an IP. Most firewall don't accept host names at all.

George
 
Instead of pure ip adresses, you can use macros, which expand to IP adresses
That's how I do it.

This way If address change, you can simply change macro
 
Using tables in place of those host names should work, provided you populate these tables externally by means of a script using pfctl, after DNS is up and running.

i.e.
Code:
#! /bin/sh

pfctl -t smtphosts -T flush
pfctl -t smtphosts -T add smtp.isp.com

pfctl -t pophosts -T flush
pfctl -t pophosts -T add pop3.isp.com

With some more work you could turn this script into an rc script, which is automatically run, after DNS has started up. See rc(8), rc.subr(8).
 
killasmurf86 said:
Instead of pure ip adresses, you can use macros, which expand to IP adresses
That's how I do it.

This way If address change, you can simply change macro

That's right. Hard coded host names or host names in tables will expand in the same manner but if pf starts before named, name resolution will not be done and all the rules not loaded. That's the way i understand it. Maybe i'm wrong.


mickey said:
Using tables in place of those host names should work, provided you populate these tables externally by means of a script using pfctl, after DNS is up and running.

i.e.
Code:
#! /bin/sh

pfctl -t smtphosts -T flush
pfctl -t smtphosts -T add smtp.isp.com

pfctl -t pophosts -T flush
pfctl -t pophosts -T add pop3.isp.com

With some more work you could turn this script into an rc script, which is automatically run, after DNS has started up. See rc(8), rc.subr(8).

This is what i want to do but in a simplified manner.

I want to store all my host names in files linked to tables. At pf loading, those host names will be expanded to numerical addresses.
Then, i will have just to reload the tables to have numerical addresses up to date.

In my researches, i found a way to start named before pf. Have to test now if it works the way i want it.
 
kisscool-fr said:
That's right. Hard coded host names or host names in tables will expand in the same manner but if pf starts before named, name resolution will not be done and all the rules not loaded. That's the way i understand it. Maybe i'm wrong.
[...]
In my researches, i found a way to start named before pf. Have to test now if it works the way i want it.

There is a reason for starting the firewall before anything else that accesses the network, including but not limited to DNS service, and that is security. If you delay the start of PF until after DNS (and possibly other stuff) is running, you open up a window of opportunity where the system is not protected by the firewall.

The only reasonable solution to your problem can be, to make firewall initialization a two-phase process:
  1. Start PF with the base rules, only containing numerical IP addresses, to allow for basic networking to function.
  2. Initialize all host-name based rules after DNS service is running.

Additionally, if the intention for using host names rather than IP-addresses is to be aware of address changes, you will want to repeat step 2 every once in a while.
 
Make rc script with `/etc/rc.d/pf reload` in it and set correct "# REQUIRE:" in it. You can do same with 1 selected table. There is nothing to talk about...
 
kisscool-fr said:
In my researches, i found a way to start named before pf. Have to test now if it works the way i want it.

Does not work like I want it. Named starts before pf which start before routing ... Don't know why but i wasn't convinced that it will work :r


mickey said:
The only reasonable solution to your problem can be, to make firewall initialization a two-phase process:
  1. Start PF with the base rules, only containing numerical IP addresses, to allow for basic networking to function.
  2. Initialize all host-name based rules after DNS service is running.

Additionally, if the intention for using host names rather than IP-addresses is to be aware of address changes, you will want to repeat step 2 every once in a while.

Yes it's the way i want it to do and ...

Alt said:
Make rc script with `/etc/rc.d/pf reload` in it and set correct "# REQUIRE:" in it. You can do same with 1 selected table. There is nothing to talk about...

... don't know why i don't thought about that before :)

I'm going to read some docs about the creation of rc files.

Thank you guys :)
 
OK, i just wrote a little rc script and stored it in the /usr/local/etc/rc.d directory.

Code:
cat /usr/local/etc/rc.d/pf_reloader
#!/bin/sh
#

# PROVIDE: pf_reloader
# REQUIRE: pf named

pf_reloader_enable=${pf_reloader_enable-"NO"}
pf_reloader_flags=${pf_reloader_flags-""}

. /etc/rc.subr

name="pf_reloader"
rcvar=`set_rcvar`
command="/etc/rc.d/pf"

load_rc_config $name

start_cmd="pf_reloader_start"

pf_reloader_start()
{
        ${command} ${pf_reloader_flags}
}

run_rc_command "$1"

I have this in my /etc/rc.conf

Code:
pf_reloader_enable="YES"
pf_reloader_flags="reload"

It seems to react like i want it. Have to check now at reboot time if it works good.
 
I tried this at lunch time.

Still have the message "pf can't resolv ..." at the beginning of the services starting process but have also a "Reloading pf rules" at the end of this process.

Rules are populated and the access to the outside is working.

It seems to work like a charm. I will wait some days to be sure :)
 
Back
Top