Linux 2.4 in production: first impressions

Following the long planning and netfilter design reading of 2000, I have moved my home firewall to a stable Linux 2.4 kernel with iptables. The migration was a January project; the production experience has been smooth.

This is a short writeup of what changed and what I have learned.

The migration

The procedure was essentially what I planned in February 2000:

  1. Built a 2.4.2 kernel with the necessary netfilter modules.
  2. Installed iptables and the supporting userspace tools.
  3. Translated my existing ipchains ruleset to iptables syntax — this was a hand-rewrite, not a mechanical conversion, and was the right approach.
  4. Tested the new ruleset on a separate machine first.
  5. Cut over the production firewall during a planned maintenance window.

The whole exercise was about a weekend of work. The cutover itself was fifteen minutes — most of the time was the rewrite and the testing.

What is better

Three specific improvements.

Connection tracking is integrated. My old ipchains rules expressed "established connections" through TCP-flag matching, which was approximate. The new iptables rules use state ESTABLISHED,RELATED, which is exact. The expression is shorter and the semantics are correct.

For example, the old:

ipchains -A input -p tcp --tcp-flags ACK ACK -j ACCEPT
ipchains -A input -p tcp --tcp-flags SYN,ACK SYN,ACK -j ACCEPT

becomes the new:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

One rule, semantically correct, performance-equivalent.

The chain-organisation is more structured. I have my rules now in named sub-chains: inbound-public, inbound-trusted, outbound-internet, outbound-internal. Each chain is single-purpose; the main chains dispatch into them. The whole thing is materially easier to audit.

Logging is more uniform. The LOG target produces structured output that my log-analysis discipline can consume directly. The format is consistent across kernel versions and stable across distributions.

What is the same or worse

Performance is unchanged. My traffic level is modest enough that any performance difference would be invisible. Larger deployments may see differences either direction; for me, it is wash.

The configuration size is similar. The structural improvement is in legibility, not in conciseness.

The userspace tooling is still rough. iptables-save and iptables-restore work; they are not as smooth as ipchains-save/ipchains-restore. The state-of-the-art save/restore tooling has not yet caught up.

What I have run into

A few specific issues during the first month.

A subtle bug in connection tracking for FTP. My old ipchains configuration handled FTP via a separate set of rules. The new iptables connection-tracking handles FTP via the ip_conntrack_ftp helper module. I had not loaded the helper. FTP's data connections were silently failing.

Fix: load the module. Time to diagnose: an hour. Lesson: the new framework has more implicit behaviour, and when something is missing the failure is at the application layer rather than at the firewall.

A timing issue at boot. My boot scripts were starting iptables after the network interfaces, which left a brief window where the interface was up but no rules were applied. For a few seconds at every boot, the firewall was effectively open.

Fix: rearrange the boot order. The fix is general — firewall rules should be applied before interfaces come up, not after. I had been getting this wrong on ipchains too but had not noticed because the rules were written different.

Compatibility with my custom Snort preprocessor. The preprocessor I wrote in summer 2000 used some raw-socket interfaces that have changed slightly in 2.4. A 5-line patch made it work. Worth being aware of for anyone with custom code.

What this enables

Three things I am thinking about for the next quarter.

Better outbound-traffic monitoring. The connection-tracking module exposes the active connection list. I can now query, at any moment, exactly which connections are open, with full state. This is useful for my honeypot where outbound connections are the indicator of compromise.

More aggressive rate-limiting. The limit and recent modules let me write rules like "no more than 5 connections per source per minute". I can now apply per-source rate limits without the cumbersome custom logic I would have needed in ipchains.

Cleaner integration with Snort. Specific modules let me redirect packets to the Snort sensor for inspection, then handle them based on the sensor's verdict. The integration was awkward in ipchains; it is straightforward in iptables.

A small reflection on the migration

The operational migration from ipchains to iptables is, in retrospect, the model I would recommend for anyone in my position. The hand-rewrite forced me to think about each rule explicitly, which produced a better ruleset than a mechanical translation would have. The cumulative discipline — auditing, testing, structured chains — was its own benefit.

For friends still on ipchains: the migration is straightforward and the result is better. The main barrier is the time investment, which is real but bounded.

More as the year develops.


Back to all writing