[v1.0.2] Suit lower version iptables and Add inotify service.

This commit is contained in:
chendefine 2019-03-31 18:28:29 +08:00
parent 76fb4ff667
commit b867eb72aa
6 changed files with 170 additions and 84 deletions

114
README.md
View File

@ -15,7 +15,7 @@ This is a v2ray module for Magisk, and includes binaries for arm, arm64, x86, x6
## Install ## Install
- You can download the release installer zip file and install it via the Magisk Manager App. You can download the release installer zip file and install it via the Magisk Manager App.
@ -26,78 +26,108 @@ This is a v2ray module for Magisk, and includes binaries for arm, arm64, x86, x6
- Please make sure the config is correct. You can check it by running a command : - 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. `export V2RAY_LOCATION_ASSET=/data/v2ray; v2ray -test -config /data/v2ray/config.json` in android terminal or ssh.
- Tips: Please notice that the default configuration has already set inbounds section to cooperate work with transparent proxy script. It is recommended that you only edit the first element of outbounds section to your proxy server and edit file `/data/v2ray/appid.list` to select which App to proxy.
## Usage
## Start/Stop service ### Normal usage ( Default and Recommended )
- V2ray service is autorun on boot. If you don't want it run automatically, you can just add a file `/data/v2ray/no-autostart` . #### Manage service start / stop
- 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` . - V2Ray service is auto-run after system boot up by default.
- You can start or stop v2ray service by simply turn on or turn off the module via Magisk Manager App. Start service may wait about 10 second and stop service may take effect immediately.
- So, if you want to start v2ray service, just run:
`/sbin/.magisk/img/v2ray/v2ray.service start`
or stop v2ray service: #### Select which App to proxy
`/sbin/.magisk/img/v2ray/v2ray.service stop ` - If you expect transparent proxy ( read Transparent proxy section for more detail ) for some Apps, just write down these App' uid in file `/data/v2ray/appid.list` .
Each App's uid should separate by space or just one App's uid per line. ( for Android App's uid , you can search App's package name in file `/data/system/packages.list` , or you can look into some App like Shadowsocks. )
- If you expect all Apps proxy by V2Ray with transparent proxy, just write a single number `0` in file `/data/v2ray/appid.list` .
- Transparent proxy won't take effect until the V2Ray service start normally and file `/data/v2ray/appid.list` is not empty.
### Advanced usage ( for Debug and Develop only )
#### Enter manual mode
If you want to control V2Ray by running command totally, just add a file `/data/v2ray/manual`. In this situation, V2Ray service won't start on boot automatically and you cann't manage service start/stop via Magisk Manager App.
#### Manage service start / stop
- V2Ray service script is `$MODDIR/scripts/v2ray.service`.
- For example, in my environment ( Magisk version: 18100 ; Magisk Manager version v7.1.1 )
- Start service :
`/sbin/.magisk/img/v2ray/scripts/v2ray.service start`
- Stop service :
`/sbin/.magisk/img/v2ray/scripts/v2ray.service stop`
#### Manage transparent proxy enable / disable
- Transparent proxy script is `$MODDIR/scripts/v2ray.tproxy`.
- For example, in my environment ( Magisk version: 18100 ; Magisk Manager version v7.1.1 )
- Enable Transparent proxy :
`/sbin/.magisk/img/v2ray/scripts/v2ray.tproxy enable`
- Disable Transparent proxy :
`/sbin/.magisk/img/v2ray/scripts/v2ray.tproxy disable`
or restart v2ray service:
`/sbin/.magisk/img/v2ray/v2ray.service restart`
## Transparent proxy ## Transparent proxy
### What is "Transparent proxy"
> "A 'transparent proxy' is a proxy that does not modify the request or response beyond what is required for proxy authentication and identification". "A 'non-transparent proxy' is a proxy that modifies the request or response in order to provide some added service to the user agent, such as group annotation services, media type transformation, protocol reduction, or anonymity filtering".
>
> -- [Transparent proxy explanation in Wikipedia](https://en.wikipedia.org/wiki/Proxy_server#Transparent_proxy)
### Working principle ### 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 : 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 ... ... ) **Android App** ( Google, Facebook, Twitter ... )
⇕ ( TCP & UDP network protocol ) ⇕ ( TCP & UDP network protocol )
Android system **iptables** [ localhost inside ] Android system **iptables** [ localhost inside ]
⇕ ( REDIRECT & TPROXY iptables rules ) ⇕ ( REDIRECT & TPROXY iptables rules )
127.0.0.1:65535 [ Inbond ] ----- **V2Ray** ----- [ Outbond ] [ 127.0.0.1:65535 Inbond ] -- **V2Ray** -- [ Outbond ]
( Shadowsocks, Vmess ) ⇕ ⇕ ( Shadowsocks, Vmess )
[ Internet outside ] ( SS, V2Ray) **Proxy Server** **Proxy Server** ( SS, V2Ray) [ Internet outside ]
( HTTP, TCP, ... other application protocol ) ⇕ ⇕ ( HTTP, TCP, ... other application protocol )
( Google, Facebook, Twitter ... ... ) **App Server** **App Server** ( Google, Facebook, Twitter ... )
### 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`

