%deffont "standard" xfont "utopia-medium-r", vfont "goth", tfont "arial.ttf" %deffont "thick" xfont "utopia-bold-r", vfont "goth", tfont "arialbd.ttf" %deffont "typewriter" xfont "courier-medium-r", vfont "goth", tfont "courbd.ttf" %default 1 leftfill, size 3, fore "white", back "black", font "thick" %default 2 size 7, vgap 10, prefix " " %default 3 size 2, bar "gray70", vgap 10 %default 4 size 5, fore "white", vgap 30, prefix " ", font "standard" %tab 1 size 4, vgap 40, prefix " ", icon box "green" 50 %tab 2 size 4, vgap 40, prefix " ", icon arc "lightblue" 50 %tab 3 size 3, vgap 40, prefix " ", icon delta3 "red" 40 %default 1 xfont "utopia-bold-r", size 4, fore "white", back "black" %default 2 xfont "utopia-bold-r", size 3, fore "white", back "black" %default 3 xfont "utopia-bold-r", size 4, fore "white", back "black" %default 4 xfont "utopia-bold-r", size 4, fore "white", back "black" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page Introduction %center %size 8, lcutin Netfilter %rcutin from Wallfire point of view %size 4 Netfilter workshop, Budapest, 18th Aug 2003 Hervé Eychenne %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page user/kernel communication There is no sane way to add verbose error reporting back to iptables userspace Operations on the ruleset (insertions, deletions, listing) are way too slow, even with iptables-restore -> The use of set/getsockopt interface is wrong: netlink is a better choice (but netlink can drop packets...) -> Data structure should not be rebuilt from scratch each time: nf-hipac? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page performance Netfilter does not cope well with Gigabit/s networks. -> Adopt nf-hipac framework? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page missing features (existing ones) Some existing things should make it into vanilla kernel: There's no way of listing the available matches/targets at runtime. Harald made a patch. [Update: it had very recently been submitted for inclusion in vanilla kernel] NETMAP target (192.168.1.0/24 -> 10.0.0.0/24) is still not in vanilla kernel, though well tested and often demanded in companies (to harmonize network addresses) [Update: after this talk, it has been submitted for inclusion in vanilla kernel] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page kernel/user netfilter modules It's somewhat difficult to have a new match/target work with old kernels (or the other way round): this restricts evolution capabilities To add a netfilter module, a whole kernel recompilation is needed (patch-o-matic): this is unthinkable for the average user, it is impossible to automatize completely, and even if it was, it is much too long -> The mechanism of adding a new netfilter functionnality (module) should not require a kernel recompilation (no kernel modules as-is). -> Full versioning of kernel and user netfilter modules should be achieved. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page userspace library Libiptc was clearly written with one-shot execution of the iptables command in mind: it used to be full of memory leaks, and some can still last. -> Write a clean userspace library, with a clean API %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page find a rule responsible for a given action It's hard to know the exact rule that issued a given log line (except by tagging each log entry with a different prefix, which is not very elegant) It's difficult to find the rule which will accept or drop a given packet (with known characteristics): you have to find it by hand by following the ruleset traversal -> Solutions? To be discussed... [Update: the TRACE target can help, but it seems to be slow] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page ruleset description format (1) Iptables-save files are unreadable and too difficult to write by hand and maintain as they are today. We probably agree that the best way to create a ruleset is to write a script. Why? comments dynamic execution of arbitrary commands loops (multiple hosts per protocol, etc.) variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page ruleset description format (2) Scripts are good, but! script execution is very slow, as the iptables command is launched for each rule (even 3000 executions of /bin/true can take more than 10s on slow machines) script parsing is virtually impossible, so automatic conversion of most netfilter rulesets to another format is tricky: you have to execute the script first (ugly!), then do a dump with iptables-save or parse iptables -nL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page ruleset description format (3) Scripts are good, but! no syntax checking can be done before execution: it's difficult to handle execution errors in these conditions. Especially, it's really dangerous to modify the ruleset of a distant site over ssh: you don't have the right to fail. For the moment, I use: iptables-save of the former ruleset execution of the script with set -e and a trap on error, restore the old configuration It's a hack, it's all but atomic, and it's slow. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page ruleset description format (4) -> There has to be a real configuration file, not a script. We could think of an evolved iptables-save format, with comments, variables, includes, etc. Note: we want a file, but still with the ability to do small updates to the ruleset by running the iptables command. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page atomicity For the moment, we must have this in a script to ensure some kind of atomicity: %size 3 # Set initial blocking rules. $IPTABLES -A INPUT -i $LOOPBACK_INT -j ACCEPT $IPTABLES -A OUTPUT -o $LOOPBACK_INT -j ACCEPT $IPTABLES -A INPUT -j DROP $IPTABLES -A OUTPUT -j DROP $IPTABLES -A FORWARD -j DROP # Insert rules. [...] # Delete initial blocking rules. $IPTABLES -D INPUT 2 $IPTABLES -D INPUT 1 $IPTABLES -D OUTPUT 2 $IPTABLES -D OUTPUT 1 $IPTABLES -D FORWARD 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page atomicity, testing: double buffering But it's not atomic, and especially problematic when rules insertion takes a long time. It's also difficult to test 2 rulesets (quickly switch between the 2 without losing anything). -> Double buffering: production and testing rulesets (like in ipfilter) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %page MASQUERADE/SNAT target: a matter of addresses MASQUERADE target "guesses" the interface address, but connections are flushed when the interface goes down SNAT target keeps connections even when the interface goes down, but cannot guess the interface address -> It would be good to add to the SNAT target the ability to guess the address if none is specified. This would be interesting for ADSL and cable connections (PPP or DHCP), with dynamically attributed addresses, but almost always stable ones over time if the session is killed and restarted, which is a very common case. [Update: Rusty has made a patch for the MASQUERADE target, flushing connections only if the address is different. Let's wait for the inclusion into the kernel]