1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Add Shadowsocks-rust

This commit is contained in:
Ycarus (Yannick Chabanois) 2023-09-29 14:59:32 +02:00
parent ee1ffa2bd8
commit cab2b285e9
7 changed files with 1223 additions and 0 deletions

78
shadowsocks-rust/Makefile Normal file
View file

@ -0,0 +1,78 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2017-2020 Yousong Zhou <yszhou4tech@gmail.com>
# Copyright (C) 2021-2023 ImmortalWrt.org
include $(TOPDIR)/rules.mk
PKG_NAME:=shadowsocks-rust
PKG_VERSION:=1.16.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/shadowsocks/shadowsocks-rust/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=da4c6256247207b2579721046292bab1a2ac62301878c73ff778c168caa8a990
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
PKG_BUILD_DEPENDS:=rust/host
RUST_PKG_FEATURES:=local-redir
include $(INCLUDE_DIR)/package.mk
#include $(TOPDIR)/feeds/packages/lang/rust/rust-package.mk
include $(TOPDIR)/feeds/openmptcprouter/rust/rust-package.mk
define Package/shadowsocks-rust/Default
define Package/shadowsocks-rust-$(1)
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=shadowsocks-rust $(1)
URL:=https://github.com/shadowsocks/shadowsocks-rust
DEPENDS:=$$(RUST_ARCH_DEPENDS)
endef
define Package/shadowsocks-rust-$(1)/install
$$(INSTALL_DIR) $$(1)/usr/bin
$$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/bin/$(1) $$(1)/usr/bin/
endef
endef
define Package/shadowsocks-rust-config
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=shadowsocks-rust config
URL:=https://github.com/shadowsocks/shadowsocks-rust
DEPENDS:=$$(RUST_ARCH_DEPENDS)
endef
define Package/shadowsocks-rust-config/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/ssr-rules $(1)/usr/bin
$(INSTALL_BIN) ./files/ssr-rules6 $(1)/usr/bin
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) ./files/firewall.ssr-rules $(1)/etc
$(INSTALL_BIN) ./files/ssr-rules.defaults $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/shadowsocks-rust.config $(1)/etc/config/shadowsocks-rust
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/shadowsocks-rust.init $(1)/etc/init.d/shadowsocks-rust
endef
SHADOWSOCKS_COMPONENTS:=sslocal ssmanager ssserver ssurl ssservice
define shadowsocks-rust/templates
$(foreach component,$(SHADOWSOCKS_COMPONENTS),
$(call Package/shadowsocks-rust/Default,$(component))
)
endef
$(eval $(call shadowsocks-rust/templates))
$(eval $(call BuildPackage,shadowsocks-rust-config))
$(foreach component,$(SHADOWSOCKS_COMPONENTS), \
$(eval $(call BuildPackage,shadowsocks-rust-$(component))) \
)

View file

@ -0,0 +1,2 @@
#!/bin/sh
/etc/init.d/shadowsocks-rust rules_up

View file

@ -0,0 +1,51 @@
config ss_redir hi1
option server 'sss0'
option local_address '::'
option local_port '1100'
option mode 'tcp_and_udp'
option timeout '1000'
option fast_open 0
option verbose 0
option syslog 1
option reuse_port 1
option mptcp 1
option ipv6_first 1
option no_delay 1
config ss_redir hi2
option server 'sss0'
option local_address '0.0.0.0'
option local_port '1100'
option mode 'tcp_and_udp'
option timeout '1000'
option fast_open 1
option verbose 0
option syslog 1
option reuse_port 1
option mptcp 1
option ipv6_first 1
option no_delay 1
option disabled 1
config ss_rules 'ss_rules'
option disabled 0
option redir_tcp 'hi1'
option src_default 'forward'
option dst_default 'forward'
option local_default 'forward'
option server 'sss0'
config server 'sss0'
option disabled 1
option server '192.168.1.3'
option server_port '65280'
option key ''
option method '2022-blake3-aes-256-gcm'
option obfs 0
config ss_tunnel 'dns'
option disabled 1
option mode 'tcp_and_udp'
option server 'sss0'
option local_port '5353'
option tunnel_address '8.8.8.8:53'

View file

@ -0,0 +1,494 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2017-2019 Yousong Zhou <yszhou4tech@gmail.com>
# Copyright (C) 2019-2021 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
USE_PROCD=1
EXTRA_COMMANDS="rules_up rules_down rules_exist"
START=91
ss_confdir=/var/etc/shadowsocks-rust
ss_bindir=/usr/bin
ss_mkjson_server_conf() {
local cfgserver
config_get cfgserver "$cfg" server
[ -n "$cfgserver" ] || return 1
eval "$(validate_server_section "$cfg" ss_validate_mklocal)"
validate_server_section "$cfgserver" || return 1
[ "$disabled" = 0 ] || return 1
ss_mkjson_server_conf_ "$cfgserver"
}
ss_mkjson_server_conf_() {
[ -n "$server_port" ] || return 1
[ -z "$method" ] || json_add_string method "$method"
[ -z "$server" ] || json_add_string server "$server"
json_add_int server_port "$server_port"
[ -z "$password" ] || {
#password="$(echo $password | sed 's/+/-/g; s/\//_/g;')"
json_add_string password "$password"
}
[ -z "$password" ] && return 1
[ -z "$plugin" ] || json_add_string plugin "$plugin"
[ -z "$plugin_opts" ] || json_add_string plugin_opts "$plugin_opts"
if [ "$obfs" = 1 ]; then
if [ "$obfs_plugin" = "obfs" ]; then
obfs_options="obfs=$obfs_type"
[ -z "$obfs_host" ] || obfs_options="$obfs_options;obfs-host=$obfs_host"
[ -z "$obfs_uri" ] || obfs_options="$obfs_options;obfs-uri=$obfs_uri"
[ "$fast_open" = 1 ] && obfs_options="$obfs_options;fast-open"
[ "$mptcp" = 1 ] && obfs_options="$obfs_options;mptcp"
[ -z "$timeout" ] || obfs_options="$obfs_options;t=$timeout"
json_add_string plugin "/usr/bin/obfs-local"
json_add_string plugin_opts "$obfs_options"
fi
if [ "$obfs_plugin" = "v2ray" ]; then
obfs_options="loglevel=default"
[ "$obfs_type" = "tls" ] && obfs_options="tls"
[ -z "$obfs_host" ] || obfs_options="$obfs_options;host=$obfs_host"
[ -z "$obfs_uri" ] || obfs_options="$obfs_options;path=$obfs_uri"
[ "$fast_open" = 1 ] && obfs_options="$obfs_options;fast-open"
json_add_string plugin "/usr/bin/v2ray-plugin"
json_add_string plugin_opts "$obfs_options"
fi
fi
}
ss_mkjson_ss_local_conf() {
ss_mkjson_server_conf
}
ss_mkjson_ss_redir_conf() {
ss_mkjson_server_conf
}
ss_mkjson_ss_server_conf() {
ss_mkjson_server_conf_
}
ss_mkjson_ss_tunnel_conf() {
ss_mkjson_server_conf || return 1
[ -n "$tunnel_address" ] || return 1
json_add_string tunnel_address "$tunnel_address"
}
ss_xxx() {
local cfg="$1"
local cfgtype="$2"
local bin="$ss_bindir/sslocal"
local confjson="$ss_confdir/$cfgtype.$cfg.json"
[ -x "$bin" ] || return
eval "$("validate_${cfgtype}_section" "$cfg" ss_validate_mklocal)"
"validate_${cfgtype}_section" "$cfg" || return
[ "$disabled" = 0 ] || return
json_init
ss_mkjson_${cfgtype}_conf || return
json_add_boolean use_syslog 1
json_add_boolean ipv6_first "$ipv6_first"
json_add_boolean fast_open "$fast_open"
json_add_boolean reuse_port "$reuse_port"
json_add_boolean no_delay "$no_delay"
json_add_boolean mptcp "$mptcp"
[ "$cfgtype" != "ss_local" ] && json_add_string protocol "${cfgtype/ss_/}"
[ -z "$local_address" ] || json_add_string local_address "$local_address"
[ -z "$local_port" ] || json_add_int local_port "$local_port"
[ -z "$mode" ] || json_add_string mode "$mode"
[ -z "$mtu" ] || json_add_int mtu "$mtu"
[ -z "$timeout" ] || json_add_int timeout "$timeout"
[ -z "$user" ] || json_add_string user "$user"
json_dump -i >"$confjson"
procd_open_instance "$cfgtype.$cfg"
procd_set_param command "$bin" -c "$confjson"
[ "$verbose" = 0 ] || procd_append_param command -v
[ -z "$bind_address" ] || procd_append_param command -b "$bind_address"
procd_set_param file "$confjson"
procd_set_param limits nofile="512000 512000"
procd_set_param respawn
procd_close_instance
ss_rules_cb
}
ss_rules_restart() {
local cfg="$1"
local cfgtype="$2"
eval "$("validate_${cfgtype}_section" "$cfg" ss_validate_mklocal)"
"validate_${cfgtype}_section" "$cfg" || return 1
ss_rules_cb
}
ss_rules_cb() {
local cfgserver server
if [ "$cfgtype" = ss_redir ]; then
config_get cfgserver "$cfg" server
config_get server "$cfgserver" server
ss_redir_servers="$ss_redir_servers $server"
if [ "$mode" = "tcp_only" -o "$mode" = "tcp_and_udp" ]; then
eval "ss_rules_redir_tcp_$cfg=$local_port"
eval "ss_rules6_redir_tcp_$cfg=$local_port"
fi
if [ "$mode" = "udp_only" -o "$mode" = "tcp_and_udp" ]; then
eval "ss_rules_redir_udp_$cfg=$local_port"
eval "ss_rules6_redir_udp_$cfg=$local_port"
fi
fi
}
ss_redir_ports() {
port=$(uci -q get shadowsocks-rust.$1.local_port)
server=$(uci -q get shadowsocks-rust.$1.server)
disabled=$(uci -q get shadowsocks-rust.$1.disabled)
if [ "$disabled" != "1" ] && ([ "$server" = "$2" ] || [ "$2" = "" ]); then
if [ "$port" -lt "$min_ss_redir_ports" ]; then
min_ss_redir_ports=$port
fi
if [ "$port" -gt "$max_ss_redir_ports" ]; then
max_ss_redir_ports=$port
fi
fi
}
ss_rules() {
local cfg="$1"
local bin="$ss_bindir/ssr-rules"
local bin6="$ss_bindir/ssr-rules6"
local cfgtype
local cfgrulesserver
local local_port_tcp local_port_udp
local local_port_tcp6 local_port_udp6
local args
local rule_name
if [ "$cfg" = "ss_rules" ]; then
rule_name="def"
else
rule_name="$(echo $cfg | sed 's/_rule//' | cut -c -7)"
fi
[ -x "$bin" ] || return 1
#"$bin" -f
[ -x "$bin6" ] || return 1
#"$bin6" -f
config_get cfgtype "$cfg" TYPE
[ "$cfgtype" = ss_rules ] || return 1
config_get cfgrulesserver "$cfg" server
eval "$(validate_ss_rules_section "$cfg" ss_validate_mklocal)"
validate_ss_rules_section "$cfg" || return 1
[ "$disabled" != "1" ] || return 0
[ "$(uci -q get shadowsocks-rust.${cfgrulesserver}.disabled)" != "1" ] || return 0
if [ "$ss_rules_redir_tcp_$redir_tcp" = "all" ]; then
min_ss_redir_ports="65535"
max_ss_redir_ports="0"
config_load shadowsocks-rust
config_foreach ss_redir_ports ss_redir $cfgrulesserver
if [ "$min_ss_redir_ports" != "$max_ss_redir_ports" ]; then
all_ss_redir_ports=$min_ss_redir_ports-$max_ss_redir_ports
else
all_ss_redir_ports=$min_ss_redir_ports
fi
local_port_tcp="$all_ss_redir_ports"
if [ "$ss_rules_redir_udp_$redir_udp" = "all" ] || [ "$ss_rules_redir_udp_$redir_udp" = "hi1" ]; then
local_port_udp="$min_ss_redir_ports"
fi
#eval local_port_udp="\$ss_rules_redir_udp_$redir_udp"
local_port_tcp6="$all_ss_redir_ports"
if [ "$ss_rules_redir_udp_$redir_udp" = "all" ] || [ "$ss_rules_redir_udp_$redir_udp" = "hi1" ]; then
local_port_udp6="$min_ss_redir_ports"
fi
#eval local_port_udp6="\$ss_rules6_redir_udp_$redir_udp"
else
eval local_port_tcp="\$ss_rules_redir_tcp_$redir_tcp"
eval local_port_udp="\$ss_rules_redir_udp_$redir_udp"
eval local_port_tcp6="\$ss_rules6_redir_tcp_$redir_tcp"
eval local_port_udp6="\$ss_rules6_redir_udp_$redir_udp"
fi
[ -n "$local_port_tcp" -o -n "$local_port_udp" ] || return 1
ss_redir_servers4="$(echo "$ss_redir_servers" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort -u)"
ss_redir_servers6="$(echo "$ss_redir_servers" | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}' | sort -u)"
[ -z "$ss_redir_servers4" ] && [ -z "$ss_redir_servers6" ] && {
ss_redir_servers4="$ss_redir_servers"
ss_redir_servers6="$ss_redir_servers"
}
#ss_redir_servers="$(echo "$ss_redir_servers" | tr ' ' '\n' | sort -u)"
dst_ips_bypass4="$(echo "$dst_ips_bypass" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort -u)"
dst_ips_forward4="$(echo "$dst_ips_forward" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort -u)"
src_ips_bypass4="$(echo "$src_ips_bypass" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort -u)"
src_ips_forward4="$(echo "$src_ips_forward" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort -u)"
src_ips_checkdst4="$(echo "$src_ips_checkdst" | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' | sort -u)"
dst_ips_bypass6="$(echo "$dst_ips_bypass" | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}' | sort -u)"
dst_ips_forward6="$(echo "$dst_ips_forward" | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}' | sort -u)"
src_ips_bypass6="$(echo "$src_ips_bypass" | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}' | sort -u)"
src_ips_forward6="$(echo "$src_ips_forward" | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}' | sort -u)"
src_ips_checkdst6="$(echo "$src_ips_checkdst" | grep -o '\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}' | sort -u)"
[ -z "$dst_ips_bypass4" ] && [ -z "$dst_ips_bypass6" ] && {
dst_ips_bypass4="$dst_ips_bypass"
dst_ips_bypass6="$dst_ips_bypass"
}
[ -z "$dst_ips_forward4" ] && [ -z "$dst_ips_forward6" ] && {
dst_ips_forward4="$dst_ips_forward"
dst_ips_forward6="$dst_ips_forward"
}
[ -z "$src_ips_bypass4" ] && [ -z "$src_ips_bypass6" ] && {
src_ips_bypass4="$src_ips_bypass"
src_ips_bypass6="$src_ips_bypass"
}
[ -z "$src_ips_forward4" ] && [ -z "$src_ips_forward6" ] && {
src_ips_forward4="$src_ips_forward"
src_ips_forward6="$src_ips_forward"
}
[ -z "$src_ips_checkdst4" ] && [ -z "$src_ips_checkdst6" ] && {
src_ips_checkdst4="$src_ips_checkdst"
src_ips_checkdst6="$src_ips_checkdst"
}
[ "$dst_forward_recentrst" = 0 ] || args="$args --dst-forward-recentrst"
ss_rules_call
ss_rules_call6
}
ss_rules_call() {
"$bin" "$@" \
-s "$ss_redir_servers4" \
${local_port_tcp:+-l "$local_port_tcp"} \
${local_port_udp:+-L "$local_port_udp"} \
${src_default:+--src-default "$src_default"} \
${dst_default:+--dst-default "$dst_default"} \
${local_default:+--local-default "$local_default"} \
${dst_ips_bypass_file:+--dst-bypass-file "$dst_ips_bypass_file"} \
${dst_ips_forward_file:+--dst-forward-file "$dst_ips_forward_file"} \
${dst_ips_bypass4:+--dst-bypass "$dst_ips_bypass4"} \
${dst_ips_forward4:+--dst-forward "$dst_ips_forward4"} \
${src_ips_bypass4:+--src-bypass "$src_ips_bypass4"} \
${src_ips_forward4:+--src-forward "$src_ips_forward4"} \
${src_ips_checkdst4:+--src-checkdst "$src_ips_checkdst4"} \
${ifnames:+--ifnames "$ifnames"} \
${ipt_args:+--ipt-extra "$ipt_args"} \
${cfg:+--rule-name "$rule_name"} \
$args \
|| "$bin" "$@" -f
}
ss_rules_call6() {
"$bin6" "$@" \
-s "$ss_redir_servers6" \
${local_port_tcp:+-l "$local_port_tcp6"} \
${local_port_udp:+-L "$local_port_udp6"} \
${src_default:+--src-default "$src_default"} \
${dst_default:+--dst-default "$dst_default"} \
${local_default:+--local-default "$local_default"} \
${dst_ips_bypass_file:+--dst-bypass-file "$dst_ips_bypass_file"} \
${dst_ips_forward_file:+--dst-forward-file "$dst_ips_forward_file"} \
${dst_ips_bypass6:+--dst-bypass "$dst_ips_bypass6"} \
${dst_ips_forward6:+--dst-forward "$dst_ips_forward6"} \
${src_ips_bypass6:+--src-bypass "$src_ips_bypass6"} \
${src_ips_forward6:+--src-forward "$src_ips_forward6"} \
${src_ips_checkdst6:+--src-checkdst "$src_ips_checkdst6"} \
${ifnames:+--ifnames "$ifnames"} \
${ipt_args:+--ipt-extra "$ipt_args"} \
${cfg:+--rule-name "$rule_name"} \
$args \
|| "$bin6" "$@" -f
}
start_service() {
local cfgtype
mkdir -p "$ss_confdir"
config_load shadowsocks-rust
for cfgtype in ss_local ss_redir ss_server ss_tunnel; do
config_foreach ss_xxx "$cfgtype" "$cfgtype"
done
# Add rule to match traffic marked by firewall for bypass
ip rule add prio 1 fwmark 0x539 lookup 991337 > /dev/null 2>&1
rules_up
[ -f /etc/firewall.gre-tunnel ] && sh /etc/firewall.gre-tunnel > /dev/null 2>&1
}
stop_service() {
rules_down
rm -rf "$ss_confdir"
}
reload_service() {
restart "$@"
}
rules_exist() {
[ -n "$(iptables-save 2>/dev/null | grep 'A ssr')" ] && return 0
return 1
}
server_state() {
config_get disabled "$1" disabled "0"
[ "$disabled" = "0" ] && enabled="1"
config_get password "$1" password
[ -n "$password" ] && passkey=$password
}
rules_up() {
rules_exist && {
[ -f /bin/blocklanfw ] && /bin/blocklanfw 2>&1 >/dev/null
return 0
}
[ "$(uci -q get shadowsocks-rust.ss_rules.disabled)" = "1" ] && return 0
enabled="0"
passkey=""
config_load shadowsocks-rust
config_foreach server_state server
[ "$enabled" = "0" ] && return
[ -z "$passkey" ] && return
logger -t "Shadowsocks-rust" "Rules UP"
for cfgtype in ss_redir; do
config_foreach ss_rules_restart "$cfgtype" "$cfgtype"
done
config_foreach ss_rules ss_rules
[ -z "$(iptables-save 2>/dev/null | grep :ssr)" ] && logger -t "Shadowsocks-rust" "Rules not applied"
[ -f /etc/init.d/omr-bypass ] && [ -z "$(pgrep -f omr-bypass)" ] && {
logger -t "Shadowsocks-rust" "Reload omr-bypass rules"
/etc/init.d/omr-bypass reload_rules
}
[ -f /bin/blocklanfw ] && /bin/blocklanfw 2>&1 >/dev/null
}
rules_down() {
rules_exist || return 0
logger -t "Shadowsocks-rust" "Rules DOWN"
local bin="$ss_bindir/ssr-rules"
[ -x "$bin" ] && {
"$bin" -f >/dev/null 2>&1
}
local bin6="$ss_bindir/ssr-rules6"
[ -x "$bin6" ] && {
"$bin6" -f >/dev/null 2>&1
}
}
service_triggers() {
procd_add_reload_interface_trigger wan*
procd_add_reload_trigger shadowsocks-rust
procd_open_validate
validate_server_section
validate_ss_local_section
validate_ss_redir_section
validate_ss_rules_section
validate_ss_server_section
validate_ss_tunnel_section
procd_close_validate
}
ss_validate_mklocal() {
local tuple opts
shift 2
for tuple in "$@"; do
opts="${tuple%%:*} $opts"
done
[ -z "$opts" ] || echo "local $opts"
}
ss_validate() {
uci_validate_section shadowsocks-rust "$@"
}
validate_common_server_options_() {
local cfgtype="$1"; shift
local cfg="$1"; shift
local func="$1"; shift
local stream_methods='"none", "plain", "chacha20-ietf-poly1305"'
local aead_methods='"aes-128-gcm", "aes-256-gcm","2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "chacha20-ietf-poly1305", "2022-blake3-chacha20-poly1305","2022-blake3-chacha8-poly1305"'
"${func:-ss_validate}" "$cfgtype" "$cfg" "$@" \
'disabled:bool:0' \
'server:host' \
'server_port:port' \
'password:string' \
"method:or($stream_methods, $aead_methods)" \
'plugin:string' \
'plugin_opts:string' \
'obfs:bool:0' \
'obfs_plugin:or("v2ray","obfs"):v2ray' \
'obfs_type:or("http","tls"):http'
}
validate_common_client_options_() {
validate_common_options_ "$@" \
'server:uci("shadowsocks-rust", "@server")' \
'local_address:host:0.0.0.0' \
'local_port:port'
}
validate_common_options_() {
local cfgtype="$1"; shift
local cfg="$1"; shift
local func="$1"; shift
"${func:-ss_validate}" "$cfgtype" "$cfg" "$@" \
'disabled:bool:0' \
'fast_open:bool:0' \
'ipv6_first:bool:0' \
'no_delay:bool:0' \
'mptcp:bool:0' \
'reuse_port:bool:0' \
'verbose:bool:0' \
'mode:or("tcp_only", "udp_only", "tcp_and_udp"):tcp_only' \
'mtu:uinteger' \
'timeout:uinteger' \
'user:string'
}
validate_server_section() {
validate_common_server_options_ server "$1" "$2"
}
validate_ss_local_section() {
validate_common_client_options_ ss_local "$1" "$2"
}
validate_ss_redir_section() {
validate_common_client_options_ ss_redir "$1" "$2"
}
validate_ss_rules_section() {
"${2:-ss_validate}" ss_rules "$1" \
'disabled:bool:0' \
'redir_tcp:or(uci("shadowsocks-rust", "@ss_redir"),"all")' \
'redir_udp:or(uci("shadowsocks-rust", "@ss_redir"),"all")' \
'src_ips_bypass:or(ipaddr,cidr)' \
'src_ips_forward:or(ipaddr,cidr)' \
'src_ips_checkdst:or(ipaddr,cidr)' \
'dst_ips_bypass_file:file' \
'dst_ips_bypass:or(ipaddr,cidr)' \
'dst_ips_forward_file:file' \
'dst_ips_forward:or(ipaddr,cidr)' \
'src_default:or("bypass", "forward", "checkdst"):checkdst' \
'dst_default:or("bypass", "forward"):bypass' \
'local_default:or("bypass", "forward", "checkdst"):bypass' \
'dst_forward_recentrst:bool:0' \
'ifnames:maxlength(15)' \
'ipt_args:string'
}
validate_ss_server_section() {
validate_common_server_options_ ss_server "$1" \
validate_common_options_ \
"$2" \
'bind_address:ipaddr'
}
validate_ss_tunnel_section() {
validate_common_client_options_ ss_tunnel "$1" \
"$2" \
'tunnel_address:regex(".+\:[0-9]+")'
}

