mirror of
https://github.com/Ysurac/openmptcprouter-feeds.git
synced 2025-02-14 19:41:51 +00:00
Add nftables support to Shadowsocks-rust
This commit is contained in:
parent
1d4a964169
commit
e6bcc2951c
5 changed files with 628 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
#
|
||||
# Copyright (C) 2017-2020 Yousong Zhou <yszhou4tech@gmail.com>
|
||||
# Copyright (C) 2021-2023 ImmortalWrt.org
|
||||
# Copyright (C) 2023 Yannick Chabanois (Ycarus) for OpenMPTCProuter
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
|
@ -64,6 +65,34 @@ define Package/shadowsocks-rust-config/install
|
|||
$(INSTALL_BIN) ./files/shadowsocks-rust.init $(1)/etc/init.d/shadowsocks-rust
|
||||
endef
|
||||
|
||||
define Package/shadowsocks-rust-config-nft
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Web Servers/Proxies
|
||||
TITLE:=shadowsocks-rust config
|
||||
URL:=https://github.com/shadowsocks/shadowsocks-rust
|
||||
DEPENDS:=+firewall4 \
|
||||
+ip \
|
||||
+resolveip \
|
||||
+ucode \
|
||||
+ucode-mod-fs \
|
||||
+kmod-nft-tproxy
|
||||
endef
|
||||
|
||||
|
||||
define Package/shadowsocks-rust-config-nft/install
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(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-nft $(1)/etc/init.d/shadowsocks-rust
|
||||
$(INSTALL_DIR) $(1)/usr/share/ssr-rules
|
||||
$(INSTALL_DATA) ./files/nft-rules/* $(1)/usr/share/ssr-rules/
|
||||
endef
|
||||
|
||||
|
||||
|
||||
SHADOWSOCKS_COMPONENTS:=sslocal ssmanager ssserver ssurl ssservice
|
||||
define shadowsocks-rust/templates
|
||||
$(foreach component,$(SHADOWSOCKS_COMPONENTS),
|
||||
|
@ -73,6 +102,7 @@ endef
|
|||
$(eval $(call shadowsocks-rust/templates))
|
||||
|
||||
$(eval $(call BuildPackage,shadowsocks-rust-config))
|
||||
$(eval $(call BuildPackage,shadowsocks-rust-config-nft))
|
||||
$(foreach component,$(SHADOWSOCKS_COMPONENTS), \
|
||||
$(eval $(call BuildPackage,shadowsocks-rust-$(component))) \
|
||||
)
|
||||
|
|
126
shadowsocks-rust/files/nft-rules/chain.uc
Normal file
126
shadowsocks-rust/files/nft-rules/chain.uc
Normal file
|
@ -0,0 +1,126 @@
|
|||
{%
|
||||
function get_local_verdict() {
|
||||
let v = o_local_default;
|
||||
if (v == "checkdst") {
|
||||
return "goto ss_rules_dst_" + proto;
|
||||
} else if (v == "forward") {
|
||||
return "goto ss_rules_forward_" + proto;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function get_src_default_verdict() {
|
||||
let v = o_src_default;
|
||||
if (v == "checkdst") {
|
||||
return "goto ss_rules_dst_" + proto;
|
||||
} else if (v == "forward") {
|
||||
return "goto ss_rules_forward_" + proto;
|
||||
} else {
|
||||
return "accept";
|
||||
}
|
||||
}
|
||||
|
||||
function get_dst_default_verdict() {
|
||||
let v = o_dst_default;
|
||||
if (v == "forward") {
|
||||
return "goto ss_rules_forward_" + proto;
|
||||
} else {
|
||||
return "accept";
|
||||
}
|
||||
}
|
||||
|
||||
function get_ifnames() {
|
||||
let res = [];
|
||||
for (let ifname in split(o_ifnames, /[ \t\n]/)) {
|
||||
ifname = trim(ifname);
|
||||
if (ifname) push(res, ifname);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
let type, hook, priority, redir_port;
|
||||
if (proto == "tcp") {
|
||||
type = "nat";
|
||||
hook = "prerouting";
|
||||
priority = -1;
|
||||
redir_port = o_redir_tcp_port;
|
||||
} else if (proto == "udp") {
|
||||
type = "filter";
|
||||
hook = "prerouting";
|
||||
priority = "mangle";
|
||||
redir_port = o_redir_udp_port;
|
||||
if (system("
|
||||
set -o errexit
|
||||
iprr() {
|
||||
while ip $1 rule del fwmark 1 lookup 100 2>/dev/null; do true; done
|
||||
ip $1 rule add fwmark 1 lookup 100
|
||||
ip $1 route flush table 100 2>/dev/null || true
|
||||
ip $1 route add local default dev lo table 100
|
||||
}
|
||||
iprr -4
|
||||
iprr -6
|
||||
") != 0) {
|
||||
return ;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
%}
|
||||
{% if (redir_port): %}
|
||||
|
||||
chain ss_rules_pre_{{ proto }} {
|
||||
type {{ type }} hook {{ hook }} priority {{ priority }};
|
||||
meta l4proto {{ proto }}{%- let ifnames=get_ifnames(); if (length(ifnames)): %} iifname { {{join(", ", ifnames)}} }{% endif %} goto ss_rules_pre_src_{{ proto }};
|
||||
}
|
||||
|
||||
chain ss_rules_pre_src_{{ proto }} {
|
||||
ip daddr @ss_rules_dst_bypass_ accept;
|
||||
ip6 daddr @ss_rules6_dst_bypass_ accept;
|
||||
goto ss_rules_src_{{ proto }};
|
||||
}
|
||||
|
||||
chain ss_rules_src_{{ proto }} {
|
||||
ip saddr @ss_rules_src_bypass accept;
|
||||
ip saddr @ss_rules_src_forward goto ss_rules_forward_{{ proto }};
|
||||
ip saddr @ss_rules_src_checkdst goto ss_rules_dst_{{ proto }};
|
||||
ip6 saddr @ss_rules6_src_bypass accept;
|
||||
ip6 saddr @ss_rules6_src_forward goto ss_rules_forward_{{ proto }};
|
||||
ip6 saddr @ss_rules6_src_checkdst goto ss_rules_dst_{{ proto }};
|
||||
{{ get_src_default_verdict() }};
|
||||
}
|
||||
|
||||
chain ss_rules_dst_{{ proto }} {
|
||||
ip daddr @ss_rules_dst_bypass accept;
|
||||
ip daddr @ss_rules_remote_servers accept;
|
||||
ip daddr @ss_rules_dst_forward goto ss_rules_forward_{{ proto }};
|
||||
ip6 daddr @ss_rules6_dst_bypass accept;
|
||||
ip6 daddr @ss_rules6_remote_servers accept;
|
||||
ip6 daddr @ss_rules6_dst_forward goto ss_rules_forward_{{ proto }};
|
||||
{{ get_dst_default_verdict() }};
|
||||
}
|
||||
|
||||
{% if (proto == "tcp"): %}
|
||||
chain ss_rules_forward_{{ proto }} {
|
||||
meta l4proto tcp {{ o_nft_tcp_extra }} redirect to :{{ redir_port }};
|
||||
}
|
||||
{% let local_verdict = get_local_verdict(); if (local_verdict): %}
|
||||
chain ss_rules_local_out {
|
||||
type {{ type }} hook output priority -1;
|
||||
meta l4proto != tcp accept;
|
||||
ip daddr @ss_rules_remote_servers accept;
|
||||
ip daddr @ss_rules_dst_bypass_ accept;
|
||||
ip daddr @ss_rules_dst_bypass accept;
|
||||
ip6 daddr @ss_rules6_remote_servers accept;
|
||||
ip6 daddr @ss_rules6_dst_bypass_ accept;
|
||||
ip6 daddr @ss_rules6_dst_bypass accept;
|
||||
{{ local_verdict }};
|
||||
}
|
||||
{% endif %}
|
||||
{% elif (proto == "udp"): %}
|
||||
chain ss_rules_forward_{{ proto }} {
|
||||
meta l4proto udp {{ o_nft_udp_extra }} meta mark set 1 tproxy to :{{ redir_port }};
|
||||
}
|
||||
{% endif %}
|
||||
{% endif %}
|
117
shadowsocks-rust/files/nft-rules/set.uc
Normal file
117
shadowsocks-rust/files/nft-rules/set.uc
Normal file
|
@ -0,0 +1,117 @@
|
|||
{%
|
||||
let fs = require("fs");
|
||||
|
||||
let o_dst_bypass4_ = "
|
||||
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.168.0.0/16
|
||||
192.31.196.0/24
|
||||
192.52.193.0/24
|
||||
192.88.99.0/24
|
||||
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
|
||||
";
|
||||
let o_dst_bypass6_ = "
|
||||
::1/128
|
||||
::/128
|
||||
::ffff:0:0/96
|
||||
64:ff9b:1::/48
|
||||
100::/64
|
||||
fe80::/10
|
||||
2001::/23
|
||||
fc00::/7
|
||||
";
|
||||
let o_dst_bypass_ = o_dst_bypass4_ + " " + o_dst_bypass6_;
|
||||
|
||||
let set_suffix = {
|
||||
"src_bypass": {
|
||||
str: o_src_bypass,
|
||||
},
|
||||
"src_forward": {
|
||||
str: o_src_forward,
|
||||
},
|
||||
"src_checkdst": {
|
||||
str: o_src_checkdst,
|
||||
},
|
||||
"remote_servers": {
|
||||
str: o_remote_servers
|
||||
},
|
||||
"dst_bypass": {
|
||||
str: o_dst_bypass,
|
||||
file: o_dst_bypass_file,
|
||||
},
|
||||
"dst_bypass_": {
|
||||
str: o_dst_bypass_,
|
||||
},
|
||||
"dst_forward": {
|
||||
str: o_dst_forward,
|
||||
file: o_dst_forward_file,
|
||||
},
|
||||
"dst_forward_rrst_": {},
|
||||
};
|
||||
|
||||
function set_name(suf, af) {
|
||||
if (af == 4) {
|
||||
return "ss_rules_"+suf;
|
||||
} else {
|
||||
return "ss_rules6_"+suf;
|
||||
}
|
||||
}
|
||||
|
||||
function set_elements_parse(res, str, af) {
|
||||
for (let addr in split(str, /[ \t\n]/)) {
|
||||
addr = trim(addr);
|
||||
if (!addr) continue;
|
||||
if (af == 4 && index(addr, ":") != -1) continue;
|
||||
if (af == 6 && index(addr, ":") == -1) continue;
|
||||
push(res, addr);
|
||||
}
|
||||
}
|
||||
|
||||
function set_elements(suf, af) {
|
||||
let obj = set_suffix[suf];
|
||||
let res = [];
|
||||
let addr;
|
||||
|
||||
let str = obj["str"];
|
||||
if (str) {
|
||||
set_elements_parse(res, str, af);
|
||||
}
|
||||
|
||||
let file = obj["file"];
|
||||
if (file) {
|
||||
let fd = fs.open(file);
|
||||
if (fd) {
|
||||
str = fd.read("all");
|
||||
set_elements_parse(res, str, af);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
%}
|
||||
|
||||
{% for (let suf in set_suffix): for (let af in [4, 6]): %}
|
||||
set {{ set_name(suf, af) }} {
|
||||
type ipv{{af}}_addr;
|
||||
flags interval;
|
||||
auto-merge;
|
||||
{% let elems = set_elements(suf, af); if (length(elems)): %}
|
||||
elements = {
|
||||
{% for (let i = 0; i < length(elems); i++): %}
|
||||
{{ elems[i] }}{% if (i < length(elems) - 1): %},{% endif %}{% print("\n") %}
|
||||
{% endfor %}
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
{% endfor; endfor %}
|
8
shadowsocks-rust/files/nft-rules/ss-rules.uc
Normal file
8
shadowsocks-rust/files/nft-rules/ss-rules.uc
Normal file
|
@ -0,0 +1,8 @@
|
|||
{%
|
||||
|
||||
include("set.uc");
|
||||
include("chain.uc", {proto: "tcp"});
|
||||
include("chain.uc", {proto: "udp"});
|
||||
|
||||
%}
|
||||
|
347
shadowsocks-rust/files/shadowsocks-rust.init-nft
Executable file
347
shadowsocks-rust/files/shadowsocks-rust.init-nft
Executable file
|
@ -0,0 +1,347 @@
|
|||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (C) 2017-2019 Yousong Zhou <yszhou4tech@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
USE_PROCD=1
|
||||
START=99
|
||||
|
||||
EXTRA_COMMANDS="rules_up rules_down rules_exist"
|
||||
|
||||
ss_confdir=/var/etc/shadowsocks-rust
|
||||
ss_bindir=/usr/bin
|
||||
|
||||
ssrules_uc="/usr/share/ssr-rules/ss-rules.uc"
|
||||
ssrules_nft="/etc/nftables.d/90-ssr-rules.nft"
|
||||
|
||||
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 "$server" ] || json_add_string server "$server"
|
||||
json_add_int server_port "$server_port"
|
||||
[ -z "$method" ] || json_add_string method "$method"
|
||||
[ -z "$key" ] || json_add_string key "$key"
|
||||
[ -z "$password" ] || json_add_string password "$password"
|
||||
[ -z "$plugin" ] || json_add_string plugin "$plugin"
|
||||
[ -z "$plugin_opts" ] || json_add_string plugin_opts "$plugin_opts"
|
||||
}
|
||||
|
||||
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/${cfgtype/_/-}"
|
||||
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 "$local_ipv4_address" ] || json_add_string local_ipv4_address "$local_ipv4_address"
|
||||
[ -z "$local_ipv6_address" ] || json_add_string local_ipv6_address "$local_ipv6_address"
|
||||
[ -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"
|
||||
[ -z "$acl" ] || json_add_string acl "$acl"
|
||||
json_dump -i >"$confjson"
|
||||
|
||||
procd_open_instance "$cfgtype.$cfg"
|
||||
procd_set_param command "$bin" -c "$confjson"
|
||||
[ "$verbose" = 0 ] || procd_append_param command -v
|
||||
if [ -n "$bind_address" ]; then
|
||||
echo "$cfgtype $cfg: uci option bind_address deprecated, please switch to local_address" >&2
|
||||
procd_append_param command -b "$bind_address"
|
||||
fi
|
||||
procd_set_param file "$confjson"
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
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"
|
||||
fi
|
||||
if [ "$mode" = udp_only -o "$mode" = "tcp_and_udp" ]; then
|
||||
eval "ss_rules_redir_udp_$cfg=$local_port"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
ss_rules_nft_gen() {
|
||||
local cfg="ss_rules"
|
||||
local cfgtype
|
||||
local local_port_tcp local_port_udp
|
||||
local remote_servers
|
||||
[ -s "$ssrules_uc" ] || return 1
|
||||
config_get cfgtype "$cfg" TYPE
|
||||
[ "$cfgtype" = ss_rules ] || return 1
|
||||
eval "$(validate_ss_rules_section "$cfg" ss_validate_mklocal)"
|
||||
validate_ss_rules_section "$cfg" || return 1
|
||||
[ "$disabled" = 0 ] || return 2
|
||||
eval local_port_tcp="\$ss_rules_redir_tcp_$redir_tcp"
|
||||
eval local_port_udp="\$ss_rules_redir_udp_$redir_udp"
|
||||
[ -n "$local_port_tcp" -o -n "$local_port_udp" ] || return 1
|
||||
remote_servers="$(echo $ss_redir_servers \
|
||||
| tr ' ' '\n' \
|
||||
| sort -u \
|
||||
| xargs -n 1 resolveip \
|
||||
| sort -u)"
|
||||
|
||||
local tmp="/tmp/ssrrules"
|
||||
json_init
|
||||
json_add_string o_remote_servers "$remote_servers"
|
||||
json_add_int o_redir_tcp_port "$local_port_tcp"
|
||||
json_add_int o_redir_udp_port "$local_port_udp"
|
||||
json_add_string o_ifnames "$ifnames"
|
||||
json_add_string o_local_default "$local_default"
|
||||
json_add_string o_src_bypass "$src_ips_bypass"
|
||||
json_add_string o_src_forward "$src_ips_forward"
|
||||
json_add_string o_src_checkdst "$src_ips_checkdst"
|
||||
json_add_string o_src_default "$src_default"
|
||||
json_add_string o_dst_bypass "$dst_ips_bypass"
|
||||
json_add_string o_dst_forward "$dst_ips_forward"
|
||||
json_add_string o_dst_bypass_file "$dst_ips_bypass_file"
|
||||
json_add_string o_dst_forward_file "$dst_ips_forward_file"
|
||||
json_add_string o_dst_default "$dst_default"
|
||||
json_add_string o_nft_tcp_extra "$nft_tcp_extra"
|
||||
json_add_string o_nft_udp_extra "$nft_udp_extra"
|
||||
json_dump -i >"$tmp.json"
|
||||
|
||||
if utpl -S -F "$tmp.json" "$ssrules_uc" >"$tmp.nft" \
|
||||
&& ! cmp -s "$tmp.nft" "$ssrules_nft"; then
|
||||
echo "table inet chk {include \"$tmp.nft\";}" >"$tmp.nft.chk"
|
||||
if nft -f "$tmp.nft.chk" -c; then
|
||||
mv "$tmp.nft" "$ssrules_nft"
|
||||
fw4 restart
|
||||
fi
|
||||
rm -f "$tmp.nft.chk"
|
||||
fi
|
||||
rm -f "$tmp.json"
|
||||
rm -f "$tmp.nft"
|
||||
}
|
||||
|
||||
ss_rules_nft_reset() {
|
||||
if [ -f "$ssrules_nft" ]; then
|
||||
rm -f "$ssrules_nft"
|
||||
fw4 restart
|
||||
fi
|
||||
}
|
||||
|
||||
ss_rules() {
|
||||
if ! ss_rules_nft_gen; then
|
||||
ss_rules_nft_reset
|
||||
fi
|
||||
}
|
||||
|
||||
rules_up() {
|
||||
if [ -f "${ssrules_nft}.down" ]; then
|
||||
mv -f "${ssrules_nft}.down" "$ssrules_nft"
|
||||
fw4 restart
|
||||
fi
|
||||
}
|
||||
|
||||
rules_down() {
|
||||
if [ -f "${ssrules_nft}" ]; then
|
||||
mv -f "$ssrules_nft" "${ssrules_nft}.down"
|
||||
fw4 restart
|
||||
fi
|
||||
}
|
||||
|
||||
rules_exist() {
|
||||
if [ -f "$ssrules_nft" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
ss_rules
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
ss_rules_nft_reset
|
||||
rm -rf "$ss_confdir"
|
||||
}
|
||||
|
||||
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' \
|
||||
'key:string' \
|
||||
"method:or($stream_methods, $aead_methods)" \
|
||||
'plugin:string' \
|
||||
'plugin_opts:string'
|
||||
}
|
||||
|
||||
validate_common_client_options_() {
|
||||
validate_common_options_ "$@" \
|
||||
'server:uci("shadowsocks-rust", "@server")' \
|
||||
'local_address:ipaddr: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' \
|
||||
'reuse_port:bool:0' \
|
||||
'mptcp: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" \
|
||||
'acl:file'
|
||||
}
|
||||
|
||||
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:uci("shadowsocks-rust", "@ss_redir")' \
|
||||
'redir_udp:uci("shadowsocks-rust", "@ss_redir")' \
|
||||
'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' \
|
||||
'nft_tcp_extra:string' \
|
||||
'nft_udp_extra:string' \
|
||||
'ifnames:maxlength(15)'
|
||||
}
|
||||
|
||||
validate_ss_server_section() {
|
||||
validate_common_server_options_ ss_server "$1" \
|
||||
validate_common_options_ \
|
||||
"$2" \
|
||||
'local_address:ipaddr' \
|
||||
'local_ipv4_address:ip4addr' \
|
||||
'local_ipv6_address:ip6addr' \
|
||||
'bind_address:ipaddr' \
|
||||
'acl:file'
|
||||
}
|
||||
|
||||
validate_ss_tunnel_section() {
|
||||
validate_common_client_options_ ss_tunnel "$1" \
|
||||
"$2" \
|
||||
'tunnel_address:regex(".+\:[0-9]+")'
|
||||
}
|
Loading…
Reference in a new issue