TCP connect timeout with proxy

Anand Buddhdev anandb at
Fri Mar 27 19:27:57 AEDT 2020

On 27/03/2020 00:15, Bob Proulx wrote:

Hi Bob,

> The root cause of the problem is a host advertising IPv6 AAAA records
> in the DNS but not supporting a working IPv6 connection.  Fix either
> of those two things and your problem goes away at the source.  Either
> fix IPv6 so that it works or remove the AAAA records so that no
> attempt is made to use IPv6 to connect to it.  Anything else is simply
> piling on layers of workaround instead of fixing the root cause of the
> problem.

I know, I know, I know! But instead of preaching, perhaps try to
understand that the host *does* have IPv6. However, the Internet is not
always perfect, and IPv6 connectivity is still patchy in parts of the
world. So sometimes it doesn't work. I don't want to remove the AAAA
records just because the IPv6 is temporarily down for a few days, while
an operator attempts to fix it.

> It is possible to configure /etc/gai.conf to prefer IPv4 for that host
> address.  But that is just a workaround.

I am an experienced network operator. I am *also* aware of gai.conf.
This requires root on the proxy... but is also assuming that I want to
permanently prefer IPv4 for that host, which is not the case. I just
want to try connecting over IPv6, but time out quickly.

> It is possible to force this for one host with something like this.
> Which is just another workaround but perhaps the least bad option.
>   Host
>     HostKeyAlias
>     HostName
>     ProxyCommand ssh -W %h:%p

Yes, yes, yes. I am aware of every one of these work-arounds. For a
single host. But if I'm doing automation, and connecting to 500 hosts, I
don't know which ones of those have broken IPv6 or broken IPv4 at that
time. So I can't set things up in advance.

See, if I *know* in advance that a host's IPv6 isn't working at the time
I want to connect, I can introduce a temporary work-around for that one
host. Doesn't scale if I want to connect to 500 hosts with ansible, and
some of them are going to time out.

> The "ssh -W %h:%p" uses whatever your client
> defaults to for inet family.  That seems to be what you want.  Then
> the %h expands to forcing IPv4 from the proxyhost to
> the broken IPv6 host.  Which is also what you want.  I tested this and
> was able to force the inet family using this technique.

Yes, I know this. I think everyone here is assuming that I don't know
how to use all these features of ssh. I do. I really do.

>> 1. ssh -tt proxyhost ssh -tt host
> ...
>> I don't like method #1 at all, for obvious reasons.
> I don't know why #1 "works" because on proxyhost I assume it would get
> the IPv6 address.  If it gets the IPv4 address then #2 & #3 would also
> get the IPv4 address.  But you reported it doesn't.  Which seems in conflict.

On the proxy host, I have "ConnectTimeout 10" in the .ssh/config file.
So it honours that setting, and tries the IPv6 address for 10 seconds,
and then fails and moves on to the IPv4 address.

> If there is already automation via ansible then it seems to me that
> there could easily be automation on the client side too.  At least for
> me there is.  But whatever.  All of these things are simply layers of
> workaround on top of the original breakage.  Remember that two wrongs
> are... well... really just the beginning! :-)

Okay, I don't understand something. Almost all TCP client applications,
such as curl, wget, ftp, netcat, etc, offer the ability to control the
TCP connection timeout, and override the OS default. Heck, even ssh
offers this via the ConnectTimeout option, and this even works! But only
when initiating a direct connection. But use a proxy, and you lose all
ability to influence the TCP timeout :(

More information about the openssh-unix-dev mailing list