BSD DevCenter
oreilly.comSafari Books Online.Conferences.


Greylisting with PF
Pages: 1, 2, 3, 4, 5, 6, 7

Notice that the status indicates PF is disabled. To enable PF, issue the command:

# pfctl -e
No ALTQ support in kernel
ALTQ related functions disabled
pf enabled

There are no filter rules loaded. To test your rules, without loading them:

pfctl -n -f /etc/pf.rules

This will report any syntax errors. To load the rules:

pfctl -f /etc/pf.rules

Read the man page for more -s options. You can pull out NAT, RDR, filtering, etc.

Very Simple Rules

This section shows very simple rules. It is a trimmed down version of what I use at home. fxp0 faces my ISP. fxp1 talks to my home network. This setting in /etc/rc.conf allows the gateway to forward packets between the two NICs:


The rule set is:

  1. ext_if="fxp0"
  2. int_if="fxp1"
  3. internal_net=""
  4. external_addr="m.n.o.p"
  5. icmp_types="echoreq"
  6. NoRouteIPs = "{,,, }"
  7. # machines inside
  8. webserver=""
  9. # machines outside
  10. FISH="a.b.c.d"
  11. STIN="e.f.g.h"
  12. THEF="i.j.k.l"
  13. table <AllowedToSSH> { $FISH, $STIN, $THEF }
  14. set skip on lo0
  15. set skip on gif0
  16. scrub in all
  17. nat on $ext_if from $internal_net to any -> ($ext_if)
  18. rdr on $ext_if proto tcp from any to $external_addr port 80 -> $webserver
  19. # block all by default
  20. block all
  21. block in quick on $ext_if from $NoRouteIPs to any
  22. block out quick on $ext_if from any to $NoRouteIPs
  23. antispoof quick for $int_if inet
  24. # pass all traffic to and from the local network
  25. pass in on $int_if from $internal_net to any
  26. pass out on $int_if from any to $internal_net
  27. pass out on $ext_if proto tcp all modulate state flags S/SA
  28. pass out on $ext_if proto { udp, icmp } all keep state
  29. pass in on $ext_if inet proto tcp from any to $webserver port 80 flags S/SA synproxy state
  30. pass in quick on $ext_if inet proto tcp from <AllowedToSSH> to $external_addr port 22 flags S/SA keep state

A few notes on specific lines above:

  • 1-2 are macros that define my external and internal NICs.
  • 3-4 are macros that define my internal network and my public IP address.
  • 8 is my development web server.
  • 9-13 are machines that are allowed to SSH to my gateway.
  • 13 is a table of those machines.
  • 17 is my nat rules.
  • 18 allows redirection of port 80 on my gateway to my web server.
  • 30 allows those machines to SSH in.

I hope that's enough to get you started with your own rule set.

Treating Different OSes Differently

Equality is a nice concept. The theory is great. The practice is not universal, especially when it comes to operating systems. Why discriminate? I will answer that question in the form of a story related to me by someone who uses OS fingerprinting at home to lessen his domestic workload. To protect the guilty, I will call this person Phil.

Phil uses BSD in his everyday work. At home, his kids use BSD. Their machines also dual-boot with Windows in case they need to do specific things for homework. In general, they use BSD. When using Windows, they can only use the Web; nothing else. Why do these rules exist? To lessen Phil's workload. He doesn't want to remove viruses and spamware all the time. How do you keep them off the Windows computers? You keep the Windows computers off the Internet.

Sure, rules are nice, but some kids, and some adults, don't follow the rules. It would be nice if there was some way to enforce this at the firewall. Enter OS fingerprinting.

OS fingerprinting is not new. nmap, for example, uses it. From man pf.conf:

Passive OS Fingerprinting is a mechanism to inspect nuances of a TCP connection's initial SYN packet and guess at the host's operating system.

PF's ability to detect the Operating System at the other end of the TCP/IP connection allows Phil to prevent his kids from breaking the rules. To illustrate this, I'll try blocking incoming queries based upon the OS you use. On my web server at home, I created a website: To demonstrate that the website is actually running, you will be able to browse freely to the URL, but if you try, you will not be able to connect if you use Windows.

How do I do this? I'll show you the PF rules, but the Apache setup is outside the scope of this article.

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow

Sponsored by: