Linux 2.6 in production

Linux 2.6 has been in stable release since late 2003 and is now operationally mature enough for production deployment. I have just completed migrating my home firewall and one production host from the 2.4 series to 2.6. A short note on the migration and on the operational implications.

The content here is more compact than recent posts but the operational lessons are worth recording.

What is improved in 2.6

Three main areas of substantive change.

Better SMP support. The 2.4 kernel handled multi-CPU systems but not particularly well; the locking model was coarse-grained and produced contention under heavy load. 2.6 substantially refines the locking. Multi-CPU machines see meaningful performance improvements; the relevance for my modest single-CPU systems is small but the principle is correct.

More efficient scheduler. The 2.6 scheduler is the O(1) scheduler that handles many simultaneous processes more efficiently than 2.4's. For typical workloads the difference is invisible; for high-load systems it is substantial. Web servers, database servers, mail relays under significant load all benefit measurably.

Updated netfilter framework. New match types, new target types, generally cleaner integration. The migration from 2.4's iptables to 2.6's iptables is essentially seamless — the syntax is unchanged and rules transfer directly. The new capabilities are additive; existing rule sets continue to work.

Native NPTL threading. The threading model in 2.4 was the LinuxThreads implementation, which had several quirks compared to standard POSIX threads. NPTL in 2.6 is closer to standard behaviour. For applications that depend heavily on threading, the difference is meaningful; for typical infrastructure it is invisible.

Improved security mechanisms. LSM (Linux Security Modules) hooks are more mature in 2.6. SELinux is functional. The capability infrastructure is more usable. The cumulative effect is that finer-grained privilege separation is more achievable than it was in 2.4.

The migration

The migration was straightforward. For my home firewall:

  1. Built 2.6.10 from source on a test machine with the configuration I planned to use.
  2. Tested the configuration against my workload for a week.
  3. Verified that all my custom rules and configurations transferred without modification.
  4. Cut over the production firewall during a planned maintenance window.
  5. Monitored for a week; nothing problematic emerged.

The whole exercise took roughly a weekend of evening work. The most time-consuming part was confirming that all the small custom configurations I had accumulated over the years still worked.

What changed and what did not

The iptables rules transferred exactly. My carefully-organised named sub-chains work identically in 2.6. The structured-log analysis integration continues to work; the log format is unchanged.

The boot process is slightly different. 2.6 uses a slightly different initramfs structure than 2.4's initrd. The initial migration produced a brief boot failure that I traced to the initramfs not being correctly assembled. A documentation read and a config adjustment fixed it.

Device naming has changed in some cases. 2.6 uses udev for dynamic device-node management; my older rules referenced static device nodes. The transition required updating a small number of references. Nothing complicated; just a difference to be aware of.

The sysctl parameters have been reorganised in places. Some 2.4 sysctl entries have moved or been renamed. Most of my customisations transferred without change; a few needed minor adjustment.

What is operationally better

Four specific improvements I notice in routine operation.

Boot time is faster. The 2.6 boot sequence is more parallel; my firewall boots in roughly half the time that 2.4 took. For a server that rarely reboots this is barely visible; for development and testing it is meaningful.

Network throughput is slightly higher. Not dramatically — my modest workload was not network-bound — but measurably. Larger deployments will see larger gains.

Memory usage is more efficient. The 2.6 kernel uses memory somewhat more efficiently than 2.4. The improvement is modest but real.

The hot-plug infrastructure is more mature. USB devices, FireWire devices, hot-add CPUs and RAM — all work substantially better in 2.6. For my home use this is mostly relevant for USB; for serious server deployments it is more substantial.

What is operationally similar

The basic firewall operation is identical. The same rules produce the same packet-filtering decisions. The same logging produces the same logs. The same monitoring produces the same alerts.

This is, in some ways, the most useful property of the migration: it does not change the operational character of my infrastructure. The benefits accrue without disrupting the established rhythms.

What I would tell someone considering the migration

Just do it during the next maintenance window. 2.6 is stable, mature, and meaningfully better than 2.4 in several measurable ways. The migration cost is bounded; the benefits compound over years.

Plan for a small set of configuration adjustments. The migration is mostly seamless but not entirely. Plan for a half-day of configuration tweaks; the actual time is usually less.

Read the relevant kernel changelog before starting. 2.6 is a substantial release; understanding what has changed informs the migration decisions. The reading is a few hours; the value is meaningful.

Test before production. A test deployment on non-production hardware identifies issues that would otherwise surface during the production cutover. The test cycle is bounded; the operational benefit is substantial.

A small note on the LSM infrastructure

One specific 2.6 capability worth dwelling on. The Linux Security Modules framework allows operators to deploy fine-grained access-control policies on top of the standard Unix permission model. SELinux is the most prominent; AppArmor and others exist as alternatives.

