sshtools / maverick-synergy

Next Generation Java SSH API
https://jadaptive.com
GNU Lesser General Public License v3.0
96 stars 26 forks source link

Unable to connect through proxy using enableHTTPProxy #38

Closed jamoros closed 2 years ago

jamoros commented 2 years ago

Greetings again!

I am trying to connect to a site using our proxy. I have tested the proxy in another instance (WinSCP) so connectivity is not an issue. The code seems pretty simple

sshClientContext.enableHTTPProxy(PROXY_HOSTNAME, PROXY_PORT, HOST, PORT, PROXY_USERNAME, PROXY_PASSWORD, null, null);

Also tried:
sshClientContext.enableHTTPProxy(PROXY_HOSTNAME, PROXY_PORT, HOST, PORT, PROXY_USERNAME, PROXY_PASSWORD, "", Map.of());

I should mention we have two proxies one with username/password and one without and I have not been able to get either to work.

sshClientContext.enableHTTPProxy(PROXY_HOSTNAME, PROXY_PORT, HOST, PORT, null, null, "", Map.of());

And then:

 try (SshClient ssh = new SshClient(host, port, username, sshClientContext,
                30000,
                password.toCharArray(),
                identities)) {
}

However, there is no action. I tested both the SFTP I am trying to connect to without the proxy and it passes. Then I tested with the proxy and it fails. I tested the proxy itself via WinSCP (as mentioned) and it works.

Here is the logging with the proxy on, I didnt include everything because its the same with the proxy code off:

14 Feb 2022 17:58:51,610 [                main]  DEBUG -    ecdh-sha2-nistp521 (client) will be supported using JCE Provider SunEC
14 Feb 2022 17:58:51,612 [                main]  DEBUG -    rsa2048-sha256 (client) will not be supported: Cannot find any provider supporting RSA/None/OAEPWithSHA256AndMGF1Padding
Using Proxy: proxy.corp.net:9119
Private Key Path: /home/theKey
14 Feb 2022 17:58:51,762 [                main]  TRACE - Adding registration request to queue
14 Feb 2022 17:58:51,762 [     SSHD-TRANSFER-1]  TRACE - Registering channel with interested ops 5
14 Feb 2022 17:58:51,762 [     SSHD-TRANSFER-1]  TRACE - Channel is open
14 Feb 2022 17:58:51,763 [     SSHD-TRANSFER-1]  TRACE - Channel is registered
14 Feb 2022 17:58:51,770 [     SSHD-TRANSFER-1]  DEBUG - Posting message com.sshtools.client.TransportProtocolClient$1 to queue
14 Feb 2022 17:58:51,771 [     SSHD-TRANSFER-1]  TRACE - Registration complete
14 Feb 2022 17:58:51,771 [     SSHD-TRANSFER-1]  TRACE - Flag selector as READ/WRITE
14 Feb 2022 17:58:51,771 [     SSHD-TRANSFER-1]  TRACE - Selected key
14 Feb 2022 17:58:51,771 [     SSHD-TRANSFER-1]  TRACE - Processing transport-client WRITE
14 Feb 2022 17:58:51,772 [     SSHD-TRANSFER-1]  ERROR - Selector thread encountered an error
java.lang.IllegalArgumentException
    at com.sshtools.common.ssh.ConnectionAwareTask.<init>(ConnectionAwareTask.java:32)
    at com.sshtools.synergy.nio.SshEngine$SocketReadWriteTask.<init>(SshEngine.java:656)
    at com.sshtools.synergy.nio.SshEngine$TransferSelectorThread.processSelectionKey(SshEngine.java:641)
    at com.sshtools.synergy.nio.SelectorThread.run(SelectorThread.java:492)

Exception: IOException
Exception message: Failed to connect to sftp.can.com:22
End of SFTP Download

This one I am really stumped on so any help would be greatly appreciated!

ludup commented 2 years ago

Ah.. yes that feature has not tested or completed. It looks like there is a basic implementation (unlike the SOCKS methods that do nothing).

host and port from your SshClient constructor are the HTTP proxy host/port or the SSH endpoint host/port ?

It looks like they should be HTTP proxy host/port although looking at the code I really don't think the feature is complete, I don't see anywhere it processes the HTTP response after sending the request.

jamoros commented 2 years ago

The host/Port in SshClient matches the SSH host/port. Instead of connecting directly to the proxy I am now using cntlm and instead of a failure I get a connection time out. So the code looks like this:

sshClientContext.enableHTTPProxy(localhost, 3128, HOST, PORT, null, null, "", Map.of());

// To avoid confusion the variables match
try (SshClient ssh = new SshClient(HOST, PORT, username, sshClientContext,
                30000,
                password.toCharArray(),
                identities)) {
}

I test using ssh and was able to connect using cntlm (localhost:3128) so I was able to eliminate that from being an issue. The proxy is a HTTP so we don't need SOCKS (whew!).

Running it again with TRACE (System out are mine)

15 Feb 2022 14:35:12,266 [                main]  DEBUG -    rsa2048-sha256 (client) will not be supported: Cannot find any provider supporting RSA/None/OAEPWithSHA256AndMGF1Padding
Using Proxy: localhost:3128. ProxyUser: .
Exception: ConnectException
Exception message: Connection timed out
End of SFTP Download

Unfortunately theres no logging. If theres any way I can help please let me know.

ludup commented 2 years ago

It will need a developer to look at it. I can't say when that will be presently.

It looks like its mostly complete, if you want to have a go at finishing the implementation and create a PR I can provide some direction...

TransportProtocolClient is where the changes need to be made.

