# PF and Webmin



## xy16644 (Jul 29, 2009)

Today I started to setup pf on my FreeBSD box in preparation for putting in on the internet in the coming weeks. My setup is (mostly) pretty simple, I have a single machine with one NIC, one private IP and it sits behind a NAT'd router.

I want to be able to allow SSH, http, https, imap, webmin and smtp to the server. I want to block everything else coming INTO the machine but allow everything going OUT of the machine.

Currently my rule base looks as follows:


```
tcp_services = "{ 22, 25, 80, 143, 443, 587, 993 }"

block in all
pass in on bge0 proto tcp from any to bge0 port $tcp_services
pass in on bge0 proto tcp from any to bge0 port 10000
```

Everything seems to work fine except Webmin. I have Webmin running under Apache using mod_proxy so that when someone
browses:

https://www.mydomain.com/webmin

it proxies them to:

http://www.mydomain.com:10000 (this is all on the same server)

Funny thing is I can't browse Webmin when I enable the pf rules. Everything else appears to run fine except webmin.

Does anyone have any ideas why webmin is being blocked? I know its got something to do with the proxying but I just can't figure it out...

PS: This is my first attempt at pf rules, if they look hopelessly wrong or you have any suggestions as to how I can improve them I am listening! :e


----------



## DutchDaemon (Jul 29, 2009)

Just to make sure: can you post the output of [cmd=]pfctl -s rules[/cmd]?


----------



## xy16644 (Jul 29, 2009)

No problem, here we go:


```
No ALTQ support in kernel
ALTQ related functions disabled
block drop in all
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = ssh flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = smtp flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = http flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = imap flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = https flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = submission flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = imaps flags S/SA keep state
pass in on bge0 inet proto tcp from any to 192.168.0.200 port = 10000 flags S/SA keep state
pass in on bge0 inet proto udp from any to 192.168.0.200 port = 10000 keep state
```


----------



## DutchDaemon (Jul 29, 2009)

Try adding 'set skip on lo0' before the block/pass rules.


----------



## xy16644 (Jul 29, 2009)

You did it! That works perfectly. Thanks!

The rules look as follows now:


```
tcp_services = "{ 22, 25, 80, 143, 443, 587, 993 }"

set skip on lo0

block in all
pass in log on bge0 proto tcp from any to bge0 port $tcp_services
pass in log on bge0 proto tcp from any to bge0 port 10000
```

One thing I dont understand is I have added the log option to the rules now but nothing is appearing in the /var/log/pf.today file (its zero bytes in size), why's this?


----------



## DutchDaemon (Jul 29, 2009)

[cmd=]tcpdump -i pflog0[/cmd] should do the trick (assuming you have pflog enabled).

I think you can wipe the additional port 10000 rule, depending on how the proxying takes place. The fact that lo0 is involved makes me think that the client stays connected to port 80 all the time, and that the port 10000 connection is done 'in-house'. Try anyway.


----------



## xy16644 (Jul 29, 2009)

I guess not...


```
tcpdump: BIOCSETIF: pflog0: Device not configured
```


----------



## DutchDaemon (Jul 29, 2009)

Set pflog_enable="YES" in /etc/rc.conf and run [cmd=]/etc/rc.d/pflog start[/cmd]. You may have to reload pf to make it talk to the device.


----------



## xy16644 (Jul 29, 2009)

I tried what you said in your post and restarted pf but still an empty logfile. 

The syntax must be correct as pf started the service.

I can run this now:


```
alpha# tcpdump -i pflog0
tcpdump: WARNING: pflog0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on pflog0, link-type PFLOG (OpenBSD pflog file), capture size 96 bytes
```


----------



## DutchDaemon (Jul 29, 2009)

Try 'set loginterface bge0' in /etc/pf.conf. Note that pf.today is only populated at 3 AM by the nightly system scripts.


----------



## xy16644 (Jul 29, 2009)

OK I added that to the pf.conf file now.

Does that mean I can only see the traffic thats been logged at 3AM the next day?


----------



## DutchDaemon (Jul 29, 2009)

No, tcpdump was invented for that ..


----------



## xy16644 (Jul 29, 2009)

Fair enough.

When I load the rules now, it takes ssh aaaages to login. Must take about 30-45 seconds for me to be able to enter my username/password.

Is this normal?


----------



## DutchDaemon (Jul 29, 2009)

Is DNS resolving from that box slow as well? I can't really see why, because you have no outbound rules in pf, thus nothing in the way of DNS lookups. You could try adding 'pass out quick on bge0' before the first block rule.


----------



## xy16644 (Jul 29, 2009)

Can't be DNS as I am connecting using an IP address.

When I connect using Putty, the "login as" prompt displays immediately but once I enter my username and hit enter I have to wait...and wait (it took 20 seconds).


----------



## xy16644 (Jul 29, 2009)

Aaaah yes:

pass out quick on bge0

enables me to login instantly (as normal).

What would cause a delay like this?


----------



## DutchDaemon (Jul 29, 2009)

xy16644 said:
			
		

> Can't be DNS as I am connecting using an IP address.



That's not the point  The sshd session you're starting would like to know who's connecting to it, so it's performing a reverse DNS lookup on your IP address.


----------



## DutchDaemon (Jul 29, 2009)

xy16644 said:
			
		

> Aaaah yes:
> 
> pass out quick on bge0
> 
> ...



Don't know really. Like I said: you had no rules blocking outbound traffic to begin with, and now you have even less .. Having said that, I _always_ define rules for inbound and outbound traffic on every firewall I have, and I always use 'quick' rules wherever possible, so I guess pf has _some_ influence on 'undefined traffic'.


----------



## xy16644 (Jul 29, 2009)

Is it worth defining outbound rules? Sorry if this sounds like a stupid question but why would I want to block out going requests if its a server I built and "trust"? Is this just to be super secure so you know EXACTLY what your server is doing when connecting to the outside world?


----------



## DutchDaemon (Jul 29, 2009)

Hang on, that was a major mindfart on my part ... 

If you don't use a 'pass out' rule, the response to the outbound DNS request will hit your inbound rules, and DNS replies are not part of your 'pass in' rules, so they are blocked -- that caused your timeout.. 

But _with_ a 'pass out' rule (which is stateful), the reply back is allowed back in. 

That's why you always need inbound and outbound rules.

Anyway, I can't feed the entire contents of pf.conf(5) here, so: good reading 

http://www.freebsd.org/doc/en/books/handbook/firewalls-pf.html
http://www.openbsd.org/faq/pf/


----------



## dennylin93 (Jul 30, 2009)

Another link that might be useful: Firewalling with OpenBSD's PF packet filter.


----------



## xy16644 (Jul 30, 2009)

Thanks DutchDaemon you've been MOST helpful.

I think I have a lot of experimenting to do!

I still don't understand what DNS has to do with it though since I was using an IP when SSHing into the server. Am I missing something?

I understand what you saying about the pass out rule when DNS is involved but in this case its all IP based...


----------



## SirDice (Jul 30, 2009)

xy16644 said:
			
		

> I still don't understand what DNS has to do with it though since I was using an IP when SSHing into the server. Am I missing something?


One of the checks that sshd (the bit that runs on the server) does is a reverse DNS lookup (IP address->hostname) of the client's IP address.


----------



## xy16644 (Jul 30, 2009)

Aaaaah, got it, thank you!

Am starting to read the "Book of pf" today so hopefully that clarifies all the options in pf.conf.

Thanks everyone.


----------

