|
BSD::Ipfwgen - Module to aid in the creation of ipfw-based firewalls
|
BSD::Ipfwgen - Module to aid in the creation of ipfw-based firewalls
use BSD::Ipfwgen;
outside qw(**interface list**);
leaf qw(**interface list**);
consolidate qw(**network list**);
us qw(**network list**);
not_us qw(**network list**);
to_us qw(**network list**);
from_us qw(**network list**);
symmetric qw(**network list**);
count_by_interface();
count_by_address qw(**network list**);
count_by_udp qw(**port list**);
count_by_tcp qw(**port list**);
no_looping()
no_spoofing_us()
no_spoofing_by_us()
no_leaf_spoofing()
tcp_from_rules($port, $rules);
tcp_to_rules($port, $rules);
udp_from_rules($port, $rules);
udp_to_rules($port, $rules);
from_net_rules($network, $rules);
to_net_rules($network, $rules);
to_me_rules($rules)
not_to_me_rules($rules)
from_me_rules($rules)
not_from_me_rules($rules)
in_interface_rules($interface, $rules);
out_interface_rules($interface, $rules);
drop_unwanted qw(**network list**);
generate qw(**options**)
**port list** is a list of integers. 80, 23, etc.
**network list** is a list of network address. 207.33.90.32/27 etc.
**interface list** is a list of interface names. de0, fxp1 etc
**options** is a list of the valid options: DEFAULT-ACCEPT, INSECURE
$rules is a newline separated set of L<ipfw> rules.
Ipfwgen is designed to make writing complex firewalls easier and
safer. It handles generating some of the harder rulesets: anti-spoofing,
anti-looping, and anti land-attack.
Ipfwgen does not try to reduce the complexity of firewall building.
What it does do is allow you to write a perl program which generates
a firewal. It's expected that the firewalls generated by Ipfwgen will
be examined by a human and installed manually.
Ipfwgen commands must be given in a particular sequence. First are
the declaritive commands: outside, leaf, consolidate, us,
not_us, and symmetric.
Then the rule-specification commands: almost everything else. Ipfwgen
keeps an internal database of the rules that are in progress. After all
the rule-specification commands are done, then the firewall gets
compiled.
The generate command compiles the specifications into actuall the ipfw manpage
commands and dumps them on STDOUT.
The declaritive commands must preceed all others.
- outside(INTERFACEs)
-
Specifies that an interface is connected to the Internet at large
and that the packets coming in from that interface should not be from
``us''.
- leaf(INTERFACEs)
-
Specifies that an interface leads to a network with no other
connections. Routing to a leaf can be assumed to be symmetric.
- consolidate(NETWORKSs)
-
Specifies that addresses within the network specified should be ignored
and that the network address should be used instead when a list of
IP addresses for the firewall system is needed. This is primarily
used to avoid needing to list a large number of IP addresses on
web servers with many virtual hosts.
- us(NETWORKs)
-
Specifies network ranges that comprise the address space that is routed
by ``us''. The us command implies that we are the only source of routes
for the addresses specifed.
- not_us(NETWORKs)
-
Specifies networks that are within ``us'' but should not be. For example,
``us'' may claim to include 209.66.121.0/24, but in reality, the first few
addresses aren't ours. This situation can be handled using ``not_us''.
- to_us(NETWORKs)
-
Specifies networks that we may legitimately receive traffic on
behalf of. Don't filter it when incomming at the edges.
- from_us(NETWORKs)
-
Specifies networks that we may legitimately send traffic on
behalf of. Don't filter it when outgoing at the edges.
- symmetric(NETWORKs)
-
Specifies that the routes to a network are expected to be symmetric.
These are all optional.
- count_by_interface()
-
Requests that traffic be counted by interface. Both incoming and
outgoing will be counted.
- count_by_address(NETWORKs)
-
Requests that traffic be tracked on a per NETWORK bases.
- count_by_udp(PORTs)
-
Requests that traffic be tracked on a per PORT basis for udp.
- count_by_tcp(PORTs)
-
Requests that traffic be tracked on a per PORT basis for udp.
Ipfwgen makes an attempt to generate all the anti-looping and anti-spoofing
rules. These are all optional, but anti land-attack rules will be
added automatically.
- no_looping()
-
Specifies that obvious packet loops should be prevented. For example,
do not route packets meant for us out and outside interface.
- no_spoofing_us()
-
Specifies that if there is an ``outside'' interface, the packets arriving
on it should be checked to make sure that they don't claim to come from
ourselves.
- no_spoofing_by_us()
-
Specifies that we should only route packets out our ``outside'' interface
that came from us.
- no_leaf_spoofing()
-
Only accept packets from a leaf interface that come from and address
that routes over the leaf interface. Do not accept any packets from
anyone that claim to be from addresses that route over a leaf interface
unless that came in over the leaf interface.
These are all optional.
- from_net_rules(network,rules)
-
Apply the specified ruleset to packets that came from an address
with the network specified.
- to_net_rules(network,rules)
-
Apply the specified ruleset to packets that are destined for an address
with the network specified.
- drop_unwanted(networks)
-
A quick way to list the networks that you do not with to communicate
with.
These are all optional.
- tcp_from_rules(port,rules)
-
Apply the rules specified to tcp packets that came from the specified port.
- tcp_to_rules(port,rules)
-
Apply the rules specified to tcp packets that are destined for the
specified port.
- udp_from_rules(port,rules)
-
Apply the rules specified to udp packets that came from the specified port.
- udp_to_rules(port,rules)
-
Apply the rules specified to udp packets that are destined for the
specified port.
These are all optional. These filters will be generated anyway to
handle the anti land-attack rules.
- to_me_rules(rules)
-
Apply the specified rules to packets that are destined for this machine.
- not_to_me_rules(rules)
-
Apply the specified rules to packets that are not destined for this machine.
- from_me_rules(rules)
-
Apply the specified rules to packets that are sent from this machine.
- not_from_me_rules(rules)
-
Apply the specified rules to packets that came from some other machine.
These are all optional, but these filters will be generated anyway
to do the anti-looping and anti-spoofing rules.
- in_interface_rules(interface,rules)
-
Apply the specified rules to packets that arrived on the specified
interface.
- out_interface_rules(interface,rules)
-
Apply the specified rules to packets that are departing over the
specified interface.
Once the rules have been declared, they must be compiled into
actual firewall commands. The command to compile them is
generate(options). The generate command should be given
last.
The compiled rules are dumped on STDOUT. They are not automatically
executed. Running generate() cannot harm your system. Running the
output from a program that includes generate() can harm your system
so be careful!
The following options are understood.
- DEFAULT-ACCEPT
-
Specifies that unless packets are specifically rejected, they should be
accepted. The default is that packets that are not specifically accpeted
are rejected.
- INSECURE
-
When building the firewall, add in a rule to accept all packets
as a temporary measure. When the firewall is completely built, remove
the rule. This creates a window of opportunity for attack. On the
other hand, it helps prevent accididental computer death when rebuilding
the firewall. It's a good idea to use INSECURE while testing your
firewall, but not to use it for final deployment.
- LOG_DENIES
-
Specifies that in general, when packets are denied, they should be
logged. Some rules will still not log: the anti-looping rules tend
to deny a lot of packets and logging those is both boring and wasteful.
Rules that are defined by hand will that use =deny will log the denies
if this is set.
Whenever a command argument includes filtering rules, the rules
are expected to be passed in as a single string with the individual
rules separated with newlines.
Ipfwgen rule generation can be modified with special ``rules''.
- =label name
-
Specifies a skipto target label. Don't worry about the numbering
of the rules. Add a label wherever needed. Some labels are already
defined so don't be alarmed if you get an un-expected duplicate.
- =rulenum num
-
If possible, set the current rule number to num.
- =gap [size]
-
Make a gap in the rule numbering by rounding up to the
next multiple of size.
- =countby num
-
When incrementing rule numbers, increment by num.
In addtion to the standard actions defined by the ipfw manpage, there are
some new ones defined by Ipfwgen.
- =skiprule
-
Specifies that the action for this filter rule is to skip over the
following rule.
- =skipto label
-
Specifies that the action for this filter rule is to skip to the rule
after where the label is specified.
- =deny
-
Specifies that the action for this filter rule is to deny the packet.
Packets denied using =deny will be logged if the generate option
LOG_DENIES is specified.
- =deny_log
-
Specifies that the action for this filter is to deny the packet. Just
plain deny log can be used insted.
- =deny_no_log
-
Specifies that the action for this filter is to deny the packet. Just
plain deny can be used instead.
Ipfwgen provides a shorthand way to specify certain things.
- =ME
-
The =ME specifier will be replaced by the IP address of the firewall
system. If the firewall system has more than one IP address the
rule will be replicated as necessary to put them all in. =skiprule
still works.
- =US
-
The =US specifier will be replaced by the network defined by the
us() command. If more than one network was defined, then the rule
with the =US specifier will be replicated as necessary to put them all
in. =skiprule still works.
- =TOUS
-
The =US specifier will be replaced by the network defined by the
to_us() command. If more than one network was defined, then the rule
with the =US specifier will be replicated as necessary to put them all
in. =skiprule still works.
- =FROMUS
-
The =FROMUS specifier will be replaced by the network defined by the
from_us() command. If more than one network was defined, then the rule
with the =US specifier will be replicated as necessary to put them all
in. =skiprule still works.
- =IN
-
The =IN specifier will be replaced by the interfaces that the firewall
system has. This will likely require replicating the rule with the specifier.
=skiprule still works.
- =host:hostname
-
The =host:hostname specifier will be replaced with the IP address of
the hosthame given. Only one IP address will be substituted in so do not
use this with hosts that have multiple IP addresses. The =host:hostname
specifier is the only specifier that can be used more than once in a
rule and the only one that can be combined with other specifiers.
- =IF0
-
FreeBSD treats the first interface a specially. The =IF0 specifier will
be replaced by the name of the first interface. =IF0 can be combined with
other meta specifiers.
The rules generated by Ipfwgen are processed in the following sequence:
-
Counting rules. Count packets in by interfaces; count
packets out by interface; count packets from udp ports;
count packets to udp ports; count packets from tcp ports;
count packets to tcp pots; count packets from and to particular
networks.
-
Apply filters on packets that are from the firewall system
(to_me_rules). Apply
filters on packets that are not from the firewall system
(not_to_me_rules).
-
Apply filters on packets that are to the firewall system
(from_me_rules). Apply filters
on packets that are not to the firewall system
(not_from_me_rules).
-
Apply filters for packets that came in via a particular interface.
(in_interface_rules). This includes loop prevention on point-to-point
interfaces. This also includes preventing others from spoofing us and
leaf nodes from spoofing anyone.
-
Apply filters for packets that are going out via a particular interface
(out_interface_rules). This includes loop prevention on outside
interfaces and on broadcast networks. This also includes preventing
us from spoofing others.
-
Accept packets that are part of established TCP connections.
-
Apply filters for packets that are coming from a particular
network (from_net_rules). This includes preventing anyone from spoofing
traffic from leaf nodes.
-
Apply filters for packets that are going to a particular
network (to_net_rules). This includes dropping unwanted networks.
-
Apply filters for packets that are coming from a particular udp port.
-
Apply filters for packets that are going to a particular udp port.
-
Apply filters for packets that are coming from a particular tcp port.
-
Apply filters for packets that are going to a particular tcp port.
-
Accept or deny the rest as per the DEFAULT-ACCEPT option.
#/usr/local/bin/perl -w
use strict;
use BSD::Ipfwgen;
use IO::Handle;
outside 'fxp0';
leaf 'etha32';
consolidate '209.66.121.128/25';
us qw(
140.174.82.0/24
207.33.232.0/22
207.33.184.0/22
207.33.240.0/21
209.157.64.0/19
140.174.154.0/24
207.33.66.0/24
209.66.121.0/24
);
not_us qw(
209.66.121.0/29
);
symmetric qw(
209.66.121.0/27
);
count_by_interface();
count_by_tcp qw(80 119 21 53 25 871 513 23 6667);
count_by_address qw();
drop_unwanted qw(
192.168.0.0:255.255.0.0
172.16.0.0:255.240.0.0
10.0.0.0:255.0.0.0
);
no_looping();
no_spoofing_us();
no_spoofing_by_us();
no_leaf_spoofing();
to_me_rules <<'';
=deny udp from not 140.174.82.0/26 to any 111,2049 # portmap, NFS
=deny tcp from not 140.174.82.0/26 to any 111 # portmap
from_me_rules <<'';
=deny udp from any 111,2049 to not 140.174.82.0/26 # portmap, NFS
=deny tcp from any 111 to not 140.174.82.0/26 # portmap
to_net_rules ('=host:mac84', <<'');
=skiprule tcp from 140.174.82.32/27 to =host:mac84 6000 # mac84
=deny tcp from any to =host:mac84 6000
generate qw(INSECURE DEFAULT-ACCEPT);
Ipfwgen generates commands that work with FreeBSD 2.2.5's
firewall program: the ipfw manpage. Ipfwgen makes use of features that were
only recently added to ipfw: skipto, xmit, recv.
Ipfwgen cannot currently deal non-exclusive thru traffic. For ISPs
this means that it cannot deal with customers that have redundent
connections. Fixing this is not terribly hard.
The firewalls generated by Ipfwgen are often not optimal. If anyone
wishes to write an optimizer, that would be great!
The firewalls generated by Ipfwgen can be hard to read.
Ipfwgen expects the netmasks on point to point links to be accurate.
Nothing else really cares about such netmasks so this may lead to some
problems.
Some of the internal structures aren't very enlightened. For example,
everything having to do with get_netmask() and mark_addresses() could be
redone for clarity and speed.
Copyright (C) 1998, David Muir Sharnoff. All rights reserved.
License hearby granted for anyone to use this module at their own risk.
Please feed useful changes back to muir@idiom.com.
|
BSD::Ipfwgen - Module to aid in the creation of ipfw-based firewalls
|