diff mbox

[3/5] netfilter: xt_TCPMSS: Fix violation of RFC879 in absence of MSS option

Message ID 1370880461-4265-4-git-send-email-pablo@netfilter.org
State Accepted
Headers show

Commit Message

Pablo Neira Ayuso June 10, 2013, 4:07 p.m. UTC
From: Phil Oester <kernel@linuxace.com>

The clamp-mss-to-pmtu option of the xt_TCPMSS target can cause issues
connecting to websites if there was no MSS option present in the
original SYN packet from the client. In these cases, it may add a
MSS higher than the default specified in RFC879. Fix this by never
setting a value > 536 if no MSS option was specified by the client.

This closes netfilter's bugzilla #662.

Signed-off-by: Phil Oester <kernel@linuxace.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/xt_TCPMSS.c |    6 ++++++
 1 file changed, 6 insertions(+)

Comments

Phil Oester June 10, 2013, 7:19 a.m. UTC | #1
On Tue, Jun 11, 2013 at 09:43:07AM +0100, David Laight wrote:
> Is setting the mss to 536 actually ever sensible?
> RFC 879 might say that it is the default (and the minimum
> that must be supported), but in practise the actual mss
> is very likely to be only slightly shorter than the standard
> ethernet mss.
> Although strict conformance with RFC 879 might require the mss
> be clamped to 536, pragmatically a value much nearer 1400 would
> make sense - systems with very low mtu/mss are probably likely
> to advertise it.

Read the associated bugzilla - there was at least one real world
example where setting a higher MSS was causing breakage.

Phil

https://bugzilla.netfilter.org/show_bug.cgi?id=662
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Phil Oester June 10, 2013, 8:27 a.m. UTC | #2
On Tue, Jun 11, 2013 at 04:00:06PM +0100, David Laight wrote:
> To quote that bug:
> 
> I stumbled upon this problem in debian bug #541658[1] ("[iceweasel] cannot open 
> research.microsoft.com" - only worth reading for entertainment purposes) and,
> after that bug was closed, analysed it in my blog[2] until a friend of mine
> found out why the page loads when clamping mss to pmtu is disabled or
> restricted to a range (like with "iptables -A FORWARD -p tcp --tcp-flags
> SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu") but
> doesn't load with "simple" clamping. His really great and detailed analysation
> of the problem may be seen at [3].
> 
> If I read/understand that correctly, clamping to 1400 worked - there was
> no need to clamp all the way down to 536.

You are not understanding the issue correctly.  The reason the command worked with
"-m tcpmss --mss 1400:1536" is because that implies an MSS option was provided.
The issue occurs only when NO MSS option is sent.  In these cases, we cannot
ASSUME that it is ok to use some arbitrarily high value (1400 as you propose).
The RFC is clear on this point.

Phil
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Laight June 11, 2013, 8:43 a.m. UTC | #3
> The clamp-mss-to-pmtu option of the xt_TCPMSS target can cause issues
> connecting to websites if there was no MSS option present in the
> original SYN packet from the client. In these cases, it may add a
> MSS higher than the default specified in RFC879. Fix this by never
> setting a value > 536 if no MSS option was specified by the client.
> 
> This closes netfilter's bugzilla #662.
...
> +	/* RFC 879 states that the default MSS is 536 without specific
> +	 * knowledge that the destination host is prepared to accept larger.
> +	 * Since no MSS was provided, we MUST NOT set a value > 536.
> +	 */
> +	newmss = min(newmss, (u16)536);
> +

Is setting the mss to 536 actually ever sensible?
RFC 879 might say that it is the default (and the minimum
that must be supported), but in practise the actual mss
is very likely to be only slightly shorter than the standard
ethernet mss.
Although strict conformance with RFC 879 might require the mss
be clamped to 536, pragmatically a value much nearer 1400 would
make sense - systems with very low mtu/mss are probably likely
to advertise it.

	David



--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Laight June 11, 2013, 3 p.m. UTC | #4
> On Tue, Jun 11, 2013 at 09:43:07AM +0100, David Laight wrote:
> > Is setting the mss to 536 actually ever sensible?
> > RFC 879 might say that it is the default (and the minimum
> > that must be supported), but in practise the actual mss
> > is very likely to be only slightly shorter than the standard
> > ethernet mss.
> > Although strict conformance with RFC 879 might require the mss
> > be clamped to 536, pragmatically a value much nearer 1400 would
> > make sense - systems with very low mtu/mss are probably likely
> > to advertise it.
> 
> Read the associated bugzilla - there was at least one real world
> example where setting a higher MSS was causing breakage.
> 
> Phil
> 
> https://bugzilla.netfilter.org/show_bug.cgi?id=662

To quote that bug:

I stumbled upon this problem in debian bug #541658[1] ("[iceweasel] cannot open 
research.microsoft.com" - only worth reading for entertainment purposes) and,
after that bug was closed, analysed it in my blog[2] until a friend of mine
found out why the page loads when clamping mss to pmtu is disabled or
restricted to a range (like with "iptables -A FORWARD -p tcp --tcp-flags
SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu") but
doesn't load with "simple" clamping. His really great and detailed analysation
of the problem may be seen at [3].

If I read/understand that correctly, clamping to 1400 worked - there was
no need to clamp all the way down to 536.

	David



--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Laight June 11, 2013, 4:09 p.m. UTC | #5
> On Tue, Jun 11, 2013 at 04:00:06PM +0100, David Laight wrote:
> > To quote that bug:
> >
> > I stumbled upon this problem in debian bug #541658[1] ("[iceweasel] cannot open
> > research.microsoft.com" - only worth reading for entertainment purposes) and,
> > after that bug was closed, analysed it in my blog[2] until a friend of mine
> > found out why the page loads when clamping mss to pmtu is disabled or
> > restricted to a range (like with "iptables -A FORWARD -p tcp --tcp-flags
> > SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu") but
> > doesn't load with "simple" clamping. His really great and detailed analysation
> > of the problem may be seen at [3].
> >
> > If I read/understand that correctly, clamping to 1400 worked - there was
> > no need to clamp all the way down to 536.
> 
> You are not understanding the issue correctly.  The reason the command worked with
> "-m tcpmss --mss 1400:1536" is because that implies an MSS option was provided.
> The issue occurs only when NO MSS option is sent.  In these cases, we cannot
> ASSUME that it is ok to use some arbitrarily high value (1400 as you propose).
> The RFC is clear on this point.

My problem is that I don't want TCP connections to drop the mss to
536 when talking to minimal/old implementations that don't add any
options to SYN packets.

	David



--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pablo Neira Ayuso June 11, 2013, 4:25 p.m. UTC | #6
On Tue, Jun 11, 2013 at 05:09:11PM +0100, David Laight wrote:
> > On Tue, Jun 11, 2013 at 04:00:06PM +0100, David Laight wrote:
> > > To quote that bug:
> > >
> > > I stumbled upon this problem in debian bug #541658[1] ("[iceweasel] cannot open
> > > research.microsoft.com" - only worth reading for entertainment purposes) and,
> > > after that bug was closed, analysed it in my blog[2] until a friend of mine
> > > found out why the page loads when clamping mss to pmtu is disabled or
> > > restricted to a range (like with "iptables -A FORWARD -p tcp --tcp-flags
> > > SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu") but
> > > doesn't load with "simple" clamping. His really great and detailed analysation
> > > of the problem may be seen at [3].
> > >
> > > If I read/understand that correctly, clamping to 1400 worked - there was
> > > no need to clamp all the way down to 536.
> > 
> > You are not understanding the issue correctly.  The reason the command worked with
> > "-m tcpmss --mss 1400:1536" is because that implies an MSS option was provided.
> > The issue occurs only when NO MSS option is sent.  In these cases, we cannot
> > ASSUME that it is ok to use some arbitrarily high value (1400 as you propose).
> > The RFC is clear on this point.
> 
> My problem is that I don't want TCP connections to drop the mss to
> 536 when talking to minimal/old implementations that don't add any
> options to SYN packets.

That will not happen if you use:

... -m tcpmss --mss 1400:1536 ...

as in your example above.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Haran June 11, 2013, 6 p.m. UTC | #7
> -----Original Message-----
> From: netfilter-devel-owner@vger.kernel.org [mailto:netfilter-devel-owner@vger.kernel.org] On Behalf Of Pablo Neira Ayuso
> Sent: Tuesday, June 11, 2013 9:25 AM
> To: David Laight
> Cc: Phil Oester; netfilter-devel@vger.kernel.org; davem@davemloft.net; netdev@vger.kernel.org
> Subject: Re: [PATCH 3/5] netfilter: xt_TCPMSS: Fix violation of RFC879 in absence of MSS option
> 
> On Tue, Jun 11, 2013 at 05:09:11PM +0100, David Laight wrote:
> > > On Tue, Jun 11, 2013 at 04:00:06PM +0100, David Laight wrote:
> > > > To quote that bug:
> > > >
> > > > I stumbled upon this problem in debian bug #541658[1] ("[iceweasel] cannot open
> > > > research.microsoft.com" - only worth reading for entertainment purposes) and,
> > > > after that bug was closed, analysed it in my blog[2] until a friend of mine
> > > > found out why the page loads when clamping mss to pmtu is disabled or
> > > > restricted to a range (like with "iptables -A FORWARD -p tcp --tcp-flags
> > > > SYN,RST SYN -m tcpmss --mss 1400:1536 -j TCPMSS --clamp-mss-to-pmtu") but
> > > > doesn't load with "simple" clamping. His really great and detailed analysation
> > > > of the problem may be seen at [3].
> > > >
> > > > If I read/understand that correctly, clamping to 1400 worked - there was
> > > > no need to clamp all the way down to 536.
> > >
> > > You are not understanding the issue correctly.  The reason the command worked with
> > > "-m tcpmss --mss 1400:1536" is because that implies an MSS option was provided.
> > > The issue occurs only when NO MSS option is sent.  In these cases, we cannot
> > > ASSUME that it is ok to use some arbitrarily high value (1400 as you propose).
> > > The RFC is clear on this point.
> >
> > My problem is that I don't want TCP connections to drop the mss to
> > 536 when talking to minimal/old implementations that don't add any
> > options to SYN packets.
> 
> That will not happen if you use:
> 
> ... -m tcpmss --mss 1400:1536 ...
> 
> as in your example above.

There is likely no "right" answer for this issue, but for what it's worth I can report a somewhat related experience I had a few years ago when updating my PC at home with a new Suse distro. The machine had been running previous versions of Suse with my Comcast cable internet service just fine for several years. I downloaded the ISO from opensuse, burned the DVD, did the install but when it came back up again the internet service was quite unreliable. It would work for a few minutes, but then no packets would flow. I happened to run ifconfig eth0 and it showed an MTU of 576. It seems the version of the DHCP client that came with the new distro honored the DHCP MTU option, but Comcast was advertising DHCP offers with an MTU of 576.

Problem was, the cable modem that Comcast supplied apparently didn't like that short MTU. I found that if I power cycled the modem, packets would flow again, for a little while. When I modified the configuration of the DHCP client to ignore the MTU option and use a fixed 1500, it started working fine like it did before. I suppose the Windows versions of the time ignored the MTU option by default, so this was not something that impacted most of Comcast's users.

The moral of the story for me was that despite what the RFC says, the de facto default MTU of the Internet is 1500 and MSS's derived from shorter MTUs are likely to cause interoperability problems.

Jeff Haran

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rick Jones June 11, 2013, 6:14 p.m. UTC | #8
> There is likely no "right" answer for this issue, but for what it's
> worth I can report a somewhat related experience I had a few years
> ago when updating my PC at home with a new Suse distro. The machine
> had been running previous versions of Suse with my Comcast cable
> internet service just fine for several years. I downloaded the ISO
> from opensuse, burned the DVD, did the install but when it came back
> up again the internet service was quite unreliable. It would work for
> a few minutes, but then no packets would flow. I happened to run
> ifconfig eth0 and it showed an MTU of 576. It seems the version of
> the DHCP client that came with the new distro honored the DHCP MTU
> option, but Comcast was advertising DHCP offers with an MTU of 576.

Presumably then, your system rejected any incoming packet which was 
larger than the 576 byte MTU it got from the Comcast DHCP server..

I can think of two reasons for larger packets to be arriving at your 
system then:

1) UDP

2) Broken TCPs ass-u-me-ing a TCP MSS larger than 536 bytes when there 
wasn't an MSS option in the SYN(s).

Did your SuSE system send actual TCP MSS options based on the 576 byte MTU?


rick jones
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jeff Haran June 11, 2013, 6:31 p.m. UTC | #9
> -----Original Message-----
> From: netfilter-devel-owner@vger.kernel.org [mailto:netfilter-devel-owner@vger.kernel.org] On Behalf Of Rick Jones
> Sent: Tuesday, June 11, 2013 11:14 AM
> To: Jeff Haran
> Cc: Pablo Neira Ayuso; David Laight; Phil Oester; netfilter-devel@vger.kernel.org; davem@davemloft.net; netdev@vger.kernel.org
> Subject: Re: [PATCH 3/5] netfilter: xt_TCPMSS: Fix violation of RFC879 in absence of MSS option
> 
> > There is likely no "right" answer for this issue, but for what it's
> > worth I can report a somewhat related experience I had a few years
> > ago when updating my PC at home with a new Suse distro. The machine
> > had been running previous versions of Suse with my Comcast cable
> > internet service just fine for several years. I downloaded the ISO
> > from opensuse, burned the DVD, did the install but when it came back
> > up again the internet service was quite unreliable. It would work for
> > a few minutes, but then no packets would flow. I happened to run
> > ifconfig eth0 and it showed an MTU of 576. It seems the version of
> > the DHCP client that came with the new distro honored the DHCP MTU
> > option, but Comcast was advertising DHCP offers with an MTU of 576.
> 
> Presumably then, your system rejected any incoming packet which was
> larger than the 576 byte MTU it got from the Comcast DHCP server..
> 
> I can think of two reasons for larger packets to be arriving at your
> system then:
> 
> 1) UDP
> 
> 2) Broken TCPs ass-u-me-ing a TCP MSS larger than 536 bytes when there
> wasn't an MSS option in the SYN(s).
> 
> Did your SuSE system send actual TCP MSS options based on the 576 byte MTU?
> 
> 
> rick jones

I didn't debug it further so I can't answer that question. But the problem was clearly in the cable modem. Power cycling the modem brought back connectivity, for a little while. I was able to muddle through this since I work with this stuff for a living, but if I had been an IP-unsavvy Joe Sixpack who was trying out a Linux live CD on his home PC as an alternative to Windows, I suspect I would have given up in disgust.

Something to think about for those of us who would like to see wider adoption of Linux on the PC desktop.

Jeff Haran

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
John Heffner June 11, 2013, 6:36 p.m. UTC | #10
While it's not likely to harm anything, this isn't quite right for
IPv6, with a lower bound MTU of 1280.

Thanks,
  -John

(Sorry, re-sending as gmail silently turned on HTML formatting.)



On Mon, Jun 10, 2013 at 12:07 PM, Pablo Neira Ayuso <pablo@netfilter.org> wrote:
>
> From: Phil Oester <kernel@linuxace.com>
>
> The clamp-mss-to-pmtu option of the xt_TCPMSS target can cause issues
> connecting to websites if there was no MSS option present in the
> original SYN packet from the client. In these cases, it may add a
> MSS higher than the default specified in RFC879. Fix this by never
> setting a value > 536 if no MSS option was specified by the client.
>
> This closes netfilter's bugzilla #662.
>
> Signed-off-by: Phil Oester <kernel@linuxace.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
>  net/netfilter/xt_TCPMSS.c |    6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
> index a75240f..afaebc7 100644
> --- a/net/netfilter/xt_TCPMSS.c
> +++ b/net/netfilter/xt_TCPMSS.c
> @@ -125,6 +125,12 @@ tcpmss_mangle_packet(struct sk_buff *skb,
>
>         skb_put(skb, TCPOLEN_MSS);
>
> +       /* RFC 879 states that the default MSS is 536 without specific
> +        * knowledge that the destination host is prepared to accept larger.
> +        * Since no MSS was provided, we MUST NOT set a value > 536.
> +        */
> +       newmss = min(newmss, (u16)536);
> +
>         opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
>         memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
>
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Jan Engelhardt June 21, 2013, 8:27 a.m. UTC | #11
On Tuesday 2013-06-11 20:31, Jeff Haran wrote:
>> > It seems the version of
>> > the DHCP client that came with the new distro honored the DHCP MTU
>> > option, but Comcast was advertising DHCP offers with an MTU of 576.
>>
>> Did your SuSE system send actual TCP MSS options based on the 576
>> byte MTU?

Yes and it makes for horrible performance. In fact, the "Unitymedia"
cable provider in Germany does exactly the same stupid thing, sending
MTU=576 in their DHCP responses, despite the link actually being
capable of MTU 1500 ("capable" as in, not returning a Fragmentation
Needed ICMP). The only way to get around this provider's idiocy is to
manually set MTU=1500 in SUSE's network config, which overrides the
DHCP values. The way it works is probably by way of using the
scripting functions of prominent DHCP and VPN clients (the C programs
only does the network job and otherwise calls /bin/sh-type logic to
actually modify the interface parameters) like dhclient,dhcpcd,vpnc.


>> Presumably then, your system rejected any incoming packet which was
>> larger than the 576 byte MTU it got from the Comcast DHCP server..

The MTU is not used to block incoming packets. That would not make
sense either (because you already have received the packet and
therefore can use it). In fact, TCP-receive-offloading hardware may
even pass to the kernel packets that are larger than both the output
MTU of your own system as well as larger as the output MTU of the
router you got it from.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index a75240f..afaebc7 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -125,6 +125,12 @@  tcpmss_mangle_packet(struct sk_buff *skb,
 
 	skb_put(skb, TCPOLEN_MSS);
 
+	/* RFC 879 states that the default MSS is 536 without specific
+	 * knowledge that the destination host is prepared to accept larger.
+	 * Since no MSS was provided, we MUST NOT set a value > 536.
+	 */
+	newmss = min(newmss, (u16)536);
+
 	opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
 	memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));