Fri, 19 Dec 2003

Broken firewalls refuse ECN enabled connections

I worked through an interesting problem last night at the office.

One of our users was unable to reach the State of California's website. We recently installed a Squid proxy and he assumed the proxy server was blocking his request. He got a connection refused error reported back from Squid.

I tried to reach the site without using the Squid proxy and could do so from the firewall but not from the machine hosting the Squid proxy. Packet sniffing with tcpdump revealed the connection attempt was, indeed, reaching and was being refused by it. That was confusing, because the firewall provides NAT and the target system should not have been able to distinguish any difference between a request coming directly from the firewall box and one coming from the box hosting the Squid proxy.

Comparing the captured packet headers between the successful and unsuccessful attempts I did discover a difference. The firewall box was sending a packet with the Syn flag set (as expected) which simply appears in tcpdump as 'S' in the flags field. The failed attempt from the Squid proxy box had flags 'SWE'.

A Google search turned up a useful hit:

Are you running kernel 2.4.x?  If so, _and_ you have TCP
ECN enabled, that's the problem.
How to check?
  # sysctl net.ipv4.tcp_ecn
  1 means on.
How to fix? Short term:
  # sysctl –w net.ipv4.tcp_ecn=0

That was indeed the problem. The Linux kernel configuration help file includes the following note:

Note that, on the Internet, there are many broken
firewalls which refuse connections from ECN-enabled
machines, and it may be a while before these firewalls
are fixed.  Until then, to access a site behind such a
firewall (some of which are major sites, at the time of
this writing) you will have to disable this option,
either by saying N now or by using the sysctl.

Given the odd symptoms, I was very pleased to have been able to find and fix the problem in just a few minutes. Thanks goes to Nathan E Norman whose post on the debian-user mailing list provided the solution and to Google fantastic search engine for making it easy to find.

I'm a Debian user myself. For the time being, I've added the following line to the appropriate interface's section in /etc/networking/interfaces:

up /sbin/sysctl –w net.ipv4.tcp_ecn=0 || true

That seems to do the trick.

[/internet] [link]

About this weblog

This site is the personal weblog of Marc Mims. You can contact Marc by sending e-mail to:

Marc writes here about cycling, programming, Linux, and other items of personal interest.

This site is syndicated with RSS.



CSS stolen from Tom Coates who didn't even complain.