The hostname and port passed to SshClient will need to be the HTTP proxy hostname and port because in TransportProtocolClient in onSocketConnect it generates and sends a HTTP request and sends it on the current socket, which needs to be connected to the HTTP proxy (see sendHTTPProxyRequest). This requests a tunnel to the remote hostname configured when you called enableHTTPProxy on the SshClientContext.

What's missing is in onSocketRead, it should process the HTTP response and then set the class field proxyDone boolean to true.

There is already a class to process the response called HttpResponse.

If the response is successful (200) the tunnel is established, any remaining data in the incoming bytebuffer would need to be passed to super.onSocketRead although I doubt it will have any (but for sake of complete implementation need to be done), once proxyDone is set, future socket data will be passed to super method too.

The only other thing to ensure the SSH connection gets started, is to call super.onSocketConnect once the HttpResponse has been received in full.

jamoros commented 2 years ago

I cloned the repo and followed your instructions but I just cant get it to work. I updated the SshClient to use the proxy host and port. I updated TransportProtocolClient as per your instructions. I have a debug point in onSocketRead which doesn't seem to be hit at all, so I think something else may be missing.

jamoros commented 2 years ago

Greetings, any updates on your end, perhaps assigning a dev to look at this? As I mentioned in my previous comment I'm unable to get it to work following your instructions.

ludup commented 2 years ago

There are problems with trying to implement it as described above. It needs a different approach which we are looking into.

ludup commented 2 years ago

Working support for HTTP proxy has been committed to the develop branch and should be available in the new 3.0.7-SNAPSHOT in maven.

Here is an example of the basic usage, notice that you no longer now have to pass the SSH host/port to the client context. And you connect the SshClient just as you would a normal connection by passing the SSH hostname/port there.

SshClientContext ctx = new SshClientContext();
ctx.enableHTTPProxy("localhost", 9999);

try(SshClient ssh = new SshClient("localhost", 22, "lee", ctx)) {
  if(!ssh.isConnected()) {
    throw new IOException("HTTP proxy failed");
  }
  ssh.disconnect();
}

There are now multiple signatures of enableHTTPProxy that allow you to provide just the info you have/need.

Full support for SOCKS has also been completed and committed to our hotfix branch so will be ported to the open-source version in due course.

jamoros commented 2 years ago

Wonderful!! Looking forward to the release.

jamoros commented 2 years ago

Hello! When is the next release due? Still waiting to get to use this new feature. Thank you!!

ludup commented 2 years ago

The SNAPSHOT should already be in the maven repositories as they build automatically. Do you use maven?

jamoros commented 2 years ago

Yes, I use Maven but its not returning the dependencies


---------------< mavericksftpclient:MaverickSftpClient >----------------
Building MaverickSftpClient 1.0-SNAPSHOT
--------------------------------[ jar ]---------------------------------
The POM for com.sshtools:maverick-synergy-client:jar:3.0.7-SNAPSHOT is missing, no dependency information available
ludup commented 2 years ago

Did you add the maven snapshots repository?

<!-- You may also need this repository if the version is a SNAPSHOT -->
<repository>
   <id>oss-snapshots</id>
   <url>https://oss.sonatype.org/content/repositories/snapshots</url>
   <snapshots>
      <enabled>true</enabled>
   </snapshots>
   <releases>
      <enabled>false</enabled>
   </releases>
</repository>

There will be a final release towards the end of the month.

jamoros commented 2 years ago

Hmm something weird, I thought it was on my end

Failed to execute goal on project MaverickSftpClient: Could not resolve dependencies for project mavericksftpclient:MaverickSftpClient:jar:1.0-SNAPSHOT: Could not find artifact com.sshtools:maverick-synergy-client:jar:3.0.7-SNAPSHOT -> [Help 1]

ludup commented 2 years ago

Did you use -U switch to force updates.

On Wed, 9 Mar 2022, 19:59 jamoros, @.***> wrote:

Hmm something weird, I thought it was on my end

Failed to execute goal on project MaverickSftpClient: Could not resolve dependencies for project mavericksftpclient:MaverickSftpClient:jar:1.0-SNAPSHOT: Could not find artifact com.sshtools:maverick-synergy-client:jar:3.0.7-SNAPSHOT -> [Help 1]

— Reply to this email directly, view it on GitHub https://github.com/sshtools/maverick-synergy/issues/38#issuecomment-1063311902, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABRZRY5DSGABK53RKFG2GZ3U7D7JLANCNFSM5OM2I4IQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

jamoros commented 2 years ago

Yeah Ive tried that, Not sure why its giving me issues. I thought it was a conex issue but its not.

jamoros commented 2 years ago

Can you please verify the SNAPSHOT's are uploaded? Ive tried everything on my end, Im able to connect to the site, but it keeps saying 3.0.7-SNAPSHOT is unavailable.

I don't see it listed here either: https://mvnrepository.com/artifact/com.sshtools/maverick-synergy-client

ludup commented 2 years ago

The build on 24th February was the last successful build which appears to match above with when I commited the changes. I've merged a bunch of changes from our hotfix repository today for the end of March release and these are now building and will be deployed shortly.

Worst case scenario, you can always clone and mvn clean install with maven to build it locally :|

jamoros commented 2 years ago

I used your worst case scenario and built the develop branch locally and was able to get the code to work! Now we're able to login using our proxy. I'll keep this ticket open until the release and our release and then I will close it, in case I find any nuances.

Thank you!!

jamoros commented 2 years ago

Hello, when is the release with the proxy code going to be deployed? Thanks!

ludup commented 2 years ago

The 3.0.7 release is now available.