*************************************************************************
I have already INCLUDED A PATCH at the BOTTOM OF THIS REPORT that
fixes this issue.  PLEASE, for the sake of Debian's users, get this
into Jessie before its quiet period starts on April 18th (5 days
away)!
*************************************************************************


Hi, Sebastien and Jonathan!

Before getting into the meat of this issue, I want to stop and thank
you both for all of your hard work and contributions as Debian
developers.  Your efforts ARE appreciated! :)


Now, getting to the bug itself...

Look, guys, I don't want to be argumentative, but I really have to
insist that both the severity and, very likely, the number of users
affected by this issue have been massively underestimated.  This bug
is really a big deal.

All it takes to trigger this is:

1) to have a custom kernel without legacy PC parallel-port modules; and
2) to "apt-get install cups"

That's it.

This is a perfectly acceptable configuration. There's nothing wrong
with not having these parallel-port modules, so we really can't blame
this on the user.

No one can reasonably be expected to think that installing "cups"
(possibly at some distant point in the future long after configuring
iptables-persistent) will break their existing firewall configuration
on the next reboot.

I also suspect that the impact of this bug is fairly wide-spread, as
these days the majority of new hardware lacks a legacy parallel-port,
and thus very many users will choose not to build support for one into
their kernel.

Package "cups", in its default configuration, depends on
"cups-filters", which installs this:

$ dpkg -L cups-filters | grep modules
/etc/modules-load.d
/etc/modules-load.d/cups-filters.conf

$ cat /etc/modules-load.d/cups-filters.conf
# Parallel printer driver modules loading for cups
# LOAD_LP_MODULE was 'yes' in /etc/default/cups
lp
ppdev
parport_pc

This file is what causes systemd to insist on the presence of legacy
PC parallel-port kernel modules (does anyone actually use a
parallel-port printer these days?) before considering the
"systemd-modules-load" unit to have succeeded.

It seems likely that certain third-party software (old/unused versions
of proprietary nvidia/ATI video drivers?) might put files in
/etc/modules-load.d/, such that eventually AT LEAST ONE of the
referenced modules isn't (any longer) actually present on the user's
system for the CURRENT kernel version in use (i.e. missing in
/lib/modules/$(uname -r)/).

There are very likely many users out there right now who have had
their systems' firewalls disabled by this issue and are unaware of it.
Legacy PC parallel ports are increasingly uncommon on newer hardware,
with perhaps the majority of newly produced systems not having one.
And "cups" is presumably a very popular package.

The fact that the disappearance of the system's firewall doesn't
actually go into effect until the next reboot after installation of
"cups", which very well might be installed AFTER
"netfilter-persistent", only serves to exacerbate the issue, by making
it more likely to escape detection by postponing the appearance of its
symptoms from a time when the system is likely under heavy scrutiny by
the user/administrator during the period of initial system setup or
configuration of a new service ("cups"), to some distant point in the
future when the machine is rebooted by a random crash or power
failure, possibly in the middle of the night.

At the time of this later reboot the system is likely to be under far
less scrutiny, with the user/administrator operating under the
assumption that less vigilance is required since the system has
seemingly already been properly configured and tested and that its
configuration has not changed.

Moreover, this passage of time between the true onset of the problem
and the first appearance of its symptoms will only serve to obscure
the cause of the issue, assuming it's even noticed at all before the
machine is rooted.


--------------------------------------------------------------------------
The ROOT cause (a bug in netfilter-persistent itself) and the fix:
--------------------------------------------------------------------------

The underlying root cause of this issue is a bug in the systemd unit
file of "netfilter-persistent" itself, **NOT** user misconfiguration
of their kernel or firewall settings!

$ dpkg -L netfilter-persistent | grep systemd
/lib/systemd
/lib/systemd/system
/lib/systemd/system/netfilter-persistent.service

Inspection of netfilter-persistent's systemd unit file yields the
following:

$ nl /lib/systemd/system/netfilter-persistent.service
     1  [Unit]
     2  Description=netfilter persistent configuration
     3  DefaultDependencies=no
     4  Before=network.target
     5  Requires=systemd-modules-load.service local-fs.target
     6  After=systemd-modules-load.service local-fs.target
       
     7  [Service]
     8  Type=oneshot
     9  RemainAfterExit=yes
    10  ExecStart=/usr/sbin/netfilter-persistent start
    11  ExecStop=/usr/sbin/netfilter-persistent stop
       
    12  [Install]
    13  WantedBy=multi-user.target
       
Take note of line 5, which uses systemd's unit directive "Requires="
instead of "Wants=".

The systemd.unit(5) documentation[1] for each directive states:

