Unexpected behavior (a.k.a. bug) on local tunnel
@drieseng arbeitet bereits daran.
Seit 16.11.2016.
- Vorherrschende Sprache
- C#
- Sterne
- 4.4k
- Forks
- 993
- Ø Merge
- 9 T. 21 Std.
- Gemergte PRs (30 T.)
- 1
Beschreibung
Bug as seen on the net
People try to use local tunnels and that fails like on:
- c# - Creating a forwarded port within an SSH tunnel - Stack Overflow.
- C# SSH tunnel to MySQL server - Stack Overflow
- SSH tunneling a MySQL connection using C# - Stack Overflow
Usually the user has found a workaround but not clarified what happens.
This bug report clarifies and suggests an improvements.
How to reproduce
OS is Win7 here but probably happens with other configurations.
From c# - Creating a forwarded port within an SSH tunnel - Stack Overflow:
PrivateKeyFile file = new PrivateKeyFile(@" .. path to private key .. ");
using (var client = new SshClient(" .. remote server .. ", "ubuntu", file))
{
client.Connect();
var port = new ForwardedPortLocal(3306, "localhost", 3306);
client.AddForwardedPort(port);
port.Start();
Thread.Sleep(10000000);
client.Disconnect();
}
Expected behaviour
OS accepts connections to any local IP (127.0.0.1, ::1), port 3306.
Observed behaviour
OS does not accept connections to local IP (127.0.0.1) (not sure if tester ::1), port 3306.
It does accept connection to a particular IPV6 address, though.
Technical analysis: what's happening
Expected behavior
When opening a local tunnel without specifying IP to bind, OpenSSH implementation binds to all local IPs. Here's an example on Linux:
ssh somehost -L 1234:127.0.0.1:1234
On another terminal:
netstat -n -at | grep -i listen | grep 1234
tcp 0 0 127.0.0.1:1234 0.0.0.0:* LISTEN
tcp6 0 0 ::1:1234 :::* LISTEN
Observed behavior
Instead, SSH.NET does this (from SSH.NET/ForwardedPortLocal.NET.cs at 5f6c3b0bc7a5916d92467931ecacdfc0917f83d7 · sshnet/SSH.NET):
var addr = DnsAbstraction.GetHostAddresses(BoundHost)[0];
which on local machine provides IP addresses provided by DHCP server, not 127.0.0.1 or ::1.
Taking only the first result from array returned by DnsAbstraction.GetHostAddresses(BoundHost) is code smell.
Suggested change
(1) Make a foreach loop that binds to all adresses returned by DnsAbstraction.GetHostAddresses(BoundHost)
(2) if String.IsNullOrEmpty(BoundHost), use something like IPAddress.Loopback (or something ensuring IPv4 and IPv6 compatibility).
Though I'm not using that at the moment, can SSH.NET bind to "any IP" (pseudo-address '*') like OpenSSH does:
ssh somehost -L *:localport:remotehost:remoteport
That suggests : (3) if ("*".Equals(BoundHost)) { ... }
Conclusion
IMHO such a change would make SSH.NET more inline with expected behavior and avoid much frustration for people.
Thank you for your attention.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Bewertung
Dieses Issue wurde noch nicht bewertet.