Skip to content

Instantly share code, notes, and snippets.

@ssrlive
Last active July 3, 2023 04:27
Show Gist options
  • Save ssrlive/dfb3b0b51c65bb7034727c5bd5267053 to your computer and use it in GitHub Desktop.
Save ssrlive/dfb3b0b51c65bb7034727c5bd5267053 to your computer and use it in GitHub Desktop.
Transparent proxy in Linux
#!/bin/bash
# SOCKS5 服务器的 IP 地址
REMOTE_SERVER_IP=
# 本地 SOCKS5 服务器的端口
LOCAL_LISTEN_PORT=0
# 自动获取家用网关(路由器)的 IP 地址,你也可以手动指定,如 192.168.28.2
REAL_GATEWAY=$(ip route | grep "default .* dhcp" | awk '{print $3}')
# 选一个不冲突的 tun 设备号
TUN_NETWORK_DEV=tun0
# 选一个不冲突的内网 IP 段的前缀
TUN_NETWORK_PREFIX=10.0.0
TUN_NETWORK_IP=${TUN_NETWORK_PREFIX}.1
TUN_NETWORK_GATEWAY=${TUN_NETWORK_PREFIX}.2
RUN_FLAG="error"
function check_args() {
while getopts s:p:r: flag
do
case "${flag}" in
s) REMOTE_SERVER_IP=${OPTARG};;
p) LOCAL_LISTEN_PORT=${OPTARG};;
r) RUN_FLAG=${OPTARG};;
esac
done
if [ -z ${REMOTE_SERVER_IP} ] || [ ${LOCAL_LISTEN_PORT} -eq 0 ] || ([[ ${RUN_FLAG} != start ]] && [[ ${RUN_FLAG} != stop ]]) ; then
cat << EOF
脚本 "$(basename $0)" 使用方法:
script "$(basename $0)" usage:
$0 -s REMOTE_SERVER_IP -p LOCAL_LISTEN_PORT -r start/stop
EOF
exit 1
fi
}
function check_root_account() {
if [ `id -u` != 0 ]; then
echo -e "当前账号不是 root 账号,请切换到 root 账号再运行本脚本。"
echo -e "Current account is not root user, please switch to root user and re-execute this script."
exit 1
fi
}
function start_tun_fwd() {
# 添加虚拟网卡
ip tuntap add dev ${TUN_NETWORK_DEV} mode tun
if false; then
# 给虚拟网卡绑定 IP 地址
ifconfig ${TUN_NETWORK_DEV} ${TUN_NETWORK_IP} netmask 255.255.255.0
# 启动虚拟网卡
ip link set ${TUN_NETWORK_DEV} up
route add ${REMOTE_SERVER_IP} gw ${REAL_GATEWAY} metric 4
route add default gw ${TUN_NETWORK_GATEWAY} metric 6
else
# 给虚拟网卡绑定 IP 地址
ip addr add ${TUN_NETWORK_IP}/24 dev ${TUN_NETWORK_DEV}
# 启动虚拟网卡
ip link set ${TUN_NETWORK_DEV} up
ip route del default via ${REAL_GATEWAY}
ip route add ${REMOTE_SERVER_IP} via ${REAL_GATEWAY}
# 特殊ip段走家用网关(路由器)的 IP 地址(如局域网联机)
# ip route add "172.16.39.0/24" via ${REAL_GATEWAY}
## 国内网段走家用网关(路由器)的 IP 地址
#for i in $(cat /home/yang/bin/路由表/cn_rules.conf); do
# ip route add "$i" via ${REAL_GATEWAY}
#done
# 将默认网关设为虚拟网卡的 IP 地址
ip route add 0.0.0.0/1 via ${TUN_NETWORK_IP}
ip route add 128.0.0.0/1 via ${TUN_NETWORK_IP}
# 以上兩句可以使用以下一句代替
# ip route add 0.0.0.0/0 via ${TUN_NETWORK_IP}
fi
sleep 1
badvpn-tun2socks --tundev ${TUN_NETWORK_DEV} --netif-ipaddr ${TUN_NETWORK_GATEWAY} --netif-netmask 255.255.255.0 --socks-server-addr 127.0.0.1:${LOCAL_LISTEN_PORT} --socks5-udp &
}
function stop_tun_fwd() {
killall -w badvpn-tun2socks
sleep 1
if false; then
route del ${REMOTE_SERVER_IP} gw ${REAL_GATEWAY} metric 4
route del default gw ${TUN_NETWORK_GATEWAY} metric 6
else
ip route del 128.0.0.0/1 via ${TUN_NETWORK_IP}
ip route del 0.0.0.0/1 via ${TUN_NETWORK_IP}
#for i in $(cat /home/yang/bin/路由表/cn_rules.conf); do
# ip route del "$i" via ${REAL_GATEWAY}
#done
#ip route del "172.16.39.0/24" via ${REAL_GATEWAY}
fi
ip route del ${REMOTE_SERVER_IP} via ${REAL_GATEWAY}
ip route add default via ${REAL_GATEWAY}
ip link set ${TUN_NETWORK_DEV} down
ip addr del ${TUN_NETWORK_IP}/24 dev ${TUN_NETWORK_DEV}
sleep 1
ip tuntap del dev ${TUN_NETWORK_DEV} mode tun
}
function main() {
check_root_account
check_args $@
stop_tun_fwd
if [[ ${RUN_FLAG} == stop ]]; then
exit 0
elif [[ ${RUN_FLAG} == start ]]; then
start_tun_fwd
fi
}
main $@
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment