Last active
June 3, 2024 13:35
-
-
Save rsanden/ba29b8ea7d5d3bd482e717413a745243 to your computer and use it in GitHub Desktop.
tun2socks TCP+UDP user-wide proxy through shadowsocks and udpgw
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#--- Build tun2socks and udpgw (as the user who will use the proxy) --- | |
mkdir -p $HOME/src | |
cd $HOME/src | |
git clone "https://github.com/ambrop72/badvpn" | |
cd badvpn | |
mkdir -p build | |
cd build | |
export OUTDIR=$PWD | |
export SRCDIR=$(dirname $PWD) | |
export CC=gcc | |
export ENDIAN=little | |
bash $SRCDIR/compile-tun2socks.sh | |
bash $SRCDIR/compile-udpgw.sh | |
mkdir -p $HOME/bin/badvpn | |
cp tun2socks $HOME/bin/badvpn/ | |
cp udpgw $HOME/bin/badvpn/ | |
#--- We also need Shadowsocks --- | |
export GOPATH="$HOME/go" | |
go get "github.com/shadowsocks/shadowsocks-go" | |
go get "github.com/Yawning/chacha20" | |
go get "golang.org/x/crypto/blowfish" | |
go get "golang.org/x/crypto/cast5" | |
go get "golang.org/x/crypto/salsa20/salsa" | |
cd "$GOPATH/src/github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-local" | |
CGO_ENABLED=0 go build | |
cd "$GOPATH/src/github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server" | |
CGO_ENABLED=0 go build | |
# Do install -- remember to set SHADOWSOCKS_VERSION | |
SHADOWSOCKS_VERSION=1.2.1 | |
mkdir -p $HOME/bin/shadowsocks | |
cd $HOME/bin/shadowsocks | |
cp "$GOPATH/src/github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-local/shadowsocks-local" shadowsocks-local-linux64-${SHADOWSOCKS_VERSION} | |
cp "$GOPATH/src/github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-server/shadowsocks-server" shadowsocks-server-linux64-${SHADOWSOCKS_VERSION} | |
ln -sf shadowsocks-local-linux64-${SHADOWSOCKS_VERSION} shadowsocks-local | |
ln -sf shadowsocks-server-linux64-${SHADOWSOCKS_VERSION} shadowsocks-server | |
# Sample config file (same for client and server) -- "myserver.conf" | |
{ | |
"server":"machine1.example.com", | |
"server_port":8888, | |
"local_port":8080, | |
"password":"xxxxxxxxxxxx", | |
"timeout":600, | |
"method":"aes-256-cfb", | |
"fast_open": false, | |
"workers": 1 | |
} | |
# Server (with -u for UDP support -- though, I'm not sure if it can be used with tun2socks) | |
$HOME/bin/shadowsocks/shadowsocks-server -c $HOME/bin/shadowsocks/myserver.conf -u | |
# Client | |
$HOME/bin/shadowsocks/shadowsocks-local -c $HOME/bin/shadowsocks/myserver.conf | |
#--- Now, the start/stop script which proxifies a user ("foo" in this case) --- | |
## | |
## First, be sure to start Shadowsocks on 127.0.0.1 (on port 8080 in this case) | |
## Second, be sure to start the udpgw on the remote server (on port 7300 in this case) | |
## | |
## Then, put the following into a script like "tun2socks_proxy_foo.bash" which will be run as root | |
## | |
## If you need multple scripts, a more general naming scheme is as follows: | |
## tun2socks_proxy_${LOCAL_USER}_${NET_IFACE}_${REMOTE_SERVER}_${TCPPORT}_${TUN_IFACE}.bash | |
## | |
#!/bin/bash | |
LOCAL_USER=foo | |
NET_IFACE=wlan0 | |
TUN_IFACE=tun0 | |
REMOTE_USER=me | |
REMOTE_SERVER=100.200.300.400 | |
ROUTER_IP=192.168.1.1 | |
TCPPORT=8080 | |
UDPPORT=7300 | |
VPN_TUN_IP=10.0.0.1 | |
VPN_GW_IP=10.0.0.2 | |
TABLE_MARK=11 | |
#--- Get Local Network --- | |
ROUTER_NET=$(echo $ROUTER_IP | sed -E 's/[[:digit:]]+$/0\/24/g') | |
#--- Redirect for $LOCAL_USER (as root) --- | |
echo "Setting up proxy for ${LOCAL_USER}" | |
ip tuntap add dev ${TUN_IFACE} mode tun user ${LOCAL_USER} | |
ip addr add ${VPN_TUN_IP}/24 dev ${TUN_IFACE} | |
ip link set ${TUN_IFACE} up | |
ip rule add fwmark ${TABLE_MARK} table ${TABLE_MARK} | |
ip route add $ROUTER_NET dev ${NET_IFACE} table ${TABLE_MARK} | |
ip route add ${REMOTE_SERVER}/32 via ${ROUTER_IP} table ${TABLE_MARK} | |
ip route add default via ${VPN_TUN_IP} table ${TABLE_MARK} | |
iptables -t mangle -A OUTPUT -m owner --uid-owner $(id -u ${LOCAL_USER}) -j MARK --set-mark ${TABLE_MARK} | |
iptables -t nat -A POSTROUTING -o ${TUN_IFACE} -j SNAT --to-source ${VPN_GW_IP} | |
sysctl -w net.ipv4.conf.${TUN_IFACE}.rp_filter=2 | |
ip route flush cache | |
#--- start local redirection daemon (as user) --- | |
sudo -u ${LOCAL_USER} /home/${LOCAL_USER}/bin/badvpn/tun2socks --tundev ${TUN_IFACE} --netif-ipaddr ${VPN_GW_IP} --netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:${TCPPORT} --udpgw-remote-server-addr ${REMOTE_SERVER}:${UDPPORT} | |
#--- Stop redirect for $LOCAL_USER (as root) --- | |
echo "Tearing down proxy for ${LOCAL_USER}" | |
ip rule del fwmark ${TABLE_MARK} table ${TABLE_MARK} | |
ip route flush table ${TABLE_MARK} | |
iptables -t mangle -D OUTPUT -m owner --uid-owner $(id -u ${LOCAL_USER}) -j MARK --set-mark ${TABLE_MARK} | |
iptables -t nat -D POSTROUTING -o ${TUN_IFACE} -j SNAT --to-source ${VPN_GW_IP} | |
sysctl -w net.ipv4.conf.${TUN_IFACE}.rp_filter=1 | |
ip link set ${TUN_IFACE} down | |
ip tuntap del dev ${TUN_IFACE} mode tun | |
ip route flush cache | |
#--- Start the proxy --- | |
## | |
## Just run the script as root to start the proxy, and Ctrl-C to stop it. | |
## | |
## In the meantime, you can try "curl ip.ryansanden.com" to see your effective IP as the user ("foo") or another user. | |
## What should happen is that you see the $REMOTE_SERVER ip from "foo" only. | |
## | |
./tun2socks_proxy_foo.bash | |
#--- GUI applications --- | |
## | |
## Since you're usually running this proxy for a separate user, that user needs to be able to access your X session. | |
## Ensuring that user can access /dev/dri means it can fully use OpenGL (i.e. glxgears) as well. | |
## | |
xhost +SI:localuser:foo | |
sudo usermod -a -G video foo | |
# For the correct group ("video" in my case), see /dev/dri/card0: | |
# | |
# me@MyMachine:~$ getfacl /dev/dri/card0 | |
# getfacl: Removing leading '/' from absolute path names | |
# # file: dev/dri/card0 | |
# # owner: root | |
# # group: video | |
# user::rw- | |
# user:me:rw- | |
# group::rw- | |
# mask::rw- | |
# other::--- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So did both tcp and udp work for you using this?