shadowsocks / shadowsocks-rust

A Rust port of shadowsocks
https://shadowsocks.org/
MIT License
8.71k stars 1.19k forks source link

`sslocal` redir not working on OpenWRT #1713

Closed Jason0214 closed 1 month ago

Jason0214 commented 1 month ago

Environment

OpenWRT 23.05.4 kernel 5.15.162 shadowsocks-rust 1.20.3

Client Config:

  ...
  "mode": "tcp_and_udp",
  "locals": [
          {                                   
            "protocol": "http", 
            "local_address": "127.0.0.1", 
            "local_port": 1087, 
         },
          {                                   
            "protocol": "redir",             
            "tcp_redir": "redirect",         
            "udp_redir": "tproxy",
            "local_address": "192.168.1.1", 
            "local_port": 1080,   
         },
  ]

Server config is all default with "mode": "tcp_and_udp".

http_proxy=http://127.0.0.1:1087 curl www.google.com -v works, however, http_proxy=http://192.168.1.1:1080 curl www.google.com -v stuck at

> GET http://www.google.com/ HTTP/1.1
> Host: www.google.com
> User-Agent: curl/8.7.1
> Accept: */*
> Proxy-Connection: Keep-Alive
> 

then timeout with curl: (52) Empty reply from server.

Client log

2024-10-13T08:09:28.96725047Z TRACE   tokio-runtime-worker ThreadId(02) shadowsocks_service::local::redir::tcprelay: /project/crates/shadowsocks-service/src/local/redir/tcprelay/mod.rs:136: got connection 192.168.1.1:38930    
2024-10-13T08:09:29.047388484Z TRACE   tokio-runtime-worker ThreadId(02) shadowsocks::relay::tcprelay::proxy_stream::client: /project/crates/shadowsocks/src/relay/tcprelay/proxy_stream/client.rs:135: connected tcp remote <IP:Port> (outbound: <IP:Port>) with ConnectOpts { fwmark: None, bind_local_addr: None, bind_interface: None, tcp: TcpSocketOpts { send_buffer_size: None, recv_buffer_size: None, nodelay: false, fastopen: false, keepalive: Some(15s), mptcp: false }, udp: UdpSocketOpts { mtu: None } }    
2024-10-13T08:09:29.0474779Z TRACE   tokio-runtime-worker ThreadId(02) shadowsocks::relay::tcprelay::crypto_io: /project/crates/shadowsocks/src/relay/tcprelay/crypto_io.rs:366: generated AEAD cipher salt b""    
2024-10-13T08:09:29.04754036Z DEBUG   tokio-runtime-worker ThreadId(02) shadowsocks_service::local::utils: /project/crates/shadowsocks-service/src/local/utils.rs:29: established tcp tunnel 192.168.1.1:38930 <-> 192.168.1.1:1080 through sever <IP:Port> (outbound: <IP:Port>)  

Server log

2024-10-13T16:09:29.150755599+08:00 TRACE tokio-runtime-worker ThreadId(02) shadowsocks_service::server::tcprelay: /project/crates/shadowsocks-service/src/server/tcprelay.rs:191: accepted tcp client connection <IP:Port>, establishing tunnel to 192.168.1.1:1080 

Seems nothing special..

TCP dump from the server for the HTTP request:

listening on if, link-type EN10MB (Ethernet), snapshot length 262144 bytes
16:13:22.671288 IP <ClientIP.port> > <ServerIP.port>: Flags [S], seq 2052569281, win 64240, options [mss 1380,sackOK,TS val 3013133292 ecr 0,nop,wscale 7], length 0
16:13:22.671344 IP <ServerIP.port> > <ClientIP.port>: Flags [S.], seq 3690860066, ack 2052569282, win 64768, options [mss 1420,sackOK,TS val 3597929168 ecr 3013133292,nop,wscale 6], length 0
16:13:22.746243 IP <ClientIP.port> > <ServerIP.port>: Flags [.], ack 1, win 502, options [nop,nop,TS val 3013133368 ecr 3597929168], length 0
16:13:22.747743 IP <ClientIP.port> > <ServerIP.port>: Flags [P.], seq 1:202, ack 1, win 502, options [nop,nop,TS val 3013133369 ecr 3597929168], length 201
16:13:22.747801 IP <ServerIP.port> > <ClientIP.port>: Flags [.], ack 202, win 1009, options [nop,nop,TS val 3597929245 ecr 3013133369], length 0

It seem the TCP handshake is established?

I start losing ideas of how to debugging further. Any idea on how to proceed? I had a slight concern if the firewall on OpenWRT messed up with the redir, but not sure how to check.

Thanks in advance for any suggestions/ideas.

zonyitoo commented 1 month ago

Your test cases were all about HTTP proxy protocol, so there is nothing about redir.

however, http_proxy=http://192.168.1.1:1080 curl www.google.com -v stuck at

Of course it would stuck, your HTTP local server was listening on 127.0.0.1:1087, not 192.168.1.1:1080.

zonyitoo commented 1 month ago

On the other hand, if you want to use redir in your environment, you should set iptables rules to redirect TCP and UDP packets to 192.168.1.1:1080. Please search more about the redir mode about what it was actually doing and how to make it work.

iptables rules example could be found at https://github.com/shadowsocks/shadowsocks-rust/blob/master/configs/iptables_mixed.sh . These rules for TCP with redirect mode and UDP with tproxy mode.