-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
I'm trying to proxy all traffic (other than that destined for a private IP) from the local machine through shadowsocks. That is to say, sslocal
is running on the system that I want outgoing traffic to be proxied on, and not a separate system/router. Initially I was using shadowsocks like this: sslocal -b "127.0.0.1:1080" --protocol redir -s "192.168.x.y:8388" -m none --tcp-redir "redirect"
, with iptables rules taken from redsocks (and only slightly modified), i.e.:
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:REDSOCKS - [0:0]
-A OUTPUT -p tcp -j REDSOCKS
-A REDSOCKS -d 0.0.0.0/8 -j RETURN
-A REDSOCKS -d 10.0.0.0/8 -j RETURN
-A REDSOCKS -d 127.0.0.0/8 -j RETURN
-A REDSOCKS -d 169.254.0.0/16 -j RETURN
-A REDSOCKS -d 172.16.0.0/12 -j RETURN
-A REDSOCKS -d 192.168.0.0/16 -j RETURN
-A REDSOCKS -d 224.0.0.0/4 -j RETURN
-A REDSOCKS -d 240.0.0.0/4 -j RETURN
-A REDSOCKS -p tcp -j REDIRECT --to-ports 1080
COMMIT
This works, but obviously only proxies TCP traffic. As I'd like to also proxy UDP, I went looking first for what iptables rules should look like, and found this script, which I modified slightly as I'm not trying to bypass the GFW:
#!/bin/bash
iptables-save | grep -v shadowsocks- | iptables-restore
SHADOWSOCKS_REDIR_IP=127.0.0.1
SHADOWSOCKS_REDIR_PORT=1080
readonly IPV4_RESERVED_IPADDRS="\
0/8 \
10/8 \
127/8 \
172.16/12 \
169.254/16 \
192.168/16 \
224/4 \
240/4 \
255.255.255.255/32 \
"
## TCP+UDP
# Strategy Route
ip -4 rule del fwmark 0x1 table 803
ip -4 rule add fwmark 0x1 table 803
ip -4 route del local 0.0.0.0/0 dev lo table 803
ip -4 route add local 0.0.0.0/0 dev lo table 803
# TPROXY for LAN
iptables -t mangle -N shadowsocks-tproxy
# Skip LoopBack, Reserved
for addr in ${IPV4_RESERVED_IPADDRS}; do
iptables -t mangle -A shadowsocks-tproxy -d "${addr}" -j RETURN
done
# Bypass LAN data
iptables -t mangle -A shadowsocks-tproxy -m addrtype --dst-type LOCAL -j RETURN
# Bypass sslocal's outbound data
iptables -t mangle -A shadowsocks-tproxy -m mark --mark 0xff/0xff -j RETURN
# UDP: TPROXY UDP to SS's port
iptables -t mangle -A shadowsocks-tproxy -p udp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01
# TCP: TPROXY TCP to SS's port
iptables -t mangle -A shadowsocks-tproxy -p tcp -j TPROXY --on-ip ${SHADOWSOCKS_REDIR_IP} --on-port ${SHADOWSOCKS_REDIR_PORT} --tproxy-mark 0x01/0x01
# TPROXY for Local
iptables -t mangle -N shadowsocks-tproxy-mark
# Skip LoopBack, Reserved
for addr in ${IPV4_RESERVED_IPADDRS}; do
iptables -t mangle -A shadowsocks-tproxy-mark -d "${addr}" -j RETURN
done
# TCP: conntrack
iptables -t mangle -A shadowsocks-tproxy-mark -p tcp -m conntrack --ctdir REPLY -j RETURN
# Bypass sslocal's outbound data
iptables -t mangle -A shadowsocks-tproxy-mark -m mark --mark 0xff/0xff -j RETURN
# UDP: Set MARK and reroute
iptables -t mangle -A shadowsocks-tproxy-mark -p udp -j MARK --set-xmark 0x01/0xffffffff
# TCP: Set MARK and reroute
iptables -t mangle -A shadowsocks-tproxy-mark -p tcp -j MARK --set-xmark 0x01/0xffffffff
# Apply TPROXY to LAN
iptables -t mangle -A PREROUTING -p udp -j shadowsocks-tproxy
iptables -t mangle -A PREROUTING -p tcp -j shadowsocks-tproxy
#iptables -t mangle -A PREROUTING -p udp -m addrtype ! --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy
# Apply TPROXY for Local
iptables -t mangle -A OUTPUT -p udp -j shadowsocks-tproxy-mark
iptables -t mangle -A OUTPUT -p tcp -j shadowsocks-tproxy-mark
#iptables -t mangle -A OUTPUT -p udp -m addrtype --src-type LOCAL ! --dst-type LOCAL -j shadowsocks-tproxy-mark
As this uses TPROXY, I changed my shadowsocks command a bit too: sslocal -b "127.0.0.1:1080" --protocol redir -s "192.168.x.y:8388" -m none -U --tcp-redir "tproxy" --udp-redir "tproxy" --outbound-fwmark 255
(and yes, I remembered to add -U
to the system running ssserver
as well). I cleared the redsocks rules out of iptables, ran the script for the new rules, and restarted sslocal
with the new command.
However, this does not work for proxying, either TCP or UDP. I also tried uncommenting those last two rules that are commented out (as I'm not sure if they need to be there or not), and rerunning the script, but it didn't seem to make any difference. So, does anyone know what I'm doing wrong?