Skip to content

Instantly share code, notes, and snippets.

@Geofferey
Created April 29, 2025 00:29
Show Gist options
  • Select an option

  • Save Geofferey/4dbb2518f2aaa605ba239edc3ba6118c to your computer and use it in GitHub Desktop.

Select an option

Save Geofferey/4dbb2518f2aaa605ba239edc3ba6118c to your computer and use it in GitHub Desktop.
A script to setup wireguard tunnel on Android
#!/system/bin/sh
if [ -z ${INTERACTIVE} ]; then
until [[ $(getprop sys.boot_completed) = 1 ]] && [[ $(getprop dev.bootcomplete) = 1 ]] && [[ $(getprop service.bootanim.exit) = 1 ]] && [[ $(getprop init.svc.bootanim) = stopped ]]; do
sleep 5
done
sleep 60
fi
CONF="/mnt/reserve/.conf/wireguard/tun_vpn0.conf"
CONF_DIR="/mnt/reserve/.conf/wireguard"
TUN_TAB="tun_vpn0"
TUN_IN_TAB="8861"
DEV="tun_vpn0"
WLAN_INTF="wlan0"
AP_INTF="wlan1"
LISTEN_PORT="51822"
FWMARK="0x20000"
## Internal IP of Endpoint ##
ENDPOINT_INT_IP="10.0.0.1"
ENDPOINT_PORT="51822"
## Goto pref for bypassing VPN ##
SKIP_VPN="19000"
ENDPOINT_HOSTNAME=netlabwork.dns.army
ENDPOINT_IP=$(nslookup ${ENDPOINT_HOSTNAME} 8.8.8.8 | awk -F': ' 'NR==5 { print $2 } ')
## Send marked packets of tunnel envelope to end of routing table to exit active interface
#ip rule add from all fwmark ${FWMARK} goto ${SKIP_VPN} pref 1000
if ! -e /data/misc/wireguard; then
if [ -z ${INTERACTIVE} ]; then
ln -sf ${CONF_DIR} /data/misc/wireguard
fi
fi
until /system/xbin/wg-quick up ${CONF}; do
sleep 10
done
## It's crucial we wait some time before making IPtables + IP Rule modifications, SystemUI crashes, soft reboots, locks and such. Not sure where conflict lies.
if [ -z ${INTERACTIVE} ]; then
sleep 40
fi
## Wireguard binds to all interfaces/IPs and will attempt to connect to peers (even dynamic ones) from any available interface/IP (shortest path wins).... In the case of a roaming client/peer that goes to/from a LAN where a firewall (like Pfsnese) has Wireguard running this can cause issues. Once the static endpoint (firewall) establishes a connection to a dynamic peer from an internal interface the peer will update the endpoint on it's tunnel interface to reflect the IP from which the connection came, EVEN though the IP was initially set to a public facing one.. Once the client leaves the LAN it's game over because it is behind NAT and attempting to connect to it's peer via an internal IP.
## Explicitly deny connections from known internal IP(s) of remote peer(s)
iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source 192.168.0.0/16 -j REJECT
iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source 192.168.0.0/16 -j REJECT
iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source 172.16.0.0/12 -j REJECT
iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source 172.16.0.0/12 -j REJECT
iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source 10.0.0.0/8 -j REJECT
iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source 10.0.0.0/8 -j REJECT
#iptables -D INPUT -i wlan0 -p udp --dport ${LISTEN_PORT} --source ${ENDPOINT_INT_IP} -j REJECT
#iptables -I INPUT 3 -i wlan0 -p udp --dport ${LISTEN_PORT} --source ${ENDPOINT_INT_IP} -j REJECT
## Explicitly accept connection from the endpoint IP that was specified in .conf
iptables -D INPUT -s ${ENDPOINT_IP} -p udp --dport ${LISTEN_PORT} -j ACCEPT
iptables -I INPUT 3 -s ${ENDPOINT_IP} -p udp --dport ${LISTEN_PORT} -j ACCEPT
## If the local peer attempts to establish connection to internal IP of remote endpoint, redirect to the IP specified in .conf
iptables -t nat -D OUTPUT $(iptables -t nat -L OUTPUT -v --line-numbers |grep -w "wireguard: roaming LAN issue workaround" | cut -d " " -f1)
iptables -t nat -I OUTPUT -m comment --comment "wireguard: roaming LAN issue workaround" -p udp -d ${ENDPOINT_INT_IP} --dport ${ENDPOINT_PORT} -j DNAT --to-destination ${ENDPOINT_IP}:${ENDPOINT_PORT}
## ^^ Fucking crazy, I know! ^^ ##
## Remove the default rule added by wg-quick that allows connections to the local WG interface envelope port from anywhere
iptables -D INPUT $(iptables -L INPUT --line-numbers |grep "wireguard rule ${DEV}" |cut -d " " -f1)
V6_TUN_IP=$(ifconfig tun_vpn0 |grep inet6 |grep Global |cut -d ' ' -f13)
## Delete default route(s) created by wg-quick when allowing all traffic
ip ro del default dev ${DEV} ta ${TUN_TAB}
ip -6 ro del default dev ${DEV} ta ${TUN_TAB}
## Add rules to allow lookups on other interface(s) to/from VPN
ip ru add iif ${DEV} lookup main pref 17250
ip -6 ru add iif ${DEV} lookup main pref 17250
ip ru add iif ${WLAN_INTF} lookup ${TUN_TAB} pref 17250
ip -6 ru add iif ${WLAN_INTF} lookup ${TUN_TAB} pref 17250
ip ru add iif ${AP_INTF} lookup ${TUN_TAB} pref 17250
ip -6 ru add iif ${AP_INTF} lookup ${TUN_TAB} pref 17250
## Add special use case route to virt0
ip ro add 172.16.230.1 dev virt0 scope link src 172.16.230.1 ta ${TUN_TAB}
## Add a table + default route for inbound IPv6 traffic
ip -6 ro add default dev ${DEV} ta ${TUN_IN_TAB}
ip -6 ru add to ${V6_TUN_IP} lookup ${TUN_IN_TAB} pref 18010
ip -6 ru add from ${V6_TUN_IP} lookup ${TUN_IN_TAB} pref 18010
## Space delimited list of v4/v6 nets/ips to always route over VPN ##
V4_NETWORKS="10.0.0.0/24 10.1.2.0/24 10.8.0.0/22 172.16.80.0/30 172.16.225.0/30 172.16.226.0/30 172.16.227.0/30 172.16.228.0/30 172.16.229.0/30 172.16.232.0/30"
V6_NETWORKS="2001:470:f023::/48 2001:470:d:20b::/64 2a01:7e03:e002:cb00::/56"
## Space delimited list of nets/ips to not route over VPN ##
V4_EXCLUDED="208.54.0.0/16 66.94.0.0/19"
V6_EXCLUDED=""
##^ v4 default example excludes T-Mobile WiFi Calling ^##
## Android APPs to not route over VPN ##
EXCLUDE_PKGS=""
get_app_uid() {
#APP_UID=$(dumpsys package ${PKG} |grep userId |cut -d ' ' -f 5 |cut -d '=' -f 2)
APP_UID=$(echo $(dumpsys package ${PKG} |grep "userId" |cut -d "=" -f2 |cut -d " " -f1) | cut -d ' ' -f2)
}
# Get default chroot UID so they can use VPN #
#DEFAULT_USER="d3b14n"
#DEFAULT_UID=$(id ${DEFAULT_USER} |cut -d '=' -f 2 |cut -d '(' -f 1)
#######################################################
## Add IPv4 routes
ip ro add 10.0.0.0/24 dev ${DEV} scope link src 172.16.225.2
for NETWORK in ${V4_NETWORKS}; do
ip route add ${NETWORK} dev ${DEV} table ${TUN_TAB}
ip route add ${NETWORK} dev ${DEV} table main scope link src 172.16.225.2 metric 1
done
#######################################################
## Add IPv6 Routes
for NETWORK in ${V6_NETWORKS}; do
ip -6 route add ${NETWORK} dev ${DEV} tab ${TUN_TAB}
ip -6 route add ${NETWORK} dev ${DEV} tab main
done
######################################################
## Skip VPN on v4 for marked packages
for PKG in ${EXCLUDE_PKGS}; do
get_app_uid
if [ ! -z ${APP_UID} ]; then
ip ru add uidrange ${APP_UID}-${APP_UID} goto ${SKIP_VPN} pref 10525
unset APP_UID
fi
done
## Skip v4 Networks
for NETWORK in ${V4_EXCLUDED}; do
ip ru add to ${NETWORK} goto ${SKIP_VPN} pref 10525
done
## Establish v6 routing tables
# Skip VPN on v6 for marked packages #
for PKG in ${EXCLUDE_PKGS}; do
get_app_uid
if [ ! -z ${APP_UID} ]; then
ip -6 ru add uidrange ${APP_UID}-${APP_UID} goto ${SKIP_VPN} pref 10525
unset APP_UID
fi
done
# Skip v6 Networks #
for NETWORK in ${V6_EXCLUDED}; do
ip -6 ru add to ${NETWORK} goto ${SKIP_VPN} pref 10525
done
####################################################
## MLDB Evil GW TTL hack to bypass firewall(s) on private nets when routed to via VPN client ##
echo "## You may safely ignore these iptables errors:"
echo "Removing the evil GW TTL hack..."
iptables -t mangle -D FORWARD -i ${DEV} -o eth0 -j TTL --ttl-set 64
iptables -t mangle -D FORWARD -o ${DEV} -i eth0 -j TTL --ttl-set 64
iptables -t mangle -D FORWARD -i ${DEV} -o wlan0 -j TTL --ttl-set 64
iptables -t mangle -D FORWARD -o ${DEV} -i wlan0 -j TTL --ttl-set 64
iptables -t mangle -D FORWARD -i ${DEV} -o tun0 -j TTL --ttl-set 64
iptables -t mangle -D FORWARD -o ${DEV} -i tun0 -j TTL --ttl-set 64
echo "^ You may safely ignore these iptables errors ^"
echo "Applying the evil GW TTL hack..."
iptables -t mangle -I FORWARD -i ${DEV} -o eth0 -j TTL --ttl-set 64
iptables -t mangle -I FORWARD -o ${DEV} -i eth0 -j TTL --ttl-set 64
iptables -t mangle -I FORWARD -i ${DEV} -o wlan0 -j TTL --ttl-set 64
iptables -t mangle -I FORWARD -o ${DEV} -i wlan0 -j TTL --ttl-set 64
iptables -t mangle -I FORWARD -i ${DEV} -o tun0 -j TTL --ttl-set 64
iptables -t mangle -I FORWARD -o ${DEV} -i tun0 -j TTL --ttl-set 64
####################################################
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment