Tuesday, May 18, 2010

OpenBSD 4.7 Release pf.conf conversion tool

Today marks the release of OpenBSD 4.7, with this are many new changes outlined here. One of the changes requires pre 4.7 pf.conf files to be modified before they will load, changes to the nat/rdr/route-to/reply-to syntax are the reason for this. These changes are outlined here, normally these can be edited by hand fairly easily, but with many boxes to manage the following script seemed to save me a little time, this hasn't been tested extensively, but seems to work for me. If you find a bug let me know and I'll fix it.

Usage: prompt> perl pfconvert.pl /etc/pf.conf > /etc/pf.conf.new

!!! Note, make sure you verify the converted file will work, ie "pfctl -nf /etc/pf.conf.new"

#!/usr/bin/perl

# Read the config into a scaler
my $pfconf = do { local( @PFCONF, $/ ) = $ARGV[0] ; <> } ;

# Merge any multiline rules into a single line
$pfconf =~ s/\\\n/+multilinebreak+/g;

# Read the file into an array so we can process line by line
@PFCONF = split('\n', $pfconf);

foreach $line (@PFCONF) {
# Remove rdr-anchors for relayd ftp-proxy and tftp-proxy
if ($line =~ m/^nat-anchor|^rdr-anchor/) {
if ($line =~ m/relayd|ftp-proxy|tftp-proxy/) {
next;
}
}

# Convert rdr rules to new 4.7 syntax
if ($line =~ m/^rdr on/) {
$line =~ s/^rdr/match in/;
$line =~ s/->/rdr-to/;
}

# Convert nat rules to new 4.7 syntax
if ($line =~ m/^nat on/) {
$line =~ s/^nat/match out/;
$line =~ s/->/nat-to/;
}

# Convert binat rules to new 4.7 syntax
if ($line =~ m/^binat on/) {
$line =~ s/^binat/match/;
$line =~ s/->/binat-to/;
}

# Convert reply-to rules to new 4.7 syntax
if ($line =~ m/reply-to/) {
if ($line =~ m/\sto\s+(.*)/) {
$dest = $1;
}
if ($line =~ m/\s(\(.*\))/) {
$ifaddr = $1;
}
$line =~ s/reply-to .+/to $dest reply-to $ifaddr/;
}

# Convert route-to rules to new 4.7 syntax
if ($line =~ m/route-to/) {
if ($line =~ m/\sfrom\s+(.*)/) {
$dest = $1;
}
if ($line =~ m/\s(\(.*\))/) {
$ifaddr = $1;
}
$line =~ s/route-to .+/from $dest route-to $ifaddr/;
}

# Unmerge any multiline rules
$line =~ s/\+multilinebreak\+/\\\n/g;
print "$line\n";
}

3 comments:

  1. THANK YOU SO MUCH !!!!!!! you saved me 10000 hours of work !!!

    ReplyDelete
  2. Hi, thank you, but I think that the "scrub in" no longer exists and should be deleted with the new version ?

    ReplyDelete
  3. Excelent!!, works ok!.
    Its true...."scrub in" was replaced for "match in all scrub"
    Thanks!

    ReplyDelete