Sometimes brute force is the answer (on Unix)

June 2, 2009

Suppose that you want to extract all of the IP addresses used by your (OpenBSD) firewall's PF rules, so that you can (for example) validate that all of the internal addresses mentioned still exist.

(For the purposes of this exercise we can ignore IP addresses in PF tables, because those are already easy to dump. Also, I am ignoring IP address ranges, netblocks, and so on; I am just interested in specific IP addresses.)

If you think that parsing PF's pf.conf file yourself is the answer to this problem, you have two problems (to riff from a famous remark). That way lies rewriting PF's rule parser yourself, and the language is not a simple one. You could parse the output of 'pfctl -s rules', which dumps the post-parsed rules in a simplified, expanded form that looks like, for example:

pass in quick on em1 inet proto tcp from any to IP port = smtp

But with this approach you'd still be writing a parser, and there are a fair number of cases for it to cover.

And then there's brute force in the finest Unix traditions:

pftctl -s rules | tr ' ' '\012' | grep '^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$' | sort -u

We list all the rules, turn spaces into newlines to give us one word per line, and discard all words that don't look like IP addresses (and then discard duplicates). That pfctl separates words for us makes this both possible and the easiest, simplest approach. It's probably also the most reliable, since it's counting on almost nothing in pfctl's output.

So: sometimes brute force really is the best answer.

Sidebar: sorting IP addresses into ascending order

Because I keep having to do this: assuming that you have regularly formed IP addresses (using all decimal digits), the incantation on a modern version of sort to get them into proper ascending order by IP address is:

sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4

(As I keep forgetting, you have to explicitly tell sort that each sort key is only one field long. Otherwise it starts at field N and goes to the end of the line, which is not what we want.)

Written on 02 June 2009.
« A thought on giving custom redundant storage systems some history
The costs of development versus the costs of operation »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Jun 2 01:00:14 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.