mirror of
				https://github.com/Ysurac/openmptcprouter-feeds.git
				synced 2025-03-09 15:40:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			310 lines
		
	
	
		
			No EOL
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			310 lines
		
	
	
		
			No EOL
		
	
	
		
			11 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
| #!/bin/sh -e
 | |
| #
 | |
| # Copyright (C) 2017 Yousong Zhou <yszhou4tech@gmail.com>
 | |
| # Copyright (C) 2018-2021 Ycarus (Yannick Chabanois) <ycarus@zugaina.org>
 | |
| #
 | |
| # The design idea was derived from ss-rules by Jian Chang <aa65535@live.com>
 | |
| #
 | |
| # This is free software, licensed under the GNU General Public License v3.
 | |
| # See /LICENSE for more information.
 | |
| #
 | |
| 
 | |
| if [ -f /usr/sbin/iptables-legacy ]; then
 | |
| 	IP6TABLES="/usr/sbin/ip6tables-legacy"
 | |
| 	IP6TABLESRESTORE="/usr/sbin/ip6tables-legacy-restore"
 | |
| 	IP6TABLESSAVE="/usr/sbin/ip6tables-legacy-save"
 | |
| else
 | |
| 	IP6TABLES="/usr/sbin/ip6tables"
 | |
| 	IP6TABLESRESTORE="/usr/sbin/ip6tables-restore"
 | |
| 	IP6TABLESSAVE="/usr/sbin/ip6tables-save"
 | |
| fi
 | |
| 
 | |
| 
 | |
| 
 | |
| xray_rules6_usage() {
 | |
| 	cat >&2 <<EOF
 | |
| Usage: xray-rules6 [options]
 | |
| 
 | |
| 	-h, --help      Show this help message then exit
 | |
| 	-f, --flush     Flush rules, ipset then exit
 | |
| 	-l <port>       Local port number of ss-redir with TCP mode
 | |
| 	-L <port>       Local port number of ss-redir with UDP mode
 | |
| 	-s <ips>        List of ip addresses of remote shadowsocks server
 | |
| 	--ifnames       Only apply rules on packets from these ifnames
 | |
| 	--src-bypass <ips|cidr>
 | |
| 	--src-forward <ips|cidr>
 | |
| 	--src-checkdst <ips|cidr>
 | |
| 	--src-default <bypass|forward|checkdst>
 | |
| 	                Packets will have their src ip checked in order against
 | |
| 	                bypass, forward, checkdst list and will bypass, forward
 | |
| 	                through, or continue to have their dst ip checked
 | |
| 	                respectively on the first match.  Otherwise, --src-default
 | |
| 	                decide the default action
 | |
| 	--dst-bypass <ips|cidr>
 | |
| 	--dst-forward <ips|cidr>
 | |
| 	--dst-bypass-file <file>
 | |
| 	--dst-forward-file <file>
 | |
| 	--dst-default <bypass|forward>
 | |
| 	                Same as with their --src-xx equivalent
 | |
| 	--dst-forward-recentrst
 | |
| 	                Forward those packets whose destinations have recently
 | |
| 	                sent to us multiple tcp-rst packets
 | |
| 	--local-default <bypass|forward|checkdst>
 | |
| 	                Default action for local out TCP traffic
 | |
| 
 | |
| The following ipsets will be created by xray-rules.  They are also intended to be
 | |
| populated by other programs like dnsmasq with ipset support
 | |
| 
 | |
| 	xray_rules6_src_bypass
 | |
| 	xray_rules6_src_forward
 | |
| 	xray_rules6_src_checkdst
 | |
| 	xray_rules6_dst_bypass
 | |
| 	xray_rules6_dst_forward
 | |
| EOF
 | |
| }
 | |
| 
 | |
| o_dst_bypass_="
 | |
| 	fe80::/10
 | |
| 	fd00::/8
 | |
| 	::1
 | |
| "
 | |
| o_src_default=bypass
 | |
| o_dst_default=bypass
 | |
| o_local_default=bypass
 | |
| 
 | |
| __errmsg() {
 | |
| 	echo "xray-rules6: $*" >&2
 | |
| }
 | |
| 
 | |
| xray_rules6_parse_args() {
 | |
| 	while [ "$#" -gt 0 ]; do
 | |
| 		case "$1" in
 | |
| 			-h|--help) xray_rules6_usage; exit 0;;
 | |
| 			-f|--flush) xray_rules6_flush; exit 0;;
 | |
| 			-l) o_redir_tcp_port="$2"; shift 2;;
 | |
| 			-L) o_redir_udp_port="$2"; shift 2;;
 | |
| 			-s) o_remote_servers="$2"; shift 2;;
 | |
| 			--ifnames) o_ifnames="$2"; shift 2;;
 | |
| 			--ipt-extra) o_ipt_extra="$2"; shift 2;;
 | |
| 			--src-default) o_src_default="$2"; shift 2;;
 | |
| 			--dst-default) o_dst_default="$2"; shift 2;;
 | |
| 			--local-default) o_local_default="$2"; shift 2;;
 | |
| 			--src-bypass) o_src_bypass="$2"; shift 2;;
 | |
| 			--src-forward) o_src_forward="$2"; shift 2;;
 | |
| 			--src-checkdst) o_src_checkdst="$2"; shift 2;;
 | |
| 			--dst-bypass) o_dst_bypass="$2"; shift 2;;
 | |
| 			--dst-bypass_all) o_dst_bypass_all="$2"; shift 2;;
 | |
| 			--dst-forward) o_dst_forward="$2"; shift 2;;
 | |
| 			--dst-forward-recentrst) o_dst_forward_recentrst=1; shift 1;;
 | |
| 			--dst-bypass-file) o_dst_bypass_file="$2"; shift 2;;
 | |
| 			--dst-forward-file) o_dst_forward_file="$2"; shift 2;;
 | |
| 			--rule-name) rule="$2"; shift 2;;
 | |
| 			*) __errmsg "unknown option $1"; return 1;;
 | |
| 		esac
 | |
| 	done
 | |
| 
 | |
| 	if [ -z "$o_redir_tcp_port" -a -z "$o_redir_udp_port" ]; then
 | |
| 		__errmsg "Requires at least -l or -L option"
 | |
| 		return 1
 | |
| 	fi
 | |
| 	if [ -n "$o_dst_forward_recentrst" ] && ! $IP6TABLES -w -m recent -h >/dev/null; then
 | |
| 		__errmsg "Please install ip6tables-mod-conntrack-extra with opkg"
 | |
| 		return 1
 | |
| 	fi
 | |
| 	o_remote_servers="$(for s in $o_remote_servers; do resolveip -6 "$s"; done)"
 | |
| }
 | |
| 
 | |
| xray_rules6_flush() {
 | |
| 	local setname
 | |
| 
 | |
| 	$IP6TABLESSAVE --counters 2>/dev/null | grep -v xr6_ | $IP6TABLESRESTORE --counters
 | |
| 	while ip -f inet6 rule del fwmark 1 lookup 100 2>/dev/null; do true; done
 | |
| 	ip -f inet6 route flush table 100 || true
 | |
| 	for setname in $(ipset -n list | grep "ssr6_${rule}"); do
 | |
| 		ipset destroy "$setname" 2>/dev/null || true
 | |
| 	done
 | |
| }
 | |
| 
 | |
| xray_rules6_ipset_init() {
 | |
| 	ipset --exist restore <<-EOF
 | |
| 		create ssr6_${rule}_src_bypass hash:net family inet6 hashsize 64
 | |
| 		create ssr6_${rule}_src_forward hash:net family inet6 hashsize 64
 | |
| 		create ssr6_${rule}_src_checkdst hash:net family inet6 hashsize 64
 | |
| 		create ssr6_${rule}_dst_bypass hash:net family inet6 hashsize 64
 | |
| 		create ss_rules6_dst_bypass_all hash:net family inet6 hashsize 64
 | |
| 		create ssr6_${rule}_dst_bypass_ hash:net family inet6 hashsize 64
 | |
| 		create ssr6_${rule}_dst_forward hash:net family inet6 hashsize 64
 | |
| 		create ss_rules6_dst_forward_recrst_ hash:ip family inet6 hashsize 64 timeout 3600
 | |
| 		$(xray_rules6_ipset_mkadd ssr6_${rule}_dst_bypass_ "$o_dst_bypass_ $o_remote_servers")
 | |
| 		$(xray_rules6_ipset_mkadd ss_rules6_dst_bypass_all "$o_dst_bypass $(cat "$o_dst_bypass_file" 2>/dev/null | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}')")
 | |
| 		$(xray_rules6_ipset_mkadd ssr6_${rule}_dst_bypass "$o_dst_bypass $(cat "$o_dst_bypass_file" 2>/dev/null | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}')")
 | |
| 		$(xray_rules6_ipset_mkadd ssr6_${rule}_src_bypass "$o_src_bypass")
 | |
| 		$(xray_rules6_ipset_mkadd ssr6_${rule}_src_forward "$o_src_forward")
 | |
| 		$(xray_rules6_ipset_mkadd ssr6_${rule}_src_checkdst "$o_src_checkdst")
 | |
| 		$(xray_rules6_ipset_mkadd ssr6_${rule}_dst_forward "$o_dst_forward $(cat "$o_dst_forward_file" 2>/dev/null | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}')")
 | |
| 	EOF
 | |
| }
 | |
| 
 | |
| xray_rules6_ipset_mkadd() {
 | |
| 	local setname="$1"; shift
 | |
| 	local i
 | |
| 
 | |
| 	for i in $*; do
 | |
| 		echo "add $setname $i"
 | |
| 	done
 | |
| }
 | |
| 
 | |
| xray_rules6_iptchains_init() {
 | |
| 	xray_rules6_iptchains_init_mark
 | |
| 	xray_rules6_iptchains_init_tcp
 | |
| 	xray_rules6_iptchains_init_udp
 | |
| }
 | |
| 
 | |
| xray_rules6_iptchains_init_mark() {
 | |
| 	$IP6TABLESRESTORE --noflush <<-EOF
 | |
| 		*mangle
 | |
| 		-A PREROUTING -m set --match-set ss_rules6_dst_bypass_all dst -j MARK --set-mark 0x6539
 | |
| 		COMMIT
 | |
| 	EOF
 | |
| }
 | |
| 
 | |
| 
 | |
| xray_rules6_iptchains_init_tcp() {
 | |
| 	local local_target
 | |
| 
 | |
| 	[ -n "$o_redir_tcp_port" ] || return 0
 | |
| 
 | |
| 	#xray_rules6_iptchains_init_ nat tcp
 | |
| 	xray_rules6_iptchains_init_ mangle tcp
 | |
| 
 | |
| 	case "$o_local_default" in
 | |
| 		checkdst) local_target=xr6_${rule}_dst ;;
 | |
| 		forward) local_target=xr6_${rule}_forward ;;
 | |
| 		bypass|*) return 0;;
 | |
| 	esac
 | |
| 
 | |
| #	echo "tcp mangle"
 | |
| #	$IP6TABLESRESTORE --noflush <<-EOF
 | |
| #		*mangle
 | |
| #		:xr6_${rule}_local_out -
 | |
| #		-I OUTPUT 1 -p tcp -j xr6_${rule}_local_out
 | |
| #		-A xr6_${rule}_local_out -m set --match-set ss_rules6_dst_bypass dst -j RETURN
 | |
| #		-A xr6_${rule}_local_out -m set --match-set ss_rules6_dst_bypass_all dst -j RETURN
 | |
| #		-A xr6_${rule}_local_out -m set --match-set ss_rules6_dst_bypass_ dst -j RETURN
 | |
| #		-A xr6_${rule}_local_out -m mark --mark 0x6539 -j RETURN
 | |
| #		-A xr6_${rule}_local_out -p tcp $o_ipt_extra -j $local_target -m comment --comment "local_default: $o_local_default"
 | |
| #		COMMIT
 | |
| #	EOF
 | |
| #	echo "done"
 | |
| }
 | |
| 
 | |
| xray_rules6_iptchains_init_udp() {
 | |
| 	[ -n "$o_redir_udp_port" ] || return 0
 | |
| 	xray_rules6_iptchains_init_ mangle udp
 | |
| }
 | |
| 
 | |
| xray_rules6_iptchains_init_() {
 | |
| 	local table="$1"
 | |
| 	local proto="$2"
 | |
| 	local forward_rules
 | |
| 	local src_default_target dst_default_target
 | |
| 	local recentrst_mangle_rules recentrst_addset_rules
 | |
| 
 | |
| 	case "$proto" in
 | |
| 		tcp)
 | |
| 			#forward_rules="-A xr6_${rule}_forward -p tcp -j REDIRECT --to-ports $o_redir_tcp_port"
 | |
| 			forward_rules="-A xr6_${rule}_forward -p tcp -j TPROXY --on-port $o_redir_tcp_port --tproxy-mark 0x01/0x01"
 | |
| 			if [ -n "$o_dst_forward_recentrst" ]; then
 | |
| 				recentrst_mangle_rules="
 | |
| 					*mangle
 | |
| 					-I PREROUTING 1 -p tcp -m tcp --tcp-flags RST RST -m recent --name ss_rules6_recentrst --set --rsource
 | |
| 					COMMIT
 | |
| 				"
 | |
| 				recentrst_addset_rules="
 | |
| 					-A xr6_${rule}_dst -m recent --name ss_rules6_recentrst --rcheck --rdest --seconds 3 --hitcount 3 -j SET --add-set ss_rules6_dst_forward_recrst_ dst --exist
 | |
| 					-A xr6_${rule}_dst -m set --match-set ss_rules6_dst_forward_recrst_ dst -j xr6_${rule}_forward
 | |
| 				"
 | |
| 			fi
 | |
| 			;;
 | |
| 		udp)
 | |
| 			ip -f inet6 rule add fwmark 1 lookup 100 || true
 | |
| 			ip -f inet6 route add local default dev lo table 100 || true
 | |
| 			forward_rules="
 | |
| 				-A xr6_${rule}_forward -p udp -j TPROXY --on-port "$o_redir_udp_port" --tproxy-mark 0x01/0x01
 | |
| 				-A xr6_${rule}_forward -p tcp -j TPROXY --on-port "$o_redir_udp_port" --tproxy-mark 0x01/0x01
 | |
| 			"
 | |
| 			;;
 | |
| 	esac
 | |
| 	case "$o_src_default" in
 | |
| 		forward) src_default_target=xr6_${rule}_forward ;;
 | |
| 		checkdst) src_default_target=xr6_${rule}_dst ;;
 | |
| 		bypass|*) src_default_target=RETURN ;;
 | |
| 	esac
 | |
| 	case "$o_dst_default" in
 | |
| 		forward) dst_default_target=xr6_${rule}_forward ;;
 | |
| 		bypass|*) dst_default_target=RETURN ;;
 | |
| 	esac
 | |
| 	sed -e '/^\s*$/d' -e 's/^\s\+//' <<-EOF | $IP6TABLESRESTORE --noflush
 | |
| 		*$table
 | |
| 		:xr6_${rule}_pre_src -
 | |
| 		:xr6_${rule}_src -
 | |
| 		:xr6_${rule}_dst -
 | |
| 		:xr6_${rule}_forward -
 | |
| 		$(xray_rules6_iptchains_mkprerules "udp")
 | |
| 		$(xray_rules6_iptchains_mkprerules "tcp")
 | |
| 		-A xr6_${rule}_pre_src -m set --match-set ssr6_${rule}_dst_bypass_ dst -j RETURN
 | |
| 		-A xr6_${rule}_pre_src -m set --match-set ss_rules6_dst_bypass_all dst -j MARK --set-mark 0x6539
 | |
| 		-A xr6_${rule}_pre_src -m set --match-set ss_rules6_dst_bypass_all dst -j RETURN
 | |
| 		-A xr6_${rule}_pre_src -m set --match-set ssr6_${rule}_dst_bypass dst -j RETURN
 | |
