Re: [Tails-dev] Reducing attack surface of kernel and tighte…

Supprimer ce message

Répondre à ce message
Auteur: Oliver-Tobias Ripka
Date:  
À: The Tails public development discussion list
Sujet: Re: [Tails-dev] Reducing attack surface of kernel and tightening firewall/sysctls
Hey,

I agree that removing the attack surface is a good idea. Some thoughts
and material for discussion on this...:

You make no distinction between the INPUT and OUTPUT chains and suggest
that both should be changed to "NEW, ESTABLISHED". I understand your
argument for the OUTPUT chain but I would argue that that NEW would not
be desirable for the INPUT chain as it would open up the firewall to the
outside. However ESTABLISHED may be sufficent for the INPUT chain in
order to allow stateful egress connections.

My second thought is what core network protocols might be affected by
this change.

The network protocols that I see used in Tails are ARP, DHCP and TCP.
(I also saw an outgoing ICMP packet after shortly after the DHCP
discover. But this may be an artifact from the virtualisation software).

I did do some tests using the following testing procedure
    - setup sniffer
    - boot the live system (allow for root login)
    - kill network connection
    - edit /etc/ferm/ferm.conf to included the iptables tweak:
        INPUT: [...] mod state state (ESTABLISHED) ACCEPT;
        OUTPUT: [...] mod state state (NEW ESTABLISHED) ACCEPT;
    - set the iptables rules to DROP everything
    - use network manager to reestablish connection (works)


Evaluating the results for the protocols required by Tails:

- ARP should not be (and is not) affected by the changes you propose as
it is handled by lower level netfilter code

- DHCP still works. Which is strange, isn't? I configured the firewall
to drop everything so DHCP should not work.

To debug a little I inserted some code into
/etc/NetworkManager/dispatcher.d/00-firewall.sh to see what the state
if ifconfig and iptables is right before bringing up the firewall:

      Result: The IP adress is already is configured (DHCP was
      renewed) and the iptables configuration is still set to DROP.
      So I am not sure how the DHCP packets could get through. Maybe
      I have a flaw in my debugging procedure or this is another
      issue.


- TCP still works and Tor succeeds in establishing a connection.

While this seems fine at first I think we should investigate the
following potential impact that might surface in some circumstances:

Reading through the iptables man page it states that:

    RELATED meaning that the packet is starting a new connection,
    but is associated with an existing connection, such as an FTP
    data transfer, or an ICMP error.


While Tails does not use UDP which might need ICMP as a helper protocol
(e.g. for closed ports) there are some cases where TCP also depends on
ICMP. What comes to mind is PATH MTU discovery. As TCP always has the DF
bit set it, packets might get rejected by routers on the path that only
allow for a small MTU. This results in an ICMP destination
unreachable/fragmentation needed(DU/FN) message that has the "next hop mtu"
value set.

Currently I have no router to set up a small MTU path and test this. But
I guess that with the above firewall config the ICMP packet would not be
allowed and thus the Linux kernel would not get the information that it
has to decrease the packets sizes (e.g. during an upload or large POST).

So here is some more speculation what would happen is this case:

In such a case the impact and behavior of not receiving the ICMP DU/FN
then depends on the following Linux kernel sysctls:

    - /proc/sys/net/ipv4/ip_no_pmtu_disc (path mtu discovery)
    - /proc/sys/net/ipv4/tcp_mtu_probing (mtu probing)


The Tails configuration for path mtu discovery and TCP mtu probing are
as follows: 0 (Path MTU discovery is On), 0 (MTU probing is Off)

I did some test with a 2.6 kernel using these settings some years ago
and the result was the with the settings above the Linux Kernel would
not be able to deal with a situation where it sends large packets (e.g.
1400 bytes) via a router with a small MTU (e.g. 900 bytes). The router
would refuse to relay packets and send ICMP DU/FN that would not reach the
Tails client. Because of the sysclt settings the Linux kernel would try
to sent TCP retransmissions 5 times with increasing delta delays and
then give up on the connection (-> people would not be able to upload
large data in this circumstances)

