Open hunmar opened 3 months ago
I'm not sure how to implement this logic. Currently, I'm using this logic: https://github.com/purkylin/proxy-nio/blob/92fbd9564b90b6bd7c270596bb03d53df7cf8b34/Sources/proxy-nio/socks5/SocksHandler.swift#L55
Can you guide me on how to do it? because I don't have experience on SOCKS
Current Behavior
When running a command like curl -x socks5://localhost:{proxyman port} google.com -H 'Host: foobar.com'
, Proxyman attempts to route the request based on the Host header (foobar.com). If foobar.com is not reachable, the connection fails.
Expected Behavior The request should be routed to the destination specified in the SOCKS5 proxy request (google.com), regardless of what is in the Host header.
Ideas To get the expected behavior, you should make sure the routing uses the address provided by the SOCKS5 proxy (request.addr.host! and request.port) instead of anything in the Host header.
I guess it'll look something like this
case .command(let request):
logger.debug("receive command")
switch request.cmd {
case .connect:
// Route to the SOCKS-provided host and port, not the HTTP Host header
connectTo(host: request.addr.host!, port: request.port, context: context)
case .bind:
// Handle unsupported BIND command
let response = SocksResponse.command(type: .unsupported, addr: SocksAddress.zero(for: .v4), port: 0)
context.write(self.wrapOutboundOut(response), promise: nil)
case .udp:
// Handle UDP if needed
beginUDP(context: context)
}
This way, the traffic should go to the correct destination, like google.com in the example, and not to whatever is in the Host header.
@hunmar I assume you're talking about the External Proxy with SOCKS Proxy, right?
It means:
Your Remote SOCKS Server can define the SOCKS Destination, and Proxyman should follow it, instead of using the Host
.
Or you're talking about the SOCKS Proxy in Proxyman (Tools menu -> Proxy Setting -> SOCKS Proxy).
If it's how can I defined the SOCKS Destination?
Or you're talking about the SOCKS Proxy in Proxyman (Tools menu -> Proxy Setting -> SOCKS Proxy).
yes, that's the case.
In other words, in case of calling
curl -x socks5://localhost:{proxyman port} google.com -H 'Host: foobar.com'
Proxyman uses value described in Host
header, and goes to foobar.com
And we expect Proxyman to go to google.com
and just forward Host header
Tested with curl -v -x socks5://localhost:8889 https://httpbin.org/get?id=123 -H 'Host: www.google.com
and Proxyman SOCKS Server works as expected behavior.
HTTPS://httpbin.org/get?id=123
and the Host is www.google.comHowever, if it's HTTP, curl -v -x socks5://localhost:8889 httpbin.org/get?id=123 -H 'Host: www.google.com
, Proxyman will send the request to www.google.com
.
From what I debug, the problem is cURL doesn't send the entire URL (httpbin.org/get?id=123), instead, it sends /get?id=123
-> Proxyman gets the Host Header and connects to this server.
From what I debug, the problem is cURL doesn't send the entire URL (httpbin.org/get?id=123), instead, it sends /get?id=123 -> Proxyman gets the Host Header and connects to this server.
The entire URL will not necessarily be sent according to HTTP protocol. Any way the target IP will be send by SOCKS5 request message. See RFC.
Tested with
curl -v -x socks5://localhost:8889 https://httpbin.org/get?id=123 -H 'Host: www.google.com
and Proxyman SOCKS Server works as expected behavior.* Please note that the URL is `HTTPS://httpbin.org/get?id=123` and the Host is [www.google.com](http://www.google.com)
However, if it's HTTP,
curl -v -x socks5://localhost:8889 httpbin.org/get?id=123 -H 'Host: www.google.com
, Proxyman will send the request towww.google.com
.From what I debug, the problem is cURL doesn't send the entire URL (httpbin.org/get?id=123), instead, it sends
/get?id=123
-> Proxyman gets the Host Header and connects to this server.
Hi! This issue is still actual. RFC assumes that the address of the target server will be transmitted as part of the message (not as a "Host" header). Please let me know if this problem cannot be fixed due to technical reasons 🙏
@acelost not sure how to fix it. Proxyman is using this code (https://github.com/purkylin/proxy-nio/blob/92fbd9564b90b6bd7c270596bb03d53df7cf8b34/Sources/proxy-nio/socks5/SocksHandler.swift#L55) when making a SOCKS connection.
The code actually uses the DST.ADDR
from SOCKS Requests.
Good news: I'm able to reproduce the bug. I'm fixing it now 👍
@acelost @KasyanDiGris @ignatovSA @hunmar It's fixed with this Beta build: https://download.proxyman.io/beta/Proxyman_5.10.0_Fix_SOCKS5_issue.dmg
curl -x socks5://localhost:8889 google.com -H 'Host: foobar.com'
Here is the v2: https://download.proxyman.io/beta/Proxyman_5.10.0_Fix_SOCKS_issue_v2.dmg
https://download.proxyman.io/beta/Proxyman_5.10.0_Fix_SOCKS_issue_v2.dmg
@NghiaTranUIT It works as expected! Thank you very much! I'm really looking forward to the official release :)
Description
When using a SOCKS5 proxy with Proxyman, the traffic is incorrectly routed based on the Host header rather than the destination specified by the SOCKS proxy. This leads to incorrect proxy behavior, where traffic is not directed to the intended target but instead to whatever is specified in the Host header. This behavior undermines the purpose of using a SOCKS proxy and could result in incorrect routing and potential security issues.
Steps to Reproduce:
Environment