301
shadowsocks-rust/files/ssr-rules Executable file
View file

@ -0,0 +1,301 @@
#!/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
IPTABLES="/usr/sbin/iptables-legacy"
IPTABLESRESTORE="/usr/sbin/iptables-legacy-restore"
IPTABLESSAVE="/usr/sbin/iptables-legacy-save"
else
IPTABLES="/usr/sbin/iptables"
IPTABLESRESTORE="/usr/sbin/iptables-restore"
IPTABLESSAVE="/usr/sbin/iptables-save"
fi
ss_rules_usage() {
cat >&2 <<EOF
Usage: ss-rules [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 ss-rules. They are also intended to be
populated by other programs like dnsmasq with ipset support
ss_rules_src_bypass
ss_rules_src_forward
ss_rules_src_checkdst
ss_rules_dst_bypass
ss_rules_dst_bypass_all
ss_rules_dst_forward
EOF
}
o_dst_bypass_="
0.0.0.0/8
10.0.0.0/8
100.64.0.0/10
127.0.0.0/8
169.254.0.0/16
172.16.0.0/12
192.0.0.0/24
192.0.2.0/24
192.31.196.0/24
192.52.193.0/24
192.88.99.0/24
192.168.0.0/16
192.175.48.0/24
198.18.0.0/15
198.51.100.0/24
203.0.113.0/24
224.0.0.0/4
240.0.0.0/4
255.255.255.255
"
o_src_default=bypass
o_dst_default=bypass
o_local_default=bypass
__errmsg() {
echo "ss-rules: $*" >&2
}
ss_rules_parse_args() {
while [ "$#" -gt 0 ]; do
case "$1" in
-h|--help) ss_rules_usage; exit 0;;
-f|--flush) ss_rules_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" ] && ! $IPTABLES -w -m recent -h >/dev/null; then
__errmsg "Please install iptables-mod-conntrack-extra with opkg"
return 1
fi
o_remote_servers="$(for s in $o_remote_servers; do resolveip -4 "$s"; done)"
}
ss_rules_flush() {
local setname
$IPTABLESSAVE --counters 2>/dev/null | grep -v ssr_ | $IPTABLESRESTORE --counters
while ip rule del fwmark 1 lookup 100 2>/dev/null; do true; done
ip route flush table 100 || true
for setname in $(ipset -n list | grep "ssr_${rule}"); do
ipset destroy "$setname" 2>/dev/null || true
done
}
ss_rules_ipset_init() {
ipset --exist restore <<-EOF
create ssr_${rule}_src_bypass hash:net hashsize 64
create ssr_${rule}_src_forward hash:net hashsize 64
create ssr_${rule}_src_checkdst hash:net hashsize 64
create ss_rules_dst_bypass_all hash:net hashsize 64
create ssr_${rule}_dst_bypass hash:net hashsize 64
create ssr_${rule}_dst_bypass_ hash:net hashsize 64
create ssr_${rule}_dst_forward hash:net hashsize 64
create ss_rules_dst_forward_recentrst_ hash:ip hashsize 64 timeout 3600
$(ss_rules_ipset_mkadd ssr_${rule}_dst_bypass_ "$o_dst_bypass_ $o_remote_servers")
$(ss_rules_ipset_mkadd ss_rules_dst_bypass_all "$o_dst_bypass_all")
$(ss_rules_ipset_mkadd ssr_${rule}_dst_bypass "$o_dst_bypass $(cat "$o_dst_bypass_file" 2>/dev/null | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}')")
$(ss_rules_ipset_mkadd ssr_${rule}_src_bypass "$o_src_bypass")
$(ss_rules_ipset_mkadd ssr_${rule}_src_forward "$o_src_forward")
$(ss_rules_ipset_mkadd ssr_${rule}_src_checkdst "$o_src_checkdst")
$(ss_rules_ipset_mkadd ssr_${rule}_dst_forward "$o_dst_forward $(cat "$o_dst_forward_file" 2>/dev/null | grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}')")
EOF
}
ss_rules_ipset_mkadd() {
local setname="$1"; shift
local i
for i in $*; do
echo "add $setname $i"
done
}
ss_rules_iptchains_init() {
ss_rules_iptchains_init_mark
ss_rules_iptchains_init_tcp
ss_rules_iptchains_init_udp
}
ss_rules_iptchains_init_mark() {
if [ "$($IPTABLES -w -t mangle -L PREROUTING | grep ss_rules_dst_bypass_all)" = "" ]; then
$IPTABLESRESTORE --noflush <<-EOF
*mangle
-A PREROUTING -m set --match-set ss_rules_dst_bypass_all dst -j MARK --set-mark 0x539
COMMIT
EOF
fi
}
ss_rules_iptchains_init_tcp() {
local local_target
[ -n "$o_redir_tcp_port" ] || return 0
ss_rules_iptchains_init_ nat tcp
case "$o_local_default" in
checkdst) local_target=ssr_${rule}_dst ;;
forward) local_target=ssr_${rule}_forward ;;
bypass|*) return 0;;
esac
if [ "$($IPTABLESSAVE 2>/dev/null | grep ssr_${rule}_local_out | grep ssr_${rule}_dst_bypass)" = "" ]; then
$IPTABLESRESTORE --noflush <<-EOF
*nat
:ssr_${rule}_local_out -
-I OUTPUT 1 -p tcp -j ssr_${rule}_local_out
-A ssr_${rule}_local_out -m set --match-set ssr_${rule}_dst_bypass dst -j RETURN
-A ssr_${rule}_local_out -m set --match-set ss_rules_dst_bypass_all dst -j RETURN
-A ssr_${rule}_local_out -m set --match-set ssr_${rule}_dst_bypass_ dst -j RETURN
-A ssr_${rule}_local_out -m mark --mark 0x539 -j RETURN
-A ssr_${rule}_local_out -p tcp $o_ipt_extra -j $local_target -m comment --comment "local_default: $o_local_default"
COMMIT
EOF
fi
}
ss_rules_iptchains_init_udp() {
[ -n "$o_redir_udp_port" ] || return 0
ss_rules_iptchains_init_ mangle udp
}
ss_rules_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 ssr_${rule}_forward -p tcp -j REDIRECT --to-ports $o_redir_tcp_port"
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_rules_recentrst --set --rsource
COMMIT
"
recentrst_addset_rules="
-A ssr_${rule}_dst -m recent --name ss_rules_recentrst --rcheck --rdest --seconds 3 --hitcount 3 -j SET --add-set ss_rules_dst_forward_recentrst_ dst --exist
-A ssr_${rule}_dst -m set --match-set ss_rules_dst_forward_recentrst_ dst -j ssr_${rule}_forward
"
fi
;;
udp)
ip rule add fwmark 1 lookup 100 || true
ip route add local default dev lo table 100 || true
forward_rules="-A ssr_${rule}_forward -p udp -j TPROXY --on-port "$o_redir_udp_port" --tproxy-mark 0x01/0x01"
;;
esac
case "$o_src_default" in
forward) src_default_target=ssr_${rule}_forward ;;
checkdst) src_default_target=ssr_${rule}_dst ;;
bypass|*) src_default_target=RETURN ;;
esac
case "$o_dst_default" in
forward) dst_default_target=ssr_${rule}_forward ;;
bypass|*) dst_default_target=RETURN ;;
esac
sed -e '/^\s*$/d' -e 's/^\s\+//' <<-EOF | $IPTABLESRESTORE --noflush
*$table
:ssr_${rule}_pre_src -
:ssr_${rule}_src -
:ssr_${rule}_dst -
:ssr_${rule}_forward -
$(ss_rules_iptchains_mkprerules "$proto")
-A ssr_${rule}_pre_src -m set --match-set ssr_${rule}_dst_bypass_ dst -j RETURN
-A ssr_${rule}_pre_src -m set --match-set ss_rules_dst_bypass_all dst -j MARK --set-mark 0x539
-A ssr_${rule}_pre_src -m set --match-set ss_rules_dst_bypass_all dst -j RETURN
-A ssr_${rule}_pre_src -m set --match-set ssr_${rule}_dst_bypass dst -j RETURN
-A ssr_${rule}_pre_src -m mark --mark 0x539 -j RETURN
-A ssr_${rule}_dst -m set --match-set ss_rules_dst_bypass_all dst -j RETURN
-A ssr_${rule}_dst -m set --match-set ssr_${rule}_dst_bypass dst -j RETURN
-A ssr_${rule}_pre_src -p $proto $o_ipt_extra -j ssr_${rule}_src
-A ssr_${rule}_src -m set --match-set ssr_${rule}_src_bypass src -j RETURN
-A ssr_${rule}_src -m set --match-set ssr_${rule}_src_forward src -j ssr_${rule}_forward
-A ssr_${rule}_src -m set --match-set ssr_${rule}_src_checkdst src -j ssr_${rule}_dst
-A ssr_${rule}_src -j $src_default_target -m comment --comment "src_default: $o_src_default"
-A ssr_${rule}_dst -m set --match-set ssr_${rule}_dst_forward dst -j ssr_${rule}_forward
$recentrst_addset_rules
-A ssr_${rule}_dst -j $dst_default_target -m comment --comment "dst_default: $o_dst_default"
$forward_rules
COMMIT
$recentrst_mangle_rules
EOF
}
ss_rules_iptchains_mkprerules() {
local proto="$1"
if [ -z "$o_ifnames" ]; then
echo "-A PREROUTING -p $proto -j ssr_${rule}_pre_src"
else
echo $o_ifnames \
| tr ' ' '\n' \
| sed "s/.*/-I PREROUTING 1 -i \\0 -p $proto -j ssr_${rule}_pre_src/"
fi
}
ss_rules_parse_args "$@"
#ss_rules_flush
ss_rules_ipset_init
ss_rules_iptchains_init

