Re: [Shorewall-users] Macro files bug

Andrew Suffield
Fri, 26 Oct 2007 16:23:42 -0000

On Fri, Oct 26, 2007 at 08:11:55AM -0700, Tom Eastep
wrote:
> I regret having to inform you that macro files don''t have an
ORIGINAL DEST
> column.

Perhaps it''s time to completely rethink macros. They''re
obviously
designed to be convinient to process in shell; shorewall-perl should
be able to do something much more flexible with very little effort.

Let me just pull something out of the air, to give you some ideas. I''m
making this up as I go along, so it may set fire to your cat. This is
a description of one possible feature set that would make a good
replacement:

In the rules file, a ''function'' is any line of the form:

name/args

where ''args'' is a whitespace-delimited list of arguments.
Example:

#ACTION          SOURCE   DEST            PROTO    DEST PORT(S)
SMTP/DNAT:info   net      192.168.1.5

This is a call to the function ''SMTP'' with the arguments
''DNAT:info'',
''net'', and ''192.168.1.5''. Shorewall breaks
the line up by whitespace
but otherwise places no particular significance on the arguments;
they''re passed through to the function as-is.

When evaluating a function, shorewall first looks for the file
''function.name'' (function.SMTP in this example) on the usual
paths; if
it exists, it first evaluates this file in the perl interpreter, then
calls $Shorewall::Function::functions{$name}->(@args). The result of
that call is treated as a list of rules lines to be processed. Such a
file might look something like this (minus the comments):

package Shorewall::Function::SMTP; # By convention, this namespace is reserved
                                   # for functions to define whatever they
                                   # want; shorewall itself won''t put
anything
                                   # in here.

use Shorewall::Function; # @EXPORT = qw{add_function}

sub process {
  $_[3] = ''tcp'';
  $_[4] = 25;
  return [@_],
         [qw{ACCEPT fw}, $_[2], qw{tcp 465}]; # Example only. This line is
                                              # nonsense. Don''t
actually do
                                              # this.
}

add_function(SMTP => \&process); # sub add_function {$functions{$_[0]} =
$_[1]}

1;

But it could be any arbitrarily complicated perl code. You could fetch
stuff from a database or whatever. You could also install functions
from an extension script ahead of time - if there''s already a function
of the right name in the hash, shorewall won''t try to load a file. You
could even mess around with add_rule() and the other extension script
interfaces if you were being particularly evil (ie, return nothing and
insert the rules yourself, presumably because you didn''t like how
Shorewall::Rules normally processed them). This feature set should be
sufficient to generate anything somebody could reasonably want to do
in the rules file.

If no function can be located in this manner, shorewall attempts to
construct one out of a macro file: macro.SMTP is loaded, and processed
as usual. Macros are a subset of functions here.


It should be possible to implement all of that in under a hundred
lines of new code, or about an afternoon''s work.