For my own infrastructure, I have not yet deployed SELinux. The cost-benefit, for my modest workload, has not yet justified the operational complexity. For production-scale deployments where the security improvement is more meaningful, the deployment is worth considering.

The broader observation: the 2.6 kernel has the mechanisms for substantially stronger security than 2.4. Whether operators deploy those mechanisms is a separate question, with its own cost-benefit. Most operators will not, in 2005; some will, in subsequent years; the mechanisms will eventually be the default.

What I expect for 2.6 in the next year

Two specific things.

The development cadence stabilises. The 2.6 series has been moving fast; new releases every few weeks. The pace will probably slow as the kernel matures. By end of 2005 I expect the per-release changes to be smaller and the deployment confidence higher.

Distribution adoption completes. Most major distributions have shipped 2.6-based releases by now. The transition will, by end of 2005, be essentially complete; 2.4-based distributions will be in maintenance-only mode.

What this teaches

The Linux kernel continues its slow march toward operational maturity. Each major release adds capabilities; each release improves performance; each release tightens the security model.

The trajectory is good. The pace is sustainable. The cumulative effect, over years, is that Linux has become a serious production platform that competes seriously with commercial alternatives.

For anyone running mission-critical Linux infrastructure: the discipline of running stable kernel versions with current security patches is the right operational posture. The 2.6 migration is the right next step from 2.4.

For my own writing: more of my technical content will assume 2.6 features as the platform changes. The 2.4-specific writing has been relevant for the past four years; 2.6-specific writing will be relevant for the next several.

A small operational reflection

The kernel migration is the kind of operational task that is easy to defer indefinitely. There is no immediate forcing function; 2.4 continues to work; the migration takes time that could be spent on more visible priorities.

The defensive discipline I have been practising for years includes specifically not deferring this kind of upgrade indefinitely. The cost of running an old kernel grows over time as patches stop being backported, as new capabilities become standard expectations, as the rest of the ecosystem moves on.

The right cadence, in my experience, is to migrate to a new kernel series within 12-18 months of its stable release. This gives time for the inevitable early bugs to be fixed; it avoids the long-tail problem of being stuck on an unsupported version. For 2.6 (stable in late 2003), the migration in early 2005 is at the late end of this window but still acceptable.

More as the year develops.

Closing thoughts

The 2.6 migration is, in some real sense, the major Linux operational event of recent years. The transition from 2.4 to 2.6 is the largest kernel-level shift since the 2.0-to-2.2 transition that I wrote about back in 1999. The operational implications are substantial; the structural improvements are real.

For anyone managing Linux infrastructure: this is the year to migrate, if you have not. The cost is modest; the benefits compound; the alternative (running unsupported 2.4 indefinitely) becomes increasingly untenable.

More in time.

A deeper exploration of 2.6's security improvements

I want to extend this post with a more careful examination of the specific security-relevant improvements in Linux 2.6. The earlier sections covered the headline changes; this section dives deeper.

LSM and the security framework

The Linux Security Modules framework is the most consequential security architecture change in 2.6. The framework allows multiple security modules to be loaded into the kernel, each enforcing its own policy. The major modules:

SELinux. Type Enforcement and Multi-Level Security. Originally developed by the NSA; now mainstream in major distributions. Provides fine-grained access control beyond what the standard Unix permission model can express. Operationally complex; powerful when deployed correctly.

AppArmor. Path-based access control. Simpler than SELinux but less expressive. Originally developed by Immunix; now part of various distributions. Easier to deploy; less powerful in specific cases.

Smack. Simplified Mandatory Access Control. Designed to be simpler than SELinux while providing similar protection. Less mature than the alternatives.

For my own infrastructure, I have not yet deployed any of these. The cost-benefit, for my modest workload, has not yet justified the operational complexity. For production-scale deployments where the security improvement is more meaningful, the deployment is worth considering.

The broader observation: 2.6 has the mechanisms for substantially stronger security than 2.4. Whether operators deploy those mechanisms is a separate question. The mechanisms are now mature enough that the deployment cost is bounded; the deployment will eventually be standard.

Capability inheritance and ambient capabilities

The capability infrastructure I wrote about in 1999 and followed up on in 2001 has matured further in 2.6. Specific improvements:

File capabilities. Files can be marked with specific capabilities; processes that exec those files inherit only the marked capabilities, not full root. This finally provides the long-promised replacement for setuid-root binaries.

Bounded inheritance. The capability inheritance rules are clearer than in 2.4; specific capabilities can be passed across exec or restricted from being passed.

Better tooling. The libcap library and the cap-related utilities are more mature; deployment is more practical than it was a few years ago.

