1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-02-15 03:51:51 +00:00
This commit is contained in:
suyuan 2024-01-11 23:07:47 +08:00
commit 31ad833a71
45 changed files with 8194 additions and 539 deletions

View file

@ -183,7 +183,8 @@ return view.extend({
s.tab('timed', _('Time Restrictions'));
s.filter = function(section_id) {
return (uci.get('firewall', section_id, 'target') != 'SNAT');
//return (uci.get('firewall', section_id, 'target') != 'SNAT');
return (uci.get('firewall', section_id, 'target') != 'SNAT' && section_id.startsWith('omr_dst') == false && section_id.startsWith('omr_dscp') == false);
};
s.sectiontitle = function(section_id) {

View file

@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Interface to bypass domains
#LUCI_DEPENDS:=+dnsmasq-full +shadowsocks-libev-ss-rules +(LINUX_5_4||LINUX_5_15||TARGET_x86_64):iptables-mod-ndpi +iptables-mod-extra +(LINUX_5_4||LINUX_5_15||TARGET_x86_64):kmod-ipt-ndpi +iptables
LUCI_DEPENDS:=+omr-bypass
LUCI_DEPENDS:=+LINUX_5_4:omr-bypass +!LINUX_5_4:omr-bypass-nft
#ifneq ($(CONFIG_TARGET_ramips),y)
# #LUCI_DEPENDS+=+(LINUX_5_4||LINUX_5_15):iptables-mod-ndpi +(LINUX_5_4||LINUX_5_15):kmod-ipt-ndpi
# LUCI_DEPENDS+=+iptables-mod-ndpi +kmod-ipt-ndpi

View file

@ -49,6 +49,7 @@ return L.view.extend({
o.rmempty = false;
o = s.option(form.Flag, 'vpn', _('VPN on server'),_('Bypass using VPN configured on server.'));
o.modalonly = true
o = s.option(widgets.DeviceSelect, 'interface', _('Interface'),_('When none selected, MPTCP master interface is used.'));
o.noaliases = true;
@ -82,6 +83,7 @@ return L.view.extend({
o.rmempty = false;
o = s.option(form.Flag, 'vpn', _('VPN on server'),_('Bypass using VPN configured on server.'));
o.modalonly = true
o = s.option(widgets.DeviceSelect, 'interface', _('Interface'),_('When none selected, MPTCP master interface is used.'));
o.noaliases = true;
@ -206,7 +208,7 @@ return L.view.extend({
o.rmempty = false;
o = s.option(form.Flag, 'vpn', _('VPN on server'),_('Bypass using VPN configured on server.'));
o.modalonly = true
o = s.option(widgets.DeviceSelect, 'interface', _('Interface'),_('When none selected, MPTCP master interface is used.'));
o.noaliases = true;
@ -266,6 +268,7 @@ return L.view.extend({
};
o = s.option(form.Flag, 'vpn', _('VPN on server'),_('Bypass using VPN configured on server.'));
o.modalonly = true
o = s.option(widgets.DeviceSelect, 'interface', _('Interface'),_('When none selected, MPTCP master interface is used (or an other interface if master is down).'));
o.noaliases = true;

View file

@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Interface to DSCP
LUCI_DEPENDS:=+LINUX_5_4:omr-dscp +!LINUX_5_4:omr-dscp-nft
PKG_LICENSE:=GPLv3
#include ../luci/luci.mk

View file

@ -41,13 +41,13 @@ var modes = [
var methods = [
'none',
// aead
'aes-128-gcm',
'aes-256-gcm',
'chacha20-ietf-poly1305',
'2022-blake3-aes-128-gcm',
// 'aes-128-gcm',
// 'aes-256-gcm',
// 'chacha20-ietf-poly1305',
// '2022-blake3-aes-128-gcm',
'2022-blake3-aes-256-gcm',
'2022-blake3-chacha8-poly1305',
'2022-blake3-chacha20-poly1305',
// '2022-blake3-chacha8-poly1305',
// '2022-blake3-chacha20-poly1305',
];
function ucival_to_bool(val) {
@ -72,7 +72,7 @@ return L.Class.extend({
}
});
o.value('', '<unset>');
o.value('all', 'all');
//o.value('all', 'all');
o.default = '';
},
values_serverlist: function(o) {
@ -133,7 +133,7 @@ return L.Class.extend({
o.datatype = 'port';
o.size = 5;
o = optfunc(form.ListValue, 'method', _('Method'),_('Only 2022-blake3-aes-256-gcm is supported by OpenMPTCProuter Shadowsocks-GO'));
o = optfunc(form.ListValue, 'method', _('Method'));
methods.forEach(function(m) {
o.value(m);
});

View file

@ -20,15 +20,33 @@ DEPENDS:=+curl +dnsmasq-full +sqlite3-cli +iptables +iptables-mod-extra +ipset
TITLE:=OMR-ByPass
endef
define Package/$(PKG_NAME)-nft
SECTION:=net
CATEGORY:=Network
DEPENDS:=+curl +dnsmasq-full +sqlite3-cli +firewall4
TITLE:=OMR-ByPass NFT
endef
define Package/$(PKG_NAME)/description
OMR-ByPass
endef
define Package/$(PKG_NAME)/description
OMR-ByPass nft support
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(CP) ./files/* $(1)/
$(CP) ./files/* $(1)/
rm -f $(1)/etc/init.d/omr-bypass-nft
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
define Package/$(PKG_NAME)-nft/install
$(CP) ./files/* $(1)/
mv $(1)/etc/init.d/omr-bypass-nft $(1)/etc/init.d/omr-bypass
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
$(eval $(call BuildPackage,$(PKG_NAME)-nft))

View file

@ -1,5 +1,5 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2018-2020 Ycarus (Yannick Chabanois) <ycarus@zugaina.org>
# Copyright (C) 2018-2023 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
START=98
STOP=10
@ -8,13 +8,14 @@ EXTRA_COMMANDS="reload_rules bypass_asn"
. /usr/lib/unbound/iptools.sh
if [ -f /usr/sbin/iptables-legacy ]; then
IPTABLES="/usr/sbin/iptables-legacy"
IPTABLESRESTORE="/usr/sbin/iptables-legacy-restore"
IPTABLESSAVE="/usr/sbin/iptables-legacy-save"
IP6TABLES="/usr/sbin/ip6tables-legacy"
IP6TABLESRESTORE="/usr/sbin/ip6tables-legacy-restore"
IP6TABLESSAVE="/usr/sbin/ip6tables-legacy-save"
# Still used by ndpi
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
IPTABLESRESTORE="/usr/sbin/iptables-nft-restore"
IPTABLESSAVE="/usr/sbin/iptables-nft-save"
IP6TABLES="/usr/sbin/ip6tables-nft"
IP6TABLESRESTORE="/usr/sbin/ip6tables-nft-restore"
IP6TABLESSAVE="/usr/sbin/ip6tables-nft-save"
else
IPTABLES="/usr/sbin/iptables"
IPTABLESRESTORE="/usr/sbin/iptables-restore"
@ -58,9 +59,13 @@ _bypass_ip() {
valid_ip4=$( valid_subnet4 $ip)
valid_ip6=$( valid_subnet6 $ip)
if [ "$valid_ip4" = "ok" ]; then
ipset -q add omr_dst_bypass_$type $ip
uci -q add_list firewall.omr_dst_bypass_${type}_4.entry=$ip
uci -q set firewall.omr_dst_bypass_${type}_4.enabled='1'
uci -q set firewall.omr_dst_bypass_${type}_dstip_4.enabled='1'
elif [ "$valid_ip6" = "ok" ]; then
ipset -q add omr6_dst_bypass_$type $ip
uci -q add_list firewall.omr_dst_bypass_${type}_6.entry=$ip
uci -q set firewall.omr_dst_bypass_${type}_6.enabled='1'
uci -q set firewall.omr_dst_bypass_${type}_dstip_6.enabled='1'
fi
}
@ -76,6 +81,7 @@ _bypass_domains() {
[ -z "$intf" ] && intf="all"
config_get vpn $1 vpn
[ "$vpn" = "1" ] && intf="srv_vpn1"
#echo "bypass $domain $enabled $family $intf $vpn"
[ "$enabled" = "0" ] && return
[ -z "$domain" ] && return
[ -z "$family" ] && family="ipv4ipv6"
@ -107,6 +113,7 @@ _bypass_domains() {
_bypass_domain $validdomain $intf $family $noipv6
done
else
#echo "_bypass_domain $domain $intf $family $noipv6"
_bypass_domain $domain $intf $family $noipv6
fi
}
@ -117,7 +124,6 @@ _bypass_domain() {
local family=$3
local noipv6=$4
intf=$(echo $intf | sed -e 's/\./_/')
[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
[ -z "$intf" ] && intf="all"
if [ -n "$domain" ]; then
domain=$(echo $domain | sed 's:^\.::')
@ -134,35 +140,13 @@ _bypass_domain() {
done
fi
fi
if [ "$(uci -q get dhcp.@dnsmasq[0].ipset | grep /$domain/)" = "" ]; then
if [ "$family" = "ipv4ipv6" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="/$domain/omr_dst_bypass_$intf,omr6_dst_bypass_$intf"
elif [ "$family" = "ipv4" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="/$domain/omr_dst_bypass_$intf"
elif [ "$family" = "ipv6" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="/$domain/omr6_dst_bypass_$intf"
fi
if [ "$(uci -q get dhcp.omr_dst_bypass_$intf | grep /$domain/)" = "" ]; then
uci -q add_list dhcp.omr_dst_bypass_$intf.domain=$domain
add_domains="true"
else
dnsmasqipset=$(uci -q get dhcp.@dnsmasq[0].ipset | sed 's/ /\n/g')
for dnsipset in $dnsmasqipset; do
if [ "$(echo $dnsipset | cut -d/ -f2)" = "$domain" ]; then
uci -q del_list dhcp.@dnsmasq[0].ipset=$dnsipset
if [ "$family" = "ipv4ipv6" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="$dnsipset,omr_dst_bypass_$intf,omr6_dst_bypass_$intf"
elif [ "$family" = "ipv4" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="$dnsipset,omr_dst_bypass_$intf"
elif [ "$family" = "ipv6" ]; then
uci -q add_list dhcp.@dnsmasq[0].ipset="$dnsipset,omr6_dst_bypass_$intf"
fi
add_domains="true"
fi
done
fi
if [ "$(uci -q get dhcp.@dnsmasq[0].noipv6 | grep /$domain/)" = "" ] && [ "$noipv6" = "1" ]; then
uci -q add_list dhcp.@dnsmasq[0].noipv6="$domain"
fi
#logger -t "omr-bypass" "Get IPs of $domain... Done"
fi
}
@ -176,38 +160,13 @@ _bypass_mac() {
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$mac" ] && return
if [ "$intf" = "all" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass -m mac --mac-source $mac -j MARK --set-mark 0x539
COMMIT
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 -m mac --mac-source $mac -j MARK --set-mark 0x6539
COMMIT
EOF
fi
else
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass -m mac --mac-source $mac -j MARK --set-mark 0x539$intfid
COMMIT
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 -m mac --mac-source $mac -j MARK --set-mark 0x6539$intfid
COMMIT
EOF
fi
fi
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_$intf_mac.src_mac="$mac"
EOF
}
_bypass_lan_ip() {
@ -226,44 +185,16 @@ _bypass_lan_ip() {
[ -z "$ip" ] && return
valid_ip4=$(valid_subnet4 $ip)
valid_ip6=$(valid_subnet6 $ip)
if [ "$intf" = "all" ]; then
if [ "$valid_ip4" = "ok" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass -s $ip -j MARK --set-mark 0x539
COMMIT
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local -s $ip -j MARK --set-mark 0x539
COMMIT
EOF
elif [ "$valid_ip6" = "ok" ] && [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 -s $ip -j MARK --set-mark 0x6539
COMMIT
EOF
fi
else
if [ "$valid_ip4" = "ok" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass -s $ip -j MARK --set-mark 0x539$intfid
COMMIT
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local -s $ip -j MARK --set-mark 0x539$intfid
COMMIT
EOF
elif [ "$valid_ip6" = "ok" ] && [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 -s $ip -j MARK --set-mark 0x6539$intfid
COMMIT
EOF
fi
if [ "$valid_ip4" = "ok" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_srcip_4.src_ip="$ip"
set firewall.omr_dst_bypass_${intf}_srcip_4.enabled='1'
EOF
elif [ "$valid_ip6" = "ok" ] && [ "$disableipv6" = "0" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_srcip_6.src_ip="$ip"
set firewall.omr_dst_bypass_${intf}_srcip_6.enabled='1'
EOF
fi
}
@ -278,49 +209,24 @@ _bypass_dest_port() {
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$dport" ] && return
dport="$(echo $dport | sed 's/-/:/')"
[ -z "$proto" ] && return
if [ "$intf" = "all" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass --protocol $proto --destination-port $dport -j MARK --set-mark 0x539
COMMIT
if [ "$proto" = "tcp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_tcp.dst_port="$dport"
set firewall.omr_dst_bypass_${intf}_dstport_tcp.enabled='1'
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local --protocol $proto --destination-port $dport -j MARK --set-mark 0x539
COMMIT
fi
if [ "$proto" = "udp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_udp.dst_port="$dport"
set firewall.omr_dst_bypass_${intf}_dstport_udp.enabled='1'
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 --protocol $proto --destination-port $dport -j MARK --set-mark 0x6539
COMMIT
EOF
fi
else
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass --protocol $proto --destination-port $dport -j MARK --set-mark 0x539$intfid
COMMIT
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local --protocol $proto --destination-port $dport -j MARK --set-mark 0x539$intfid
COMMIT
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 --protocol $proto --destination-port $dport -j MARK --set-mark 0x6539$intfid
COMMIT
EOF
fi
fi
}
@ -335,49 +241,24 @@ _bypass_src_port() {
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$sport" ] && return
sport="$(echo $sport | sed 's/-/:/')"
[ -z "$proto" ] && return
if [ "$intf" = "all" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass --protocol $proto --source-port $sport -j MARK --set-mark 0x539
COMMIT
if [ "$proto" = "tcp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_tcp.dst_port="$dport"
set firewall.omr_dst_bypass_${intf}_dstport_tcp.enabled='1'
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local --protocol $proto --source-port $sport -j MARK --set-mark 0x539
COMMIT
fi
if [ "$proto" = "udp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_udp.dst_port="$dport"
set firewall.omr_dst_bypass_${intf}_dstport_udp.enabled='1'
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 --protocol $proto --source-port $sport -j MARK --set-mark 0x6539
COMMIT
EOF
fi
else
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass --protocol $proto --source-port $sport -j MARK --set-mark 0x539$intfid
COMMIT
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local --protocol $proto --source-port $sport -j MARK --set-mark 0x539$intfid
COMMIT
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 --protocol $proto --source-port $sport -j MARK --set-mark 0x6539$intfid
COMMIT
EOF
fi
fi
}
@ -398,7 +279,7 @@ _bypass_proto() {
[ -z "$noipv6" ] && noipv6="0"
[ -z "$family" ] && family="ipv4ipv6"
intf=$(echo $intf | sed -e 's/\./_/')
[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
@ -408,8 +289,8 @@ _bypass_proto() {
if [ "$family" = "ipv4" ] || [ "$family" = "ipv4ipv6" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-dpi -m ndpi --proto $proto -j MARK --set-mark 0x539
-A omr-bypass-dpi -m mark --mark 0x539 -j RETURN
-A omr-bypass-dpi -m ndpi --proto $proto -j MARK --set-mark 0x4539
-A omr-bypass-dpi -m mark --mark 0x4539 -j RETURN
COMMIT
EOF
fi
@ -425,8 +306,8 @@ _bypass_proto() {
if [ "$family" = "ipv4" ] || [ "$family" = "ipv4ipv6" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-dpi -m ndpi --proto $proto -j MARK --set-mark 0x539$intfid
-A omr-bypass-dpi -m mark --mark 0x539$intfid -j RETURN
-A omr-bypass-dpi -m ndpi --proto $proto -j MARK --set-mark 0x4539$intfid
-A omr-bypass-dpi -m mark --mark 0x4539$intfid -j RETURN
COMMIT
EOF
fi
@ -497,74 +378,84 @@ _bypass_proto_without_ndpi() {
[ -z "$noipv6" ] && noipv6="0"
[ -z "$family" ] && family="ipv4ipv6"
intf=$(echo $intf | sed -e 's/\./_/')
[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ "$intf" = "all" ] && intfid=""
[ -z "$proto" ] && return
if [ "$(uci -q get openmptcprouter.settings.ndpi)" == "0" ] || [ "$ndpi" == "0" ] || [ "$vpn" = "1" ]; then
ALLIPS=$(sqlite3 /usr/share/omr-bypass/omr-bypass.db "select ip from ipproto where proto=\"$proto\";" ".exit")
if [ -n "$ALLIPS" ]; then
if [ "$vpn" != "1" ]; then
ipset -q flush bypass_$proto > /dev/null 2>&1
ipset -q flush bypass6_$proto > /dev/null 2>&1
ipset -q --exist restore <<-EOF
create bypass_$proto hash:net hashsize 64
create bypass6_$proto hash:net family inet6 hashsize 64
uci -q batch <<-EOF >/dev/null
set firewall.bypass_$proto=ipset
set firewall.bypass_$proto.name="bypass_$proto"
set firewall.bypass_$proto.match='dest_ip'
set firewall.bypass_$proto_rule=rule
set firewall.bypass_$proto_rule.name="bypass_$proto"
set firewall.bypass_$proto_rule.src='lan'
set firewall.bypass_$proto_rule.dest='*'
set firewall.bypass_$proto_rule.target='MARK'
set firewall.bypass_$proto_rule.set_xmark="4539${intfid}"
commit firewall
EOF
uci -q batch <<-EOF >/dev/null
set firewall.bypass6_$proto=ipset
set firewall.bypass6_$proto.name="bypas6s_$proto"
set firewall.bypass6_$proto.match='dest_ip'
set firewall.bypass6_$proto_rule=rule
set firewall.bypass6_$proto_rule.name="bypass6_$proto"
set firewall.bypass6_$proto_rule.src='lan'
set firewall.bypass6_$proto_rule.dest='*'
set firewall.bypass6_$proto_rule.target='MARK'
set firewall.bypass6_$proto_rule.set_xmark="6539${intfid}"
commit firewall
EOF
#if [ "$intfid" != "" ]; then
# uci -q batch <<-EOF >/dev/null
# delete network.${1}_fw_rule=rule
# set network.${1}_fw_rule=rule
# set network.${1}_fw_rule.priority=1
# set network.${1}_fw_rule.mark=0x539${intfid}
# set network.${1}_fw_rule.lookup=${intfid}
# delete network.${1}_fw_rule6=rule6
# set network.${1}_fw_rule6=rule6
# set network.${1}_fw_rule6.priority=1
# set network.${1}_fw_rule6.mark=0x6539${intfid}
# set network.${1}_fw_rule6.lookup=${intfid}
# commit network
# EOF
#fi
#ipset -q flush bypass_$proto > /dev/null 2>&1
#ipset -q flush bypass6_$proto > /dev/null 2>&1
#ipset -q --exist restore <<-EOF
#create bypass_$proto hash:net hashsize 64
#create bypass6_$proto hash:net family inet6 hashsize 64
#EOF
fi
for ip in $ALLIPS; do
valid_ip4=$( valid_subnet4 $ip)
valid_ip6=$( valid_subnet6 $ip)
if [ "$valid_ip4" = "ok" ]; then
if [ "$vpn" != "1" ]; then
ipset -q add bypass_$proto $ip
#ipset -q add bypass_$proto $ip
uci -q add_list firewall.bypass_$proto.entry=$ip
else
ipset -q add omr_dst_bypass_$intf $ip
#ipset -q add omr_dst_bypass_$intf $ip
uci -q add_list firewall.omr_dst_bypass_$intf_4.entry=$ip
fi
elif [ "$valid_ip6" = "ok" ]; then
if [ "$vpn" != "1" ]; then
ipset -q add bypass6_$proto $ip
#ipset -q add bypass6_$proto $ip
uci -q add_list firewall.bypass6_$proto.entry=$ip
else
ipset -q add omr6_dst_bypass_$intf $ip
#ipset -q add omr6_dst_bypass_$intf $ip
uci -q add_list firewall.omr6_dst_bypass_$intf_4.entry=$ip
fi
fi
done
if [ "$intf" = "all" ]; then
if [ "$family" = "ipv4" ] || [ "$family" = "ipv4ipv6" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-dpi -m set --match-set bypass_$proto dst -j MARK --set-mark 0x539
-A omr-bypass-dpi -m mark --mark 0x539 -j RETURN
COMMIT
EOF
fi
if [ "$disableipv6" = "0" ] && ([ "$family" = "ipv6" ] || [ "$family" = "ipv4ipv6" ]); then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6-dpi -m set --match-set bypass6_$proto dst -j MARK --set-mark 0x6539
-A omr-bypass6-dpi -m mark --mark 0x6539 -j RETURN
COMMIT
EOF
fi
elif [ "$vpn" != "1" ]; then
if [ "$family" = "ipv4" ] || [ "$family" = "ipv4ipv6" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-dpi -m set --match-set bypass_$proto dst -j MARK --set-mark 0x539$intfid
-A omr-bypass-dpi -m mark --mark 0x539$intfid -j RETURN
COMMIT
EOF
fi
if [ "$disableipv6" = "0" ] && ([ "$family" = "ipv6" ] || [ "$family" = "ipv4ipv6" ]); then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6-dpi -m set --match-set bypass6_$proto dst -j MARK --set-mark 0x6539$intfid
-A omr-bypass6-dpi -m mark --mark 0x6539$intfid -j RETURN
COMMIT
EOF
fi
fi
fi
fi
# Use dnsmasq ipset to bypass domains of the proto
@ -609,52 +500,15 @@ _bypass_proto_without_ndpi() {
}
_intf_rule_ss_rules() {
rule_name=$1
[ "$rule_name" = "ss_rules" ] && rule_name="def"
if [ "$($IPTABLES --wait=40 -t nat -L -n | grep ssr_${rule_name}_dst)" != "" ] && [ "$($IPTABLESSAVE 2>/dev/null | grep ssr_${rule_name}_dst | grep omr_dst_bypass_$intf)" = "" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*nat
-I ssr_${rule_name}_dst 1 -m set --match-set omr_dst_bypass_$intf dst -j MARK --set-mark 0x539$count
-I ssr_${rule_name}_dst 2 -m mark --mark 0x539$count -j RETURN
COMMIT
EOF
fi
if [ "$($IPTABLES --wait=40 -t nat -L -n | grep ssr_${rule_name}_local_out)" != "" ] && [ "$($IPTABLESSAVE 2>/dev/null | grep ssr_${rule_name}_local_out | grep omr_dst_bypass_$intf)" = "" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*nat
-I ssr_${rule_name}_local_out 1 -m set --match-set omr_dst_bypass_$intf dst -j MARK --set-mark 0x539$count
-I ssr_${rule_name}_local_out 2 -m mark --mark 0x539$count -j RETURN
COMMIT
EOF
fi
if [ "$($IPTABLES --wait=40 -t nat -L -n | grep ssr_${rule_name}_pre_src)" != "" ] && [ "$($IPTABLESSAVE 2>/dev/null | grep ssr_${rule_name}_pre_src | grep omr_dst_bypass_$intf)" = "" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*nat
-I ssr_${rule_name}_pre_src 1 -m set --match-set omr_dst_bypass_$intf dst -j MARK --set-mark 0x539$count
-I ssr_${rule_name}_pre_src 2 -m mark --mark 0x539$count -j RETURN
COMMIT
EOF
fi
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip daddr @omr_dst_bypass_${intf}_4 accept
nft insert rule inet fw4 ss_rules_local_out ip daddr @omr_dst_bypass_${intf}_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
if [ "$($IP6TABLES --wait=40 -t mangle -L -n | grep omr6_dst_bypass_$intf)" = "" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-I omr-bypass6 1 -m set --match-set omr6_dst_bypass_$intf dst -j MARK --set-mark 0x6539$count
COMMIT
EOF
fi
if [ "$($IP6TABLES --wait=40 -t nat -L -n | grep ssr6_${rule_name}_pre_src)" != "" ] && [ "$($IP6TABLESSAVE 2>/dev/null | grep ssr6 | grep omr6_dst_bypass_$intf)" = "" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*nat
-I ssr6_${rule_name}_dst 1 -m set --match-set omr6_dst_bypass_$intf dst -j MARK --set-mark 0x6539$count
-I ssr6_${rule_name}_dst 2 -m mark --mark 0x6539$count -j RETURN
-I ssr6_${rule_name}_local_out 1 -m set --match-set omr6_dst_bypass_$intf dst -j MARK --set-mark 0x6539$count
-I ssr6_${rule_name}_local_out 2 -m mark --mark 0x6539$count -j RETURN
-I ssr6_${rule_name}_pre_src 1 -m set --match-set omr6_dst_bypass_$intf dst -j MARK --set-mark 0x6539$count
-I ssr6_${rule_name}_pre_src 2 -m mark --mark 0x6539$count -j RETURN
COMMIT
EOF
fi
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip6 daddr @omr_dst_bypass_${intf}_6 accept
nft insert rule inet fw4 ss_rules_local_out ip6 daddr @omr_dst_bypass_${intf}_6 accept
EOF
fi
}
@ -766,56 +620,133 @@ _intf_rule_xray_rules() {
_intf_rule() {
local intf
intf=$(ifstatus "$1" | jsonfilter -q -e '@["l3_device"]')
[ "$1" = "all" ] && intf="all"
[ -z "$intf" ] && intf=$(ifstatus "$1" | jsonfilter -q -e '@["l3_device"]')
[ -n "$(echo $intf | grep '@')" ] && intf=$(ifstatus "$1" | jsonfilter -q -e '@["device"]')
[ -z "$intf" ] && config_get intf $1 device
[ -n "$(echo $intf | grep '/')" ] && return
#count=$((count+1))
config_get count $1 metric
[ "$intf" != "all" ] && config_get count $1 metric
[ "$intf" = "all" ] && count=""
local mode
#config_get mode $1 multipath "off"
#[ "$mode" = "off" ] && return
[ -z "$count" ] && return
[ "$intf" != "all" ] && [ -z "$count" ] && return
[ -z "$intf" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
intf=$(echo $intf | sed -e 's/-/_/')
[ "$(echo $1 | grep _dev)" != "" ] && return
[ -z "$RELOAD" ] || [ "$(ipset --list | grep omr_dst_bypass_$intf)" = "" ] && {
unset RELOAD
ipset -q flush omr_dst_bypass_$intf > /dev/null 2>&1
ipset -q flush omr6_dst_bypass_$intf > /dev/null 2>&1
ipset -q --exist restore <<-EOF
create omr_dst_bypass_$intf hash:net hashsize 64
create omr6_dst_bypass_$intf hash:net family inet6 hashsize 64
[ "$intf" = "lo" ] && return
[ -z "$intf" ] && return
# [ -z "$RELOAD" ] || [ "$(uci show firewall.omr_dst_bypass_$intf_4)" = "" ] && {
#unset RELOAD
#echo "$intf ip set dhcp"
uci batch <<-EOF
set dhcp.omr_dst_bypass_$intf=ipset
set dhcp.omr_dst_bypass_$intf.name="omr_dst_bypass_${intf}_4,omr_dst_bypass_${intf}_6"
commit dhcp
EOF
if [ "$(uci -q get openmptcprouter.settings.uci_rules)" = "1" ]; then
#echo "firewall omr_dst_bypass ipset"
uci -q batch <<-EOF
set firewall.omr_dst_bypass_${intf}_4=ipset
set firewall.omr_dst_bypass_${intf}_4.name="omr_dst_bypass_${intf}_4"
set firewall.omr_dst_bypass_${intf}_4.match='dest_ip'
EOF
#echo "firewall omr_dst_bypass rules"
if [ "$disableipv6" = "0" ]; then
protocol="4 6"
else
protocol="4"
fi
for ipv46 in $protocol; do
echo "ipv46: $ipv46 for $intf"
uci batch <<-EOF
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.name="omr_dst_bypass_${intf}_rule"
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.ipset="omr_dst_bypass_${intf}_4"
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.name="omr_dst_bypass_${intf}_srcip"
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.ipset="omr_dst_bypass_${intf}_4"
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.name='omr_dst_bypass_${intf}_mac'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.name="omr_dst_bypass_${intf}_srcport"
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.proto='tcp'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.name="omr_dst_bypass_${intf}_srcport"
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.proto='udp'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.name="omr_dst_bypass_${intf}_dstport"
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.name="omr_dst_bypass_${intf}_dstport"
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.set_xmark="${ipv46}539${count}"
commit firewall
EOF
done
if [ "$intf" = "all" ]; then
uci -q batch <<-EOF >/dev/null
delete network.${1}_fw_rule=rule
set network.${1}_fw_rule=rule
set network.${1}_fw_rule.priority=1
set network.${1}_fw_rule.mark=0x539${count}
set network.${1}_fw_rule.lookup=${count}
delete network.${1}_fw_rule6=rule6
set network.${1}_fw_rule6=rule6
set network.${1}_fw_rule6.priority=1
set network.${1}_fw_rule6.mark=0x6539${count}
set network.${1}_fw_rule6.lookup=${count}
delete network.${intf}_fw_rule=rule
set network.${intf}_fw_rule=rule
set network.${intf}_fw_rule.priority=1
set network.${intf}_fw_rule.mark=0x4539
set network.${intf}_fw_rule.lookup=991337
delete network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6.priority=1
set network.${intf}_fw_rule6.mark=0x6539
set network.${intf}_fw_rule6.lookup=6991337
commit network
EOF
else
ip rule add prio 1 fwmark 0x539$count lookup $count pref 1 > /dev/null 2>&1
ip -6 rule add prio 1 fwmark 0x6539$count lookup 6$count pref 1 > /dev/null 2>&1
uci -q batch <<-EOF >/dev/null
delete network.${intf}_fw_rule=rule
set network.${intf}_fw_rule=rule
set network.${intf}_fw_rule.priority=1
set network.${intf}_fw_rule.mark=0x4539${count}
set network.${intf}_fw_rule.lookup=${count}
delete network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6.priority=1
set network.${intf}_fw_rule6.mark=0x6539${count}
set network.${intf}_fw_rule6.lookup=${count}
commit network
EOF
fi
}
if [ "$($IPTABLESSAVE 2>/dev/null | grep omr-bypass | grep omr_dst_bypass_$intf)" = "" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-I omr-bypass 1 -m set --match-set omr_dst_bypass_$intf dst -j MARK --set-mark 0x539$count
-I omr-bypass 2 -m mark --mark 0x539$count -j RETURN
-I omr-bypass-local 1 -m set --match-set omr_dst_bypass_$intf dst -j MARK --set-mark 0x539$count
-I omr-bypass-local 2 -m mark --mark 0x539$count -j RETURN
COMMIT
EOF
fi
if [ "$(uci -q get openmptcprouter.settings.proxy)" = "shadowsocks" ]; then
config_load shadowsocks-libev
config_foreach _intf_rule_ss_rules ss_rules
@ -856,7 +787,6 @@ _bypass_asn() {
for ip in $asnips; do
_bypass_ip $ip $interface
done
}
bypass_asn() {
@ -872,40 +802,15 @@ _bypass_omr_server() {
_ss_rules_config() {
rule_name=$1
[ "$rule_name" = "ss_rules" ] && rule_name="def"
if [ "$($IPTABLES --wait=40 -t nat -L -n | grep ssr_${rule_name}_pre_src)" != "" ] && [ "$($IPTABLES --wait=40 -t nat -L -n | grep omr_dst_bypass_all)" = "" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*nat
-I ssr_${rule_name}_dst 1 -m set --match-set omr_dst_bypass_all dst -j MARK --set-mark 0x539
-I ssr_${rule_name}_dst 2 -m mark --mark 0x539 -j RETURN
-I ssr_${rule_name}_local_out 1 -m set --match-set omr_dst_bypass_all dst -j MARK --set-mark 0x539
-I ssr_${rule_name}_local_out 2 -m mark --mark 0x539 -j RETURN
-I ssr_${rule_name}_pre_src 1 -m set --match-set omr_dst_bypass_all dst -j MARK --set-mark 0x539
-I ssr_${rule_name}_pre_src 2 -m mark --mark 0x539 -j RETURN
COMMIT
EOF
fi
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip daddr @omr_dst_bypass_all_4 accept
nft insert rule inet fw4 ss_rules_local_out ip daddr @omr_dst_bypass_all_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
if [ "$($IP6TABLES --wait=40 -t mangle -L -n | grep 'match-set omr6_dst_bypass_all dst MARK set')" = "" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 -m set --match-set omr6_dst_bypass_all dst -j MARK --set-mark 0x6539
COMMIT
EOF
fi
if [ "$($IP6TABLES --wait=40 -t nat -L -n | grep ssr6_${rule_name}_pre_src)" != "" ] && [ "$($IP6TABLES --wait=40 -t nat -L -n | grep omr6_dst_bypass_all)" = "" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*nat
-I ssr6_${rule_name}_dst 1 -m set --match-set omr6_dst_bypass_all dst -j MARK --set-mark 0x6539
-I ssr6_${rule_name}_dst 1 -m mark --mark 0x6539 -j RETURN
-I ssr6_${rule_name}_local_out 1 -m set --match-set omr6_dst_bypass_all dst -j MARK --set-mark 0x6539
-I ssr6_${rule_name}_local_out 2 -m mark --mark 0x6539 -j RETURN
-I ssr6_${rule_name}_pre_src 1 -m set --match-set omr6_dst_bypass_all dst -j MARK --set-mark 0x6539
-I ssr6_${rule_name}_pre_src 2 -m mark --mark 0x6539 -j RETURN
COMMIT
EOF
fi
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip6 daddr @omr_dst_bypass_all_6 accept
nft insert rule inet fw4 ss_rules_local_out ip6 daddr @omr_dst_bypass_all_6 accept
EOF
fi
}
@ -987,6 +892,18 @@ _xray_rules_config() {
fi
}
_delete_dhcp_ipset() {
[ -n "$(echo $1 | grep omr_dst_bypass)" ] && {
uci -q delete dhcp.$1
}
}
_delete_firewall_rules() {
[ -n "$(echo $1 | grep omr_dst_bypass)" ] && {
uci -q delete firewall.$1
}
}
boot() {
BOOT=1
start "$@"
@ -995,6 +912,16 @@ boot() {
start_service() {
#local count
logger -t "omr-bypass" "Starting OMR-ByPass..."
config_load dhcp
config_foreach _delete_dhcp_ipset ipset
#uci -q commit dhcp
config_load firewall
config_foreach _delete_firewall_rules rule
config_foreach _delete_firewall_rules ipset
#uci -q commit firewall
add_domains="false"
[ -d /proc/net/xt_ndpi ] && {
config_load omr-bypass
@ -1003,128 +930,58 @@ start_service() {
disableipv6="$(uci -q get openmptcprouter.settings.disable_ipv6)"
#noipv6="$(uci -q get omr-bypass.global.noipv6)"
[ -n "$RELOAD" ] && [ "$(ipset --list | grep omr_dst_bypass_all)" = "" ] && {
unset RELOAD
}
[ -z "$RELOAD" ] && {
ipset -q flush omr_dst_bypass_all > /dev/null 2>&1
ipset -q flush omr6_dst_bypass_all > /dev/null 2>&1
ipset -q --exist restore <<-EOF
create omr_dst_bypass_all hash:net hashsize 64
create omr6_dst_bypass_all hash:net family inet6 hashsize 64
EOF
ipset -q flush omr_dst_bypass_srv_vpn1 > /dev/null 2>&1
ipset -q flush omr6_dst_bypass_srv_vpn1 > /dev/null 2>&1
ipset -q --exist restore <<-EOF
create omr_dst_bypass_srv_vpn1 hash:net hashsize 64
create omr6_dst_bypass_srv_vpn1 hash:net family inet6 hashsize 64
EOF
}
$IPTABLESSAVE --counters 2>/dev/null | grep -v omr-bypass | $IPTABLESRESTORE -w --counters 2>/dev/null
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
:omr-bypass -
-A PREROUTING -j omr-bypass
COMMIT
cat > /etc/firewall.omr-bypass <<-EOF
#!/bin/sh
#nft insert rule inet fw4 ss_rules_dst_tcp ip daddr @omr_dst_bypass_all accept
#nft insert rule inet fw4 ss_rules_local_out ip daddr @omr_dst_bypass_all accept
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
:omr-bypass-local -
-A OUTPUT -m addrtype ! --dst-type LOCAL -j omr-bypass-local
COMMIT
uci batch <<-EOF
set firewall.omr_bypass=include
set firewall.omr_bypass.enabled='1'
set firewall.omr_bypass.type='script'
set firewall.omr_bypass.path='/etc/firewall.omr-bypass'
set firewall.omr_bypass.fw4_compatible='1'
commit firewall
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESSAVE --counters 2>/dev/null | grep -v omr-bypass6 | $IP6TABLESRESTORE -w --counters 2>/dev/null
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
:omr-bypass6 -
-A PREROUTING -j omr-bypass6
COMMIT
EOF
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
:omr-bypass6-local -
-A OUTPUT -m addrtype ! --dst-type LOCAL -j omr-bypass6-local
COMMIT
EOF
fi
echo "intf_rule"
config_load network
config_foreach _intf_rule interface
_intf_rule all
local ndpi_rules=""
echo "bypass server"
if [ "$(uci -q get openmptcprouter.settings.bypass_servers)" = "1" ]; then
config_load openmptcprouter
config_foreach _bypass_omr_server server
fi
config_load omr-bypass
echo "bypass ip"
config_foreach _bypass_ip_set ips
echo "bypass mac"
config_foreach _bypass_mac macs
echo "bypass lan ip"
config_foreach _bypass_lan_ip lan_ip
echo "bypass dest port"
config_foreach _bypass_dest_port dest_port
echo "bypass src port"
config_foreach _bypass_src_port src_port
echo "bypass asn"
config_foreach _bypass_asn asns
dnsmasqipset=$(uci -q get dhcp.@dnsmasq[0].ipset | sed 's/ /\n/g' | grep -v dst_bypass)
uci -q delete dhcp.@dnsmasq[0].ipset
uci -q delete dhcp.@dnsmasq[0].noipv6
if [ -n "$dnsmasqipset" ]; then
for dnsipset in $dnsmasqipset; do
ipsets=""
allipsets=$(echo $dnsipset | cut -d/ -f3 | sed 's/,/\n/g')
for ipset in $allipsets; do
[ "$(echo $ipset | grep -v dst_bypass)" != "" ] && {
[ "$ipsets" != "" ] && ipsets="$ipsets,$ipset"
[ "$ipsets" = "" ] && ipsets="$ipset"
}
done
if [ "$ipsets" != "" ]; then
resultipset="/$(echo $dnsipset | cut -d/ -f2)/$ipsets"
[ -n "$resultipset" ] && uci -q add_list dhcp.@dnsmasq[0].ipset=$resultipset
fi
done
fi
echo "bypass domains"
config_foreach _bypass_domains domains
uci -q commit dhcp
ip rule add prio 1 fwmark 0x539 lookup 991337 > /dev/null 2>&1
ip -6 rule add prio 1 fwmark 0x6539 lookup 6991337 > /dev/null 2>&1
# ip rule add prio 1 fwmark 0x4539 lookup 991337 > /dev/null 2>&1
# ip -6 rule add prio 1 fwmark 0x6539 lookup 6991337 > /dev/null 2>&1
if [ "$($IPTABLES --wait=40 -t mangle -L -n | grep 'match-set omr_dst_bypass_all dst MARK set')" = "" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass -m set --match-set omr_dst_bypass_all dst -j MARK --set-mark 0x539
-A omr-bypass -m mark --mark 0x539 -j RETURN
COMMIT
EOF
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-local -m set --match-set omr_dst_bypass_all dst -j MARK --set-mark 0x539
-A omr-bypass-local -m mark --mark 0x539 -j RETURN
COMMIT
EOF
fi
if [ "$disableipv6" = "0" ]; then
if [ "$($IP6TABLES --wait=40 -t mangle -L -n | grep 'match-set omr6_dst_bypass_all dst MARK set')" = "" ]; then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6 -m set --match-set omr6_dst_bypass_all dst -j MARK --set-mark 0x539
-A omr-bypass6 -m mark --mark 0x539 -j RETURN
COMMIT
EOF
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6-local -m set --match-set omr6_dst_bypass_all dst -j MARK --set-mark 0x539
-A omr-bypass6-local -m mark --mark 0x539 -j RETURN
COMMIT
EOF
fi
fi
config_load shadowsocks-libev
config_foreach _ss_rules_config
config_load shadowsocks-rust
config_foreach _ss_rules_config
#config_load shadowsocks-libev
#config_foreach _ss_rules_config ss_rules
([ "$(uci -q get shadowsocks-libev.sss0.disabled)" != "1" ] || [ "$(uci -q get shadowsocks-rust.sss0.disabled)" != "1" ]) && _ss_rules_config
#config_load shadowsocks-rust
#config_foreach _ss_rules_config ss_rules
_v2ray_rules_config
_xray_rules_config
# NDPI Netfilter is not available for nftables
$IPTABLESSAVE --counters 2>/dev/null | grep -v omr-bypass-dpi | $IPTABLESRESTORE -w --counters 2>/dev/null
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
@ -1156,7 +1013,7 @@ start_service() {
logger -t "omr-bypass" "Reload dnsmasq..."
/etc/init.d/dnsmasq reload
}
fw4 restart
# Create a protocol list for UI from a sqlite DB when NDPI is not available
sqlite3 /usr/share/omr-bypass/omr-bypass.db "select distinct(proto) from (select proto from hostproto union all select proto from ipproto) a order by proto;" ".exit" > /usr/share/omr-bypass/omr-bypass-proto.lst
config_load omr-bypass
@ -1168,15 +1025,25 @@ start_service() {
stop_service() {
$IPTABLESSAVE --counters 2>/dev/null | grep -v omr-bypass | $IPTABLESRESTORE -w --counters 2>/dev/null
$IPTABLESSAVE --counters 2>/dev/null | grep -v omr_dst | $IPTABLESRESTORE -w --counters 2>/dev/null
# $IPTABLESSAVE --counters 2>/dev/null | grep -v omr_dst | $IPTABLESRESTORE -w --counters 2>/dev/null
$IP6TABLESSAVE --counters 2>/dev/null | grep -v omr-bypass6 | $IP6TABLESRESTORE -w --counters 2>/dev/null
$IP6TABLESSAVE --counters 2>/dev/null | grep -v omr6_dst | $IP6TABLESRESTORE -w --counters 2>/dev/null
for setname in $(ipset -n list | grep "omr_"); do
ipset -q destroy "$setname" 2>/dev/null || true
done
for setname in $(ipset list | awk '/Name: bypass_/ {print $2}'); do
ipset -q destroy "$setname" 2>/dev/null || true
done
# $IP6TABLESSAVE --counters 2>/dev/null | grep -v omr6_dst | $IP6TABLESRESTORE -w --counters 2>/dev/null
#for setname in $(ipset -n list | grep "omr_"); do
# ipset -q destroy "$setname" 2>/dev/null || true
#done
#for setname in $(ipset list | awk '/Name: bypass_/ {print $2}'); do
# ipset -q destroy "$setname" 2>/dev/null || true
#done
# disable all rules ?
uci -q set firewall.omr-bypass.enabled='0'
config_load dhcp
config_foreach _delete_dhcp_ipset ipset
uci -q commit dhcp
config_load firewall
config_foreach _delete_firewall_rules rule
config_foreach _delete_firewall_rules ipset
uci -q commit firewall
exit 0
}
service_triggers() {

View file

@ -0,0 +1,926 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2018-2023 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
START=98
STOP=10
USE_PROCD=1
EXTRA_COMMANDS="reload_rules bypass_asn"
. /usr/lib/unbound/iptools.sh
# Still used by ndpi
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
IPTABLESRESTORE="/usr/sbin/iptables-nft-restore"
IPTABLESSAVE="/usr/sbin/iptables-nft-save"
IP6TABLES="/usr/sbin/ip6tables-nft"
IP6TABLESRESTORE="/usr/sbin/ip6tables-nft-restore"
IP6TABLESSAVE="/usr/sbin/ip6tables-nft-save"
else
IPTABLES="/usr/sbin/iptables"
IPTABLESRESTORE="/usr/sbin/iptables-restore"
IPTABLESSAVE="/usr/sbin/iptables-save"
IP6TABLES="/usr/sbin/ip6tables"
IP6TABLESRESTORE="/usr/sbin/ip6tables-restore"
IP6TABLESSAVE="/usr/sbin/ip6tables-save"
fi
_add_proto() {
protoname=$1
[ -z "$protoname" ] && return
if [ "$(dd if=/proc/net/xt_ndpi/proto bs=4096 2> /dev/null | grep $protoname)" = "" ]; then
echo "add_custom $protoname" >/proc/net/xt_ndpi/proto
fi
allurls="$(dd if=/proc/net/xt_ndpi/host_proto bs=4096 2> /dev/null)"
hosts="$( uci -q get omr-bypass.$protoname.url )"
for url in $hosts; do
if [ "$(echo "$allurls" | grep -i ^${protoname}: | grep $url)" = "" ]; then
echo "$protoname:$url" >/proc/net/xt_ndpi/host_proto
fi
done
ip="$( uci -q get omr-bypass.$protoname.ip )"
for ip in $ips; do
if [ "$(echo "$allurls" | grep -i ^${protoname}: | grep $ip)" = "" ]; then
echo "$protoname:$ip" >/proc/net/xt_ndpi/ip_proto
fi
done
}
_add_proto_without_ndpi() {
protoname=$1
[ -z "$protoname" ] && return
echo "$protoname" >> /usr/share/omr-bypass/omr-bypass-proto.lst
}
_bypass_ip() {
local ip=$1
local type=$2
[ -z "$type" ] && type="all"
valid_ip4=$( valid_subnet4 $ip)
valid_ip6=$( valid_subnet6 $ip)
if [ "$valid_ip4" = "ok" ]; then
uci -q add_list firewall.omr_dst_bypass_${type}_4.entry=$ip
uci -q set firewall.omr_dst_bypass_${type}_4.enabled='1'
uci -q set firewall.omr_dst_bypass_${type}_dstip_4.enabled='1'
elif [ "$valid_ip6" = "ok" ]; then
uci -q add_list firewall.omr_dst_bypass_${type}_6.entry=$ip
uci -q set firewall.omr_dst_bypass_${type}_6.enabled='1'
uci -q set firewall.omr_dst_bypass_${type}_dstip_6.enabled='1'
fi
}
_bypass_domains() {
local domain
local intf
local enabled
config_get domain $1 name
config_get intf $1 interface
config_get enabled $1 enabled
config_get noipv6 $1 noipv6
config_get family $1 family
[ -z "$intf" ] && intf="all"
config_get vpn $1 vpn
[ "$vpn" = "1" ] && intf="srv_vpn1"
#echo "bypass $domain $enabled $family $intf $vpn"
[ "$enabled" = "0" ] && return
[ -z "$domain" ] && return
[ -z "$family" ] && family="ipv4ipv6"
[ -z "$noipv6" ] && noipv6="0"
if [ "$(echo $domain | grep '\.$')" != "" ] || [ "$(echo $domain | grep '\.\*$')" != "" ]; then
tlds=`curl --max-time 4 -s -k https://data.iana.org/TLD/tlds-alpha-by-domain.txt`
domain="$(echo '"$domain"' | sed 's:*::')"
domainlist=""
# construct list of domains to query
i=0
for tld in $tlds; do
i=$((i+1))
# trim off header
if [ "$i" -lt "12" ] || [ "$i" -gt "50" ]; then
continue
fi
# add to command
domainlist="${domainlist} ${domain}${tld}"
done
domainlist="$(echo $domainlist `# Get the list of valid domains, pass it to awk` \
| awk '{print tolower($0)}' `# awk lowercases the whole string and passes it to ` \
| xargs -n8 -P12 `# xargs sends 8 arguments at a time to` \
dig a +timeout=1 +tries=1 +retry=1 +nocmd +noall +answer `# dig, which passes results (if any) to` \
| awk '{print $1}' `# awk, which outputs queried domain to` \
| sed -e 's/.$//' `# sed, which trims off the trailing dot (google.com. -> google.com)` to \
| grep $domain `# grep, only keep wanted domain` \
| awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')" # deduplicate
for validdomain in $domainlist; do
_bypass_domain $validdomain $intf $family $noipv6
done
else
#echo "_bypass_domain $domain $intf $family $noipv6"
_bypass_domain $domain $intf $family $noipv6
fi
}
_bypass_domain() {
local domain=$1
local intf=$2
local family=$3
local noipv6=$4
intf=$(echo $intf | sed -e 's/\./_/')
[ -z "$intf" ] && intf="all"
if [ -n "$domain" ]; then
domain=$(echo $domain | sed 's:^\.::')
#logger -t "omr-bypass" "Get IPs of $domain..."
if [ -z $RELOAD ]; then
resolve=$(dig a +timeout=1 +tries=1 +nocmd +noall +answer $domain | grep -v CNAME | awk '{print $5}')
for ip in $resolve; do
_bypass_ip $ip $intf
done
if [ "$disableipv6" = "0" ]; then
resolve=$(dig aaaa +timeout=1 +tries=1 +nocmd +noall +answer $domain | grep AAAA | awk '{print $5}')
for ip in $resolve; do
_bypass_ip $ip $intf
done
fi
fi
if [ "$(uci -q get dhcp.omr_dst_bypass_$intf | grep /$domain/)" = "" ]; then
uci -q add_list dhcp.omr_dst_bypass_$intf.domain=$domain
add_domains="true"
fi
if [ "$(uci -q get dhcp.@dnsmasq[0].noipv6 | grep /$domain/)" = "" ] && [ "$noipv6" = "1" ]; then
uci -q add_list dhcp.@dnsmasq[0].noipv6="$domain"
fi
#logger -t "omr-bypass" "Get IPs of $domain... Done"
fi
}
_bypass_mac() {
local mac
local intf
local enabled
config_get mac $1 mac
config_get intf $1 interface
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$mac" ] && return
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_$intf_mac.src_mac="$mac"
EOF
}
_bypass_lan_ip() {
local ip
local intf
local enabled
config_get ip $1 ip
config_get intf $1 interface
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$ip" ] && return
valid_ip4=$(valid_subnet4 $ip)
valid_ip6=$(valid_subnet6 $ip)
if [ "$valid_ip4" = "ok" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_srcip_4.src_ip="$ip"
set firewall.omr_dst_bypass_${intf}_srcip_4.enabled='1'
EOF
elif [ "$valid_ip6" = "ok" ] && [ "$disableipv6" = "0" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_srcip_6.src_ip="$ip"
set firewall.omr_dst_bypass_${intf}_srcip_6.enabled='1'
EOF
fi
}
_bypass_dest_port() {
local intf
local enabled
local dport
local proto
config_get dport $1 dport
config_get proto $1 proto
config_get intf $1 interface
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$dport" ] && return
dport="$(echo $dport | sed 's/:/-/')"
[ -z "$proto" ] && return
if [ "$proto" = "tcp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_tcp.dest_port="$dport"
set firewall.omr_dst_bypass_${intf}_dstport_tcp.enabled='1'
EOF
fi
if [ "$proto" = "udp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_udp.dest_port="$dport"
set firewall.omr_dst_bypass_${intf}_dstport_udp.enabled='1'
EOF
fi
}
_bypass_src_port() {
local intf
local enabled
local sport
local proto
config_get sport $1 sport
config_get proto $1 proto
config_get intf $1 interface
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$sport" ] && return
sport="$(echo $sport | sed 's/:/-/')"
[ -z "$proto" ] && return
if [ "$proto" = "tcp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_tcp.src_port="$sport"
set firewall.omr_dst_bypass_${intf}_dstport_tcp.enabled='1'
EOF
fi
if [ "$proto" = "udp" ] || [ "$proto" = "tcp udp" ]; then
uci -q batch <<-EOF
add_list firewall.omr_dst_bypass_${intf}_dstport_udp.src_port="$sport"
set firewall.omr_dst_bypass_${intf}_dstport_udp.enabled='1'
EOF
fi
}
_bypass_proto() {
local proto
local intf
local enabled
config_get proto $1 proto
config_get intf $1 interface
config_get enabled $1 enabled
config_get ndpi $1 ndpi
config_get noipv6 $1 noipv6
config_get family $1 family
config_get vpn $1 vpn
[ "$vpn" = "1" ] && intf="srv_vpn1"
[ "$enabled" = "0" ] && return
[ -z "$noipv6" ] && noipv6="0"
[ -z "$family" ] && family="ipv4ipv6"
intf=$(echo $intf | sed -e 's/\./_/')
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ -z "$proto" ] && return
if [ "$(uci -q get openmptcprouter.settings.ndpi)" != "0" ] && [ "$ndpi" != "0" ] && [ "$vpn" != "1" ]; then
if [ "$intf" = "all" ]; then
if [ "$family" = "ipv4" ] || [ "$family" = "ipv4ipv6" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-dpi -m ndpi --proto $proto -j MARK --set-mark 0x4539
-A omr-bypass-dpi -m mark --mark 0x4539 -j RETURN
COMMIT
EOF
fi
if [ "$disableipv6" = "0" ] && ([ "$family" = "ipv6" ] || [ "$family" = "ipv4ipv6" ]); then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6-dpi -m ndpi --proto $proto -j MARK --set-mark 0x6539
-A omr-bypass6-dpi -m mark --mark 0x6539 -j RETURN
COMMIT
EOF
fi
else
if [ "$family" = "ipv4" ] || [ "$family" = "ipv4ipv6" ]; then
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass-dpi -m ndpi --proto $proto -j MARK --set-mark 0x4539$intfid
-A omr-bypass-dpi -m mark --mark 0x4539$intfid -j RETURN
COMMIT
EOF
fi
if [ "$disableipv6" = "0" ] && ([ "$family" = "ipv6" ] || [ "$family" = "ipv4ipv6" ]); then
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
-A omr-bypass6-dpi -m ndpi --proto $proto -j MARK --set-mark 0x6539$intfid
-A omr-bypass6-dpi -m mark --mark 0x6539$intfid -j RETURN
COMMIT
EOF
fi
fi
fi
# Use dnsmasq ipset to bypass domains of the proto
local domains
domains="$(cat /proc/net/xt_ndpi/host_proto | grep -i $proto: | sed -e "s/$proto://i" -e 's/*//' -e 's/,/ /g')"
if [ -n "$domains" ]; then
tlds=`curl --max-time 4 -s -k https://data.iana.org/TLD/tlds-alpha-by-domain.txt`
for domain in $domains; do
if [ -n "$domain" ]; then
domain="$(echo $domain | sed 's/^\.//')"
if [ "$(echo $domain | grep '\.$')" != "" ]; then
domainlist=""
# construct list of domains to query
i=0
for tld in $tlds; do
i=$((i+1))
# trim off header
if [ "$i" -lt "12" ] || [ "$i" -gt "50" ]; then
continue
fi
# add to command
domainlist="${domainlist} ${domain}${tld}"
done
domainlist="$(echo $domainlist `# Get the list of valid domains, pass it to awk` \
| awk '{print tolower($0)}' `# awk lowercases the whole string and passes it to ` \
| xargs -n8 -P12 `# xargs sends 8 arguments at a time to` \
dig a +timeout=1 +tries=1 +retry=1 +nocmd +noall +answer `# dig, which passes results (if any) to` \
| awk '{print $1}' `# awk, which outputs queried domain to` \
| sed -e 's/.$//' `# sed, which trims off the trailing dot (google.com. -> google.com)` to \
| grep $domain `# grep, only keep wanted domain` \
| awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')" # deduplicate
for validdomain in $domainlist; do
_bypass_domain $validdomain $intf $family $noipv6
done
else
_bypass_domain $domain $intf $family $noipv6
fi
fi
done
fi
}
_bypass_proto_without_ndpi() {
local proto
local intf
local enabled
config_get proto $1 proto
config_get intf $1 interface
config_get enabled $1 enabled
config_get ndpi $1 ndpi "0"
config_get noipv6 $1 noipv6
config_get family $1 family
config_get vpn $1 vpn
[ "$vpn" = "1" ] && intf="srv_vpn1"
[ "$enabled" = "0" ] && return
[ -z "$noipv6" ] && noipv6="0"
[ -z "$family" ] && family="ipv4ipv6"
intf=$(echo $intf | sed -e 's/\./_/')
#[ -n "$intf" ] && [ -z "$(ipset --list | grep omr_dst_bypass_$intf)" ] && return
local intfid="$(uci -q get omr-bypass.$intf.id)"
[ -z "$intf" ] && intf="all"
[ "$intf" = "all" ] && intfid=""
[ -z "$proto" ] && return
if [ "$(uci -q get openmptcprouter.settings.ndpi)" == "0" ] || [ "$ndpi" == "0" ] || [ "$vpn" = "1" ]; then
ALLIPS=$(sqlite3 /usr/share/omr-bypass/omr-bypass.db "select ip from ipproto where proto=\"$proto\";" ".exit")
if [ -n "$ALLIPS" ]; then
if [ "$vpn" != "1" ]; then
uci -q batch <<-EOF >/dev/null
set firewall.bypass_$proto=ipset
set firewall.bypass_$proto.name="bypass_$proto"
set firewall.bypass_$proto.match='dest_ip'
set firewall.bypass_$proto_rule=rule
set firewall.bypass_$proto_rule.name="bypass_$proto"
set firewall.bypass_$proto_rule.src='lan'
set firewall.bypass_$proto_rule.dest='*'
set firewall.bypass_$proto_rule.target='MARK'
set firewall.bypass_$proto_rule.set_xmark="4539${intfid}"
commit firewall
EOF
uci -q batch <<-EOF >/dev/null
set firewall.bypass6_$proto=ipset
set firewall.bypass6_$proto.name="bypas6s_$proto"
set firewall.bypass6_$proto.match='dest_ip'
set firewall.bypass6_$proto_rule=rule
set firewall.bypass6_$proto_rule.name="bypass6_$proto"
set firewall.bypass6_$proto_rule.src='lan'
set firewall.bypass6_$proto_rule.dest='*'
set firewall.bypass6_$proto_rule.target='MARK'
set firewall.bypass6_$proto_rule.set_xmark="6539${intfid}"
commit firewall
EOF
#if [ "$intfid" != "" ]; then
# uci -q batch <<-EOF >/dev/null
# delete network.${1}_fw_rule=rule
# set network.${1}_fw_rule=rule
# set network.${1}_fw_rule.priority=1
# set network.${1}_fw_rule.mark=0x539${intfid}
# set network.${1}_fw_rule.lookup=${intfid}
# delete network.${1}_fw_rule6=rule6
# set network.${1}_fw_rule6=rule6
# set network.${1}_fw_rule6.priority=1
# set network.${1}_fw_rule6.mark=0x6539${intfid}
# set network.${1}_fw_rule6.lookup=${intfid}
# commit network
# EOF
#fi
#ipset -q flush bypass_$proto > /dev/null 2>&1
#ipset -q flush bypass6_$proto > /dev/null 2>&1
#ipset -q --exist restore <<-EOF
#create bypass_$proto hash:net hashsize 64
#create bypass6_$proto hash:net family inet6 hashsize 64
#EOF
fi
for ip in $ALLIPS; do
valid_ip4=$( valid_subnet4 $ip)
valid_ip6=$( valid_subnet6 $ip)
if [ "$valid_ip4" = "ok" ]; then
if [ "$vpn" != "1" ]; then
#ipset -q add bypass_$proto $ip
uci -q add_list firewall.bypass_$proto.entry=$ip
else
#ipset -q add omr_dst_bypass_$intf $ip
uci -q add_list firewall.omr_dst_bypass_$intf_4.entry=$ip
fi
elif [ "$valid_ip6" = "ok" ]; then
if [ "$vpn" != "1" ]; then
#ipset -q add bypass6_$proto $ip
uci -q add_list firewall.bypass6_$proto.entry=$ip
else
#ipset -q add omr6_dst_bypass_$intf $ip
uci -q add_list firewall.omr6_dst_bypass_$intf_4.entry=$ip
fi
fi
done
fi
fi
# Use dnsmasq ipset to bypass domains of the proto
local domains
#domains="$(cat /proc/net/xt_ndpi/host_proto | grep -i $proto: | sed -e "s/$proto://i" -e 's/*//' -e 's/,/ /g')"
domains=$(sqlite3 /usr/share/omr-bypass/omr-bypass.db "select host from hostproto where proto='"$proto"';" ".exit")
if [ -n "$domains" ]; then
tlds=`curl --max-time 4 -s -k https://data.iana.org/TLD/tlds-alpha-by-domain.txt`
for domain in $domains; do
if [ -n "$domain" ]; then
domain="$(echo $domain | sed 's/^\.//')"
if [ "$(echo $domain | grep '\.$')" != "" ]; then
domainlist=""
# construct list of domains to query
i=0
for tld in $tlds; do
i=$((i+1))
# trim off header
if [ "$i" -lt "2" ] || [ "${#tld}" -gt "3" ]; then
continue
fi
# add to command
domainlist="${domainlist} ${domain}${tld}"
done
domainlist="$(echo $domainlist `# Get the list of valid domains, pass it to awk` \
| awk '{print tolower($0)}' `# awk lowercases the whole string and passes it to ` \
| xargs -n8 -P12 `# xargs sends 8 arguments at a time to` \
dig a +timeout=1 +tries=1 +retry=1 +nocmd +noall +answer `# dig, which passes results (if any) to` \
| awk '{print $1}' `# awk, which outputs queried domain to` \
| sed 's/.$//' `# sed, which trims off the trailing dot (google.com. -> google.com) to` \
| grep $domain `# grep, only keep wanted domain` \
| awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')" # deduplicate
for validdomain in $domainlist; do
_bypass_domain $validdomain $intf $family $noipv6
done
else
_bypass_domain $domain $intf $family $noipv6
fi
fi
done
fi
}
_intf_rule_ss_rules() {
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip daddr @omr_dst_bypass_${intf}_4 accept
nft insert rule inet fw4 ss_rules_local_out ip daddr @omr_dst_bypass_${intf}_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip6 daddr @omr_dst_bypass_${intf}_6 accept
nft insert rule inet fw4 ss_rules_local_out ip6 daddr @omr_dst_bypass_${intf}_6 accept
EOF
fi
}
_intf_rule_v2ray_rules() {
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 v2r_rules_dst_tcp ip daddr @omr_dst_bypass_${intf}_4 accept
nft insert rule inet fw4 v2r_rules_local_out ip daddr @omr_dst_bypass_${intf}_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 v2r_rules_dst_tcp ip6 daddr @omr_dst_bypass_${intf}_6 accept
nft insert rule inet fw4 v2r_rules_local_out ip6 daddr @omr_dst_bypass_${intf}_6 accept
EOF
fi
}
_intf_rule_xray_rules() {
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 xr_rules_dst_tcp ip daddr @omr_dst_bypass_${intf}_4 accept
nft insert rule inet fw4 xr_rules_local_out ip daddr @omr_dst_bypass_${intf}_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 xr_rules_dst_tcp ip6 daddr @omr_dst_bypass_${intf}_6 accept
nft insert rule inet fw4 xr_rules_local_out ip6 daddr @omr_dst_bypass_${intf}_6 accept
EOF
fi
}
_intf_rule() {
local intf
[ "$1" = "all" ] && intf="all"
[ -z "$intf" ] && intf=$(ifstatus "$1" | jsonfilter -q -e '@["l3_device"]')
[ -n "$(echo $intf | grep '@')" ] && intf=$(ifstatus "$1" | jsonfilter -q -e '@["device"]')
[ -z "$intf" ] && config_get intf $1 device
[ -n "$(echo $intf | grep '/')" ] && return
#count=$((count+1))
[ "$intf" != "all" ] && config_get count $1 metric
[ "$intf" = "all" ] && count=""
local mode
#config_get mode $1 multipath "off"
#[ "$mode" = "off" ] && return
[ "$intf" != "all" ] && [ -z "$count" ] && return
[ -z "$intf" ] && return
intf=$(echo $intf | sed -e 's/\./_/')
intf=$(echo $intf | sed -e 's/-/_/')
[ "$(echo $1 | grep _dev)" != "" ] && return
[ "$intf" = "lo" ] && return
[ -z "$intf" ] && return
# [ -z "$RELOAD" ] || [ "$(uci show firewall.omr_dst_bypass_$intf_4)" = "" ] && {
#unset RELOAD
#echo "$intf ip set dhcp"
uci batch <<-EOF
set dhcp.omr_dst_bypass_$intf=ipset
add_list dhcp.omr_dst_bypass_$intf.name="omr_dst_bypass_${intf}_4"
add_list dhcp.omr_dst_bypass_$intf.name="omr_dst_bypass_${intf}_6"
commit dhcp
EOF
#echo "firewall omr_dst_bypass ipset"
uci -q batch <<-EOF
set firewall.omr_dst_bypass_${intf}_4=ipset
set firewall.omr_dst_bypass_${intf}_4.name="omr_dst_bypass_${intf}_4"
set firewall.omr_dst_bypass_${intf}_4.match='dest_ip'
EOF
#echo "firewall omr_dst_bypass rules"
if [ "$disableipv6" = "0" ]; then
protocol="4 6"
else
protocol="4"
fi
for ipv46 in $protocol; do
echo "ipv46: $ipv46 for $intf"
uci batch <<-EOF
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.name="omr_dst_bypass_${intf}_rule"
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.ipset="omr_dst_bypass_${intf}_4"
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_dstip_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.name="omr_dst_bypass_${intf}_srcip"
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.ipset="omr_dst_bypass_${intf}_4"
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_srcip_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.name='omr_dst_bypass_${intf}_mac'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_mac_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.name="omr_dst_bypass_${intf}_srcport"
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.proto='tcp'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_srcport_tcp_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.name="omr_dst_bypass_${intf}_srcport"
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.proto='udp'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_srcport_udp_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.name="omr_dst_bypass_${intf}_dstport"
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_dstport_tcp_${ipv46}.set_xmark="${ipv46}539${count}"
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}=rule
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.name="omr_dst_bypass_${intf}_dstport"
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.src='lan'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.dest='*'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.target='MARK'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.enabled='0'
set firewall.omr_dst_bypass_${intf}_dstport_udp_${ipv46}.set_xmark="${ipv46}539${count}"
commit firewall
EOF
done
if [ "$intf" = "all" ]; then
uci -q batch <<-EOF >/dev/null
delete network.${intf}_fw_rule=rule
set network.${intf}_fw_rule=rule
set network.${intf}_fw_rule.priority=1
set network.${intf}_fw_rule.mark=0x4539
set network.${intf}_fw_rule.lookup=991337
delete network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6.priority=1
set network.${intf}_fw_rule6.mark=0x6539
set network.${intf}_fw_rule6.lookup=6991337
commit network
EOF
else
uci -q batch <<-EOF >/dev/null
delete network.${intf}_fw_rule=rule
set network.${intf}_fw_rule=rule
set network.${intf}_fw_rule.priority=1
set network.${intf}_fw_rule.mark=0x4539${count}
set network.${intf}_fw_rule.lookup=${count}
delete network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6=rule6
set network.${intf}_fw_rule6.priority=1
set network.${intf}_fw_rule6.mark=0x6539${count}
set network.${intf}_fw_rule6.lookup=${count}
commit network
EOF
fi
if [ "$(uci -q get openmptcprouter.settings.proxy)" = "shadowsocks" ]; then
config_load shadowsocks-libev
config_foreach _intf_rule_ss_rules ss_rules
elif [ "$(uci -q get openmptcprouter.settings.proxy)" = "shadowsocks-rust" ]; then
config_load shadowsocks-rust
config_foreach _intf_rule_ss_rules ss_rules
elif [ "$(uci -q get openmptcprouter.settings.proxy)" = "v2ray" ]; then
_intf_rule_v2ray_rules
elif [ "$(uci -q get openmptcprouter.settings.proxy)" = "xray" ]; then
_intf_rule_xray_rules
fi
uci -q set omr-bypass.$intf=interface
uci -q set omr-bypass.$intf.id=$count
}
_bypass_ip_set() {
local ip
local interface
local enabled
config_get ip $1 ip
config_get interface $1 interface
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
_bypass_ip $ip $interface
}
_bypass_asn() {
local asn
local interface
local enabled
config_get asn $1 asn
config_get interface $1 interface
config_get enabled $1 enabled
[ "$enabled" = "0" ] && return
local asnips
asnips=`curl --max-time 4 -s -k https://stat.ripe.net/data/announced-prefixes/data.json?resource=${asn} | jsonfilter -q -e '@.data.prefixes.*.prefix'`
for ip in $asnips; do
_bypass_ip $ip $interface
done
}
bypass_asn() {
config_load omr-bypass
config_foreach _bypass_asn asns
}
_bypass_omr_server() {
local ip
config_get ip $1 ip
_bypass_ip $ip
}
_ss_rules_config() {
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip daddr @omr_dst_bypass_all_4 accept
nft insert rule inet fw4 ss_rules_local_out ip daddr @omr_dst_bypass_all_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 ss_rules_dst_tcp ip6 daddr @omr_dst_bypass_all_6 accept
nft insert rule inet fw4 ss_rules_local_out ip6 daddr @omr_dst_bypass_all_6 accept
EOF
fi
}
_v2ray_rules_config() {
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 v2r_rules_dst_tcp ip daddr @omr_dst_bypass_all_4 accept
nft insert rule inet fw4 v2r_rules_local_out ip daddr @omr_dst_bypass_all_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 v2r_rules_dst_tcp ip6 daddr @omr_dst_bypass_all_6 accept
nft insert rule inet fw4 v2r_rules_local_out ip6 daddr @omr_dst_bypass_all_6 accept
EOF
fi
}
_xray_rules_config() {
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 xr_rules_dst_tcp ip daddr @omr_dst_bypass_all_4 accept
nft insert rule inet fw4 xr_rules_local_out ip daddr @omr_dst_bypass_all_4 accept
EOF
if [ "$disableipv6" = "0" ]; then
cat >> /etc/firewall.omr-bypass <<-EOF
nft insert rule inet fw4 xr_rules_dst_tcp ip6 daddr @omr_dst_bypass_all_6 accept
nft insert rule inet fw4 xr_rules_local_out ip6 daddr @omr_dst_bypass_all_6 accept
EOF
fi
}
_delete_dhcp_ipset() {
[ -n "$(echo $1 | grep omr_dst_bypass)" ] && {
uci -q delete dhcp.$1
}
}
_delete_firewall_rules() {
([ -n "$(echo $1 | grep omr_dst_bypass)" ] || [ -n "$(echo $1 | grep omr6_dst_bypass)" ]) && {
uci -q delete firewall.$1
}
}
boot() {
BOOT=1
start "$@"
}
start_service() {
#local count
logger -t "omr-bypass" "Starting OMR-ByPass..."
config_load dhcp
config_foreach _delete_dhcp_ipset ipset
#uci -q commit dhcp
config_load firewall
config_foreach _delete_firewall_rules rule
config_foreach _delete_firewall_rules ipset
#uci -q commit firewall
add_domains="false"
[ -d /proc/net/xt_ndpi ] && {
config_load omr-bypass
config_foreach _add_proto proto
}
disableipv6="$(uci -q get openmptcprouter.settings.disable_ipv6)"
#noipv6="$(uci -q get omr-bypass.global.noipv6)"
cat > /etc/firewall.omr-bypass <<-EOF
#!/bin/sh
#nft insert rule inet fw4 ss_rules_dst_tcp ip daddr @omr_dst_bypass_all accept
#nft insert rule inet fw4 ss_rules_local_out ip daddr @omr_dst_bypass_all accept
EOF
uci batch <<-EOF
set firewall.omr_bypass=include
set firewall.omr_bypass.enabled='1'
set firewall.omr_bypass.type='script'
set firewall.omr_bypass.path='/etc/firewall.omr-bypass'
set firewall.omr_bypass.fw4_compatible='1'
commit firewall
EOF
echo "intf_rule"
config_load network
config_foreach _intf_rule interface
_intf_rule all
_intf_rule srv_vpn1
local ndpi_rules=""
echo "bypass server"
if [ "$(uci -q get openmptcprouter.settings.bypass_servers)" = "1" ]; then
config_load openmptcprouter
config_foreach _bypass_omr_server server
fi
config_load omr-bypass
echo "bypass ip"
config_foreach _bypass_ip_set ips
echo "bypass mac"
config_foreach _bypass_mac macs
echo "bypass lan ip"
config_foreach _bypass_lan_ip lan_ip
echo "bypass dest port"
config_foreach _bypass_dest_port dest_port
echo "bypass src port"
config_foreach _bypass_src_port src_port
echo "bypass asn"
config_foreach _bypass_asn asns
echo "bypass domains"
config_foreach _bypass_domains domains
uci -q commit dhcp
# ip rule add prio 1 fwmark 0x4539 lookup 991337 > /dev/null 2>&1
# ip -6 rule add prio 1 fwmark 0x6539 lookup 6991337 > /dev/null 2>&1
#config_load shadowsocks-libev
#config_foreach _ss_rules_config ss_rules
([ "$(uci -q get shadowsocks-libev.sss0.disabled)" != "1" ] || [ "$(uci -q get shadowsocks-rust.sss0.disabled)" != "1" ]) && _ss_rules_config
#config_load shadowsocks-rust
#config_foreach _ss_rules_config ss_rules
[ "$(uci -q get v2ray.main.enabled)" = "1" ] && _v2ray_rules_config
[ "$(uci -q get xray.main.enabled)" = "1" ] && _xray_rules_config
# NDPI Netfilter is not available for nftables
$IPTABLESSAVE --counters 2>/dev/null | grep -v omr-bypass-dpi | $IPTABLESRESTORE -w --counters 2>/dev/null
$IPTABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
:omr-bypass-dpi -
-A INPUT -j omr-bypass-dpi
-A FORWARD -j omr-bypass-dpi
COMMIT
EOF
if [ "$disableipv6" = "0" ]; then
$IP6TABLESSAVE --counters | grep -v omr-bypass6-dpi | $IP6TABLESRESTORE -w --counters 2>/dev/null
$IP6TABLESRESTORE -w --wait=60 --noflush <<-EOF
*mangle
:omr-bypass6-dpi -
-A INPUT -j omr-bypass6-dpi
-A FORWARD -j omr-bypass6-dpi
COMMIT
EOF
fi
config_load omr-bypass
[ -d /proc/net/xt_ndpi/proto ] && config_foreach _bypass_proto dpis
config_foreach _bypass_proto_without_ndpi dpis
uci -q commit omr-bypass
[ -z "$RELOAD" ] && [ "$add_domains" = "true" ] && {
logger -t "omr-bypass" "Restart dnsmasq..."
/etc/init.d/dnsmasq restart
}
[ -n "$RELOAD" ] && [ "$add_domains" = "true" ] && {
logger -t "omr-bypass" "Reload dnsmasq..."
/etc/init.d/dnsmasq reload
}
fw4 restart
# Create a protocol list for UI from a sqlite DB when NDPI is not available
sqlite3 /usr/share/omr-bypass/omr-bypass.db "select distinct(proto) from (select proto from hostproto union all select proto from ipproto) a order by proto;" ".exit" > /usr/share/omr-bypass/omr-bypass-proto.lst
config_load omr-bypass
config_foreach _add_proto_without_ndpi proto
sort < /usr/share/omr-bypass/omr-bypass-proto.lst > /usr/share/omr-bypass/omr-bypass-proto.lst.new
mv /usr/share/omr-bypass/omr-bypass-proto.lst.new /usr/share/omr-bypass/omr-bypass-proto.lst
logger -t "omr-bypass" "OMR-ByPass is running"
}
stop_service() {
# Rules for ndpi
$IPTABLESSAVE --counters 2>/dev/null | grep -v omr-bypass | $IPTABLESRESTORE -w --counters 2>/dev/null
$IP6TABLESSAVE --counters 2>/dev/null | grep -v omr-bypass6 | $IP6TABLESRESTORE -w --counters 2>/dev/null
# disable all rules
uci -q set firewall.omr_bypass.enabled='0'
config_load dhcp
config_foreach _delete_dhcp_ipset ipset
uci -q commit dhcp
config_load firewall
config_foreach _delete_firewall_rules rule
config_foreach _delete_firewall_rules ipset
uci -q commit firewall
fw4 restart
exit 0
}
service_triggers() {
procd_add_reload_trigger omr-bypass network firewall
}
reload_service() {
RELOAD=1
start
}
reload_rules() {
#[ "$( ipset -n list | grep omr_ )" = "" ] && return 0
RELOAD=1
start
}

52
omr-dscp/Makefile Normal file
View file

@ -0,0 +1,52 @@
#
# Copyright (C) 2018-2023 Ycarus (Yannick Chabanois) <ycarus@zugaina.org> for OpenMPTCProuter
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=omr-dscp
PKG_VERSION:=0.1
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
DEPENDS:= +dnsmasq-full +LINUX_5_4:iptables +LINUX_5_4:iptables-mod-extra +LINUX_5_4:ipset
TITLE:=OMR-DSCP
endef
define Package/$(PKG_NAME)-nft
SECTION:=net
CATEGORY:=Network
DEPENDS:= +dnsmasq-full
TITLE:=OMR-DSCP nft
endef
define Package/$(PKG_NAME)/description
OMR-ByPass
endef
define Package/$(PKG_NAME)-nft/description
OMR-ByPass nft support
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(CP) ./files/* $(1)/
rm -f $(1)/etc/init.d/omr-dscp-nft
endef
define Package/$(PKG_NAME)-nft/install
$(CP) ./files/* $(1)/
mv $(1)/etc/init.d/omr-dscp-nft $(1)/etc/init.d/omr-dscp
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
$(eval $(call BuildPackage,$(PKG_NAME)-nft))

View file

@ -11,9 +11,9 @@ USE_PROCD=1
# shellcheck disable=SC1091
. /lib/functions.sh
if [ -f /usr/sbin/iptables-legacy ]; then
IPTABLES="/usr/sbin/iptables-legacy"
IP6TABLES="/usr/sbin/ip6tables-legacy"
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
IP6TABLES="/usr/sbin/ip6tables-nft"
else
IPTABLES="/usr/sbin/iptables"
IP6TABLES="/usr/sbin/ip6tables"

View file

@ -0,0 +1,187 @@
#!/bin/sh /etc/rc.common
# vim: set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 :
# shellcheck disable=SC2034
START=90
# shellcheck disable=SC2034
STOP=10
# shellcheck disable=SC2034
USE_PROCD=1
# shellcheck disable=SC1091
. /lib/functions.sh
# Get the lan interface name
lan_device=
config_load network
config_get lan_device lan ifname
#config_load dscp
_add_dscp_domain() {
domain=""; config_get domain "$1" name ""
class=""; config_get class "$1" class ""
[ -n "$domain" ] && [ -n "$class" ] && [ -z "$(uci -q get dhcp.omr_dscp-$class.domain | grep $domain)" ] && {
uci -q batch <<-EOF
add_list dhcp.omr_dscp_$class.domain="$domain"
commit dhcp
EOF
}
}
_add_dscp_domains_rules() {
for class in cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7 ef; do
uci -q batch <<-EOF
set dhcp.omr_dscp_${class}=ipset
add_list dhcp.omr_dscp_${class}.name="omr_dscp_${class}_4"
add_list dhcp.omr_dscp_${class}.name="omr_dscp_${class}_6"
commit dhcp
EOF
uci batch <<-EOF
set firewall.omr_dscp_${class}_4=ipset
set firewall.omr_dscp_${class}_4.name="omr_dscp_${class}_4"
set firewall.omr_dscp_${class}_4.match='dest_ip'
set firewall.omr_dscp_${class}_6=ipset
set firewall.omr_dscp_${class}_6.name="omr_dscp_${class}_6"
set firewall.omr_dscp_${class}_6.match='dest_ip'
EOF
uci -q batch <<-EOF
set firewall.omr_dscp_${class}=rule
set firewall.omr_dscp_${class}.ipset="omr_dscp_${class}_4"
set firewall.omr_dscp_${class}.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')"
set firewall.omr_dscp_${class}.target='DSCP'
set firewall.omr_dscp_${class}.src='lan'
set firewall.omr_dscp_${class}.dest='*'
set firewall.omr6_dscp_${class}=rule
set firewall.omr6_dscp_${class}.ipset="omr_dscp_${class}_6"
set firewall.omr6_dscp_${class}.target='DSCP'
set firewall.omr6_dscp_${class}.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')"
set firewall.omr6_dscp_${class}.src='lan'
set firewall.omr6_dscp_${class}.dest='*'
commit firewall
EOF
done
}
_add_dscp_rules() {
proto="" ; config_get proto "$1" proto all
src_ip="" ; config_get src_ip "$1" src_ip 0.0.0.0/0
src_port="" ; config_get src_port "$1" src_port 0:65535
dest_ip="" ; config_get dest_ip "$1" dest_ip 0.0.0.0/0
dest_port="" ; config_get dest_port "$1" dest_port 0:65535
class="" ; config_get class "$1" class
direction="" ; config_get direction "$1" direction "upload"
comment="" ; config_get comment "$1" comment "-"
src_port="$(echo $src_port | sed 's/:/-/g')"
dest_port="$(echo $dest_port | sed 's/:/-/g')"
count=$((count + 1))
[ "$proto" = "all" ] && proto="tcp udp"
case "$direction" in
upload|both)
# Apply the rule locally
uci -q batch <<-EOF
set firewall.omr_dscp_rule$count=rule
set firewall.omr_dscp_rule$count.name="omr_dscp_rule$count"
set firewall.omr_dscp_rule$count.target="DSCP"
set firewall.omr_dscp_rule$count.set_dscp="$(echo ${class} | tr '[a-z'] '[A-Z]')"
set firewall.omr_dscp_rule$count.src="lan"
set firewall.omr_dscp_rule$count.src_ip="$src_ip"
set firewall.omr_dscp_rule$count.dest_ip="$dest_ip"
set firewall.omr_dscp_rule$count.proto="$proto"
EOF
src_port="$(echo $src_port | sed 's/,/ /g')"
dest_port="$(echo $dest_port | sed 's/,/ /g')"
for port in $src_port; do
uci -q set firewall.omr_dscp_rule$count.src_port="$src_port"
done
for port in $src_port; do
uci -q set firewall.omr_dscp_rule$count.dest_port="$dest_port"
done
#_add_dscp_rule -m multiport --sports "$src_port" -m multiport --dports "$dest_port"
;;
download|both)
;;
esac
uci -q commit firewall
}
_add_fwmark_chain() {
_ipt4 -N dscp_mark
_ipt4 -A PREROUTING -i "$lan_device" -j dscp_mark
_ipt4 -A POSTROUTING -j dscp_mark
_ipt6 -N dscp_mark
_ipt6 -A PREROUTING -i "$lan_device" -j dscp_mark
_ipt6 -A POSTROUTING -j dscp_mark
for class in cs4 cs5 cs6 cs7; do
# xtun (hex) -> 0x7874756e
_ipt4 -A dscp_mark \
-m comment --comment "$class" \
-m dscp --dscp-class "$class" \
-j MARK --set-mark 0x7874756e
_ipt6 -A dscp_mark \
-m comment --comment "$class" \
-m dscp --dscp-class "$class" \
-j MARK --set-mark 0x7874756e
done
}
_remove_ipset_dnsmasq() {
[ -n "$(echo $1 | grep omr_dscp)" ] && uci -q delete dhcp.$1
}
_remove_rules() {
([ -n "$(echo $1 | grep omr_dscp)" ] || [ -n "$(echo $1 | grep omr6_dscp)" ]) && uci -q delete firewall.$1
}
_setup_tunnel() {
# Mark the packets to route through xtun0
_add_fwmark_chain
# tun0: cs0 (default)
# xtun0: cs6
_ipt4 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6
_ipt6 -A dscp_output -o "tun0" -j DSCP --set-dscp-class cs6
}
_cleanup() {
config_load dhcp
config_foreach _remove_ipset_dnsmasq
config_load firewall
config_foreach _remove_rules
uci -q commit dhcp
uci -q commit firewall
fw4 restart
}
start_service() {
# Cleanup
_cleanup
config_load dscp
# Add chains
_add_dscp_domains_rules
# Setup the tunnels dscp / marks
#_setup_tunnel
# Add rules base on the user configuration
count=0
config_foreach _add_dscp_rules classify
config_foreach _add_dscp_domain domains
uci -q commit dhcp
fw4 restart
}
stop_service() {
_cleanup
}
reload_service() {
start
}
service_triggers() {
procd_add_reload_trigger dscp
}

38
omr-schedule/Makefile Normal file
View file

@ -0,0 +1,38 @@
#
# Copyright (C) 2018-2023 Ycarus (Yannick Chabanois) <ycarus@zugaina.org>
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=omr-schedule
PKG_VERSION:=0.1
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=OMR
CATEGORY:=OMR-Schedule
DEPENDS:=$(foreach p,$(MY_DEPENDS),+$(p))
TITLE:=OpenMPTCProuter schedule scripts
endef
define Package/$(PKG_NAME)/description
OpenMPTCProuter schedule scripts
endef
define Package/$(PKG_NAME)/conffiles
/etc/contabs/root
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View file

@ -0,0 +1,12 @@
#!/bin/sh
. /lib/functions.sh
. /lib/functions/network.sh
for schedule_bin in /usr/share/omr/schedule.d/*; do
[ -x "$schedule_bin" ] && (
_log() {
logger -t "omr-schedule-${schedule_bin##*/}" "$*"
}
. "$schedule_bin" 2>&1
)
done

View file

@ -0,0 +1,4 @@
#!/bin/sh
if [ ! -f /etc/crontabs/root ] || [ "$(cat /etc/crontabs/root | grep omr-schedule)" = "" ]; then
echo "*/5 * * * * /bin/omr-schedule" >> /etc/crontabs/root
fi

View file

@ -33,15 +33,15 @@ if [ "$(pgrep -f dnsmasq)" = "" ] && [ -f /etc/init.d/dnsmasq ]; then
/etc/init.d/dnsmasq restart 2>&1 >/dev/null
sleep 5
fi
if [ -f /etc/init.d/unbound ] && [ "$(uci -q get unbound.@unbound[0].enabled)" = "1" ] && [ "$OMR_TRACKER_STATUS" != "ERROR" ]; then
if [ -f /etc/init.d/unbound ] && [ "$(uci -q get unbound.@unbound[0].enabled)" = "1" ]; then
if [ "$(pgrep -f unbound)" = "" ]; then
_log "Can't find unbound, restart it..."
/etc/init.d/unbound restart 2>&1 >/dev/null
sleep 5
elif [ "$(uci -q get openmptcprouter.settings.external_check)" != "0" ] && [ "$(uci -q get unbound.ub_main.listen_port)" = "5353" ] && [ -n "$(dig +timeout=4 +tries=1 openmptcprouter.com -p 5353 | grep 'ANSWER: 0')" ]; then
_log "Can't resolve via unbound, restart it..."
/etc/init.d/unbound restart 2>&1 >/dev/null
sleep 20
# elif [ "$(uci -q get openmptcprouter.settings.external_check)" != "0" ] && [ "$(uci -q get unbound.ub_main.listen_port)" = "5353" ] && [ -n "$(dig +timeout=4 +tries=1 openmptcprouter.com -p 5353 | grep 'ANSWER: 0')" ]; then
# _log "Can't resolve via unbound, restart it..."
# /etc/init.d/unbound restart 2>&1 >/dev/null
# sleep 5
fi
fi
@ -101,10 +101,10 @@ if [ -z "$(pgrep ModemManager)" ] && [ -f /etc/init.d/modemmanager ] && [ -n "$(
_log "Can't find ModemManager, restart it..."
/etc/init.d/modemmanager restart 2>&1 >/dev/null
sleep 5
#elif [ -n "$(pgrep ModemManager)" ] && [ -f /etc/init.d/modemmanager ] && [ -z "$(uci -q show network | grep modemmanager)" ]; then
# _log "ModemManager not used, stop it..."
# /etc/init.d/modemmanager stop 2>&1 >/dev/null
# sleep 5
elif [ -n "$(pgrep ModemManager)" ] && [ -f /etc/init.d/modemmanager ] && [ -z "$(uci -q show network | grep modemmanager)" ]; then
_log "ModemManager not used, stop it..."
/etc/init.d/modemmanager stop 2>&1 >/dev/null
sleep 5
fi
if [ "$(uci -q get v2ray.main.enabled)" = "1" ] && [ -f /etc/init.d/v2ray ] && [ "$(pgrep -f omr-tracker-v2ray)" = "" ] && [ "$(pgrep -f '/etc/init.d/omr-tracker')" = "" ]; then
@ -138,34 +138,33 @@ restart_omrtracker() {
}
set_lan_ips() {
config_get ip4table "$1" ip4table
config_get device "$1" device
config_get proto "$1" proto
if [ "$ip4table" = "lan" ] && [ -n "$device" ] && ([ "$proto" = "dhcp" ] || [ "$proto" = "static" ]); then
[ -z "$(uci -q get shadowsocks-libev.ss_rules.ifnames | grep $device)" ] && {
uci -q add_list shadowsocks-libev.ss_rules.ifnames="$device"
uci -q add_list shadowsocks-rust.ss_rules.ifnames="$device"
}
elif [ -n "$device" ] && [ -n "$(uci -q get shadowsocks-libev.ss_rules.ifnames | grep $device)" ]; then
uci -q del_list shadowsocks-libev.ss_rules.ifnames="$device"
uci -q del_list shadowsocks-rust.ss_rules.ifnames="$device"
fi
config_get ip4table "$1" ip4table
config_get device "$1" device
config_get proto "$1" proto
if [ "$ip4table" = "lan" ] && [ -n "$device" ] && ([ "$proto" = "dhcp" ] || [ "$proto" = "static" ]); then
[ -z "$(uci -q get shadowsocks-libev.ss_rules.ifnames | grep $device)" ] && {
uci -q add_list shadowsocks-libev.ss_rules.ifnames="$device"
uci -q add_list shadowsocks-rust.ss_rules.ifnames="$device"
}
elif [ -n "$device" ] && [ -n "$(uci -q get shadowsocks-libev.ss_rules.ifnames | grep $device)" ]; then
uci -q del_list shadowsocks-libev.ss_rules.ifnames="$device"
uci -q del_list shadowsocks-rust.ss_rules.ifnames="$device"
fi
}
config_load network
config_foreach restart_omrtracker interface
#config_foreach set_lan_ips interface
mutlipath_fix() {
config_foreach set_lan_ips interface
uci -q commit shadowsocks-libev.ss_rules
uci -q commit shadowsocks-rust.ss_rules
multipath_fix() {
config_get multipath "$1" multipath
[ "$multipath" != "off" ] && return
interface="$(ifstatus $1 | jsonfilter -q -e '@.l3_device' | tr -d '\n')"
[ -n "$interface"] && [ -z "$(multipath $interface | grep deactivated)" ] && /etc/init.d/mptcp reload $interface 2>&1 >/dev/null
[ -n "$interface" ] && [ -z "$(multipath $interface | grep deactivated)" ] && /etc/init.d/mptcp reload $interface 2>&1 >/dev/null
}
config_load network
config_foreach multipath_fix interface
if [ -f /etc/init.d/shadowsocks-libev ] && [ "$(uci -q get shadowsocks-libev.sss0.disabled)" != "1" ] && [ "$(uci -q get shadowsocks-libev.sss0.key)" != "" ] && [ "$(uci -q get shadowsocks-libev.sss0.server)" != "" ] && [ "$(uci -q get shadowsocks-libev.sss0.server)" != "192.18.1.3" ] && [ "$(pgrep -f omr-tracker-ss)" = "" ] && [ "$(pgrep -f '/etc/init.d/omr-tracker')" = "" ]; then
_log "Can't find omr-tracker-ss for Shadowsocks libev, restart omr-tracker..."
/etc/init.d/omr-tracker restart 2>&1 >/dev/null
@ -201,7 +200,7 @@ if [ -n "$(logread | tail -n 2 | grep 'Ring expansion failed')" ]; then
echo 1 > /sys/bus/pci/rescan
fi
if [ -f /etc/init.d/omr-bypass ] && [ "$(iptables-save 2>/dev/null | grep omr-bypass)" = "" ] && [ "$(pgrep -f omr-bypass)" = "" ]; then
if [ -f /etc/init.d/omr-bypass ] && (([ -e /usr/sbin/iptables-nft-save ] && [ "$(iptables-nft-save 2>/dev/null | grep omr-bypass)" = "" ]) || [ "$(iptables-save 2>/dev/null | grep omr-bypass)" = "" ]) && [ "$(pgrep -f omr-bypass)" = "" ]; then
_log "Can't find omr-bypass rules, restart omr-bypass..."
/etc/init.d/omr-bypass 2>&1 >/dev/null
sleep 5
@ -231,7 +230,7 @@ if [ -n "$OMR_TRACKER_INTERFACE" ] && [ "$(uci -q get sqm.${OMR_TRACKER_INTERFAC
fi
fi
#if [ "$(uci -q show openmptcprouter | grep server)" != "" ] && [ "$(uci -q show openmptcprouter | grep password)" != "" ] && [ "$(pgrep -f openmptcprouter-vps)" = "" ] && [ "$(uci -q show openmptcprouter | grep admin_error=\'1\')" = "" ] && ([ "$(uci -q show openmptcprouter | grep set_firewall=\'1\')" != "" ] || [ -z "$(iptables-save 2>/dev/null | grep omr_dst_bypass_${OMR_TRACKER_DEVICE})" ]); then
#if [ "$(uci -q show openmptcprouter | grep server)" != "" ] && [ "$(uci -q show openmptcprouter | grep password)" != "" ] && [ "$(pgrep -f openmptcprouter-vps)" = "" ] && [ "$(uci -q show openmptcprouter | grep admin_error=\'1\')" = "" ] && ([ "$(uci -q show openmptcprouter | grep set_firewall=\'1\')" != "" ] || (([ -e /usr/sbin/iptables-nft-save ] && [ -z "$(iptables-save 2>/dev/null | grep omr_dst_bypass_${OMR_TRACKER_DEVICE})" ]) || [ -z "$(iptables-save 2>/dev/null | grep omr_dst_bypass_${OMR_TRACKER_DEVICE})" ])); then
if [ "$(pgrep -f set_vps_firewall)" = "" ] && [ "$(uci -q show openmptcprouter | grep server)" != "" ] && [ "$(uci -q show openmptcprouter | grep password)" != "" ] && [ "$(pgrep -f openmptcprouter-vps)" = "" ] && [ "$(uci -q show openmptcprouter | grep admin_error=\'1\')" = "" ] && [ "$(uci -q show openmptcprouter | grep set_firewall=\'1\')" != "" ]; then
check_server_fw() {
[ "$(uci -q get openmptcprouter.$1.set_firewall)" = "1" ] && {

View file

@ -0,0 +1,25 @@
#!/bin/sh
bypassipvs4s=$(ipset -o save list omr_dst_bypass_srv_vpn1_4 2>/dev/null)
[ -z "$bypassipvs4s" ] && {
ipv4set=$(nft -j list set inet fw4 "omr_dst_bypass_srv_vpn1_4" 2>/dev/null)
[ -n "$ipv4set" ] && bypassipv4s=$(echo "$ipv4set" | jsonfilter -e @.nftables[1].set.elem[*].prefix | awk '{gsub(/"/,"",$3);gsub(/,/,"/",$3); print $3 $5}')
}
bypassipvs6s=$(ipset -o save list omr_dst_bypass_srv_vpn1_6 2>/dev/null)
[ -z "$bypassipvs6s" ] && {
ipv6set=$(nft -j list set inet fw4 "omr_dst_bypass_srv_vpn1_6" 2>/dev/null)
[ -n "$ipv6set" ] && bypassipv6s=$(echo "$ipv6set" | jsonfilter -e @.nftables[1].set.elem[*].prefix | awk '{gsub(/"/,"",$3);gsub(/,/,"/",$3); print $3 $5}')
}
#"
vpnipv4md5=$(echo "${bypassipv4s}" | md5sum | awk '{print $1}' | tr -d "\n")
vpnipv6md5=$(echo "${bypassipv6s}" | md5sum | awk '{print $1}' | tr -d "\n")
if [ "$vpnipv4md5" != "$(uci -q get omr-bypass.global.vpn_ipv4_md5)" ] || [ "$vpnipv6md5" != "$(uci -q get omr-bypass.global.vpn_ipv6_md5)" ]; then
_log "Set bypass ip on servers"
/etc/init.d/openmptcprouter-vps set_bypass_ips
uci -q batch <<-EOF >/dev/null
set omr-bypass.global=global
set omr-bypass.global.vpn_ipv4_md5=${vpnipv4md5}
set omr-bypass.global.vpn_ipv6_md5=${vpnipv6md5}
commit omr-bypass
EOF
fi

View file

@ -37,6 +37,29 @@ _check_server() {
done
}
_check_server_intf() {
local host=$1
local port=$2
local k=0
for intf in $(multipath | awk '/default/ {print $1}'); do
while [ "$server_ping" = false ] && [ "$k" -le "$retry" ]; do
ret=$(curl \
--max-time "$OMR_TRACKER_TIMEOUT" \
-s \
-k \
--interface $intf
"https://${host}:${port}/"
)
[ -n "$ret" ] && {
server_ping=true
return
}
k=$((k+1))
sleep "${intervaltries}"
done
done
}
_disable_current() {
local serv=$1
config_set $serv current "0"
@ -80,7 +103,8 @@ _check_master() {
fi
[ -z "$ip" ] && return
#_ping_server $ip
_check_server $ip $port
#_check_server $ip $port
_check_server_intf $ip $port
if [ "$server_ping" = true ]; then
if [ "$(uci -q get shadowsocks-libev.sss${count}.server | tr -d '\n')" != "$ip" ]; then
logger -t "OMR-Tracker-Server" "Master server ${name} up ($ip), set it back"
@ -221,7 +245,8 @@ _check_backup() {
[ -n "$ip6resolve" ] && ip="$ip6resolve"
fi
#_ping_server $ip
_check_server $ip $port
#_check_server $ip $port
_check_server_intf $ip $port
#[ "$server_ping" = true ] && [ "$(uci -q get shadowsocks-libev.sss${count}.server | tr -d '\n')" = "$ip" ] && break
if [ "$server_ping" = true ]; then
if [ "$(uci -q get shadowsocks-libev.sss${count}.server | tr -d '\n')" != "$ip" ]; then

View file

@ -4,9 +4,9 @@
name=$0
basename="$(basename $0)"
if [ -f /usr/sbin/iptables-legacy ]; then
IPTABLES="/usr/sbin/iptables-legacy"
IPTABLESSAVE="/usr/sbin/iptables-legacy-save"
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
IPTABLESSAVE="/usr/sbin/iptables-nft-save"
else
IPTABLES="/usr/sbin/iptables"
IPTABLESSAVE="/usr/sbin/iptables-save"
@ -103,7 +103,7 @@ while true; do
script_alert_up="$(uci -q get omr-tracker.proxy.script_alert_up)"
[ -n "$script_alert_up" ] && eval $script_alert_up
}
if [ -z "$($IPTABLESSAVE 2>/dev/null | grep :ssr)" ]; then
if [ -z "$($IPTABLESSAVE 2>/dev/null | grep :ssr)" ] && [ -z "$(nft list ruleset 2>/dev/null | grep ss_r)" ] && [ -z "$(nft list ruleset 2>/dev/null | grep ssr_r)" ]; then
if [ "$type" = "libev" ] && [ "$(uci -q get shadowsocks-libev.ss_rules.disabled)" != "1" ]; then
_log "Reload Shadowsocks rules"
/etc/init.d/shadowsocks-libev rules_up 2> /dev/null
@ -120,7 +120,7 @@ while true; do
last=$((last + 1 ))
[ -z "$nocontact" ] && nocontact="$host" || nocontact="$nocontact, $host"
[ "${last}" -ge "${retry}" ] && {
if [ -n "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ssr)" ]; then
if [ -n "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ssr)" ] || [ -n "$(nft list ruleset 2>/dev/null | grep ss_r)" ] || [ -n "$(nft list ruleset 2>/dev/null | grep ssr_r)" ]; then
_log "Shadowsocks ${server} is down (can't contact via http ${nocontact})"
OMR_TRACKER_STATUS_MSG="Shadowsocks ${server} is down (can't contact via http ${nocontact})"
uci -q set openmptcprouter.omr.ss_${server}="down"

View file

@ -4,8 +4,8 @@
name=$0
basename="$(basename $0)"
if [ -f /usr/sbin/iptables-legacy ]; then
IPTABLES="/usr/sbin/iptables-legacy"
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
else
IPTABLES="/usr/sbin/iptables"
fi
@ -100,7 +100,7 @@ while true; do
script_alert_up="$(uci -q get omr-tracker.proxy.script_alert_up)"
[ -n "$script_alert_up" ] && eval $script_alert_up
}
if [ -z "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^v2r)" ]; then
if [ -z "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^v2r)" ] && [ -z "$(nft list ruleset 2>/dev/null | grep 'chain v2r')" ]; then
_log "Reload V2Ray rules"
/etc/init.d/v2ray rules_up 2> /dev/null
_get_ip
@ -111,7 +111,7 @@ while true; do
last=$((last + 1 ))
[ -z "$nocontact" ] && nocontact="$host" || nocontact="$nocontact, $host"
[ "${last}" -ge "${retry}" ] && {
if [ -n "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^v2r)" ]; then
if [ -n "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^v2r)" ] || [ -n "$(nft list ruleset 2>/dev/null | grep 'chain v2r')" ]; then
_log "V2Ray is down (can't contact via http ${nocontact})"
OMR_TRACKER_STATUS_MSG="V2Ray is down (can't contact via http ${nocontact})"
uci -q set openmptcprouter.omr.v2ray="down"

View file

@ -4,8 +4,8 @@
name=$0
basename="$(basename $0)"
if [ -f /usr/sbin/iptables-legacy ]; then
IPTABLES="/usr/sbin/iptables-legacy"
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
else
IPTABLES="/usr/sbin/iptables"
fi
@ -100,7 +100,7 @@ while true; do
script_alert_up="$(uci -q get omr-tracker.proxy.script_alert_up)"
[ -n "$script_alert_up" ] && eval $script_alert_up
}
if [ -z "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^xr)" ]; then
if [ -z "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^xr)" ] && [ -z "$(nft list ruleset 2>/dev/null | grep 'chain xr')" ]; then
_log "Reload xray rules"
/etc/init.d/xray rules_up 2> /dev/null
_get_ip
@ -111,7 +111,7 @@ while true; do
last=$((last + 1 ))
[ -z "$nocontact" ] && nocontact="$host" || nocontact="$nocontact, $host"
[ "${last}" -ge "${retry}" ] && {
if [ -n "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^xr)" ]; then
if [ -n "$($IPTABLES -w -t nat -L -n 2>/dev/null | grep ^xr)" ] || [ -n "$(nft list ruleset 2>/dev/null | grep 'chain xr')" ]; then
_log "xray is down (can't contact via http ${nocontact})"
OMR_TRACKER_STATUS_MSG="xray is down (can't contact via http ${nocontact})"
uci -q set openmptcprouter.omr.xray="down"

View file

@ -21,7 +21,7 @@ MY_DEPENDS := \
mc \
f2fs-tools \
openmptcprouter \
dnsmasq-full dnsmasq_full_ipset \
dnsmasq-full LINUX_5_4:dnsmasq_full_ipset !LINUX_5_4:dnsmasq_full_nftset \
uhttpd \
uhttpd-mod-ubus \
curl \
@ -29,9 +29,10 @@ MY_DEPENDS := \
arptables \
bind-dig \
libnetfilter-conntrack ip-full nstat \
iptables-mod-iface iptables-mod-ipmark iptables-mod-hashlimit iptables-mod-condition iptables-mod-trace iptables-mod-conntrack-extra iptables-mod-account \
kmod-nf-nat kmod-nf-nathelper kmod-nf-nathelper-extra iptables-mod-extra conntrack kmod-ipt-offload \
iptables-mod-ipsec kmod-crypto-authenc kmod-ipsec kmod-ipsec4 kmod-ipsec6 kmod-ipt-ipsec \
LINUX_5_4:iptables-mod-iface LINUX_5_4:iptables-mod-ipmark LINUX_5_4:iptables-mod-hashlimit LINUX_5_4:iptables-mod-condition LINUX_5_4:iptables-mod-trace LINUX_5_4:iptables-mod-conntrack-extra LINUX_5_4:iptables-mod-account \
kmod-nf-nat kmod-nf-nathelper kmod-nf-nathelper-extra LINUX_5_4:iptables-mod-extra conntrack LINUX_5_4:kmod-ipt-offload \
LINUX_5_4:iptables-mod-ipsec kmod-crypto-authenc kmod-ipsec kmod-ipsec4 kmod-ipsec6 LINUX_5_4:kmod-ipt-ipsec \
!LINUX_5_4:nftables-json !LINUX_5_4:iptables-nft !LINUX_5_4:kmod-nft-connlimit !LINUX_5_4:kmod-nft-offload
wireless-tools \
libiwinfo-lua \
ca-bundle ca-certificates \
@ -44,7 +45,7 @@ MY_DEPENDS := \
luci-app-uhttpd \
luci-mod-rpc rpcd-mod-rpcsys rpcd-mod-file rpcd-mod-iwinfo \
luci-app-openvpn \
shadowsocks-libev-ss-server shadowsocks-libev-ss-redir shadowsocks-libev-ss-rules shadowsocks-libev-ss-tunnel \
shadowsocks-libev-ss-server shadowsocks-libev-ss-redir LINUX_5_4:shadowsocks-libev-ss-rules !LINUX_5_4:shadowsocks-libev-ss-rules-nft shadowsocks-libev-ss-tunnel \
omr-6in4 ip6tables-mod-nat luci-proto-ipv6 6to4 6in4 6rd ip6tables \
!TARGET_mvebu:speedtestcpp \
iftop \
@ -82,10 +83,10 @@ MY_DEPENDS := \
luci-app-acl block-mount blockd fstools luci-app-shutdown libwebp luci-proto-gre tcptraceroute luci-proto-mbim kmod-rtl8xxxu kmod-ath9k-htc luci-app-ttyd luci-mod-dashboard (TARGET_x86||TARGET_x86_64):rtl8192eu-firmware kmod-usb2 libustream-openssl (TARGET_x86||TARGET_x86_64):kmod-ixgbevf (TARGET_x86||TARGET_x86_64):kmod-igbvf \
hwinfo (TARGET_x86||TARGET_x86_64):dmidecode luci-app-packet-capture kmod-bonding luci-proto-bonding luci-app-sysupgrade \
luci-theme-openwrt-2020 luci-proto-wireguard luci-app-wireguard kmod-crypto-lib-blake2s (TARGET_x86||TARGET_x86_64):kmod-r8125 \
!(LINUX_5_4):mptcpd (TARGET_x86||TARGET_x86_64):kmod-igc !TARGET_mvebu:kmod-mmc-spi kmod-macsec usbutils v2ray-core syslogd \
!(LINUX_5_4):mptcpd (TARGET_x86||TARGET_x86_64):kmod-igc !TARGET_mvebu:kmod-mmc-spi kmod-macsec usbutils v2ray-core LINUX_5_4:v2ray-config !LINUX_5_4:v2ray-config-nft syslogd \
(TARGET_x86||TARGET_x86_64):kmod-mlx4-core \
!(TARGET_ips40xx||TARGET_ramips):iptables-mod-ndpi !(TARGET_ips40xx||TARGET_ramips):kmod-ipt-ndpi libip4tc libip6tc \
xray-core shadowsocks-rust-sslocal shadowsocks-rust-ssservice shadowsocks-rust-config luci-app-shadowsocks-rust (LINUX_5_4&&(TARGET_x86_64||aarch64)):kmod-tcp-bbr2 kmod-ovpn-dco-v2
xray-core LINUX_5_4:xray-config !LINUX_5_4:xray-config-nft shadowsocks-rust-sslocal shadowsocks-rust-ssservice LINUX_5_4:shadowsocks-rust-config !LINUX_5_4:shadowsocks-rust-config-nft luci-app-shadowsocks-rust (LINUX_5_4&&(TARGET_x86_64||aarch64)):kmod-tcp-bbr2 kmod-ovpn-dco-v2 keepalived
# !TARGET_mvebu:kmod-usb-net-smsc75xx
# libnetfilter-conntrack ebtables ebtables-utils ip-full nstat \

View file

@ -10,13 +10,13 @@ EXTRA_COMMANDS="set_pihole backup_send backup_get backup_list set_vps_firewall g
. /usr/lib/unbound/iptools.sh
if [ -f /usr/sbin/iptables-legacy ]; then
IPTABLES="/usr/sbin/iptables-legacy"
IPTABLESRESTORE="/usr/sbin/iptables-legacy-restore"
IPTABLESSAVE="/usr/sbin/iptables-legacy-save"
IP6TABLES="/usr/sbin/ip6tables-legacy"
IP6TABLESRESTORE="/usr/sbin/ip6tables-legacy-restore"
IP6TABLESSAVE="/usr/sbin/ip6tables-legacy-save"
if [ -e /usr/sbin/iptables-nft ]; then
IPTABLES="/usr/sbin/iptables-nft"
IPTABLESRESTORE="/usr/sbin/iptables-nft-restore"
IPTABLESSAVE="/usr/sbin/iptables-nft-save"
IP6TABLES="/usr/sbin/ip6tables-nft"
IP6TABLESRESTORE="/usr/sbin/ip6tables-nft-restore"
IP6TABLESSAVE="/usr/sbin/ip6tables-nft-save"
else
IPTABLES="/usr/sbin/iptables"
IPTABLESRESTORE="/usr/sbin/iptables-restore"
@ -947,8 +947,11 @@ _set_lan_ip() {
_set_bypass_ips() {
local settings
[ -z "$servername" ] && servername=$1
bypassipv4s=$(ipset -q -o save list omr_dst_bypass_srv_vpn1 | awk '/add/ NF {print "\""$3"\""}' | tr '\n' ',' | sed 's/,$//')
bypassipv6s=$(ipset -q -o save list omr6_dst_bypass_srv_vpn1 | awk '/add/ NF {print "\""$3"\""}' | tr '\n' ',' | sed 's/,$//')
bypassipv4s=$(ipset -q -o save list omr_dst_bypass_srv_vpn1_4 | awk '/add/ NF {print "\""$3"\""}' | tr '\n' ',' | sed 's/,$//')
[ -z "$bypassipvs4" ] && bypassipv4s=$(nft -j list set inet fw4 "omr_dst_bypass_srv_vpn1_4" | jsonfilter -e @.nftables[1].set.elem[*].prefix | awk '{gsub(/"/,"",$3);gsub(/,/,"/",$3); print $3 $5}')
bypassipv6s=$(ipset -q -o save list omr6_dst_bypass_srv_vpn1_6 | awk '/add/ NF {print "\""$3"\""}' | tr '\n' ',' | sed 's/,$//')
[ -z "$bypassipvs6" ] && bypassipv4s=$(nft -j list set inet fw4 "omr_dst_bypass_srv_vpn1_6" | jsonfilter -e @.nftables[1].set.elem[*].prefix | awk '{gsub(/"/,"",$3);gsub(/,/,"/",$3); print $3 $5}')
# "
if [ "$bypassipv4s" != "" ] || [ "$bypassipv6s" != "" ]; then
settings='{"ipv4s" : ['$bypassipv4s'],"ipv6s" : ['$bypassipv6s'],"intf" : "vpn1"}'
result=$(_set_json "bypass" "$settings")
@ -1041,6 +1044,8 @@ _vps_firewall_redirect_port() {
config_get name $1 name
config_get dmz $1 dmz "0"
config_get target $1 target "REDIRECT"
[ "$target" = "MARK" ] && return
[ "$target" = "DSCP" ] && return
if [ -z "$src_dport" ] && [ -n "$dest_port" ]; then
src_dport=$dest_port
fi

View file

@ -59,4 +59,5 @@ net.ipv4.tcp_ecn = 2
#net.ipv4.tcp_sack = 0
#net.ipv4.tcp_dsack = 0
#net.ipv4.tcp_fack = 0
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.route.gc_timeout = 150

View file

@ -44,8 +44,6 @@ endef
define Package/shadowsocks-libev-config/install
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/shadowsocks-libev.config $(1)/etc/config/shadowsocks-libev
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/shadowsocks-libev.init $(1)/etc/init.d/shadowsocks-libev
endef
@ -92,8 +90,11 @@ define Package/shadowsocks-libev-ss-rules/install
$(INSTALL_DATA) ./files/firewall.ss-rules $(1)/etc
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/ss-rules.defaults $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/sysctl.d
$(INSTALL_DATA) ./files/shadowsocks.conf $(1)/etc/sysctl.d
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/shadowsocks-libev.init $(1)/etc/init.d/shadowsocks-libev
# $(INSTALL_DIR) $(1)/etc/sysctl.d
# $(INSTALL_DATA) ./files/shadowsocks.conf $(1)/etc/sysctl.d
# $(INSTALL_DIR) $(1)/usr/lib/shadowsocks-libev
# $(INSTALL_DATA) $(PKG_BUILD_DIR)/src/*.ebpf $(1)/usr/lib/shadowsocks-libev
endef
@ -108,6 +109,33 @@ uci batch <<-EOF
EOF
endef
define Package/shadowsocks-libev-ss-rules-nft
SECTION:=net
CATEGORY:=Network
SUBMENU:=Web Servers/Proxies
TITLE:=shadowsocks-libev ss-rules NFT
URL:=https://github.com/shadowsocks/shadowsocks-libev
DEPENDS:=+firewall4 \
+ip \
+resolveip \
+ucode \
+ucode-mod-fs \
+shadowsocks-libev-ss-redir \
+shadowsocks-libev-config \
+kmod-nft-tproxy
endef
define Package/shadowsocks-libev-ss-rules-nft/install
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/ss-rules.defaults $(1)/etc/uci-defaults
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/shadowsocks-libev.init-nft $(1)/etc/init.d/shadowsocks-libev
$(INSTALL_DIR) $(1)/usr/share/ss-rules
$(INSTALL_DATA) ./files/nft-rules/* $(1)/usr/share/ss-rules/
endef
define Build/Prepare
$(call Build/Prepare/Default)
$(FIND) $(PKG_BUILD_DIR) \
@ -128,6 +156,7 @@ TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
$(eval $(call BuildPackage,shadowsocks-libev-config))
$(eval $(call BuildPackage,shadowsocks-libev-ss-rules))
$(eval $(call BuildPackage,shadowsocks-libev-ss-rules-nft))
$(foreach component,$(SHADOWSOCKS_COMPONENTS), \
$(eval $(call BuildPackage,shadowsocks-libev-$(component))) \
)

View file

@ -0,0 +1,122 @@
{%
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_dst_forward goto ss_rules_forward_{{ proto }};
ip6 daddr @ss_rules6_dst_bypass 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_dst_bypass_ accept;
ip daddr @ss_rules_dst_bypass 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 %}

View file

@ -0,0 +1,114 @@
{%
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.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
";
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,
},
"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 %}

View file

@ -0,0 +1,8 @@
{%
include("set.uc");
include("chain.uc", {proto: "tcp"});
include("chain.uc", {proto: "udp"});
%}

View file

@ -0,0 +1,363 @@
#!/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-libev
ss_bindir=/usr/bin
ssrules_uc="/usr/share/ss-rules/ss-rules.uc"
ssrules_nft="/etc/nftables.d/90-ss-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 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"
[ -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
if [ "$ss_rules_redir_tcp_$redir_tcp" = "all" ]; then
min_ss_redir_ports="65535"
max_ss_redir_ports="0"
config_load shadowsocks-libev
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
else
eval local_port_tcp="\$ss_rules_redir_tcp_$redir_tcp"
eval local_port_udp="\$ss_rules_redir_udp_$redir_udp"
fi
[ -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/ssrules"
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-libev
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-libev
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-libev "$@"
}
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-libev", "@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-libev", "@ss_redir","all")' \
'redir_udp:uci("shadowsocks-libev", "@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' \
'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]+")'
}

View file

@ -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))) \
)

View 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 %}

View 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 %}

View file

@ -0,0 +1,8 @@
{%
include("set.uc");
include("chain.uc", {proto: "tcp"});
include("chain.uc", {proto: "udp"});
%}

View 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]+")'
}

View file

@ -59,6 +59,20 @@ define Package/v2ray-extra
PKGARCH:=all
endef
define Package/v2ray-config
$(call Package/v2ray/template)
TITLE+= (init script)
DEPENDS:=v2ray-core
PKGARCH:=all
endef
define Package/v2ray-config-nft
$(call Package/v2ray/template)
TITLE+= (init script with nft)
DEPENDS:=v2ray-core
PKGARCH:=all
endef
define Package/v2ray/description
Project V is a set of network tools that help you to build your own computer network.
It secures your network connections and thus protects your privacy.
@ -80,6 +94,18 @@ define Package/v2ray-extra/description
This includes extra resources for v2ray-core.
endef
define Package/v2ray-config/description
$(call Package/v2ray/description)
This includes init script
endef
define Package/v2ray-config-nft/description
$(call Package/v2ray/description)
This includes init script with nftables support
endef
define Package/v2ray-core/conffiles
/etc/config/v2ray
/etc/v2ray/
@ -92,12 +118,17 @@ define Package/v2ray-core/install
$(INSTALL_DIR) $(1)/etc/v2ray/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/release/config/config.json $(1)/etc/v2ray/
endef
define Package/v2ray-config/install
$(CP) ./files/* $(1)/
# $(INSTALL_DIR) $(1)/etc/config/
# $(INSTALL_CONF) $(CURDIR)/files/v2ray.conf $(1)/etc/config/v2ray
# $(INSTALL_DIR) $(1)/etc/init.d/
# $(INSTALL_BIN) $(CURDIR)/files/v2ray.init $(1)/etc/init.d/v2ray
rm $(1)/etc/init.d/v2ray-nft
endef
define Package/v2ray-config-nft/install
$(CP) ./files/* $(1)/
mv $(1)/etc/init.d/v2ray-nft $(1)/etc/init.d/v2ray
endef
define Package/v2ray-example/install
@ -112,5 +143,7 @@ define Package/v2ray-extra/install
endef
$(eval $(call BuildPackage,v2ray-core))
$(eval $(call BuildPackage,v2ray-config))
$(eval $(call BuildPackage,v2ray-config-nft))
$(eval $(call BuildPackage,v2ray-example))
$(eval $(call BuildPackage,v2ray-extra))

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
{%
function get_local_verdict() {
let v = o_local_default;
if (v == "checkdst") {
return "goto v2r_rules_dst_" + proto;
} else if (v == "forward") {
return "goto v2r_rules_forward_" + proto;
} else {
return null;
}
}
function get_src_default_verdict() {
let v = o_src_default;
if (v == "checkdst") {
return "goto v2r_rules_dst_" + proto;
} else if (v == "forward") {
return "goto v2r_rules_forward_" + proto;
} else {
return "accept";
}
}
function get_dst_default_verdict() {
let v = o_dst_default;
if (v == "forward") {
return "goto v2r_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 v2r_rules_pre_{{ proto }} {
type {{ type }} hook {{ hook }} priority {{ priority }};
meta l4proto {{ proto }}{%- let ifnames=get_ifnames(); if (length(ifnames)): %} iifname { {{join(", ", ifnames)}} }{% endif %} goto v2r_rules_pre_src_{{ proto }};
}
chain v2r_rules_pre_src_{{ proto }} {
ip daddr @v2r_rules_dst_bypass_ accept;
ip6 daddr @v2r_rules6_dst_bypass_ accept;
goto v2r_rules_src_{{ proto }};
}
chain v2r_rules_src_{{ proto }} {
ip saddr @v2r_rules_src_bypass accept;
ip saddr @v2r_rules_src_forward goto v2r_rules_forward_{{ proto }};
ip saddr @v2r_rules_src_checkdst goto v2r_rules_dst_{{ proto }};
ip6 saddr @v2r_rules6_src_bypass accept;
ip6 saddr @v2r_rules6_src_forward goto v2r_rules_forward_{{ proto }};
ip6 saddr @v2r_rules6_src_checkdst goto v2r_rules_dst_{{ proto }};
{{ get_src_default_verdict() }};
}
chain v2r_rules_dst_{{ proto }} {
ip daddr @v2r_rules_dst_bypass accept;
ip daddr @v2r_rules_remote_servers accept;
ip daddr @v2r_rules_dst_forward goto v2r_rules_forward_{{ proto }};
ip6 daddr @v2r_rules6_dst_bypass accept;
ip6 daddr @v2r_rules6_remote_servers accept;
ip6 daddr @v2r_rules6_dst_forward goto v2r_rules_forward_{{ proto }};
{{ get_dst_default_verdict() }};
}
{% if (proto == "tcp"): %}
chain v2r_rules_forward_{{ proto }} {
meta l4proto tcp {{ o_nft_tcp_extra }} redirect to :{{ redir_port }};
}
{% let local_verdict = get_local_verdict(); if (local_verdict): %}
chain v2r_rules_local_out {
type {{ type }} hook output priority -1;
meta l4proto != tcp accept;
ip daddr @v2r_rules_remote_servers accept;
ip daddr @v2r_rules_dst_bypass_ accept;
ip daddr @v2r_rules_dst_bypass accept;
ip6 daddr @v2r_rules6_remote_servers accept;
ip6 daddr @v2r_rules6_dst_bypass_ accept;
ip6 daddr @v2r_rules6_dst_bypass accept;
{{ local_verdict }};
}
{% endif %}
{% elif (proto == "udp"): %}
chain v2r_rules_forward_{{ proto }} {
meta l4proto udp {{ o_nft_udp_extra }} meta mark set 1 tproxy to :{{ redir_port }};
}
{% endif %}
{% endif %}

View 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 "v2r_rules_"+suf;
} else {
return "v2r_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 %}

View file

@ -0,0 +1,8 @@
{%
include("set.uc");
include("chain.uc", {proto: "tcp"});
include("chain.uc", {proto: "udp"});
%}

View file

@ -1,6 +1,6 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=xray-core
PKG_NAME:=xray
PKG_VERSION:=1.8.6
PKG_RELEASE:=1
@ -19,7 +19,7 @@ GO_PKG:=github.com/XTLS/Xray-core
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/openmptcprouter/golang/golang-package.mk
define Package/$(PKG_NAME)
define Package/$(PKG_NAME)/template
SECTION:=Custom
CATEGORY:=Extra packages
TITLE:=Xray-core
@ -27,13 +27,35 @@ define Package/$(PKG_NAME)
PROVIDES:=xray-core
endef
define Package/$(PKG_NAME)-core
$(call Package/$(PKG_NAME)/template)
endef
define Package/$(PKG_NAME)-config
$(call Package/$(PKG_NAME)/template)
TITLE+= (init script)
endef
define Package/$(PKG_NAME)-config-nft
$(call Package/$(PKG_NAME)/template)
TITLE+= (init script with nft)
endef
define Package/$(PKG_NAME)/description
Xray-core bare bones binary (compiled without cgo)
endef
define Package/$(PKG_NAME)-config/description
Xray-core init script
endef
define Package/$(PKG_NAME)-config-nft/description
Xray-core init script with nft support
endef
define Package/$(PKG_NAME)/config
menu "Xray Configuration"
depends on PACKAGE_$(PKG_NAME)
depends on PACKAGE_$(PKG_NAME)-core
config PACKAGE_XRAY_ENABLE_GOPROXY_IO
bool "Use goproxy.io to speed up module fetching (recommended for some network situations)"
@ -50,19 +72,25 @@ endif
MAKE_PATH:=$(GO_PKG_WORK_DIR_NAME)/build/src/$(GO_PKG)
MAKE_VARS += $(GO_PKG_VARS)
#define Build/Patch
# $(CP) $(PKG_BUILD_DIR)/../Xray-core-$(PKG_VERSION)/* $(PKG_BUILD_DIR)
# $(Build/Patch/Default)
#endef
define Build/Compile
cd $(PKG_BUILD_DIR); $(GO_PKG_VARS) $(USE_GOPROXY) CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o $(PKG_INSTALL_DIR)/bin/xray ./main;
endef
define Package/$(PKG_NAME)/install
define Package/$(PKG_NAME)-core/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/bin/xray $(1)/usr/bin/xray
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
define Package/$(PKG_NAME)-config/install
$(CP) ./files/* $(1)/
rm -f $(1)/etc/init.d/xray-nft
endef
define Package/$(PKG_NAME)-config-nft/install
$(CP) ./files/* $(1)/
mv $(1)/etc/init.d/xray-nft $(1)/etc/init.d/xray
endef
$(eval $(call BuildPackage,$(PKG_NAME)-core))
$(eval $(call BuildPackage,$(PKG_NAME)-config))
$(eval $(call BuildPackage,$(PKG_NAME)-config-nft))

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
{%
function get_local_verdict() {
let v = o_local_default;
if (v == "checkdst") {
return "goto xr_rules_dst_" + proto;
} else if (v == "forward") {
return "goto xr_rules_forward_" + proto;
} else {
return null;
}
}
function get_src_default_verdict() {
let v = o_src_default;
if (v == "checkdst") {
return "goto xr_rules_dst_" + proto;
} else if (v == "forward") {
return "goto xr_rules_forward_" + proto;
} else {
return "accept";
}
}
function get_dst_default_verdict() {
let v = o_dst_default;
if (v == "forward") {
return "goto xr_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 xr_rules_pre_{{ proto }} {
type {{ type }} hook {{ hook }} priority {{ priority }};
meta l4proto {{ proto }}{%- let ifnames=get_ifnames(); if (length(ifnames)): %} iifname { {{join(", ", ifnames)}} }{% endif %} goto xr_rules_pre_src_{{ proto }};
}
chain xr_rules_pre_src_{{ proto }} {
ip daddr @xr_rules_dst_bypass_ accept;
ip6 daddr @xr_rules6_dst_bypass_ accept;
goto xr_rules_src_{{ proto }};
}
chain xr_rules_src_{{ proto }} {
ip saddr @xr_rules_src_bypass accept;
ip saddr @xr_rules_src_forward goto xr_rules_forward_{{ proto }};
ip saddr @xr_rules_src_checkdst goto xr_rules_dst_{{ proto }};
ip6 saddr @xr_rules6_src_bypass accept;
ip6 saddr @xr_rules6_src_forward goto xr_rules_forward_{{ proto }};
ip6 saddr @xr_rules6_src_checkdst goto xr_rules_dst_{{ proto }};
{{ get_src_default_verdict() }};
}
chain xr_rules_dst_{{ proto }} {
ip daddr @xr_rules_dst_bypass accept;
ip daddr @xr_rules_remote_servers accept;
ip daddr @xr_rules_dst_forward goto xr_rules_forward_{{ proto }};
ip6 daddr @xr_rules6_dst_bypass accept;
ip6 daddr @xr_rules6_remote_servers accept;
ip6 daddr @xr_rules6_dst_forward goto xr_rules_forward_{{ proto }};
{{ get_dst_default_verdict() }};
}
{% if (proto == "tcp"): %}
chain xr_rules_forward_{{ proto }} {
meta l4proto tcp {{ o_nft_tcp_extra }} redirect to :{{ redir_port }};
}
{% let local_verdict = get_local_verdict(); if (local_verdict): %}
chain xr_rules_local_out {
type {{ type }} hook output priority -1;
meta l4proto != tcp accept;
ip daddr @xr_rules_remote_servers accept;
ip daddr @xr_rules_dst_bypass_ accept;
ip daddr @xr_rules_dst_bypass accept;
ip6 daddr @xr_rules6_remote_servers accept;
ip6 daddr @xr_rules6_dst_bypass_ accept;
ip6 daddr @xr_rules6_dst_bypass accept;
{{ local_verdict }};
}
{% endif %}
{% elif (proto == "udp"): %}
chain xr_rules_forward_{{ proto }} {
meta l4proto udp {{ o_nft_udp_extra }} meta mark set 1 tproxy to :{{ redir_port }};
}
{% endif %}
{% endif %}

View 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 "xr_rules_"+suf;
} else {
return "xr_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 %}

View file

@ -0,0 +1,8 @@
{%
include("set.uc");
include("chain.uc", {proto: "tcp"});
include("chain.uc", {proto: "udp"});
%}