keep state
actually do? Is it useful?
quick
affect head rules?
head
statements for a group?
keep state
actually do? Is it useful?
From Darren:
First, yes, it is useful. What it does is allows you to only allow TCP packets through your firewall which are recognised as being part of an established connection rather than just arbitary TCP packets which can be used to perform "stealth scanning". In terms of rules, the following:
pass in proto tcp all
block out proto tcp all
block in proto tcp all flags S
pass in quick from any to any port = smtp flags S
pass out proto tcp from any port = smtp to any
can be replaced by:
block in proto tcp all
block out proto tcp all
pass in quick proto tcp from any to any port = smtp flags S keep state
keep state automatically matches packets going in the reverse direction (usually out) or on other interfaces without needing explicit rules.
For UDP, it will automatically allow packets in which are the "reverse" of packets that have already been allowed through, without needing to allow too many packets through. For example, the following could be used for DNS clients:
block out proto udp all
block in proto udp all
pass out proto udp from any port > 1024 to any port = 53
pass in proto udp from any port = 53 to any port > 1024
which allows through a LOT of unwanted packets. This can be effectively replaced with the following:
block out proto udp all
block in proto udp all
pass in proto udp from any to any port = 53 keep state
Keep state will also allow ICMP packets related to a TCP or UDP session through. So if you get ICMP type 3 code 4 in response to some websurfing allowed out by a keep state rule, they will be automatically allowed in. Any packet that IPF can be certain is part of a connection, even if it's a different protocol, will be let in.
Some firewalls use last match theory, while others use first match. Neither is better, it's purely taste. By default, IP Filter is last match, and you can change that if you want to. So what does that mean. Let say you have the following rules:
pass all
block in proto tcp from any to any port = 25
block all
What you have here is essentially a 'block all' firewall: the first two rules don't do anything. When a packet comes in, lets say from 1.2.3.4 port 2000, to 2.3.4.5 port 79, the filter is going to do this: Does this packet match 'pass all'? Yes, it does, let's keep that in mind. Does this packet match 'block in proto tcp from any to any port = 25'? No. Does this packet match 'block all'? Yes it does, so I can forget whatever else it's matched so far and keep this one in mind. Oh, that's the last rule, let's go with that one. So, even if the first rule specifically allowed all port 79 (finger) traffic in, it still wouldn't actually get in. Let look at one more example:
block in all
pass in from 1.2.3.4 to any
block in proto tcp from 1.2.3.4 to any port = 25
Now, let's say a packet comes in from 1.2.3.4 headed to our SMTP port (25), what happens? It get's blocked, because rule 3 is the last rule to match that packet.
Now, if you want to CHANGE this behavior, you simply add thequick
to your rules, so:
pass in quick from 1.2.3.4 to any
block in quick proto tcp from 1.2.3.4 to any port = 25
block in quick all
Now notice I moved the 1st rule and made it the last rule. If I didn't, nothing would get through because of thequick
keywork. You can mix and matchquick
and non-quick
rules (although in general it's not advised), but basically what IPF does is when it hits a rule that matches the packet, if thequick
keyword is there, it takes that action without looking any further.
In and out are from the perspective of the actual interface. In means arriving on the interface from the external world, leading into the box for kernel processing. Out means exiting the interface headed into the external world, having already been processed by the kernel.
Let's look at a packet traversing your firewall from the inside out...
This packet, call it a port 80 SYN from your browser, goes:
(Your workstation)-->(int_if)[OS_kernel](ext_if)-->(internet)
IN on int_if
and thru the kernel, then
OUT on ext_if
The SYN+ACK reply from a 'net webserver on port 80 goes (internet)-->(ext_if)[OS_kernel](int_if)-->(Your workstation)
IN on ext_if
and thru the kernel, then
OUT on int_if
Yes, it does, BUT, you may need a source license for BSD/OS. Object modules are provided for use with BSD/OS 3.1.
Any rule that needs to refer to the outside interface should refer to the VIRTUAL interface and NOT the physical interface. For example, if your physical interface is elxl0 and your PPPoE interface is ppp0, then all you will see on elxl0 is PPP Frames which IP Filter can't understand anyway. Those frames will get unwrapped and 'come in' on ppp0 as IP packets which IP Filter can then read and filter.
map a.b.c.d/M -> w.x.y.z/32
does NAT for all protocols, why do I need a map a.b.c.d/M -> w.x.y.z/32 portmap
Well, the first one will do NAT for you. However it will ONLY try the source port requested, so if two machines on your network request a connection to the same place with the same source address, one of them will fail.
However, if you have the portmap statement first, then if the source port is in use, it will try another source port in that range (you can specify a range instead of auto
).
In general, yes, but it depends. The portmap rule will only work for TCP and UDP. They will not work for any other protocol such as ICMP, ESP, etc. The other rule matches all other protocols, so generally you want both.
See the section for your specific OS.
You'll need to make your map rules look like this:map ppp0 10.0.0.0/8 -> 0/32
The 0/32 tells IPNAT to use the current IP address for the ppp0 interface as the address to map to. Next, "ipf -y" must be run each time the interface is brought up with a new IP address to synchronise the address if currently being used. Check your ppp dialer for instructions on how to run something each time a new connection is made (DHCPd has something similar for DHCP connections, incase you are not using dialup).
In short:
Rdr rewrites destination addresses and ports of packets entering an interface.
Map rewrites source addresses and ports of packets leaving an interface.
Bimap does both.
In long:
First and foremost: You probably do not need bimap. Try rdr first.
Rdr is generally used to allow internet hosts to access servers behind the machine running IPF. As an example, apache could be running on a server behind the IPF machine, and http requests to the external ip address of the ipf machine can be redirected to that apache server.
Map is generally used for NAT'ing (masquerading) clients behind the machine running IPF, thus you can have many clients accessing the internet via a single IP address.
Bimap is generall used when you're NAT'ing all outbound traffic to some address range (could be one address), and you have an server that needs to be accessed via a another address, and ALSO has to be able to make outgoing connections (like a passive FTP server) using that same address. Warning: Using bimap when it's not really needed can get you in a lot of trouble. If your NAT'ing outbound connections to the same address as your server gets contacted on, you do not need bimap. Always try rdr first!
Incoming packets enter the interface, get NAT'd, get filtered, then (if they get through the filter) get passed onto the kernel for processing. Additionally outgoing packets get filtered then NAT'd:
interface --> NAT --> filter --> OS --> filter --> NAT --> interface
This is important to keep in mind when writing your ruleset because your rules need to use the translated (i.e. internal host) address. In other words, if your public address is Z and internal host A is talking to external host B, then the traffic from B will have a destination address of A, NOT Z because the destination NAT has already happened. For more information, see IP Filter Flow and this thread.
First let me say that you should really learn to write regular rulesets for IP Filter. They are made to be nearly plain english. Being able to write the rules yourself will also give you a better understanding for what is going on. That said...
Filter Language Compiler - A tool written by Darren (the auther of IPF) that generates rules for the various packages which perform packet filtering from a common language.
ISBA - GUI for managing IPF.
Firewall Builder - a GUI for making rulesets for multiple firewall packages.
Yes. Two I know of, probably more. There's a perl script called plog
that comes with the IP Filter source code under the perl directory. Also available is fwanalog.
ipf -z -f your_rule_file
If you want to use DNS in the LAN, you need a separate DNS server for the LAN addresses. This server should not be visible outside the LAN. It's possible to run the DNS on the firewall itself, but you need to be very careful with the configuration of both the DNS server itself (e.g. BIND) and ipfilter in order to prevent a hole big enough to drive through. A few things to remember. Do not allow zone transfers across the firewall; instead, set up the DNS server as a master for your internal hosts (e.g. 192.168.x.x) and as a forwarder (and forward only mode) for external names which can not be resolved. RTFM on your DNS server.
It might be, but if the packets come in periodic bursts from only a few machines, it is probably nothing more than a misconfigured Cisco distributed content director trying to find the shortest routes to your machine. You can eliminate the log clutter with a rule like:
block in quick on ext-interface proto tcp from any to firewall port = domain flags SA
It is possible to filter the loopback interface on every platform except Solaris and HP-UX.
In most cases, do nothing. There is no law (for the most part) against port scanning. If you notice EXCESSIVE activity from a certain IP (i.e. multiple days or large bandwidth), then you can report it to the ISP that owns that IP address... other than that, there's not much you can do. There's no harm in some portscans... and it's a waste of your time to go after them. You could spend all day every day to track down all the people who port scanning you (especially if you have a large network), and blocking their IP's would make your ruleset inefficiently long. Additionally, if you run a webserver, or any public service, you'll likely block some valid IP's since many IP's are dynamic. The best defence is to secure your network, have a secure ruleset that you've tested in-depth.
For queries from the firewall machine itself, you can the open ports for replies to archie queries:
pass in quick proto udp to ext-interface from any port = 1525 to firewall port > 30000 keep state
pass in quick proto udp to ext-interface from any port = 191 to firewall port > 30000 keep state
From NATed machines behind the firewall, you either need to modify one of the ip-filter proxies so it works with archie, or to have your users use an archie site which returns replies on the querying port, such as archie.rediris.es.
quick
affect head rules?
Essentially thequick
, like thepass
orblock
, affects the default action for the group if nothing in the group matches. Any head rule, quick or otherwise, causes immediate recursion into that rule group. For example:
block in quick on de0 all head 100
descends into group 100, seeking further matches. If nothing matches inside and group 100 returns, theblock in quick
action specified in its head rule above is taken.
If something inside group 100 does match, that rule's action is taken instead. If that inner matching rule doesn't havequick
, thequick
bit is unset, and if nothing else inside group 100 matches it returns to its head, but with the action(s) specified by the inner rule -- specifically, thequick
bit is now off and overrides the original head rule'squick
. So in that case, rule processing continues past the above head rule, because a rule in that group matched and set "not quick" as part of the processing actions to do. If the head rule is notquick
then if no rules match, the end result is not aquick
rule.
You can use:
map foo0 0/0 -> 0/32 proxy port ftp ftp/tcp
This says "map everything to my external IP address." Unfortunately there is no way to say 0/32 -> 0/32 yet, so either use the above rule, or you can have yourip-up
(see the pppd manpage) edit youripnat.conf
each time you get a new IP.
Most people send them to the IP Filter mailing list, and this is perfectly fine. If you do not feel comfortable doing this, feel free to send them to Darren directly.
There is no simple MIB, but there are perl and shell scripts available to read various ip-filter statistics into MRTG. See http://www.18james.com/utilities.html#mrtg for more information on IPF and MRTG.
There are two numbers represented in statetop, each number represents the state of one side of the connection. The meanings of the numbers follow:
Number Name Comment 0 TCPS_CLOSED closed 1 TCPS_LISTEN listening for connection 2 TCPS_SYN_SENT active, have sent syn 3 TCPS_SYN_RECEIVED have sent and received syn 4 TCPS_ESTABLISHED established 5 TCPS_CLOSE_WAIT rcvd fin, waiting for close 6 TCPS_FIN_WAIT_1 have closed, sent fin 7 TCPS_CLOSING closed xchd FIN; await FIN ACK 8 TCPS_LAST_ACK had fin and close; await FIN ACK 9 TCPS_FIN_WAIT_2 have closed, fin is acked 10 TCPS_TIME_WAIT in 2*msl quiet wait after close
Some additional notes:
States < TCPS_ESTABLISHED are those where connections not established
States > TCPS_CLOSE_WAIT are those where user has closed
States > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN
All comments are Darren's taken straight fromip_compat.h
Editipf_state.h
and look for the lines:
#ifndef IPSTATE_SIZE # define IPSTATE_SIZE 5737 #endif #ifndef IPSTATE_MAX # define IPSTATE_MAX 4013 /* Maximum number of states held */ #endif
IPSTATE_MAX
should be approx. 70% ofIPSTATE_SIZE
and both numbers should be prime. The exact values you need depend highly upon the situation, but do NOT go crazy. Numbers in the 6 digits are very excessive. If you are having trouble with your state tables check out section IV-12 first.
For very high-traffic installations this will need to be tweaked. A good number to start with is 10 connections per workstation and adjust from there. Other things that might need tweaking depending on your situation isNMBCLUSTERS
andNAT_SIZE
.
Just as a guide, here's some of the other #defines and what they mean:
NAT_SIZE
- Size of the hash table for NAT rules
RDR_SIZE
- Size of the hash table for RDR rules
NAT_TABLE_SZ
- Size of the hash table which holds all active MAP/RDR entries
HOSTMAP_SIZE
- Table for holding the mapping of internal hosts to external IPs for consistency purposes when talking to a specific remote host
Not with IP Filter itself. But the code is there to allow an external program to do this.
Additionally Andrei Syrovenko wrote a utility calledrmstate
that does just that. His code is hosted at http://www.andy.in.ua/ipfilter/rmstate-1.1.tgz. We mirror his software here. Note that it is NOT guaranteed by Andrei Syrovenko, Darren Reed, Phil Dibowitz, Jason Lingohr or anyone else, nor is it part of the official IPF codebase.
The program takes only one argument: the source IP address of the entries that should be removed from the state table. Additionally, it will only work with ipfilter 3.4.26 and later, or 4.1.29 and later.
A lot. There have been cases where there have been more than 45,000 rules without noticeable performance loss. The important thing when dealing wih large numbers of rules is to use groups. When properly written and organized you can have tons of rules.
The solution seems a bit counter-intuitive at first, but it's actually quite simple. Setup a redirect on your internal interface, like this:
rdr int-interface ext-address/32 port 110 -> int-address port 110 tcp
rdr int-interface ext-address/32 port 25 -> int-address port 25 tcp
Remember that this is only if the services are on the firewall. If the services are on machines behind the firewall see IV.8.
Unfortunately, I've never used it myself. At this point the best I can do is give you the syntax:
map ext-interface int-address/24 -> ext-address/32 proxy port 500 ipsec/udp
Unfortunately, I've never used it myself. At this point the best I can do is give you the syntax:
map ext-interface int-address/24 -> ext-address/32 proxy port 1720 h323/tcp
Unfortunately, I've never used it myself. At this point the best I can do is give you the syntax:
map ext-interface int-address/24 -> ext-address/32 proxy port 7070 raudio/tcp
head
statements for a group?
It is not possible to do this in the 3.x version of IP Filter, however this is a feature of 4.x (currently in beta).
Yes and no. A bridge won't do address translation - it's not supposed to. However, you can use IPNat's proxies to allow connections across the statetable. For example, you could use the FTP proxy as follows:
map 0/0 -> 0/0 proxy port ftp ftp/tcp
To enable FTP across your bridge. Remember that at this time, the IPF FTP proxy does not support EPSV Passive connections, only plain PSV.
This question isn't as simple as it sounds. It takes an understanding of filtering, ICMP, UDP, ping, and traceroute. Here are some of the basics to get you started. Remember that if you are keeping state on all outgoing ICMP, then outgoing pings will automatically work.
Ping uses ICMP. Specifically it entails an ICMP type 8 code 0 (herein refered to as ICMP 8/0) packet (called "echo request") being sent to the target, and an ICMP 0/0 packet (called "echo reply") being sent back to the original host. To allow pings out one might do:
pass out quick proto icmp from any to any icmp-type 8 code 0 keep state
or if you didn't want to use keep state you could do:
pass out quick proto icmp from any to any icmp-type 8 code 0
pass in quick proto icmp from any to any icmp-type 0 code 0
Traceroute requires ICMP 11/0 and 3/3 (TTL expired and Port unreachable respectively). You will let to need to let these in to your network to allow outgoing traceroutes. Additionally, UNIX traceroute requires UDP packets (to the target) to ports greater than 3000. So you will need to let those in or out of your network to let UNIX traceroutes in or out of your network. Microsoft'stracert
utilitiy does not use UDP. For more information, see various discussion in the mailing list archives.
A utility called "ipscan" will get built if you build the ipfilter package from a download. With this, you can match on the first 16 bytes of a packet.
A sample config would be:
# Track ssh connections (i.e do nothing)
#
ssh : (), ("SSH-") = track else close
#
# Things which look like smtp to be tracked else closed.
# Client can start with EHLO (ESMTP) or HELO (SMTP).
#
smtp : ("HELO ", "**??."), ("220 ", "....") = track else close
#
and then in ipfilter rules, use:
pass out proto tcp from any to any port = 22 keep state scan ssh
pass out proto tcp from any to any port = 25 keep state scan smtp
At this point, it's more about ensuring that a particular kind of services appears to be initiated over a praticular port.
Darren is still developing this new code to do more things. Eventually it will integrate differently into ipfilter rather than just via "keep state" rules.
As of IP Filter 4.x and later, you can set variables in your ipf.conf and ipnat.conf as follows:
int_iface = "hme0";
ext_iface = "iprb0";
dmz_ip = "192.168.1.0/24";
int_ip = "192.168.2.0/24";
And then you can use those variables anywhere by prepending them with a dollar sign:
pass in quick on $int_iface from $int_ip keep state
Variables can contain other variables, and may also be referenced with${variable}
syntax.