PF setup question..

Hi all..

I'm finally looking into setting up PF on my server running FreeBSD 7.1... I've got an external firewall (Cisco router) that plugs into a gigabit switch. The server is plugged into the switch along with some other networked appliances (voip,etc). Anyway, the server has the bge0 interface that goes to the switch and the server has several jails running the following services with the following IP's :

  • server.example.com (10.0.1.1) -- runs Postgres database for use by webapps
  • smtp.example.com (10.0.1.4) -- handles all mail for domain, imaps + smtp
  • http://www.example.com (10.0.1.6) -- apache port 80
  • http://www.otherdomain.com (10.0.1.7) -- apache port 80

The main server (10.0.1.1) and the jailed servers will need to handle VNC traffic. I've got no SSH traffic but do want the main server to accept telnet connections on the internal network (not available from outside the local net) for the occasional local connection. To that end, after reading some of the PF docs, I wrote up the following but it doesn't let anything through (telnet, VNC,etc) :

Code:
tcp_services = "{ 5900, 5901, 5902, 5903, telnet, smtp, domain, www, auth, pop3s imaps }"
udp_services = "{ domain }"

block all
pass out proto tcp to any port $tcp_services keep state
pass proto udp to any port $udp_services

I'm sure I'm missing a lot of 'beef' to make this work -- but getting the basic telnet from being blocked would be a start.. I do not need any NAT or anything like that -- just simple firewalling...
 
Change the "pass out" to pass in. You need to accept traffic coming in not going out (keep state will take care of that).
 
One more question if I could.. In reading one of the PF guides, I think I can add the following lines to route external web/smtp traffic to my jails -- does this sound about right?

Code:
webports="{ http https }"
smtpports="{ smtp imaps }"
webserver_jail="10.0.1.6"
smtpserver_jail="10.0.1.5"

rdr on $ext_if proto tcp from any to $ext_if port $webports -> $webserver_jail
rdr on $ext_if proto tcp from any to $ext_if port $email    -> $smtpserver_jail

pass proto tcp from any to $webserver_jail         port $webports  flags S/SA synproxy state
pass proto tcp from any to $smtpserver_jail        port $smtpports flags S/SA synproxy state
pass proto tcp from        $smtpserver_jail to any port smtp       flags S/SA synproxy state

One other question.. Is it safe to assume that my jails that talk to a PostgreSQL installation that does not reside in a jail (but is on the same machine) will need similar rules for it and also rules for my Apache proxies that forward traffic from one jail to another for some instances? My guess is yes..
 
Ok.. Below is my current pf.conf file.. For whatever reason, I'm unable to get logging going (no /var/log/pf* files) and incoming imap connections from another machine on the local network (not outside on the internet) seem to get stuck -- however, telnet and VNC connections work fine.. The imaps (port 993 SSL) timeout after a while and I checked one of the webservers and its timing out as well when tried from outside the firewall (via a web enabled phone that normally works).. I'd love to get the logging going so I can tell if incoming mail connections are working or not.. Any ideas on what I'm got horked up?

Code:
# external interfaces
ext_if                  = "bge0"

# internal jailed servers for services
jail_smtp_server        = "10.0.1.4"
jail_1_webserver = "10.0.1.6"
jail_2_webserver  = "10.0.1.7"

tcp_services            = "{ 5900, 5901, 5902, 5903, telnet, domain, www, auth }"
udp_services            = "{ domain }"
webports                = "{ http https }"
smtpports               = "{ smtp imaps }"

set loginterface $ext_if
set debug loud

rdr on $ext_if proto tcp from any to $ext_if port $webports  -> $jail_2_webserver
rdr on $ext_if proto tcp from any to $ext_if port $smtpports -> $jail_smtp_server

block all
pass in log (all, to pflog1) proto tcp to any port $tcp_services keep state
pass    proto udp to any port $udp_services

pass proto tcp from any to $jail_2_webserver  port $webports  flags S/SA synproxy state
pass proto tcp from any to $jail_smtp_server        port $smtpports flags S/SA synproxy state
pass proto tcp from        $jail_smtp_server to any port smtp       flags S/SA synproxy state
 
Ok.. I've got things mostly working.. However, in my latest tweaks, my web traffic is not getting through to my jail.. When I enable pf, I get a "Service Temporarily Unavailable", but when I disable it, it works fine.. Any ideas on what I messed up?

Code:
# external interfaces
ext_if                  = "bge0"

# internal jailed servers for services
jail_smtp_server        = "10.0.1.4"
jail_caf_webserver = "10.0.1.6"
jail_mys_webserver  = "10.0.1.7"

local_users             = "10.0.0.0/8"

NoRouteIPs = "{ 192.168.0.0/16, 172.16.0.0/12 }"

