Date: Mon, 26 Feb 1996 21:25:15 +0100 From: Poul-Henning Kamp <phk@critter.tfs.com> To: hackers@freebsd.org Subject: IP filtering strawman, comments please. Message-ID: <12238.825366315@critter.tfs.com>
next in thread | raw e-mail | index | archive | help
Sorry for the wide cross-posting, followups to "hackers" only please ! IP filtering in FreeBSD, a strawman proposal. Poul-Henning Kamp 26 feb 1996 Ver: 1.1 This is a strawman intended to foster discussion about the future support for IP packet filtering in the FreeBSD kernel. Fig 1 shows a simplified schematic of the paths of IP packets in the FreeBSD kernel, and various potential spots for applying filters. =========================================================================== if0 --->(0i)--->+ | if1 --->(1i)--->+ | applications if2 --->(2i)--->+ ^ | | | v +--->(A)---> protocol stack --->(B)--->+ | | +--->(Ci)---> route through ---->(Co)--->+ | +--->(0o)---> if0 | +--->(1o)---> if1 | +--->(2o)---> if2 == Fig 1 ================================================================== The present support (as of 960226) provides the following support: There is one chain of rules, and it is applied at (A), (B), (Ci) and (Co). The following information is available, in addition to the packet itself: At (A) and (Ci), receiving interface. At (B) and (Co), destination interface. Now, this is clearly not optimal from particular many points, therefore I suggest the following model instead: There will be multiple chains of rules as follows: For each interface, two chains of rules. One filters incoming packets, the other outgoing packets. In Fig 1 these are the pairs (0i/0o), (1i/1o) &c. No information is available apart from the packet itself. There will be a filter-chain at (A) to filter what packets we let into the local protocol stack. In addition to the packet, information about the arrival interface is available. There will be a filter-chain at (B) to filter what packets we let out of the local protocol stack. In addition to the packet, information about the destination interface is available. There will be two filter-chains at (Ci) and (Co) to filter what packets we route through this machine. At (Ci) the arrival interface is known and at (Co) the destination interface is known in addition to the packet itself. Rules are numbered with 16 bit integers, and can appear on any number of filter-chains, such that a conceptual matrix is formed, as illustrated in Fig 2: =========================================================================== Rule# criteria 0i 1i 2i A Ci Co B 0o 1o 2o --------------------------------------------------------------------------- 00010 Deny all loose source route X X X X 00020 Deny all strict source route X X X X 00030 Deny all traffic via if0 X X 00040 Deny all tcp setup packets X X 65535 Allow all traffic X X X X X X X X X X == Fig 2 ================================================================== At each filtering point, the rules are applied in numeric order, until one of them matches the packet, the action from that rule is then taken. Just as important as where a rule can be applied, is what the rule can express, I suggest this functionality, this is more or less what we have now as well: Source-ip matches target+netmask Destination-ip matches target+netmask Protocol matches (any, udp, icmp, tcp, other). Packet has (not) ip-option(s) (loose source route, strict source route, timestamp, record route, other). Interface matches name Interface matches IP. For UDP & TCP: source-port matches target(-range) destination-port matches target(-range) For TCP: packet has (not) TCP flags (syn, rst, psh, urg, ack). Packet is (not) a non-initial fragment. Packet is (not) a broadcast. Packet is (not) a multicast. And finally, what should be done when the rule matches: "drop" the packet is discarded. "refuse" as drop, but an ICMP packet is sent if applicable. "pass" the packet is OK and continues it's merry way. "count" the counters for this rule is updated, but the rule doesn't match the packet, and the next rule is tried. "divert" the packet is sent to a (specific) instance of the tun# interface, where a user-mode process can have fun with it. Some modifiers to this exist: "printf" register the match with printf. "syslog" register the match with syslog. "verbose" be very detailed. "hexdump" be very very detailed. The changes to the code to support this scheme are rather simple: Add reference counts to each rule. Add two rule-chain headers to the if structure. Add the logic to specify what chains a rule applies to. Make sure ip_output knows if the packet was locally generated or routed. Comments ? Poul-Henning
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?12238.825366315>