The bottom line is that we should test if this theory above actually
results in problems when sending large packets in these circumstances.

Possible solutions would be to tweak the sysctls to allow the Kernel to
determine an efficient MTU via black hole router detection and MTU
probing. Another solution would be to explicitly allow this specific
type of ICMP packet from the outside.

Maybe this may also be considered not to be an issue because small MTUs
are not so common (mostly only if you are somewhere behind a Tunnel,
VPN, 6in4,4in6...).

Cheers!

Olli

According to Jacob Appelbaum on Wed, Dec 03 2014:

> Hi,
>
> After talking with a new friend about netfilter and the kernel, we
> discussed a funny thing that happens to lots of people who use
> iptables. As a result, I took a look at Tails and sure enough, that
> funny little issue is present. I think as a result, we should make a
> reasonable, minimal change to our iptables rules. Looking at Ferm, the
> firewall rules say something that is extremely common which is as
> follows for INPUT and OUTPUT:
>
>             mod state state (RELATED ESTABLISHED) ACCEPT;

>
> I propose that we change the rule to be:
>
>             mod state state (NEW ESTABLISHED) ACCEPT;

>
> The reason is pretty simple - RELATED makes the kernel do a lot of
> extra lifting that is not needed by using the conntrack kernel code:
>
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/netfilter?id=refs/tags/v3.18-rc7
>
> Take a look at the various nf_conntrack_*.c files to see the various
> parsers that are exposed by using the RELATED connection tracking
> state. We should never need the kernel to automatically modify the
> firewall - as an example, we do not need it to setup an incoming FTP
> session based on the kernel believing that we've tried to do an
> outgoing FTP session. An old example of this kind of trick is
> demonstrated here:
>
> http://www.securiteam.com/unixfocus/5DP0B2040S.html
>
> An example of how RELATED opens up the firewall is written here:
>
> https://home.regit.org/netfilter-en/secure-use-of-helpers/
>
> Now, I think that the older exploit above is not functional but I
> admit, I haven't tested it or thought about how it may be extended for
> the current kernel. That however doesn't convince me that we should
> ever have that code exposed on a deployed Tails system. Unless RELATED
> literally does nothing, I think it adds attack surface - how much is
> an open research question. On the other hand, if RELATED does nothing,
> we should remove it, it isn't needed as far as I see.
>
> There are two basic issues that fell out of the discussion today: one
> where an incoming connection is allowed, another where the parser has
> a bug which is exploitable. Neither is required for our uses, right?
> Both are actually harmful to our use cases, I think.
>
> Some of the modules are written by very talented programmers and I'm
> sure they're well written. Still, if you look at the code, you'll see
> that they literally do IRC or Amanda parsing in the kernel. Here are
> some examples:
>
> Amanda: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/netfilter/nf_conntrack_amanda.c?id=refs/tags/v3.18-rc7
>
> pptp: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/net/netfilter/nf_conntrack_pptp.c?id=refs/tags/v3.18-rc7
>
> If we look at on the latest Tails, we'll see
> /proc/sys/net/netfilter/nf_conntrack_helper is set to 1. I propose
> that we set it to 0. We do not want help tracking connections, we do
> not want those extra protocol parsers in the kernel doing this kind of
> heavy lifting.
>
> Thus with two minor changes, I think we can easily tighten the system
> and it should not impact anything except for an attacker. I think we
> want to set the sysctl net.netfilter.nf_conntrack_helper to 0 and
> remove RELATED from the Ferm configuration. I think we need to replace
> it with NEW and nothing else.
>
> We'll need to research exactly what other changes to Ferm need to made
> for establishing a connection but I think it is simply (NEW
> ESTABLISHED).
>
> It seems that we should really look into tightening the network stack
> down to the absolute minimum amount of code. I think right now, the
> attack surface is larger than needed for our uses.
>
> Thoughts?
>
> All the best,
> Jake