View File

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

View File

@ -132,15 +132,15 @@ print_modname() {
on_install() { on_install() {
# The following is the default implementation: extract $ZIPFILE/system to $MODPATH # The following is the default implementation: extract $ZIPFILE/system to $MODPATH
# Extend/change the logic to whatever you want # Extend/change the logic to whatever you want
ui_print "- Extracting module files" ## ui_print "- Extracting module files"
unzip -o "$ZIPFILE" 'system/*' -d $MODPATH >&2 ## unzip -o "$ZIPFILE" 'system/*' -d $MODPATH >&2
# install v2ray execute file # install v2ray execute file
ui_print "- Install V2Ray core $ARCH execute files" ui_print "- Install V2Ray core $ARCH execute files"
mkdir -p $MODPATH/scripts
mkdir -p $MODPATH/system/bin mkdir -p $MODPATH/system/bin
mkdir -p $MODPATH/system/etc mkdir -p $MODPATH/system/etc
unzip -j -o "$ZIPFILE" "v2ray/etc/v2ray.service" -d $MODPATH >&2 unzip -j -o "$ZIPFILE" 'v2ray/scripts/*' -d $MODPATH/scripts >&2
unzip -j -o "$ZIPFILE" "v2ray/etc/v2ray.redirect" -d $MODPATH >&2
unzip -j -o "$ZIPFILE" "v2ray/bin/$ARCH/*" -d $MODPATH/system/bin >&2 unzip -j -o "$ZIPFILE" "v2ray/bin/$ARCH/*" -d $MODPATH/system/bin >&2
# copy v2ray data and config # copy v2ray data and config
@ -149,6 +149,7 @@ on_install() {
mkdir -p /data/v2ray/run 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/config.json" -d /data/v2ray >&2
[ -f /data/v2ray/resolv.conf ] || \
unzip -j -o "$ZIPFILE" "v2ray/etc/resolv.conf" -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 unzip -j -o "$ZIPFILE" "v2ray/etc/geosite.dat" -d /data/v2ray >&2
unzip -j -o "$ZIPFILE" "v2ray/etc/geoip.dat" -d /data/v2ray >&2 unzip -j -o "$ZIPFILE" "v2ray/etc/geoip.dat" -d /data/v2ray >&2
@ -163,10 +164,11 @@ set_permissions() {
inet_uid="3003" inet_uid="3003"
# The following is the default rule, DO NOT remove # The following is the default rule, DO NOT remove
set_perm_recursive $MODPATH 0 0 0755 0644 set_perm_recursive $MODPATH 0 0 0755 0644
set_perm $MODPATH/v2ray.service 0 0 0755 set_perm $MODPATH/scripts/v2ray.inotify 0 0 0755
set_perm $MODPATH/v2ray.redirect 0 0 0755 set_perm $MODPATH/scripts/v2ray.service 0 0 0755
set_perm $MODPATH/system/bin/v2ray ${inet_uid} ${inet_uid} 6755 set_perm $MODPATH/scripts/v2ray.tproxy 0 0 0755
set_perm $MODPATH/system/bin/v2ctl ${inet_uid} ${inet_uid} 6755 set_perm $MODPATH/system/bin/v2ray ${inet_uid} ${inet_uid} 0755
set_perm $MODPATH/system/bin/v2ctl ${inet_uid} ${inet_uid} 0755
set_perm /data/v2ray ${inet_uid} ${inet_uid} 0755 set_perm /data/v2ray ${inet_uid} ${inet_uid} 0755
# Here are some examples: # Here are some examples:

View File

@ -0,0 +1,34 @@
#!/system/bin/sh
inotify=`realpath $0`
scripts_dir=`dirname ${inotify}`
service="${scripts_dir}/v2ray.service"
tproxy="${scripts_dir}/v2ray.tproxy"
events=$1
monitor_dir=$2
monitor_file=$3
start_v2ray() {
${service} start && \
[ -f /data/v2ray/appid.list ] && ${tproxy} enable
}
stop_v2ray() {
${tproxy} disable
${service} stop
}
main() {
if [ ! -f /data/v2ray/manual ] ; then
if [ "${monitor_file}" = "disable" ] ; then
if [ "${events}" = "d" ] ; then
start_v2ray
elif [ "${events}" = "n" ] ; then
stop_v2ray
fi
fi
fi
}
main

View File

@ -5,6 +5,7 @@ V2RAY=/system/bin/${NAME}
DATAPATH=/data/${NAME} DATAPATH=/data/${NAME}
RUNPATH=${DATAPATH}/run RUNPATH=${DATAPATH}/run
PIDFILE=${RUNPATH}/${NAME}.pid PIDFILE=${RUNPATH}/${NAME}.pid
EXECLOG=${RUNPATH}/error.log
CONFFILE=${DATAPATH}/config.json CONFFILE=${DATAPATH}/config.json
V2RAY_OPTS="-config ${CONFFILE}" V2RAY_OPTS="-config ${CONFFILE}"
@ -36,9 +37,9 @@ do_start() {
chown -R inet:inet ${DATAPATH} chown -R inet:inet ${DATAPATH}
chown inet:inet ${V2RAY} chown inet:inet ${V2RAY}
chmod 6755 ${V2RAY} chmod 6755 ${V2RAY}
${V2RAY} ${V2RAY_OPTS} & nohup ${V2RAY} ${V2RAY_OPTS} &>${EXECLOG} &
echo -n $! > ${PIDFILE} echo -n $! > ${PIDFILE}
sleep 10 sleep 5
if probe_service ; then if probe_service ; then
echo "Start ${NAME} service Done." echo "Start ${NAME} service Done."
else else
@ -72,7 +73,11 @@ case "$1" in
do_start || \ do_start || \
simple_clean_iptables simple_clean_iptables
;; ;;
status)
probe_service || \
echo "${NAME} service is stopped."
;;
*) *)
echo "$0: usage: $0 {start|stop|restart}" echo "$0: usage: $0 {start|stop|restart|status}"
;; ;;
esac esac

View File

@ -7,11 +7,22 @@ proxy_port="65535"
proxy_mark="0x20151130" proxy_mark="0x20151130"
appid_file="/data/v2ray/appid.list" appid_file="/data/v2ray/appid.list"
table_file="/data/misc/net/rt_tables" table_file="/data/misc/net/rt_tables"
iptables_wait="iptables -w 10"
appid_list=`[ -f ${appid_file} ] && cat ${appid_file}` 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) 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)
suit_iptables_version() {
iptables_version=`iptables -V | grep -o "v1\.[0-9]"`
## just for lower version iptables
if [ "${iptables_version}" = "v1.4" ] ; then
export ANDROID_DATA=/data
export ANDROID_ROOT=/system
iptables_wait="iptables -w"
fi
}
probe_uid_app_name() { probe_uid_app_name() {
app_name=`grep " $1 " /data/system/packages.list | cut -d ' ' -f 1` app_name=`grep " $1 " /data/system/packages.list | cut -d ' ' -f 1`
app_name=`echo ${app_name} | sed 's/ / \& /g'` app_name=`echo ${app_name} | sed 's/ / \& /g'`
@ -41,81 +52,81 @@ create_route_table() {
flush_tcp_iptables() { flush_tcp_iptables() {
echo "Clean TCP redirection iptables rules." echo "Clean TCP redirection iptables rules."
iptables -w 10 -t nat -D OUTPUT -p tcp -j TCP_PRE_PROXY 2>/dev/null ${iptables_wait} -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 if eval "iptables-save -t nat | grep -q ':TCP_PRE_PROXY '" ; then
iptables -w 10 -t nat -F TCP_PRE_PROXY ${iptables_wait} -t nat -F TCP_PRE_PROXY
iptables -w 10 -t nat -X TCP_PRE_PROXY ${iptables_wait} -t nat -X TCP_PRE_PROXY
fi fi
if eval "iptables-save -t nat | grep -q ':V2RAY '" ; then if eval "iptables-save -t nat | grep -q ':V2RAY '" ; then
iptables -w 10 -t nat -F V2RAY ${iptables_wait} -t nat -F V2RAY
iptables -w 10 -t nat -X V2RAY ${iptables_wait} -t nat -X V2RAY
fi fi
} }
flush_udp_iptables() { flush_udp_iptables() {
echo "Clean UDP redirection iptables rules." echo "Clean UDP redirection iptables rules."
iptables -w 10 -t mangle -D PREROUTING -p udp -j V2RAY 2>/dev/null ${iptables_wait} -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 ${iptables_wait} -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 if eval "iptables-save -t mangle | grep -q ':UDP_PRE_PROXY '" ; then
iptables -w 10 -t mangle -F UDP_PRE_PROXY ${iptables_wait} -t mangle -F UDP_PRE_PROXY
iptables -w 10 -t mangle -X UDP_PRE_PROXY ${iptables_wait} -t mangle -X UDP_PRE_PROXY
fi fi
if eval "iptables-save -t mangle | grep -q ':V2RAY '" ; then if eval "iptables-save -t mangle | grep -q ':V2RAY '" ; then
iptables -w 10 -t mangle -F V2RAY ${iptables_wait} -t mangle -F V2RAY
iptables -w 10 -t mangle -X V2RAY ${iptables_wait} -t mangle -X V2RAY
fi fi
} }
init_tcp_iptables() { init_tcp_iptables() {
echo "Create TCP redirection iptables rules." echo "Create TCP redirection iptables rules."
## create NAT iptables for TCP redirect ## create NAT iptables for TCP redirect
iptables -w 10 -t nat -N V2RAY ${iptables_wait} -t nat -N V2RAY
iptables -w 10 -t nat -N TCP_PRE_PROXY ${iptables_wait} -t nat -N TCP_PRE_PROXY
## bypass intranet ## bypass intranet
for subnet in ${intranet[@]}; do for subnet in ${intranet[@]}; do
iptables -w 10 -t nat -A V2RAY -d ${subnet} -j RETURN ${iptables_wait} -t nat -A V2RAY -d ${subnet} -j RETURN
done done
## bypass v2ray program ## bypass v2ray program
iptables -w 10 -t nat -A TCP_PRE_PROXY -m owner --uid-owner ${inet_uid} -j RETURN ${iptables_wait} -t nat -A TCP_PRE_PROXY -m owner --uid-owner ${inet_uid} -j RETURN
## apply to NAT iptables OUTPUT ## apply to NAT iptables OUTPUT
iptables -w 10 -t nat -A V2RAY -p tcp -j REDIRECT --to-ports ${proxy_port} ${iptables_wait} -t nat -A V2RAY -p tcp -j REDIRECT --to-ports ${proxy_port}
} }
init_udp_iptables() { init_udp_iptables() {
echo "Create UDP redirection iptables rules." echo "Create UDP redirection iptables rules."
## create Mangle iptables for UDP redirect ## create Mangle iptables for UDP redirect
iptables -w 10 -t mangle -N V2RAY ${iptables_wait} -t mangle -N V2RAY
iptables -w 10 -t mangle -N UDP_PRE_PROXY ${iptables_wait} -t mangle -N UDP_PRE_PROXY
## bypass intranet ## bypass intranet
for subnet in ${intranet[@]}; do for subnet in ${intranet[@]}; do
iptables -w 10 -t mangle -A UDP_PRE_PROXY -d ${subnet} -j RETURN ${iptables_wait} -t mangle -A UDP_PRE_PROXY -d ${subnet} -j RETURN
done done
## bypass v2ray program ## bypass v2ray program
iptables -w 10 -t mangle -A UDP_PRE_PROXY -m owner --uid-owner ${inet_uid} -j RETURN ${iptables_wait} -t mangle -A UDP_PRE_PROXY -m owner --uid-owner ${inet_uid} -j RETURN
## apply to Mangle iptables OUTPUT & PREROUTING ## 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} ${iptables_wait} -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() { redirect_iptables() {
if [ "${appid_list}" = "0" ] ; then if [ "${appid_list}" = "0" ] ; then
## redirect global network ## redirect global network
echo "Redirect TCP & UDP with Global mode." 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_wait} -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} ${iptables_wait} -t mangle -A UDP_PRE_PROXY -m owner ! --uid-owner ${inet_uid} -j MARK --set-mark ${proxy_mark}
else else
## effect assign app ## effect assign app
for appid in ${appid_list}; do for appid in ${appid_list}; do
probe_uid_app_name ${appid} && \ probe_uid_app_name ${appid} && \
iptables -w 10 -t nat -A TCP_PRE_PROXY -m owner --uid-owner ${appid} -j V2RAY && \ ${iptables_wait} -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} ${iptables_wait} -t mangle -A UDP_PRE_PROXY -m owner --uid-owner ${appid} -j MARK --set-mark ${proxy_mark}
done done
fi fi
} }
apply_iptables_rules() { apply_iptables_rules() {
iptables -w 10 -t nat -A OUTPUT -p tcp -j TCP_PRE_PROXY ${iptables_wait} -t nat -A OUTPUT -p tcp -j TCP_PRE_PROXY
iptables -w 10 -t mangle -A OUTPUT -p udp -j UDP_PRE_PROXY ${iptables_wait} -t mangle -A OUTPUT -p udp -j UDP_PRE_PROXY
iptables -w 10 -t mangle -A PREROUTING -p udp -j V2RAY ${iptables_wait} -t mangle -A PREROUTING -p udp -j V2RAY
} }
disable_redirect() { disable_redirect() {
@ -125,7 +136,6 @@ disable_redirect() {
} }
enable_redirect() { enable_redirect() {
disable_redirect
create_route_table create_route_table
init_tcp_iptables init_tcp_iptables
init_udp_iptables init_udp_iptables
@ -133,14 +143,18 @@ enable_redirect() {
apply_iptables_rules apply_iptables_rules
} }
suit_iptables_version
case "$1" in case "$1" in
enable) enable)
disable_redirect
enable_redirect enable_redirect
;; ;;
disable) disable)
disable_redirect disable_redirect
;; ;;
renew) renew)
disable_redirect
enable_redirect enable_redirect
;; ;;
*) *)