Closed cowwoc closed 5 months ago
This setting is for the initial tunnel established between the client and the socks4 proxy server, before the request is sent.
secure=false
is a socks4 proxy server using a scheme of http
and no ssl.
secure=true
is a socks4 proxy server using a scheme of https
and mandatory ssl.
If you have a tunnel that's unencrypted between the client and the socks4 proxy server, but a request that's https, then the initial connection between the client and the socks4 proxy server will show the proxy protocol to establish the connection in a non-encrypted way, but the rest of the conversation is encrypted (the client negotiates the TLS connection between itself and the destination server. the socks4 proxy server is just forwarding bytes back and forth)
That help?
The most common setup we encounter is secure=false
btw.
There's really no point in encrypting twice.
@joakime If I understood you correctly, given:
When secure=false
the request and response sent between the proxy client and server will be unencrypted but the communication between the proxy and destination servers might be encrypted if the request is HTTPS.
Is that correct?
@cowwoc not sure I understand.
You start with an HttpClient that wants to talk to a destination making a request for a specific resource, using HTTP.
Lets say you have ...
This now becomes ...
Not sure how this fits in your scenario.
@joakime I think we're on the same page.
My understanding is that if secure=false
then the communication between HttpClient and the proxy server will remain unencrypted, regardless of whether the proxied request is HTTP or HTTPS.
Meaning, if I issue an HTTPS request to eclipse.org through proxy.machine.com then:
Is that correct?
My understanding is that the proxy acts as a man-in-the-middle. Are you saying otherwise? Will HttpClient somehow communicate with eclipse.org over an encrypted tunnel even if secure=false
? Thank you.
Meaning, if I issue an HTTPS request to eclipse.org through proxy.machine.com then:
- HttpClient will send an (unencrypted) HTTP request to proxy.machine.com
Incorrect, there's no HTTP request here. It's just the simple SOCKS4 proxy protocol. The only information passed to the proxy.machine.com at this step is ...
This "connect" is just a simple tcp connect from proxy.machine.com to eclipse.org:9999, nothing else, no TLS, no data is sent to eclipse.org:9999.
At this point HttpClient is free to pass anything to proxy.machine.com and it will forward those bytes unaltered to eclipse.org:9999 (and vice versa back to HttpClient).
In fact, it doesn't even have to be HTTP/HTTPS, it can be any protocol supported by your SOCKS4. A typical SOCKS4 server supports anything built on top of TCP.
- proxy.machine.com will issue an (encrypted) HTTPS request to eclipse.org based on the request from step 1.
Also incorrect, the proxy.machine.com doesn't issue HTTP or HTTPS. That's for the HttpClient to do, and it will only do that once the TLS handshake is complete once the tunnel is established. Making proxy.machine.com only aware of the destination IP and port, but not privy to any other information, definitely not the HTTP request details.
- eclipse.org will respond with an encrypted response.
Nope, the entire encrypted conversation is between HttpClient and eclipse.org, proxy.machine.com is not involved there, it's merely passing bytes back and forth. It was never involved in the TLS negotiation or the HTTP exchange.
- proxy.machine.com will decrypt the response, and forward it to HttpClient as an (unencrypted) HTTP response.
proxy.machine.com does not encrypt/decrypt between itself and eclipse.org. proxy.machine.com can only encrypt/decrypt between the HttpClient and itself. And only for the purposes of establishing the "connect" (aka tunnel) All traffic in/out of proxy.machine.com and eclipse.org are just raw bytes back and forth, no extra work is performed by proxy.machine.com on those bytes (including encryption).
Here's the basics of SOCKS ...
If we put HTTP into this mix, we get ...
If we encrypt both connections we get this ...
socks-with-tls-both-sides-with-http.puml
To conclude, the Socks4Proxy "secure" setting is about the connection between the Client and the Socks Proxy, it has no relationship or behavior with any connection to the target server.
You could even have a setup where the connection between the Client and Socks Proxy is encrypted, but the traffic from the Socks Proxy to the Target Server is NOT encrypted. (that's a perfectly valid and common scenario)
Thank you.
So if I understand correctly, secure=true
protects against man-in-the-middle attacks between the proxy and myself. It prevents third parties from finding out which servers I am connecting to and/or changing which servers I connect to. Is that correct?
I'm still a bit confused about the socks handshake though. In the following scenario, who is the "client", "socks server" and "target server"?
ssh -N -D 9090 [USER]@[SERVER_IP]
where [SERVER IP]
is some arbitrary server that I designate as my proxy.X-Forwarded-For
contains the proxy's IP address.It sounds as if the machine I am SSHing into plays the role of both the "socks server" and "target server". Any website I hit through the proxy doesn't seem to be aware that some 3rd party is directing the calls behind the proxy. Am I wrong?
This issue has been automatically marked as stale because it has been a full year without activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically marked as stale because it has been a full year without activity. It will be closed if no further activity occurs. Thank you for your contributions.
Sorry for the late reply.
So if I understand correctly, secure=true protects against man-in-the-middle attacks between the proxy and myself. It prevents third parties from finding out which servers I am connecting to and/or changing which servers I connect to. Is that correct?
Correct.
If secure=true
, the client will encrypt the communication between the client and the proxy.
The client will connect to the proxy via TLS and validate the proxy certificate.
At this point, no MITM can decrypt that traffic.
What happens next is that the client will send to the proxy the information to establish the tunnel, and that information cannot be seen by a MITM.
In the following scenario, who is the "client", "socks server" and "target server"?
"Client" is the browser.
"Socks server" is the SOCKS proxy, so in your case SERVER_IP
.
"Target server" is the server name you put in the browser's address bar (in your case myexternalip.com
, etc.).
When you use the browser for myexternalip.com
, it will look at its configuration and see it has a proxy.
Rather than connecting to myexternalip.com
it will connect to the SOCKS proxy instead, and send to the SOCKS proxy a binary packet containing the target server information (host and port) to connect to.
Then the SOCKS proxy will establish a connection to myexternalip.com
and create a tunnel between the client and the target server: the client will send bytes to the proxy, the proxy will forward them to the target server, and viceversa.
If you are using https
in your browser, the browser will send encrypted bytes into the tunnel.
I'll update the javadocs of the relevant classes.
Target Jetty version(s)
11.0.8
Enhancement Description
Socks4Proxy has a constructor that takes a
boolean secure
argument. I'd love to understand the implication oftrue
andfalse
values for this parameter. All I know is that when I setsecure=true
I am no longer able to tunnel through a SOCKS proxy :)First, I'd like to understand what's insecure about
secure=false
. Secondly, I'd like to understand whysecure=true
is failing for me.What I'm doing:
I used Apache Mina to create a SOCKS proxy over SSH tunnel. I can connect
Socks4Proxy(secure=false)
to it, butsecure=true
fails. If I understood the meaning of this parameter then maybe I could circle back to the MINA guys and ask them what it would take to makesecure=true
work.