| 		-A xr6_${rule}_pre_src -m mark --mark 0x6539 -j RETURN
 | |
| 		-A xr6_${rule}_dst -m set --match-set ss_rules6_dst_bypass_all dst -j RETURN
 | |
| 		-A xr6_${rule}_dst -m set --match-set ssr6_${rule}_dst_bypass dst -j RETURN
 | |
| 		-A xr6_${rule}_pre_src -p tcp $o_ipt_extra -j xr6_${rule}_src
 | |
| 		-A xr6_${rule}_pre_src -p udp $o_ipt_extra -j xr6_${rule}_src
 | |
| 		-A xr6_${rule}_src -m set --match-set ssr6_${rule}_src_bypass src -j RETURN
 | |
| 		-A xr6_${rule}_src -m set --match-set ssr6_${rule}_src_forward src -j xr6_${rule}_forward
 | |
| 		-A xr6_${rule}_src -m set --match-set ssr6_${rule}_src_checkdst src -j xr6_${rule}_dst
 | |
| 		-A xr6_${rule}_src -j $src_default_target -m comment --comment "src_default: $o_src_default"
 | |
| 		-A xr6_${rule}_dst -m set --match-set ssr6_${rule}_dst_forward dst -j xr6_${rule}_forward
 | |
| 		$recentrst_addset_rules
 | |
| 		-A xr6_${rule}_dst -j $dst_default_target -m comment --comment "dst_default: $o_dst_default"
 | |
| 		$forward_rules
 | |
| 		COMMIT
 | |
| 		$recentrst_mangle_rules
 | |
| 	EOF
 | |
| }
 | |
| 
 | |
| xray_rules6_iptchains_mkprerules() {
 | |
| 	local proto="$1"
 | |
| 
 | |
| 	if [ -z "$o_ifnames" ]; then
 | |
| 		echo "-A PREROUTING -p $proto -j xr6_${rule}_pre_src"
 | |
| 	else
 | |
| 		echo $o_ifnames \
 | |
| 			| tr ' ' '\n' \
 | |
| 			| sed "s/.*/-I PREROUTING 1 -i \\0 -p $proto -j xr6_${rule}_pre_src/"
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| xray_rules6_fw_drop() {
 | |
| 	fw3 -6 print 2>/dev/null | awk '/iptables/&&/zone_lan_forward/&&/tcp/&&/-t filter/&&/-j reject/ {for(i=6; i<=NF; i++) { printf "%s ",$i } print "\n" }' |
 | |
| 	while IFS=$"\n" read -r c; do
 | |
| 		fwrule=$(echo "$c" | sed 's/reject/REDIRECT --to-ports 65535/')
 | |
| 		if [ -n "$fwrule" ] && [ -z "$(iptables-save | grep zone_lan_prerouting | grep '${fwrule}')" ]; then
 | |
| 			eval "$IP6TABLES -w -t nat -A zone_lan_prerouting ${fwrule} 2>&1 >/dev/null"
 | |
| 		fi
 | |
| 	done
 | |
| 	fw3 -6 print 2>/dev/null | awk '/iptables/&&/zone_lan_forward/&&/tcp/&&/-t filter/&&/-j drop/ {for(i=6; i<=NF; i++) { printf "%s ",$i } print "\n" }' |
 | |
| 	while IFS=$"\n" read -r c; do
 | |
| 		fwrule=$(echo "$c" | sed 's/drop/REDIRECT --to-ports 65535/')
 | |
| 		if [ -n "$fwrule" ] && [ -z "$(iptables-save | grep zone_lan_prerouting | grep '${fwrule}')" ]; then
 | |
| 			eval "$IP6TABLES -t nat -A zone_lan_prerouting ${fwrule} 2>&1 >/dev/null"
 | |
| 		fi
 | |
| 	done
 | |
| }
 | |
| 
 | |
| xray_rules6_parse_args "$@"
 | |
| xray_rules6_flush
 | |
| xray_rules6_ipset_init
 | |
| xray_rules6_iptchains_init
 | |
| xray_rules6_fw_drop |