# 590x = VNC, 783 = spamd/spamc chatter
localsvcs               = "domain telnet 5900 5901 5902 5903 783"
webports                = '"http" "https"'
smtpports               = "smtp imaps"
sambaports              = "netbios-ns netbios-dgm netbios-ssn microsoft-ds loc-srv"
icmp_types              = "echoreq"
domain_ports            = "domain"

# the tcp_services below should encompass all services above except icmp..
tcp_services            = $domain_ports $localsvcs $webports $smtpports $sambaports
udp_services            = $domain_ports $sambaports

set loginterface $ext_if
set skip on l0

scrub in all

rdr on $ext_if proto tcp from any to any port     { $webports }  -> $jail_mys_webserver
rdr on $ext_if proto tcp from 127.0.0.1 to $ext_if port 783      -> $jail_smtp_server
rdr on $ext_if proto tcp from any to $ext_if port { $smtpports } -> $jail_smtp_server

block all
pass out proto tcp to any port { $tcp_services }
pass     proto udp to any port { $udp_services }

block in  quick on $ext_if from $NoRouteIPs to any
block out quick on $ext_if from any to $NoRouteIPs

# icmp Requests
pass in inet proto icmp all icmp-type $icmp_types keep state

# pass all traffic to and from the local network
pass in quick log on $ext_if proto tcp from $local_users to $ext_if                  port { $localsvcs } keep state
pass in quick log on $ext_if proto tcp from any          to $jail_mys_webserver  port { $webports } keep state
pass in quick log on $ext_if proto tcp from any          to $jail_smtp_server        port { $smtpports } keep state
 
Not sure if it's related, but change
Code:
set skip on l0
to
Code:
set skip on lo0

BTW, this is bad syntax:
Code:
tcp_services            = $domain_ports $localsvcs $webports $smtpports $sambaports
udp_services            = $domain_ports $sambaports

You don't see it yet because you're not calling these macros in your ruleset. I don't think it's possible to include macros in another macro, so using {} or "" won't help.

In general: multi-value macros should be stated thusly:

Code:
localsvcs               = "{ domain telnet 5900 5901 5902 5903 783 }"
webports                = "{ http https }"

They should be called in a rule like this:

Code:
$localsvcs
$webports

So not

Code:
localsvcs               = "domain telnet 5900 5901 5902 5903 783"

and:

Code:
{ $localsvcs }

Your syntax does work (I checked), but pf.conf(5) states otherwise, and it may confuse others ;)
 
Thanks.. I reverted back to the more verbose setup.. I was just looking for a way to reduce redundant information.. The "tcp_services" and "udp_services" are used in the pass lines but then I need reduced sets (e.g. webports) for doing redirects.. Is there any other way to reduce some of these redundancies? Below is one section of the updated stuff for reference :

Code:
# 590x = VNC, 783 = spamd/spamc chatter
localsvcs               = "{ domain telnet 5900 5901 5902 5903 783 }"
webports                = "{ http https }"
smtpports               = "{ smtp imaps }"
sambaports              = "{ netbios-ns netbios-dgm netbios-ssn microsoft-ds loc-srv }"
icmp_types              = "echoreq"
domain_ports            = "domain"

# the tcp_services below should encompass all services above except icmp..
tcp_services            = "{ domain telnet 5900 5901 5902 5903 783 http https smtp imaps netbios-ns netbios-dgm netbios-ssn microsoft-ds loc-srv }"
udp_services            = "{ domain netbios-ns netbios-dgm netbios-ssn microsoft-ds loc-srv }"

set loginterface $ext_if
set skip on lo0

scrub in all

rdr on $ext_if proto tcp from any to any port     $webports  -> $jail_mys_webserver
rdr on $ext_if proto tcp from 127.0.0.1 to $ext_if port 783  -> $jail_smtp_server
rdr on $ext_if proto tcp from any to $ext_if port $smtpports -> $jail_smtp_server

block all
pass out proto tcp to any port $tcp_services
pass     proto udp to any port $udp_services
 
They're not redundancies to PF. No matter how you state them, they get expanded anyway. Just run [cmd=]pfctl -s rules[/cmd] with or without 'reduced syntax', and you'll see how verbose it really gets ;)

Suppose you have an interface with three IP addresses, and you open up five service ports on that interface; you can write that in 1 rule, but PF will expand it to 15 separate rules. So don't invest a lot of time in trying to bundle it all up ..
 
you're correct as usual.. I was just trying to reduce the duplication in the config file.. Anyway, no biggie -- just thought I'd ask.. Thanks!
 
To be completely honest, I'm not sure yet. I've not had any time to get back and look into it further aside from making the macro and other fixes as you pointed out earlier. I'm hoping to have some time tonight to look into this further.. I'll post a note back to give status. Thanks!
 
Just a quick followup.. It appears to be working OK at the moment without any problems! Thanks again for steering me in the right direction.
 
Back
Top