Requires=

    Configures requirement dependencies on other units. If this unit
    gets activated, the units listed here will be activated as
    well. IF ONE OF THE OTHER UNITS GETS DEACTIVATED OR ITS ACTIVATION
    FAILS, THIS UNIT WILL BE DEACTIVATED.
    ...
    OFTEN IT IS A BETTER CHOICE TO USE Wants= INSTEAD OF Requires= IN
    ORDER TO ACHIEVE A SYSTEM THAT IS MORE ROBUST WHEN DEALING WITH
    FAILING SERVICES.
    ...
    [emphasis added]
    
Wants=

    A weaker version of Requires=. Units listed in this option will be
    started if the configuring unit is. HOWEVER, IF THE LISTED UNITS
    FAIL TO START OR CANNOT BE ADDED TO THE TRANSACTION, THIS HAS NO
    IMPACT ON THE VALIDITY OF THE TRANSACTION AS A WHOLE. THIS IS THE
    RECOMMENDED WAY TO HOOK START-UP OF ONE UNIT TO THE START-UP OF
    ANOTHER UNIT.
    ...
    [emphasis added]

I can see no reason why "Wants=" is not the correct, appropriate, and
superior choice versus "Requires=" for netfilter-persistent's
dependencies on kernel modules.  Only the netfilter/iptables modules
are needed, not whatever random modules requested by totally unrelated
packages such as "cups".  Moreover if the user has elected to compile
netfilter/iptables support directly into their kernel monolithically,
then NO kernel modules (beyond any already provided by their initrd)
will be needed.

Similarly, the "local-fs.target" requirement should also use "Wants="
instead of "Requires=" since NOT EVERY local filesystem is actually
needed to restore iptables rules.  We need only: /, (which I'm
assuming includes /sbin and /etc), /usr (if it exists as a separate
partition, for relevant binaries and shared libraries and scripts),
/proc and /sys.  We do NOT need, e.g. /var, /opt, /media, /mnt/*, etc.
An obsolete (and now-unneeded) line or a forgotten "noauto" entry in
/etc/fstab, or a hardware failure for a disk or RAID array containing
any other local filesystem should be handled gracefully and SHOULD NOT
prevent initialization of the system's firewall, as these mounts are
unneeded for this purpose, and such a dependency would only serve to
expose the user to unnecessary security risk.

I can see no possible harm in at least TRYING to execute
netfilter-persistent(8) -> ip{,6}tables-restore(8), even if SOME
kernel modules and/or local filesystems are unavailable (or at least
systemd THINKS they are), as the result can be NO WORSE: a failure to
raise the system's firewall along with a fleeting error message on the
console that is quickly suppressed by the login screen.

The result can only be POSSIBLY BETTER, if it actually works, which
judging by all these false/spurious dependencies it USUALLY WILL.
Therefore this change ("Requires=" -> "Wants=") is a Pareto
improvement.  In the specific case of "cups" requesting non-existent
parallel port modules, it fixes the issue readily.

Sorry if any of the above crosses over into being pedantic.  Systemd
is new to all of us, myself definitely included, and I can see how
this would be an easy mistake to make.

Thanks again for your contribution to Debian!


[1] http://www.freedesktop.org/software/systemd/man/systemd.unit.html



--------------------------------------------------------------------------
PATCH FIXING THE ISSUE:
--------------------------------------------------------------------------


---

diff -rud iptables-persistent-1.0.3.old/systemd/netfilter-persistent.service 
iptables-persistent-1.0.3.new/systemd/netfilter-persistent.service
--- iptables-persistent-1.0.3.old/systemd/netfilter-persistent.service  
2014-12-27 04:05:22.000000000 -0700
+++ iptables-persistent-1.0.3.new/systemd/netfilter-persistent.service  
2015-04-12 22:33:55.045404684 -0700
@@ -2,7 +2,7 @@
 Description=netfilter persistent configuration
 DefaultDependencies=no
 Before=network.target
-Requires=systemd-modules-load.service local-fs.target
+Wants=systemd-modules-load.service local-fs.target
 After=systemd-modules-load.service local-fs.target
 
 [Service]


diff -rud iptables-persistent-1.0.3.old/systemd/netfilter-persistent.service iptables-persistent-1.0.3.new/systemd/netfilter-persistent.service
--- iptables-persistent-1.0.3.old/systemd/netfilter-persistent.service	2014-12-27 04:05:22.000000000 -0700
+++ iptables-persistent-1.0.3.new/systemd/netfilter-persistent.service	2015-04-12 22:33:55.045404684 -0700
@@ -2,7 +2,7 @@
 Description=netfilter persistent configuration
 DefaultDependencies=no
 Before=network.target
-Requires=systemd-modules-load.service local-fs.target
+Wants=systemd-modules-load.service local-fs.target
 After=systemd-modules-load.service local-fs.target
 
 [Service]

Reply via email to