Skip to content

destination parameter -d behaves differently with local proxy vs remote proxy #84

Description

@FrostKiwi

This issue stems from the investigating done in #81. I'm very happy with my pure nginx setup which works in many challenging situations, but I believe there to be a bug in proxytunnel and it's -d parameter or a weird interaction with the intermediate proxy jump, which took a while to figure out.

I have ssh on Port 22 and had both used apache and now nginx with https://github.com/chobits/ngx_http_proxy_connect_module. Both nginx and apache were configured to encrypt with HTTPs and pass the HTTP_CONNECT packets 127.0.0.1:22 (which is not port forwarded).

When there is no corporate packet sniffing firewall in the way, the connection command looks like proxytunnel -E -p domain.com:443 -d 127.0.0.1:22. The header says:

Tunneling to 127.0.0.1:22 (destination)
Communication with local proxy:
 -> CONNECT 127.0.0.1:22 HTTP/1.1
 -> HOST: domain.com

Works for nginx and apache. Now we get to the corporate firewall case, which we tunnel through, so the command becomes proxytunnel -X -p corporate.com:8888 -r domain.com:443 -d 127.0.0.1:22. Here is where the weirdness begins. The header looks like:

Connected to corporate.com:8888 (local proxy)

Tunneling to domain.com:443 (remote proxy)
Communication with local proxy:
 -> CONNECT domain.com:443 HTTP/1.1
 -> Host: domain.com:443
 -> Proxy-Connection: Keep-Alive
 <- HTTP/1.1 200 Connection established

 <-

Set SNI hostname to domain.com

Tunneling to 127.0.0.1:22 (destination)
Communication with remote proxy:
 -> CONNECT 127.0.0.1:22 HTTP/1.1
 -> Host: 127.0.0.1:22
 -> Proxy-Connection: Keep-Alive
 <- HTTP/1.1 405 Not Allowed

HTTP return code: 405 Not Allowed
 <- Server: nginx

We land at the destination, but get denied. But looking at the communication with the remote proxy, we see domain.com:443 missing. For whatever reason, this is ok with apache, but not with nginx, both configured with the same ruleset.

Changing the destination parameter fixes this though. proxytunnel -X -p corporate.com:8888 -r domain.com:443 -d domain.com:22

Connected to corporate.com:8888 (local proxy)

Tunneling to domain.com:443 (remote proxy)
Communication with local proxy:
 -> CONNECT domain.com:443 HTTP/1.1
 -> Host: domain.com:443
 -> Proxy-Connection: Keep-Alive
 <- HTTP/1.1 200 Connection established

 <-

Set SNI hostname to domain.com

Tunneling to domain.com:22 (destination)
Communication with remote proxy:
 -> CONNECT domain.com:22 HTTP/1.1
 -> Host: domain.com:22
 -> Proxy-Connection: Keep-Alive
 <- HTTP/1.1 200 Connection Established

 <- Proxy-agent: nginx

Tunnel established.
SSH-2.0-OpenSSH_9.7

Now the HOST in the Header is correct and the connection works with nginx and the corporate firewall. Still, this is werid, as the destination is actually incorrect. There is no domain.com:22 to connect to, such a port is not open, only the local 127.0.0.1:22, but it works out. This must be some kind of bug in how -d works with local proxy vs remote proxy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions