Mailing List Archive

Connect direct and fallback
Hi,

I'm looking for a client-side tool which can be used with ProxyCommand and:

- makes a direct connection attempt
- if the connection fails, makes a second attempt via a configured SOCKS
server
- preferably uses ProxyUseFdpass, so that it gets out of the way once it
has done its job

Does anyone know if such a thing already exists?  If not, I might try
knocking something together.

(Idea is to make a direct connection to a host on IPv6 where possible,
but when connecting from an IPv4-only network fallback to SOCKS)

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On 2/18/22 13:36, Brian Candler wrote:
[snip]
> (Idea is to make a direct connection to a host on IPv6 where possible,
> but when connecting from an IPv4-only network fallback to SOCKS)

Several people have written about something similar in various blog
posts and microblog posts in recent years[1]. Use of Match Exec in
ssh_config(5) seems to be the way that is approached:

Match host ipv6only.example.org
User fred

Match host ipv6only.example.org !exec "route -n get -inet6 %h"
ProxyJump dualstack.example.org

That would allow you to connect directly to the one system if there is
IPv6 connectivity and hop through a bastion / jump host first if only
IPv4 connectivity is possible. The match blocks can be made more
general with patterns, of course.

Exec could use route(8), ping(8), nc(1), or a custom script.

In order to use a SOCKS5 proxy in place of a jump host, ProxyCommand
could use nc(1) in place of a plain ProxyJump.

/Lars

[1] Since it doesn't seem to be such a rare task, I've put a summary in
a section of this chapter:


https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts#Conditional_Use_of_Jump_Hosts
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On Fri, 18 Feb 2022 at 22:38, Brian Candler <b.candler@pobox.com> wrote:
> I'm looking for a client-side tool which can be used with ProxyCommand and:
>
> - makes a direct connection attempt
> - if the connection fails, makes a second attempt via a configured SOCKS
> server
> - preferably uses ProxyUseFdpass, so that it gets out of the way once it
> has done its job

Other than the ProxyUseFdpass part you can do that with a shell one
liner in ProxyCommand and netcat:

ProxyCommand sh -c 'nc %h %p || nc --proxy lsocksserver:1080
--proxy-type=socks4 %h %p'

--
Darren Tucker (dtucker at dtucker.net)
GPG key 11EAA6FA / A86E 3E07 5B19 5880 E860 37F4 9357 ECEF 11EA A6FA (new)
Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On Fri, Feb 18, 2022 at 02:13:15PM +0200, Lars Nood?n wrote:
> On 2/18/22 13:36, Brian Candler wrote:
> [snip]
> > (Idea is to make a direct connection to a host on IPv6 where possible,
> > but when connecting from an IPv4-only network fallback to SOCKS)
>
> Several people have written about something similar in various blog
> posts and microblog posts in recent years[1]. Use of Match Exec in
> ssh_config(5) seems to be the way that is approached:
>
> Match host ipv6only.example.org
> User fred
>
> Match host ipv6only.example.org !exec "route -n get -inet6 %h"
> ProxyJump dualstack.example.org
>
> That would allow you to connect directly to the one system if there is
> IPv6 connectivity and hop through a bastion / jump host first if only
> IPv4 connectivity is possible. The match blocks can be made more
> general with patterns, of course.
>
> Exec could use route(8), ping(8), nc(1), or a custom script.
>
I have something similar that detects whether I am on the same LAN as
the destination system, and uses ProxyJump if not:-

#
#
# esprimo may be remote or local (particularly from t470), if it's remote
# connect via cheddar.halon.
#
Match host esprimo exec "! ping -w 1 -c 1 esprimo >/dev/null 2>&1"
Hostname zbmc.eu
ProxyJump cheddar.halon.org.uk

--
Chris Green
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On 18/02/2022 12:15, Darren Tucker wrote:
> Other than the ProxyUseFdpass part you can do that with a shell one
> liner in ProxyCommand and netcat:
>
> ProxyCommand sh -c 'nc %h %p || nc --proxy lsocksserver:1080
> --proxy-type=socks4 %h %p'

Neat, that will probably do me for now :-)

Cheers,

Brian.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On 18/02/2022 12:15, Darren Tucker wrote:
> Other than the ProxyUseFdpass part you can do that with a shell one
> liner in ProxyCommand and netcat:
>
> ProxyCommand sh -c 'nc %h %p || nc --proxy lsocksserver:1080
> --proxy-type=socks4 %h %p'

