Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.debian.user > #173331 > unrolled thread

ICMPv6 and the conntrack table

Started byFlorian Pelgrim <florian.pelgrim@craneworks.de>
First post2016-10-08 20:20 +0200
Last post2016-10-20 03:10 +0200
Articles 6 — 3 participants

Back to article view | Back to linux.debian.user


Contents

  ICMPv6 and the conntrack table Florian Pelgrim <florian.pelgrim@craneworks.de> - 2016-10-08 20:20 +0200
    Re: ICMPv6 and the conntrack table Henrique de Moraes Holschuh <hmh@debian.org> - 2016-10-08 23:30 +0200
      Re: ICMPv6 and the conntrack table Florian Pelgrim <florian.pelgrim@craneworks.de> - 2016-10-19 17:50 +0200
    Re: ICMPv6 and the conntrack table Pascal Hambourg <pascal@plouf.fr.eu.org> - 2016-10-09 10:00 +0200
      Re: ICMPv6 and the conntrack table Florian Pelgrim <florian.pelgrim@craneworks.de> - 2016-10-19 17:50 +0200
        Re: ICMPv6 and the conntrack table Henrique de Moraes Holschuh <hmh@debian.org> - 2016-10-20 03:10 +0200

#173331 — ICMPv6 and the conntrack table

FromFlorian Pelgrim <florian.pelgrim@craneworks.de>
Date2016-10-08 20:20 +0200
SubjectICMPv6 and the conntrack table
Message-ID<sq4o1-21m-9@gated-at.bofh.it>

[Multipart message — attachments visible in raw view] — view raw

Hi,

I'm currently playing with ip6tables and seeing some strange stuff which
I not expected.
I configure my servers with Ansible which is able to lookup my default
IPv6 address. Therefore it uses `ip route get 2404:6800:400a:800::1012`
and parses the output.
Currently there is no IPv6 configured on the system so the default v6
address should be a link local address.

This is the expected result without a firewall:
$ ip route get 2404:6800:400a:800::1012
2404:6800:400a:800::1012 from :: via fe80::1 dev eth0  src
fe80::d481:11ff:feee:4908  metric 0
    cache  hoplimit 64

Now I setup some basic ip6tables firewall settings.
1. Set the policy to drop
2. Allow everything, input and output, on loopback
3. Allow related and established connections for input and output
4. Allow every icmpv6 package with the flag new

$ ip6tables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all      ::/0                 ::/0
ACCEPT     all      ::/0                 ::/0                 state
RELATED,ESTABLISHED
ACCEPT     icmpv6    ::/0                 ::/0                 state NEW

Chain FORWARD (policy DROP)
target     prot opt source               destination

Chain OUTPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all      ::/0                 ::/0
ACCEPT     all      ::/0                 ::/0                 state
RELATED,ESTABLISHED
ACCEPT     icmpv6    ::/0                 ::/0                 state NEW

So far I thought this would work but what I get when I try to lookup now
my default IPv6 address is this:

$ ip route get 2404:6800:400a:800::1012
unreachable 2404:6800:400a:800::1012 from :: dev lo  table unspec  proto
kernel  src fe80::d481:11ff:feee:4908  metric 4294967295  error -101

I played some time with different rules and added a new rule for icmpv6
without the state flag. And there it works again.
Uh? So lets look this up in conntrack. The results are pretty low...
There is nothing to see. No v6 package in any state.

So why is conntrack ignoring my icmpv6 traffic?

And another question is how can I flush the cached results from `ip
route get`? `ip route cache flush` is not working since I guess they
changed the caching in kernel version 3.6.

OS details:
$ uname -a
Linux mail 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03)
x86_64 GNU/Linux

$ dpkg-query -f "Package" -l iptables linux-image-* conntrack
Desired=Unknown/Install/Remove/Purge/Hold
|
Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                                   Version
+++-======================================-=================
ii  conntrack                              1:1.4.2-2+deb8u1
ii  iptables                               1.4.21-2+b1
ii  linux-image-3.16.0-4-amd64             3.16.36-1+deb8u1
ii  linux-image-amd64                      3.16+63

Cheers
Florian

[toc] | [next] | [standalone]


#173333

FromHenrique de Moraes Holschuh <hmh@debian.org>
Date2016-10-08 23:30 +0200
Message-ID<sq7lT-3Oc-3@gated-at.bofh.it>
In reply to#173331
On Sat, 08 Oct 2016, Florian Pelgrim wrote:
> This is the expected result without a firewall:
> $ ip route get 2404:6800:400a:800::1012
> 2404:6800:400a:800::1012 from :: via fe80::1 dev eth0  src
> fe80::d481:11ff:feee:4908  metric 0
>     cache  hoplimit 64

Why do you have a default route via fe80::1 ?  Where did it came from?

> Now I setup some basic ip6tables firewall settings.

"Basic" IPv6 firewalling is, unfortunately, anything but basic... mostly
because ICMPv6 overloads both L2 and L3 control-plane functions.

RFC 4890 "to the rescue" :-(
https://tools.ietf.org/html/rfc4890

*do* read the errata to RFC4890, it is relevant if you use the iptable
examples.

> $ ip route get 2404:6800:400a:800::1012
> unreachable 2404:6800:400a:800::1012 from :: dev lo  table unspec  proto
> kernel  src fe80::d481:11ff:feee:4908  metric 4294967295  error -101

Your firewalling apparently broke the IPv6 DAD (which requires a subset
of ICMPv6, and multicast).  That would cause any interface address of
link-local scope or higher to be declared invalid (for failing DAD), and
unusable.

And the kernel is not about to send locally-originated packets with an
invalid source address (unless you override it with evil black magic).

> Uh? So lets look this up in conntrack. The results are pretty low...
> There is nothing to see. No v6 package in any state.

I don't think link-local L2 control-plane traffic ends up creating
conntrack entries, at least not in any reliable way (it can't).

It is best to do stateless firewalling for everything L2, including the
subset of ICMPv6 that deals with L2 functions and multicast control.

> And another question is how can I flush the cached results from `ip
> route get`? `ip route cache flush` is not working since I guess they
> changed the caching in kernel version 3.6.

"ip route cache flush" is supposed to still work, yes.  But I don't
think your problem is in the routing table (or cache) in the first
place.

I'd try to fix the IPv6 DAD issues, first.  Check the output of "ip -6
addr" for every relevant interface... it should say when an address is
invalid for failing DAD, AFAIK.

After that, keep in mind that the forwarding destination for link-local
addresses must be resolved through neighbor tables, not routing tables.
You can manipulate the IPv6 neighbor table using "ip -6 neigh".  For
more details, refer to RFCs 4007 and 4291.

-- 
  Henrique Holschuh

[toc] | [prev] | [next] | [standalone]


#173603

FromFlorian Pelgrim <florian.pelgrim@craneworks.de>
Date2016-10-19 17:50 +0200
Message-ID<su1hV-3b7-43@gated-at.bofh.it>
In reply to#173333

[Multipart message — attachments visible in raw view] — view raw

Hi,

Am 08.10.16 um 23:19 schrieb Henrique de Moraes Holschuh:
> On Sat, 08 Oct 2016, Florian Pelgrim wrote:
>> This is the expected result without a firewall:
>> $ ip route get 2404:6800:400a:800::1012
>> 2404:6800:400a:800::1012 from :: via fe80::1 dev eth0  src
>> fe80::d481:11ff:feee:4908  metric 0
>>     cache  hoplimit 64
> 
> Why do you have a default route via fe80::1 ?  Where did it came from?
Until that the host had not a configured IPv6 address. So I guess that
was Ipv6 autoconfiguration.

> 
>> Now I setup some basic ip6tables firewall settings.
> 
> "Basic" IPv6 firewalling is, unfortunately, anything but basic... mostly
> because ICMPv6 overloads both L2 and L3 control-plane functions.
> 
> RFC 4890 "to the rescue" :-(
> https://tools.ietf.org/html/rfc4890
> 
> *do* read the errata to RFC4890, it is relevant if you use the iptable
> examples.
> 
That helped me the most.
So it was really to the rescue.

>> $ ip route get 2404:6800:400a:800::1012
>> unreachable 2404:6800:400a:800::1012 from :: dev lo  table unspec  proto
>> kernel  src fe80::d481:11ff:feee:4908  metric 4294967295  error -101
> 
> Your firewalling apparently broke the IPv6 DAD (which requires a subset
> of ICMPv6, and multicast).  That would cause any interface address of
> link-local scope or higher to be declared invalid (for failing DAD), and
> unusable.
> 
> And the kernel is not about to send locally-originated packets with an
> invalid source address (unless you override it with evil black magic).
> 
my provider offered me a public IPv6 address so I configured it and
disabled everything about DAD etc.

>> Uh? So lets look this up in conntrack. The results are pretty low...
>> There is nothing to see. No v6 package in any state.
> 
> I don't think link-local L2 control-plane traffic ends up creating
> conntrack entries, at least not in any reliable way (it can't).
> 
> It is best to do stateless firewalling for everything L2, including the
> subset of ICMPv6 that deals with L2 functions and multicast control.
There are some packages which are not shown in the conntrack module. But
I couldn't figure out yet which and which not.
For example echo-requests will be shown.

> 
>> And another question is how can I flush the cached results from `ip
>> route get`? `ip route cache flush` is not working since I guess they
>> changed the caching in kernel version 3.6.
> 
> "ip route cache flush" is supposed to still work, yes.  But I don't
> think your problem is in the routing table (or cache) in the first
> place.
I thought ip route cache flush would flush the hole cache but it did
only for v4. That make it hard for me to debug because until that I was
not aware of net.ipv6.route.mtu_expires which is per default 600s.
> 
> I'd try to fix the IPv6 DAD issues, first.  Check the output of "ip -6
> addr" for every relevant interface... it should say when an address is
> invalid for failing DAD, AFAIK.
> 
> After that, keep in mind that the forwarding destination for link-local
> addresses must be resolved through neighbor tables, not routing tables.
> You can manipulate the IPv6 neighbor table using "ip -6 neigh".  For
> more details, refer to RFCs 4007 and 4291.
I don't need neighbor discovery. So as mentioned I switched it off.
In fact I sticked pretty much to this guide[1] causes my server is a
standalone box.

[1]
https://www.ernw.de/download/ERNW_Guide_to_Securely_Configure_Linux_Servers_For_IPv6_v1_0.pdf

Cheers
Flo

[toc] | [prev] | [next] | [standalone]


#173342

FromPascal Hambourg <pascal@plouf.fr.eu.org>
Date2016-10-09 10:00 +0200
Message-ID<sqhbA-1nh-1@gated-at.bofh.it>
In reply to#173331
Le 08/10/2016 à 20:09, Florian Pelgrim a écrit :
>
> $ ip route get 2404:6800:400a:800::1012
> 2404:6800:400a:800::1012 from :: via fe80::1 dev eth0  src
> fe80::d481:11ff:feee:4908  metric 0

This does not look like a correct setup to me, unless the router 
performs source NAT (yuck!). A link local source address cannot be used 
to send packets beyond the link.

> So why is conntrack ignoring my icmpv6 traffic?

Conntrack does not ignore all ICMPv6 traffic. Only some ICMPv6 types are 
not tracked because they use multicast which is hard to track. Such 
types include part of the NDP protocol (neighbour discovery) : Neighbour 
Solicitation, Neighbour Advertisement, Router Solicitation, Router 
Advertisement, and a few others. They have the UNTRACKED state.

Blocking NDP on a broadcast interface breaks IPv6 connectivity.

Other usual ICMPv6 types such as Echo Request/Reply and error messages 
(Destination Unreachable, Packet Too Big, Parameter Problem...) are 
tracked as usual.

[toc] | [prev] | [next] | [standalone]


#173602

FromFlorian Pelgrim <florian.pelgrim@craneworks.de>
Date2016-10-19 17:50 +0200
Message-ID<su1hU-3b7-5@gated-at.bofh.it>
In reply to#173342

[Multipart message — attachments visible in raw view] — view raw

Hi,

Am 09.10.16 um 09:54 schrieb Pascal Hambourg:
> Le 08/10/2016 à 20:09, Florian Pelgrim a écrit :
>>
>> $ ip route get 2404:6800:400a:800::1012
>> 2404:6800:400a:800::1012 from :: via fe80::1 dev eth0  src
>> fe80::d481:11ff:feee:4908  metric 0
> 
> This does not look like a correct setup to me, unless the router
> performs source NAT (yuck!). A link local source address cannot be used
> to send packets beyond the link.
It was autogenerated by Debian itself.
But I configured a statical public IPv6 address.

Fun fact is that my provider is really using fe80::1 as default gateway.
And I know a lot more who are using the same technic when dealing with
IPv6 for customers.

> 
>> So why is conntrack ignoring my icmpv6 traffic?
> 
> Conntrack does not ignore all ICMPv6 traffic. Only some ICMPv6 types are
> not tracked because they use multicast which is hard to track. Such
> types include part of the NDP protocol (neighbour discovery) : Neighbour
> Solicitation, Neighbour Advertisement, Router Solicitation, Router
> Advertisement, and a few others. They have the UNTRACKED state.
> 
> Blocking NDP on a broadcast interface breaks IPv6 connectivity.
> 
> Other usual ICMPv6 types such as Echo Request/Reply and error messages
> (Destination Unreachable, Packet Too Big, Parameter Problem...) are
> tracked as usual.
Ah, nice. Thanks. That explains a lot for me now. :)

Cheers
Flo

[toc] | [prev] | [next] | [standalone]


#173618

FromHenrique de Moraes Holschuh <hmh@debian.org>
Date2016-10-20 03:10 +0200
Message-ID<sua1P-Ew-1@gated-at.bofh.it>
In reply to#173602
On Wed, Oct 19, 2016, at 13:42, Florian Pelgrim wrote:
> Fun fact is that my provider is really using fe80::1 as default gateway.
> And I know a lot more who are using the same technic when dealing with
> IPv6 for customers.

That will not end up well.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique de Moraes Holschuh <hmh@debian.org>

[toc] | [prev] | [standalone]


Back to top | Article view | linux.debian.user


csiph-web