Defining PF Macros In Multiple Anchor Files
Posted by Tres Mon, 25 Dec 2006 00:08:00 GMT
Splitting rules into multiple files allows you to easily organize rules, but the downside is that without a little scripting, you can’t really use macros effectively. Because of the way anchors work, you have to define macros in each file separately. This is a potential management overhead nightmare.
The #<–[MACROS]–> construct allows us to define all macros in a single file and distribute it to all anchor files. We keep all our macros in /usr/local/etc/pf_macros.conf. Just by putting #<–[MACROS]–> at the start of our ruleset, we can ensure that our single set of macros will be used in that file. That way, we can keep management overhead to a minimum. Here’s the ruby script that makes that possible:
#!/usr/bin/env ruby -w
# macros.rb
# script which will push macro variables from one file into all anchors files and pf.conf
# this should be run with cfengine, so when files get pushed out, or changed, the
# macros will automatically be defined.
# to allow this file to automatically push uniform macros to your pf anchors and pf.conf
# place a line like the following into the file you want to have macros pushed into
#<--[MACROS]-->
# this script will replace the entire line within which the <--[MACROS]--> element is used
require 'find'
require 'fileutils'
require 'date'
pf_base_conf_dir="/usr/local/etc"
timestamp = DateTime.now
pf_anchors_dir = "#{pf_base_conf_dir}/pf_anchors"
macro_defs_file = "#{pf_base_conf_dir}/pf_macros.conf"
pf_conf = "/etc/pf.conf"
backup_data_dir = "/tmp/"
backup_file = "data.#{timestamp}"
backup = "#{backup_data_dir}/#{backup_file}"
if File.exists?( "#{macro_defs_file}" )
macro_definitions = IO.read("#{macro_defs_file}")
else
macro_definitions = nil
end
#first take care of pf.conf
FileUtils.copy( pf_conf, backup )
File.open( backup, "r" ) do |file|
new_file = File.open( pf_conf, "w" )
file.each do |line|
new_line = line.gsub( /^.*<--\[MACROS\]--\>.*$/, macro_definitions )
new_file.write new_line
end
file.close
FileUtils.rm( backup )
end
#then take care of the anchor files
Find.find(pf_anchors_dir) do |file_name|
Find.prune if file_name =~ /\.svn/
if File.file?(file_name)
FileUtils.copy( file_name, backup )
File.open(backup, "r") do |file|
new_file = File.open( file_name, "w" )
file.each do |line|
newline = line.gsub(/^.*<--\[MACROS\]--\>.*$/, macro_definitions )
new_file.write newline
end
file.close
FileUtils.rm( backup )
end
end
end