Just a quick follow-up to this: I found that macOS 12.2.1's "nc" command
is broken when using a SOCKS5 proxy and the proxy returns an IPv6 bind
address.

  X -----------> Y --------------> Z
macOS          SOCKS5   IPv6     target
 nc            server

$ nc -X 5 -x 1.2.3.4:1080 2001:db8::1 22
??SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.4
^^
(Notice the extra spurious bytes in response)

Checking with tcpdump I see the exchange as:

--> 05 01 00
<-- 05 00
--> 05 01 00 04 ZZ(x16) 00 16    [connect, ATYP 4 = IPv6 address/port]
<-- 05 00 00 04 YY(x16) PP PP    [success, ATYP 4 = IPv6 bind address/port]
<-- start of data

This is the case with two standalone SOCKS5 servers I tried: dante and
Mikrotik.

Interestingly, the problem doesn't manifest when using ssh -D as the
proxy server.

$ ssh -D 1080 Y
...

$ nc -X 5 -x localhost:1080 2001:db8::1 22
SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.4

--> 05 01 00
<-- 05 00
--> 05 01 00 04 ZZ(x16) 00 16        [connect, ATYP 4 = IPv6 address]
<-- 05 00 00 01 00 00 00 00 00 00    [success, ATYP 1 = IPv4 bind
address 0.0.0.0:0]
<-- start of data

That is, ssh -D always returns IPv4 0.0.0.0:0 as the bind address/port,
even if the target is reached via IPv6, and regardless of whether
localhost is 127.0.0.1 or ::1.  It appears macOS's /usr/bin/nc is
hard-coded to expect that.

Workaround is to switch to "ncat" (from the makers of "nmap") which
works correctly.  Homebrew also has "netcat" and "netcat6" packages, but
neither of those support SOCKS.  With ncat, the connection fallback works.

Anyway, I just thought I'd mention it in case it trips up anyone else.

Regards,

Brian.

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On Fri, 18 Feb 2022 14:13:15 +0200
Lars Noodén <lars.nooden@gmx.com> wrote:

[SNIP]
> Use of Match Exec in
> ssh_config(5) seems to be the way that is approached:
>
> Match host ipv6only.example.org
> User fred
>
> Match host ipv6only.example.org !exec "route -n get -inet6 %h"
> ProxyJump dualstack.example.org
>
> That would allow you to connect directly to the one system if there is
> IPv6 connectivity and hop through a bastion / jump host first if only
> IPv4 connectivity is possible. The match blocks can be made more
> general with patterns, of course.
>
> Exec could use route(8), ping(8), nc(1), or a custom script.

Okay, that is super cool. I took a look at that wiki page and learned
some things.

> https://en.wikibooks.org/wiki/OpenSSH/Cookbook/Proxies_and_Jump_Hosts#Conditional_Use_of_Jump_Hosts

This reminds me of a related thing I've been wondering about.

For the second case mentioned in that wiki page, which depends on
whether you're connected to a given LAN or not, wouldn't it be nice to
have a convenient and hard-to-spoof way to check that, rather than
blindly trust hostnames?

I keep thinking that seems like something ssh could do very well, but
so far I haven't figured out how to approach it. Can I instruct ssh to
(for example) initiate a connection with 192.168.1.1, authenticate the
remote host's identity against a custom known_hosts file, hang up
without trying to log in or anything, and return a simple yes/no — or
better, on success return the line number of the matching known_hosts
entry?

Any suggestions?

Cheers!
-Chris
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
Re: Connect direct and fallback [ In reply to ]
On 17/03/2022 11:57, Chris Mitchell wrote:
> Can I instruct ssh to
> (for example) initiate a connection with 192.168.1.1, authenticate the
> remote host's identity against a custom known_hosts file, hang up
> without trying to log in or anything, and return a simple yes/no — or
> better, on success return the line number of the matching known_hosts
> entry?

You can determine the key(s) which a remote host presents, without
logging into it, using ssh-keyscan.

$ ssh-keyscan github.com
# github.com:22 SSH-2.0-babeld-4f04c79d
github.com ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
# github.com:22 SSH-2.0-babeld-4f04c79d
github.com ecdsa-sha2-nistp256
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=
# github.com:22 SSH-2.0-babeld-4f04c79d
github.com ssh-ed25519
AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
# github.com:22 SSH-2.0-babeld-4f04c79d
# github.com:22 SSH-2.0-babeld-4f04c79d

If you know what key type you're looking for:

$ ssh-keyscan -t rsa github.com
# github.com:22 SSH-2.0-babeld-4f04c79d
github.com ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==


_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev