[v1.0.1] Add Transparent proxy iptables script.

This commit is contained in:
chendefine 2019-03-30 17:22:11 +08:00
parent 38ab477763
commit 76fb4ff667
10 changed files with 424 additions and 25 deletions

View File

@ -1,10 +1,151 @@
#!/sbin/sh
# This is a dummy file that should be replaced with a proper installer script
# If you are creating a module locally for personal usage or testing,
# download the script in the following URL:
# https://github.com/topjohnwu/Magisk/blob/master/scripts/module_installer.sh
# And replace this script with the downloaded script
TMPDIR=/dev/tmp
MOUNTPATH=/dev/magisk_img
# Error, this script should always be replaced
exit 1
# Default permissions
umask 022
# Initial cleanup
rm -rf $TMPDIR 2>/dev/null
mkdir -p $TMPDIR
# echo before loading util_functions
ui_print() { echo "$1"; }
require_new_magisk() {
ui_print "***********************************"
ui_print " Please install the latest Magisk! "
ui_print "***********************************"
exit 1
}
imageless_magisk() {
[ $MAGISK_VER_CODE -gt 18100 ]
return $?
}
##########################################################################################
# Environment
##########################################################################################
OUTFD=$2
ZIPFILE=$3
mount /data 2>/dev/null
# Load utility functions
if [ -f /data/adb/magisk/util_functions.sh ]; then
. /data/adb/magisk/util_functions.sh
NVBASE=/data/adb
else
require_new_magisk
fi
# Preperation for flashable zips
setup_flashable
# Mount partitions
mount_partitions
# Detect version and architecture
api_level_arch_detect
# Setup busybox and binaries
$BOOTMODE && boot_actions || recovery_actions
##########################################################################################
# Preparation
##########################################################################################
# Extract common files
unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2
[ ! -f $TMPDIR/install.sh ] && abort "! Unable to extract zip file!"
# Load install script
. $TMPDIR/install.sh
if imageless_magisk; then
$BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules
MODULEROOT=$NVBASE/$MODDIRNAME
else
$BOOTMODE && IMGNAME=magisk_merge.img || IMGNAME=magisk.img
IMG=$NVBASE/$IMGNAME
request_zip_size_check "$ZIPFILE"
mount_magisk_img
MODULEROOT=$MOUNTPATH
fi
MODID=`grep_prop id $TMPDIR/module.prop`
MODPATH=$MODULEROOT/$MODID
print_modname
ui_print "******************************"
ui_print "Powered by Magisk (@topjohnwu)"
ui_print "******************************"
##########################################################################################
# Install
##########################################################################################
# Create mod paths
rm -rf $MODPATH 2>/dev/null
mkdir -p $MODPATH
# Remove placeholder
rm -f $MODPATH/system/placeholder 2>/dev/null
# Custom uninstaller
[ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh
# Auto Mount
if imageless_magisk; then
$SKIPMOUNT && touch $MODPATH/skip_mount
else
$SKIPMOUNT || touch $MODPATH/auto_mount
fi
# prop files
$PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop
# Module info
cp -af $TMPDIR/module.prop $MODPATH/module.prop
if $BOOTMODE; then
# Update info for Magisk Manager
if imageless_magisk; then
mktouch $NVBASE/modules/$MODID/update
cp -af $TMPDIR/module.prop $NVBASE/modules/$MODID/module.prop
else
mktouch /sbin/.magisk/img/$MODID/update
cp -af $TMPDIR/module.prop /sbin/.magisk/img/$MODID/module.prop
fi
fi
# post-fs-data mode scripts
$POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh
# service mode scripts
$LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh
on_install
# Handle replace folders
for TARGET in $REPLACE; do
mktouch $MODPATH$TARGET/.replace
done
ui_print "- Setting permissions"
set_permissions
##########################################################################################
# Finalizing
##########################################################################################
cd /
imageless_magisk || unmount_magisk_img
$BOOTMODE || recovery_cleanup
rm -rf $TMPDIR $MOUNTPATH
ui_print "- Done"
exit 0

View File

@ -6,9 +6,11 @@ This is a v2ray module for Magisk, and includes binaries for arm, arm64, x86, x6
## Included
* [V2Ray](<https://github.com/v2ray/v2ray-core>)
* [V2Ray core](<https://github.com/v2ray/v2ray-core>)
* [magisk-module-installer](https://github.com/topjohnwu/magisk-module-installer)
- V2Ray service script and Android transparent proxy iptables script
## Install
@ -19,9 +21,13 @@ This is a v2ray module for Magisk, and includes binaries for arm, arm64, x86, x6
## Config
V2ray config file is store in `/data/v2ray/config.json` .
- V2ray config file is store in `/data/v2ray/config.json` .
- Please make sure the config is correct. You can check it by running a command :
`export V2RAY_LOCATION_ASSET=/data/v2ray; v2ray -test -config /data/v2ray/config.json` in android terminal.
Please make sure the config is correct. You can do that by running a command `v2ray -test -config /data/v2ray/config.json` in android terminal.
@ -29,7 +35,7 @@ Please make sure the config is correct. You can do that by running a command `v2
- V2ray service is autorun on boot. If you don't want it run automatically, you can just add a file `/data/v2ray/no-autostart` .
- You can also start / stop manually by run the service script in `$MODDIR` . For example, in my environment , the script's absolute path is `/sbin/.magisk/img/v2ray/v2ray.service` .
- You can start / stop manually by execute the service script in `$MODDIR/v2ray.service` . For example, in my environment , the script's absolute path is `/sbin/.magisk/img/v2ray/v2ray.service` .
- So, if you want to start v2ray service, just run:
@ -43,12 +49,62 @@ Please make sure the config is correct. You can do that by running a command `v2
`/sbin/.magisk/img/v2ray/v2ray.service restart`
## Transparent proxy
### Working principle
This module also contains a simple script that helping you to make transparent proxy via iptables. In fact , the script is just make some REDIRECT and TPROXY rules to redirect app's network into 65535 port in localhost. And 65535 port is listen by v2ray inbond with dokodemo-door protocol. In summarize, the App proxy network path is looks like :
**Android App** ( Browser, Google, Facebook, Twitter ... ... )
&vArr; ( TCP & UDP network protocol )
Android system **iptables** [ localhost inside ]
&vArr; ( REDIRECT & TPROXY iptables rules )
127.0.0.1:65535 [ Inbond ] ----- **V2Ray** ----- [ Outbond ]
( Shadowsocks, Vmess ) &vArr;
[ Internet outside ] ( SS, V2Ray) **Proxy Server**
( HTTP, TCP, ... other application protocol ) &vArr;
( Google, Facebook, Twitter ... ... ) **App Server**
### Choose proxy target
- Select mode : You can write a list of App's uid into `/data/v2ray/appid.list` file so that the script would select these App's network proxy via V2Ray. Each App's uid should separate by space or just One App's uid per line.
- Global mode : You can write a single number "0" into `/data/v2ray/appid.list` file to make all App's network proxy via V2Ray.
### Enable/Disable proxy
- Only when the V2Ray service start normally on boot and `/data/v2ray/appid.list` file is not empty, the transparent proxy iptables script can run automatically.
- Otherwise, you can execute iptables script in `$MODDIR/v2ray.redirect` . For example, in my environment:
Enable transparent proxy:
`/sbin/.magisk/img/v2ray/v2ray.redirect enable`
Disable transparent proxy:
`/sbin/.magisk/img/v2ray/v2ray.redirect disable`
## Uninstall
1. Uninstall the module via Magisk Manager App.
2. Remove the directory with command `rm -rf /data/v2ray` .
2. You can clean v2ray data dir by running command `rm -rf /data/v2ray` .

View File

@ -8,4 +8,4 @@ MODDIR=${0%/*}
# This script will be executed in late_start service mode
if [ ! -f /data/v2ray/no-autostart ] ; then $MODDIR/v2ray.service start ; fi
if [ ! -f /data/v2ray/no-autostart ] ; then $MODDIR/v2ray.service start && [ -f /data/v2ray/appid.list ] && $MODDIR/v2ray.redirect enable ; fi

View File

@ -140,13 +140,14 @@ on_install() {
mkdir -p $MODPATH/system/bin
mkdir -p $MODPATH/system/etc
unzip -j -o "$ZIPFILE" "v2ray/etc/v2ray.service" -d $MODPATH >&2
unzip -j -o "$ZIPFILE" "v2ray/etc/v2ray.redirect" -d $MODPATH >&2
unzip -j -o "$ZIPFILE" "v2ray/bin/$ARCH/*" -d $MODPATH/system/bin >&2
# copy v2ray data and config
ui_print "- Copy V2Ray config and data files"
mkdir -p /data/v2ray
mkdir -p /data/v2ray/run
[ -f /data/v2ray/config.json ] || \\
[ -f /data/v2ray/config.json ] || \
unzip -j -o "$ZIPFILE" "v2ray/etc/config.json" -d /data/v2ray >&2
unzip -j -o "$ZIPFILE" "v2ray/etc/resolv.conf" -d /data/v2ray >&2
unzip -j -o "$ZIPFILE" "v2ray/etc/geosite.dat" -d /data/v2ray >&2
@ -163,6 +164,7 @@ set_permissions() {
# The following is the default rule, DO NOT remove
set_perm_recursive $MODPATH 0 0 0755 0644
set_perm $MODPATH/v2ray.service 0 0 0755
set_perm $MODPATH/v2ray.redirect 0 0 0755
set_perm $MODPATH/system/bin/v2ray ${inet_uid} ${inet_uid} 6755
set_perm $MODPATH/system/bin/v2ctl ${inet_uid} ${inet_uid} 6755
set_perm /data/v2ray ${inet_uid} ${inet_uid} 0755

View File

@ -1,6 +1,6 @@
id=v2ray
name=V2ray for Android
version=v4.18
versionCode=20190329
versionCode=20190330
author=chendefine
description=V2ray core with service scripts for Android

View File

@ -1 +0,0 @@
This file will be deleted in Magisk Manager, it is only a placeholder for git

11
uninstall.sh Normal file
View File

@ -0,0 +1,11 @@
##########################################################################################
#
# V2Ray Magisk Module Uninstaller Script
#
##########################################################################################
remove_v2ray_data_dir() {
rm -rf /data/v2ray
}
remove_v2ray_data_dir

View File

@ -8,6 +8,7 @@
// By default, V2Ray write error log to stdout.
// "error": "/path/to/error/log/file",
"error": "/data/v2ray/run/error.log",
// Log level, one of "debug", "info", "warning", "error", "none"
"loglevel": "warning"
@ -15,22 +16,22 @@
// List of inbound proxy configurations.
"inbounds": [{
// Port to listen on. You may need root access if the value is less than 1024.
"port": 1080,
"port": 65535,
// IP address to listen on. Change to "0.0.0.0" to listen on all network interfaces.
"listen": "127.0.0.1",
// Tag of the inbound proxy. May be used for routing.
"tag": "socks-inbound",
"tag": "proxy-inbound",
// Protocol name of inbound proxy.
"protocol": "socks",
"protocol": "dokodemo-door",
// Settings of the protocol. Varies based on protocol.
"settings": {
"auth": "noauth",
"udp": false,
"ip": "127.0.0.1"
"timeout": 10,
"network": "tcp,udp",
"followRedirect": true
},
// Enable sniffing on TCP connection.
@ -42,6 +43,15 @@
}],
// List of outbound proxy configurations.
"outbounds": [{
// Replace your proxy protocol in this section, like: vmess or shadowsocks
"protocol": "freedom",
// Settings of the protocol. Varies based on protocol.
"settings": {},
// Tag of the outbound. May be used for routing.
"tag": "proxy"
},{
// Protocol name of the outbound proxy.
"protocol": "freedom",
@ -65,10 +75,22 @@
"domainStrategy": "IPOnDemand",
"rules":[
{
// Blocks access to private IPs. Remove this if you want to access your router.
// Bypass private IPs.
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "blocked"
"outboundTag": "direct"
},
{
// Bypass all china IPs.
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
},
{
// Bypass all china sites.
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
// Blocks major ads.

149
v2ray/etc/v2ray.redirect Normal file
View File

@ -0,0 +1,149 @@
#!/system/bin/sh
route_id="1130"
inet_uid="3003"
route_name="v2ray"
proxy_port="65535"
proxy_mark="0x20151130"
appid_file="/data/v2ray/appid.list"
table_file="/data/misc/net/rt_tables"
appid_list=`[ -f ${appid_file} ] && cat ${appid_file}`
intranet=(0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4)
probe_uid_app_name() {
app_name=`grep " $1 " /data/system/packages.list | cut -d ' ' -f 1`
app_name=`echo ${app_name} | sed 's/ / \& /g'`
if [ "${app_name}" != "" ] ; then
echo "Redirect ${app_name} APP's network."
else
echo "APP with uid=$1 is not found."
return 1
fi
}
delete_route_table() {
if eval "ip rule | grep -q \"from all fwmark ${proxy_mark} lookup\"" ; then
echo "Clean UDP redirection route table."
ip rule del fwmark ${proxy_mark} lookup ${route_id}
ip route flush table ${route_id}
fi
sed -i "/${route_id} ${route_name}/d" ${table_file}
}
create_route_table() {
echo "Create UDP redirection route table."
echo "${route_id} ${route_name}" >> ${table_file}
ip route add local default dev lo table ${route_id}
ip rule add fwmark ${proxy_mark} lookup ${route_id}
}
flush_tcp_iptables() {
echo "Clean TCP redirection iptables rules."
iptables -w 10 -t nat -D OUTPUT -p tcp -j TCP_PRE_PROXY 2>/dev/null
if eval "iptables -w 10 -t nat -L TCP_PRE_PROXY &>/dev/null" ; then
iptables -w 10 -t nat -F TCP_PRE_PROXY
iptables -w 10 -t nat -X TCP_PRE_PROXY
fi
if eval "iptables-save -t nat | grep -q ':V2RAY '" ; then
iptables -w 10 -t nat -F V2RAY
iptables -w 10 -t nat -X V2RAY
fi
}
flush_udp_iptables() {
echo "Clean UDP redirection iptables rules."
iptables -w 10 -t mangle -D PREROUTING -p udp -j V2RAY 2>/dev/null
iptables -w 10 -t mangle -D OUTPUT -p udp -j UDP_PRE_PROXY 2>/dev/null
if eval "iptables-save -t mangle | grep -q ':UDP_PRE_PROXY '" ; then
iptables -w 10 -t mangle -F UDP_PRE_PROXY
iptables -w 10 -t mangle -X UDP_PRE_PROXY
fi
if eval "iptables-save -t mangle | grep -q ':V2RAY '" ; then
iptables -w 10 -t mangle -F V2RAY
iptables -w 10 -t mangle -X V2RAY
fi
}
init_tcp_iptables() {
echo "Create TCP redirection iptables rules."
## create NAT iptables for TCP redirect
iptables -w 10 -t nat -N V2RAY
iptables -w 10 -t nat -N TCP_PRE_PROXY
## bypass intranet
for subnet in ${intranet[@]}; do
iptables -w 10 -t nat -A V2RAY -d ${subnet} -j RETURN
done
## bypass v2ray program
iptables -w 10 -t nat -A TCP_PRE_PROXY -m owner --uid-owner ${inet_uid} -j RETURN
## apply to NAT iptables OUTPUT
iptables -w 10 -t nat -A V2RAY -p tcp -j REDIRECT --to-ports ${proxy_port}
}
init_udp_iptables() {
echo "Create UDP redirection iptables rules."
## create Mangle iptables for UDP redirect
iptables -w 10 -t mangle -N V2RAY
iptables -w 10 -t mangle -N UDP_PRE_PROXY
## bypass intranet
for subnet in ${intranet[@]}; do
iptables -w 10 -t mangle -A UDP_PRE_PROXY -d ${subnet} -j RETURN
done
## bypass v2ray program
iptables -w 10 -t mangle -A UDP_PRE_PROXY -m owner --uid-owner ${inet_uid} -j RETURN
## apply to Mangle iptables OUTPUT & PREROUTING
iptables -w 10 -t mangle -A V2RAY -p udp -m mark --mark ${proxy_mark} -j TPROXY --on-ip 127.0.0.1 --on-port ${proxy_port}
}
redirect_iptables() {
if [ "${appid_list}" = "0" ] ; then
## redirect global network
echo "Redirect TCP & UDP with Global mode."
iptables -w 10 -t nat -A TCP_PRE_PROXY -m owner ! --uid-owner ${inet_uid} -j V2RAY
iptables -w 10 -t mangle -A UDP_PRE_PROXY -m owner ! --uid-owner ${inet_uid} -j MARK --set-mark ${proxy_mark}
else
## effect assign app
for appid in ${appid_list}; do
probe_uid_app_name ${appid} && \
iptables -w 10 -t nat -A TCP_PRE_PROXY -m owner --uid-owner ${appid} -j V2RAY && \
iptables -w 10 -t mangle -A UDP_PRE_PROXY -m owner --uid-owner ${appid} -j MARK --set-mark ${proxy_mark}
done
fi
}
apply_iptables_rules() {
iptables -w 10 -t nat -A OUTPUT -p tcp -j TCP_PRE_PROXY
iptables -w 10 -t mangle -A OUTPUT -p udp -j UDP_PRE_PROXY
iptables -w 10 -t mangle -A PREROUTING -p udp -j V2RAY
}
disable_redirect() {
delete_route_table
flush_tcp_iptables
flush_udp_iptables
}
enable_redirect() {
disable_redirect
create_route_table
init_tcp_iptables
init_udp_iptables
redirect_iptables
apply_iptables_rules
}
case "$1" in
enable)
enable_redirect
;;
disable)
disable_redirect
;;
renew)
enable_redirect
;;
*)
echo "$0: usage: $0 {enable|disable|renew}"
;;
esac

View File

@ -22,6 +22,13 @@ probe_service() {
fi
}
simple_clean_iptables() {
echo "Clean relevant iptables simply."
iptables -w 10 -t nat -D OUTPUT -p tcp -j TCP_PRE_PROXY 2>/dev/null
iptables -w 10 -t mangle -D PREROUTING -p udp -j V2RAY 2>/dev/null
iptables -w 10 -t mangle -D OUTPUT -p udp -j UDP_PRE_PROXY 2>/dev/null
}
do_start() {
if ! probe_service && [ -f ${CONFFILE} ] && ${V2RAY} ${V2RAY_OPTS} -test ; then
echo "Starting ${NAME} service."
@ -31,6 +38,16 @@ do_start() {
chmod 6755 ${V2RAY}
${V2RAY} ${V2RAY_OPTS} &
echo -n $! > ${PIDFILE}
sleep 10
if probe_service ; then
echo "Start ${NAME} service Done."
else
rm -f ${PIDFILE}
echo "Start ${NAME} service Failed."
return 1
fi
else
return 2
fi
}
@ -47,11 +64,13 @@ case "$1" in
do_start
;;
stop)
simple_clean_iptables
do_stop
;;
restart)
do_stop
do_start
do_start || \
simple_clean_iptables
;;
*)
echo "$0: usage: $0 {start|stop|restart}"