-
Notifications
You must be signed in to change notification settings - Fork 506
Open
Labels
Description
Describe the bug
SOCKS5 CONNECT responses are not synchronized with the upstream connection outcome.
This can impact multiple proxy clients/tools (for example nc, nmap -sT, and other SOCKS-aware scanners using proxychains), where closed/unreachable targets may appear open or behave as if the connection is established.
This can result in the wstunnel becoming unresponsive and unable to any additional connections to the socks port.
The minimal deterministic reproduction below uses nc only:
- direct/local
ncto a closed port fails immediately (expected) proxychains + ncto the same closed port reports success and/or hangs (unexpected)
To Reproduce
- Start server:
./target/release/wstunnel server ws://127.0.0.1:18080 --log-lvl=DEBUG
- Start client exposing local SOCKS5:
./target/release/wstunnel client -R socks5://127.0.0.1:18888 ws://127.0.0.1:18080 --log-lvl=DEBUG
- Prepare proxychains config:
cat >/tmp/proxychains-wstunnel.conf <<'EOF' strict_chain proxy_dns quiet_mode tcp_read_time_out 5000 tcp_connect_time_out 5000 [ProxyList] socks5 127.0.0.1 18888 EOF
- Pick a known closed local port (example:
19998) and verify directncfails:nc -vz 127.0.0.1 19998
- Probe the same closed port through SOCKS proxy:
proxychains4 -f /tmp/proxychains-wstunnel.conf nc -vz 127.0.0.1 19998
- Closed port through the proxy appears open.
Expected behavior
- Direct/local
ncto a closed port should fail. - Proxied
proxychains + ncto the same closed port should also fail. - SOCKS5 success reply (
REP=0x00) should only be sent after upstream connect succeeds. - Closed/unreachable endpoints should return SOCKS5 failure promptly.
Your wstunnel setup
Commit Hash Of Build: 9d0ec3f
Server
./target/release/wstunnel server ws://127.0.0.1:18080 --log-lvl=DEBUG2026-02-07T03:15:55.137822Z INFO wstunnel: Starting wstunnel server v10.5.2 with config WsServerConfig { socket_so_mark: SoMark, bind: 127.0.0.1:18080, websocket_ping_frequency: Some(30s), timeout_connect: 10s, websocket_mask_frame: false, restriction_config: None, tls: false, remote_server_idle_timeout: 180s, mTLS: false }
2026-02-07T03:15:55.137887Z DEBUG wstunnel: Restriction rules: RestrictionsRules {
restrictions: [
RestrictionConfig {
name: "Allow All",
match: [
Any,
],
allow: [
Tunnel(
AllowTunnelConfig {
protocol: [],
port: [],
host: Regex(
"^.*$",
),
cidr: [
0.0.0.0/0,
::/0,
],
},
),
ReverseTunnel(
AllowReverseTunnelConfig {
protocol: [],
port: [],
port_mapping: {},
cidr: [
0.0.0.0/0,
::/0,
],
unix_path: Regex(
"^.*$",
),
},
),
],
},
],
}
2026-02-07T03:15:55.137987Z INFO wstunnel::tunnel::server::server: Starting wstunnel server listening on 127.0.0.1:18080
2026-02-07T03:16:06.548640Z INFO cnx{peer="127.0.0.1:65165"}: wstunnel::tunnel::server::server: Accepting connection
2026-02-07T03:16:06.548865Z INFO cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::server::server: Tunnel accepted due to matched restriction: Allow All
2026-02-07T03:16:06.548895Z INFO cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::protocols::socks5::tcp_server: Starting SOCKS5 server listening cnx on 127.0.0.1:18888 with credentials None
2026-02-07T03:17:00.742817Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: incoming connection from peer 127.0.0.1:65168 @ 127.0.0.1:18888
2026-02-07T03:17:00.742859Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: Handshake headers: [version: 5, methods len: 1]
2026-02-07T03:17:00.742870Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: methods supported sent by the client: [0]
2026-02-07T03:17:00.742875Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: Reply with method 0
2026-02-07T03:17:00.742957Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: Request: [version: 5, command: 1, rev: 0, address_type: 1]
2026-02-07T03:17:00.742965Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::util::target_addr: Address type `IPv4`
2026-02-07T03:17:00.742972Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: Request target is 127.0.0.1:19998
2026-02-07T03:17:00.742978Z DEBUG cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: fast_socks5::server: Domain won't be resolved because `dns_resolve`'s config has been turned off.
2026-02-07T03:17:00.743024Z INFO cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::server::server: connected to ReverseSocks5 { timeout: Some(30s), credentials: None } 127.0.0.1:19998
2026-02-07T03:17:00.743138Z INFO cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::transport::io: Closing local => remote tunnel
2026-02-07T03:17:00.743167Z INFO cnx{peer="127.0.0.1:65165"}:tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::transport::io: Closing local <= remote tunnel
2026-02-07T03:17:00.743638Z INFO cnx{peer="127.0.0.1:65170"}: wstunnel::tunnel::server::server: Accepting connection
2026-02-07T03:17:00.743761Z INFO cnx{peer="127.0.0.1:65170"}:tunnel{id="019c361a-52c7-7f03-9e44-33d5591795da" remote="127.0.0.1:18888"}: wstunnel::tunnel::server::server: Tunnel accepted due to matched restriction: Allow AllClient
./target/release/wstunnel client -R socks5://127.0.0.1:18888 ws://127.0.0.1:18080 --log-lvl=DEBUG2026-02-07T03:16:06.548182Z INFO wstunnel: Starting wstunnel client v10.5.2
2026-02-07T03:16:06.548267Z INFO wstunnel::protocols::tcp::server: Opening TCP connection to 127.0.0.1:18080
2026-02-07T03:16:06.548309Z DEBUG wstunnel::protocols::tcp::server: Connecting to 127.0.0.1:18080
2026-02-07T03:16:06.548482Z DEBUG wstunnel::protocols::tcp::server: Connected to tcp endpoint 127.0.0.1:18080, aborted all other connection attempts
2026-02-07T03:16:06.548550Z DEBUG tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::transport::websocket: with HTTP upgrade request Request { method: GET, uri: /v1/events, version: HTTP/1.1, headers: {"host": "127.0.0.1:18080", "upgrade": "websocket", "connection": "upgrade", "sec-websocket-key": "RnDQn67rYpudaI+t2xP8PA==", "sec-websocket-version": "13", "sec-websocket-protocol": "v1, authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOWMzNjE5LTdmMTQtNzI0MC05MjEyLTNjMjA1NDNkN2U3OSIsInAiOnsiUmV2ZXJzZVNvY2tzNSI6eyJ0aW1lb3V0Ijp7InNlY3MiOjMwLCJuYW5vcyI6MH0sImNyZWRlbnRpYWxzIjpudWxsfX0sInIiOiIxMjcuMC4wLjEiLCJycCI6MTg4ODh9.TWuBtVyMnULgMfLTXWthWNTbfwT2ZV5JQCajp2qDE4s"}, body: Empty }
2026-02-07T03:17:00.743229Z DEBUG tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::client::client: Server response: Parts { status: 101, version: HTTP/1.1, headers: {"connection": "upgrade", "upgrade": "websocket", "sec-websocket-accept": "Lajh7apPgvJqsIBZi55BndnNOQk=", "cookie": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMCIsInAiOnsiVGNwIjp7InByb3h5X3Byb3RvY29sIjpmYWxzZX19LCJyIjoiMTI3LjAuMC4xIiwicnAiOjE5OTk4fQ.t_SQooaArNcATzxti-90sRqGj03Fz4qeo-ReZtTbkbU", "sec-websocket-protocol": "v1", "date": "Sat, 07 Feb 2026 03:17:00 GMT"} }
2026-02-07T03:17:00.743307Z INFO tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::protocols::tcp::server: Opening TCP connection to 127.0.0.1:19998
2026-02-07T03:17:00.743339Z DEBUG wstunnel::protocols::tcp::server: Connecting to 127.0.0.1:19998
2026-02-07T03:17:00.743421Z DEBUG tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::protocols::tcp::server: Cannot connect to tcp endpoint 127.0.0.1:19998 reason Connection refused (os error 61)
2026-02-07T03:17:00.743443Z ERROR tunnel{id="019c3619-7f14-7240-9212-3c20543d7e79" remote="127.0.0.1:18888"}: wstunnel::tunnel::client::client: Cannot connect to Some(RemoteAddr { protocol: Tcp { proxy_protocol: false }, host: Ipv4(127.0.0.1), port: 19998 }): Cannot connect to tcp endpoint 127.0.0.1:19998 reason Some(Os { code: 61, kind: ConnectionRefused, message: "Connection refused" })
2026-02-07T03:17:00.743505Z INFO wstunnel::protocols::tcp::server: Opening TCP connection to 127.0.0.1:18080
2026-02-07T03:17:00.743532Z DEBUG wstunnel::protocols::tcp::server: Connecting to 127.0.0.1:18080
2026-02-07T03:17:00.743617Z DEBUG wstunnel::protocols::tcp::server: Connected to tcp endpoint 127.0.0.1:18080, aborted all other connection attempts
2026-02-07T03:17:00.743656Z DEBUG tunnel{id="019c361a-52c7-7f03-9e44-33d5591795da" remote="127.0.0.1:18888"}: wstunnel::tunnel::transport::websocket: with HTTP upgrade request Request { method: GET, uri: /v1/events, version: HTTP/1.1, headers: {"host": "127.0.0.1:18080", "upgrade": "websocket", "connection": "upgrade", "sec-websocket-key": "JomwJ6cEvVzsn7o25R2cpw==", "sec-websocket-version": "13", "sec-websocket-protocol": "v1, authorization.bearer.eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjAxOWMzNjFhLTUyYzctN2YwMy05ZTQ0LTMzZDU1OTE3OTVkYSIsInAiOnsiUmV2ZXJzZVNvY2tzNSI6eyJ0aW1lb3V0Ijp7InNlY3MiOjMwLCJuYW5vcyI6MH0sImNyZWRlbnRpYWxzIjpudWxsfX0sInIiOiIxMjcuMC4wLjEiLCJycCI6MTg4ODh9.anawOVjhnlEvxWRnhbBtb-60aKqHjm00H02yKmjx0sg"}, body: Empty }Non-proxied
nc -vz 127.0.0.1 19998localhost [127.0.0.1] 19998: Connection refusedProxychains + Netcat
proxychains4 -f /tmp/proxychains-wstunnel.conf nc -vz 127.0.0.1 19998[proxychains] config file found: /tmp/proxychains-wstunnel.conf
[proxychains] preloading /opt/homebrew/Cellar/proxychains-ng/4.17/lib/libproxychains4.dylib
[proxychains] DLL init: proxychains-ng 4.17
127.0.0.1 [127.0.0.1] 19998 openDesktop (please complete the following information):
- Linux: Fedora 43
- Mac: Tahoe 26.2
Additional context
This issue was drafted with assistance from ChatGPT 5.3 Codex; I have manually reviewed and tested before submitting.
Reactions are currently unavailable