View file

@ -0,0 +1,12 @@
#!/bin/sh
s=firewall.ssr_rules
uci get "$s" >/dev/null || {
uci batch <<-EOF
set $s=include
set $s.path=/etc/firewall.ssr-rules
set $s.reload=1
commit firewall
EOF
}
exit 0

285
shadowsocks-rust/files/ssr-rules6 Executable file
View file

@ -0,0 +1,285 @@
#!/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
ss_rules6_usage() {
cat >&2 <<EOF
Usage: ss-rules [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 ss-rules. They are also intended to be
populated by other programs like dnsmasq with ipset support
ss_rules6_src_bypass
ss_rules6_src_forward
ss_rules6_src_checkdst
ss_rules6_dst_bypass
ss_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 "ss-rules6: $*" >&2
}
ss_rules6_parse_args() {
while [ "$#" -gt 0 ]; do
case "$1" in
-h|--help) ss_rules6_usage; exit 0;;
-f|--flush) ss_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)"
}
ss_rules6_flush() {
local setname
$IP6TABLESSAVE --counters 2>/dev/null | grep -v ssr6_ | $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
}
ss_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 ssr6_${rule}_dst_forward_recrst_ hash:ip family inet6 hashsize 64 timeout 3600
$(ss_rules6_ipset_mkadd ssr6_${rule}_dst_bypass_ "$o_dst_bypass_ $o_remote_servers")
$(ss_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\}')")
$(ss_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\}')")
$(ss_rules6_ipset_mkadd ssr6_${rule}_src_bypass "$o_src_bypass")
$(ss_rules6_ipset_mkadd ssr6_${rule}_src_forward "$o_src_forward")
$(ss_rules6_ipset_mkadd ssr6_${rule}_src_checkdst "$o_src_checkdst")
$(ss_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
}
ss_rules6_ipset_mkadd() {
local setname="$1"; shift
local i
for i in $*; do
echo "add $setname $i"
done
}
ss_rules6_iptchains_init() {
ss_rules6_iptchains_init_mark
ss_rules6_iptchains_init_tcp
ss_rules6_iptchains_init_udp
}
ss_rules6_iptchains_init_mark() {
if [ "$($IP6TABLES -w -t mangle -L PREROUTING | grep ss_rules6_dst_bypass_all)" = "" ]; then
$IP6TABLESRESTORE --noflush <<-EOF
*mangle
-A PREROUTING -m set --match-set ss_rules6_dst_bypass_all dst -j MARK --set-mark 0x6539
COMMIT
EOF
fi
}
ss_rules6_iptchains_init_tcp() {
local local_target
[ -n "$o_redir_tcp_port" ] || return 0
ss_rules6_iptchains_init_ nat tcp
case "$o_local_default" in
checkdst) local_target=ssr6_${rule}_dst ;;
forward) local_target=ssr6_${rule}_forward ;;
bypass|*) return 0;;
esac
$IP6TABLESRESTORE --noflush <<-EOF
*nat
:ssr6_${rule}_local_out -
-I OUTPUT 1 -p tcp -j ssr6_${rule}_local_out
-A ssr6_${rule}_local_out -m set --match-set ssr6_${rule}_dst_bypass dst -j RETURN
-A ssr6_${rule}_local_out -m set --match-set ss_rules6_dst_bypass_all dst -j RETURN
-A ssr6_${rule}_local_out -m set --match-set ssr6_${rule}_dst_bypass_ dst -j RETURN
-A ssr6_${rule}_local_out -m mark --mark 0x6539 -j RETURN
-A ssr6_${rule}_local_out -p tcp $o_ipt_extra -j $local_target -m comment --comment "local_default: $o_local_default"
COMMIT
EOF
}
ss_rules6_iptchains_init_udp() {
[ -n "$o_redir_udp_port" ] || return 0
ss_rules6_iptchains_init_ mangle udp
}
ss_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 ssr6_${rule}_forward -p tcp -j REDIRECT --to-ports $o_redir_tcp_port"
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 ssr6_${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 ssr6_${rule}_dst -m set --match-set ss_rules6_dst_forward_recrst_ dst -j ssr6_${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 ssr6_${rule}_forward -p udp -j TPROXY --on-port "$o_redir_udp_port" --tproxy-mark 0x01/0x01"
;;
esac
case "$o_src_default" in
forward) src_default_target=ssr6_${rule}_forward ;;
checkdst) src_default_target=ssr6_${rule}_dst ;;
bypass|*) src_default_target=RETURN ;;
esac
case "$o_dst_default" in
forward) dst_default_target=ssr6_${rule}_forward ;;
bypass|*) dst_default_target=RETURN ;;
esac
sed -e '/^\s*$/d' -e 's/^\s\+//' <<-EOF | $IP6TABLESRESTORE --noflush
*$table
:ssr6_${rule}_pre_src -
:ssr6_${rule}_src -
:ssr6_${rule}_dst -
:ssr6_${rule}_forward -
$(ss_rules6_iptchains_mkprerules "$proto")
-A ssr6_${rule}_pre_src -m set --match-set ssr6_${rule}_dst_bypass_ dst -j RETURN
-A ssr6_${rule}_pre_src -m set --match-set ss_rules6_dst_bypass_all dst -j MARK --set-mark 0x6539
-A ssr6_${rule}_pre_src -m set --match-set ss_rules6_dst_bypass_all dst -j RETURN
-A ssr6_${rule}_pre_src -m set --match-set ssr6_${rule}_dst_bypass dst -j RETURN
-A ssr6_${rule}_pre_src -m mark --mark 0x6539 -j RETURN
-A ssr6_${rule}_dst -m set --match-set ss_rules6_dst_bypass_all dst -j RETURN
-A ssr6_${rule}_dst -m set --match-set ssr6_${rule}_dst_bypass dst -j RETURN
-A ssr6_${rule}_pre_src -p $proto $o_ipt_extra -j ssr6_${rule}_src
-A ssr6_${rule}_src -m set --match-set ssr6_${rule}_src_bypass src -j RETURN
-A ssr6_${rule}_src -m set --match-set ssr6_${rule}_src_forward src -j ssr6_${rule}_forward
-A ssr6_${rule}_src -m set --match-set ssr6_${rule}_src_checkdst src -j ssr6_${rule}_dst
-A ssr6_${rule}_src -j $src_default_target -m comment --comment "src_default: $o_src_default"
-A ssr6_${rule}_dst -m set --match-set ssr6_${rule}_dst_forward dst -j ssr6_${rule}_forward
$recentrst_addset_rules
-A ssr6_${rule}_dst -j $dst_default_target -m comment --comment "dst_default: $o_dst_default"
$forward_rules
COMMIT
$recentrst_mangle_rules
EOF
}
ss_rules6_iptchains_mkprerules() {
local proto="$1"
if [ -z "$o_ifnames" ]; then
echo "-A PREROUTING -p $proto -j ssr6_${rule}_pre_src"
else
echo $o_ifnames \
| tr ' ' '\n' \
| sed "s/.*/-I PREROUTING 1 -i \\0 -p $proto -j ssr6_${rule}_pre_src/"
fi
}
ss_rules6_parse_args "$@"
ss_rules6_flush
ss_rules6_ipset_init
ss_rules6_iptchains_init