For anyone managing infrastructure where setuid-root binaries are a concern (which is to say, most infrastructure): the capability-based alternatives are now operationally viable. The migration is non-trivial but bounded; the security improvement is substantial.

Netfilter improvements

The netfilter framework I wrote about migrating to in 2.4 has continued to evolve in 2.6. Specific improvements:

Faster connection tracking. The conntrack module's hash table is more efficient; lookups are faster; memory pressure under load is reduced.

More match types. New match types for specific protocols (SIP, FTP, IRC), specific packet properties (recent connections, rate limits, marks), and behavioural patterns. Rules can express more sophisticated decisions.

Better integration with the routing subsystem. Decisions can be made based on routing properties; routing decisions can be informed by netfilter state. The integration is cleaner.

IPSec integration. The kernel's IPSec implementation is more mature in 2.6. Site-to-site VPNs and individual IPSec connections are more reliable.

For my own firewall configuration, the new match types have let me write rules that I previously needed external tooling for. Specific examples:

  • Per-source rate limits using the recent module are now sufficient for most rate-limiting needs.
  • Deep-packet inspection using the string module catches certain attack patterns at the firewall layer that previously required IDS-level processing.
  • Connection-state-based rules work more reliably for complex protocols.

File-system improvements with security implications

2.6 includes several file-system improvements with security-relevant consequences:

Better extended attributes. The xattr infrastructure is more mature, supporting both user-defined attributes and security-relevant attributes (used by SELinux and similar).

Better mount-time security options. The noexec, nosuid, nodev mount options work more reliably across all filesystem types.

Improved read-only root filesystems. Distributions can ship with read-only root filesystems and writable subdirectories; the technical capability is more mature.

ext3 journal integrity. The journal-related code in 2.6 is more robust than 2.4's; recovery from unexpected shutdowns is more reliable.

For servers where security matters, mounting /tmp, /var/tmp, and similar with noexec,nosuid,nodev is now operationally clean. For desktops the trade-off is more complex; for servers it is unambiguous.

What I am thinking about deploying

Four specific things I am considering for my own infrastructure over the next year:

SELinux on a single host. Specifically my mail relay, where the threat model justifies the operational complexity. The deployment is non-trivial; the security improvement is substantial.

File capabilities for traditionally-setuid binaries. Replacing setuid-root with capability-restricted alternatives. The migration is bounded; the principle of least privilege is the right architecture.

Read-only root filesystem for the firewall. The firewall's filesystem rarely needs writes; the protection against compromise is meaningful.

Mount-option hardening across all hosts. noexec,nosuid,nodev on every filesystem where it does not break legitimate use. Low cost; bounded benefit; cumulative effect is real.

A reflection on the trajectory

Linux's security infrastructure has matured substantially over the past decade. The 2.0 kernel had basic Unix security and not much more; 2.2 added POSIX capabilities and the early netfilter work; 2.4 brought iptables to maturity; 2.6 adds LSM and the broader security framework.

The trajectory is positive but slow. Each kernel generation adds substantial capability; each generation requires several years of operational maturation before the capabilities are widely deployed.

For the next several years, I expect continued maturation of the existing 2.6 frameworks. The 2.7 development series will probably bring further capability; the migration to whatever stable series follows 2.6 will be a future writing topic.

More in time.

A wider operational reflection

Let me close with broader observations about kernel migrations and their place in the operational discipline.

Kernel migrations are the kind of operational task that is easy to defer. There is rarely an immediate forcing function; older kernels continue to work; the migration takes time that could be spent on more visible priorities.

The disciplined operator does the migrations anyway, on a sustainable schedule. The cost of running an old kernel grows over time as patches stop being backported, as new capabilities become standard expectations, as the rest of the ecosystem moves on.

For 2.6, I expect the migration window to remain open through 2006 for most operators. By 2007, operators still running 2.4 will be in the same position that operators running 2.0 were in 2002 — supportable but increasingly anomalous.

The broader pattern: operating-system migrations follow a rough decade-long cycle. The current state of Linux deployment in 2005 reflects 2.4-from-2002 deployment dominance giving way to 2.6-from-2004 dominance. By 2010 some successor will be the current default; by 2020 the picture will be different again.

For my own infrastructure planning: I aim to migrate to a new kernel series within 12-18 months of its stable release. Earlier than this exposes me to the inevitable early-adoption bugs; later than this leaves me increasingly behind on capability and potentially on patches.

The specific 2.4-to-2.6 migration is now substantially complete on my hosts. The planning for the eventual 2.6-to-successor migration is years away; the discipline of expecting that future migration is what makes the current migration sustainable.

More as the year develops.


Back to all writing