2009/2/23 Jason Dixon <[email protected]>:
> On Mon, Feb 23, 2009 at 05:58:20PM -0800, Hilco Wijbenga wrote:
>> Hi all,
>>
>> I've been trying to get a simple firewall system up-and-running in
>> OpenBSD. I have "The Book of PF" and "Secure Architectures
>> with OpenBSD" so I thought it would be very simple. Well, we're two
>> weeks later now and still no firewall. :-) The pf rules I found in
>> those books don't seem to work as I expected them to work.
>>
>> Before I list my current pf.conf, let me give a few more details. My
>> firewall will be running a few services for my network (DHCP, NTP, and
>> DNS). I need to use NAT to get my own network Internet access. DHCP
>> works. I seem to have managed to get DNS (maradns on lo0 and sk1) and
>> ICMP working.
>
> Sounds like a very basic home setup. B You want your firewall to handle
> DHCP, NTP and act as a DNS resolver for your local network. B Easy
> enough.
Yes, exactly what I thought. :-)
>> /etc/pf.conf
>> 01 ext_if = "sk0"
>> 02 int_if = "sk1"
>> 03 localnet = $int_if:network
>> 04 internet = $ext_if:network
>> 05 udp_services = "{ domain, ntp }"
>> 06 icmp_types = "{ echoreq, unreach }"
>> 07
>> 08 nat log on $ext_if from $localnet to any -> ($ext_if)
>> 09
>> 10 block log all
>> 11
>> 12 pass quick inet proto { tcp, udp } from $internet to any port
$udp_services
>> 13 pass quick inet proto { tcp, udp } from $localnet to any port
$udp_services
>> 14 pass quick inet proto { tcp, udp } from $lo0:network to any port
>> $udp_services
>> 15
>> 16 pass inet proto icmp all icmp-type $icmp_types
>> 17 pass from { lo0, $localnet } to any keep state
>>
>> a. Why do I need 12? I had expected 13 (which I don't seem to need).
>> Wouldn't 12 be for incoming requests from the Internet?
>> b. Given that ping works from my network (so that presumably routing
>> is okay), why doesn't anything else work? HTTP seems blocked by the
>> firewall.
>> c. How can I get pflog to flush immediately? I noticed I have to wait
>> a minute or so before logged lines show up.
>> d. Any other pointers?
>
> Let's start off with your questions and then a working example below.
>
> a. B If you're only intending to allow outbound traffic from your local
> network, you don't. B That rule would be to allow inbound requests from
> the internet to your firewall (and optionally, other internal services
> if you had rdr or binat rules). B By default, pf uses "keep state" on all
> pass rules, which means that it will track your connections outbound and
> allow the appropriate replies from external services.
That's what I thought, hence the question because line 12 was required
for it to work.
> b. B Because line 16 is allowing icmp outbound *and* inbound. B You have
> no directional (or interface) qualifiers.
Shouldn't 17 take care of all that for (e.g.) HTTP requests? It's from
the local net to anywhere and it keeps state (not relevant for HTTP, I
guess, but still).
> c. B I would need more details here to give you a qualified answer. B As
> in, examples. B You're only logging blocked traffic.
Yes, I thought that would make it easier. It isn't always clear to me
what a logged line is for: was it logged because it was blocked or
because it was allowed?
> d. B Read the PF FAQ.
Right. :-)
> Ok, here is a working example based on your description. B Noticed the
> beauty in the simplicity. B :)
What!?! You didn't like my near random mish-mash of rules? ;-)
> ##########################################################
> 00 ext_if = "sk0"
> 01 int_if = "sk1"
> 02
> 03 set skip on lo
> 04
> 05 scrub in
> 06
> 07 nat on $ext_if from $int_if:network to any -> ($ext_if:0)
> 08
> 09 block in log all
> 10 pass in on $int_if inet keep state
> ##########################################################
I'll try that tonight.
> The first two lines are obvious. B Why did I remove "localnet" and
> "internet"? B The first is truly unnecessary in a ruleset this small; B it
> simply adds abstraction where none is needed. B The "internet" is already
> provided via the "any" and "all" keywords.
That's one thing that isn't obvious to me. To the firewall sk0 and sk1
are just two interfaces, why/how would "any" and "all" refer to the
internet? Or do you simply mean they refer/include all interfaces so
also the internet?
> Line 3 allows us to skip state on loopback, nothing exciting there.
Yeah, I read about that and figured it could wait till later. Just
icing on the cake, right?
> Line 5 provides "scrubbing", also known as packet defragmentation. B This
> helps pf by reassembling packet fragments before applying rules. B In
> short, it's a safety mechanism.
Same thing, I figured that could wait.
> Line 7 allows outbound NAT to the internet.
Okay, so the only difference with my attempt at it is the ":0" you
added at the end. Does it mean anything special or was it simply
implied in my version?
> Line 9 provides a basic "block all" for inbound requests. B This affects
> both inbound from the internet, as well as inbound (from the firewall's
> perspective) from the local network. B Which requires...
Was this the main problem then? I was blocking everything in and out?
I was hoping to be precise and complete. :-) Don't laugh too loudly
please. :-)
> Line 10, which finishes our tidy ruleset by passing all traffic from the
> localnet to [the firewall and] the internet. B The "inet" keyword tells
> pf that this covers IPv4 traffic including TCP, UDP and ICMP.
I suppose the devil is in the details. I'll know tonight whether it works.
> P.S. B Contrary to what someone else suggested, pf is a "last match"
> packet filter. B That means that it will traverse the entire ruleset and
> apply the last matching rule... UNLESS you use the "quick" keyword. B I
> highly recommend you AVOID using "quick" until you have a solid
> comprehension of pf and packet filtering in general.
Yes, I know about the "last match". I did actually read those books.
:-) Avoiding "quick" sounds like good advice for now.
> P.P.S. B I have not actually tested this ruleset, but it should work
> fine. B If I've missed something I'm sure sthen@ will point it out for
> me. B ;)
No worries, hopefully I'll be able to send an email from my own box tonight.
Cheers,
Hilco