Description
This is a similar symptom to my earlier issue (#1473), but as the circumstances have drastically changed I thought I'd open a new issue. To summarize the changes, I am no longer running sslocal
on the host (Linux/iptables) machine; it's instead being run on my FreeBSD router which uses pf.
Obviously, this requires different firewall rules to work, but there is little if any documentation I could find for transparently proxying via pf within the shadowsocks-rust project. What I've done here is largely guesswork, but this is the rule I came up with to transparently proxy both TCP & UDP to sslocal
(and then on to ssserver
):
rdr on $int_if inet proto { tcp, udp } to !<private> -> 127.0.0.1 port 1080
sslocal
is being run on the router via the following command:
sslocal -b 127.0.0.1:1080 -U --protocol redir -s 192.168.x.y:8388 -m none --tcp-redir pf --udp-redir pf
...and finally, ssserver
is run with -U -m none -b 192.168.x.y:8388
This "works" in the sense that both TCP & UDP traffic are being redirected to sslocal
(unlike in #1473 where only TCP traffic was ever reaching sslocal
), which is then sending the traffic on to sserver
. However, once again, only TCP traffic is being fully proxied correctly.
UDP traffic does arrive at sslocal
without any doubt, as it shows up when running sslocal
with -vvv
like so (timestamps removed for brevity, and the host system's address being substituted here with simply <host>
):
TRACE tokio-runtime-worker ThreadId(05) shadowsocks::relay::udprelay::proxy_socket: crates/shadowsocks/src/relay/udprelay/proxy_socket.rs:235: UDP server client send to 127.0.0.1:1080, control: UdpSocketControlData { client_session_id: 7043831170210357480, server_session_id: 0, packet_id: 1, user: None }, payload length 96 bytes, packet length 103 bytes
TRACE tokio-runtime-worker ThreadId(05) shadowsocks_service::local::redir::udprelay: crates/shadowsocks-service/src/local/redir/udprelay/mod.rs:307: received UDP packet from <host>:44849, destination 127.0.0.1:1080, length 96 bytes
TRACE tokio-runtime-worker ThreadId(05) shadowsocks_service::local::net::udp::association: crates/shadowsocks-service/src/local/net/udp/association.rs:433: udp relay <host>:44849 -> 127.0.0.1:1080 (proxied) with 96 bytes
This traffic is then forwarded on to ssserver
, which I can verify by watching outgoing traffic on the router via tcpdump
. After they arrive at ssserver
though, they fail to reach the internet, so clearly something isn't configured correctly.
My best guess as to what is happening here, based on the logs, is that sslocal
thinks the destination of the UDP packet is 127.0.0.1
(i.e. the address that sslocal
is running on and where incoming UDP traffic on the router is redirected to), and fails to retrieve the original destination address before pf's rdr
rule took effect. This wouldn't surprise me as my rdr
rule is complete guesswork, so I assume I'm missing something.
If that is indeed the problem, what should the rdr
rule look like to transparently proxy UDP traffic with pf? Or am I barking up the wrong tree, and is the problem due to something else entirely?