parent
0c96443ce3
commit
4d12f9dece
@ -1,13 +1,13 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=nikki
|
PKG_NAME:=nikki
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
PKG_SOURCE_PROTO:=git
|
PKG_SOURCE_PROTO:=git
|
||||||
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
|
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
|
||||||
PKG_SOURCE_DATE:=2025-02-19
|
PKG_SOURCE_DATE:=2025-02-21
|
||||||
PKG_SOURCE_VERSION:=e2b75b35bbfd3be61b2b5a37142442bb259f99e4
|
PKG_SOURCE_VERSION:=5830afcbdeeb6c05a3faa56d33353282b8d1f50c
|
||||||
PKG_MIRROR_HASH:=1d377f3087e5109353c78d738424fa3e88e1dfe30a0c9eddcdafc12fabbcf839
|
PKG_MIRROR_HASH:=3f5c8aaad3959f77ab3099e0a3d76ca7329e073e1f877720b7c42360c66954c9
|
||||||
|
|
||||||
PKG_LICENSE:=GPL3.0+
|
PKG_LICENSE:=GPL3.0+
|
||||||
PKG_MAINTAINER:=Joseph Mory <morytyann@gmail.com>
|
PKG_MAINTAINER:=Joseph Mory <morytyann@gmail.com>
|
||||||
@ -16,7 +16,7 @@ PKG_BUILD_DEPENDS:=golang/host
|
|||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
PKG_BUILD_FLAGS:=no-mips16
|
PKG_BUILD_FLAGS:=no-mips16
|
||||||
|
|
||||||
PKG_BUILD_VERSION:=alpha-e2b75b3
|
PKG_BUILD_VERSION:=alpha-5830afc
|
||||||
PKG_BUILD_TIME:=$(shell date -u -Iseconds)
|
PKG_BUILD_TIME:=$(shell date -u -Iseconds)
|
||||||
|
|
||||||
GO_PKG:=github.com/metacubex/mihomo
|
GO_PKG:=github.com/metacubex/mihomo
|
||||||
@ -51,6 +51,7 @@ define Package/nikki/install
|
|||||||
$(call GoPackage/Package/Install/Bin,$(1))
|
$(call GoPackage/Package/Install/Bin,$(1))
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki
|
$(INSTALL_DIR) $(1)/etc/nikki
|
||||||
|
$(INSTALL_DIR) $(1)/etc/nikki/ucode
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki/scripts
|
$(INSTALL_DIR) $(1)/etc/nikki/scripts
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki/nftables
|
$(INSTALL_DIR) $(1)/etc/nikki/nftables
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki/profiles
|
$(INSTALL_DIR) $(1)/etc/nikki/profiles
|
||||||
@ -59,14 +60,17 @@ define Package/nikki/install
|
|||||||
$(INSTALL_DIR) $(1)/etc/nikki/run/providers
|
$(INSTALL_DIR) $(1)/etc/nikki/run/providers
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki/run/providers/rule
|
$(INSTALL_DIR) $(1)/etc/nikki/run/providers/rule
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki/run/providers/proxy
|
$(INSTALL_DIR) $(1)/etc/nikki/run/providers/proxy
|
||||||
$(INSTALL_DIR) $(1)/etc/nikki/run/ui
|
|
||||||
|
|
||||||
$(INSTALL_DATA) $(CURDIR)/files/mixin.yaml $(1)/etc/nikki/mixin.yaml
|
$(INSTALL_DATA) $(CURDIR)/files/mixin.yaml $(1)/etc/nikki/mixin.yaml
|
||||||
|
|
||||||
|
$(INSTALL_BIN) $(CURDIR)/files/ucode/include.uc $(1)/etc/nikki/ucode/include.uc
|
||||||
|
$(INSTALL_BIN) $(CURDIR)/files/ucode/mixin.uc $(1)/etc/nikki/ucode/mixin.uc
|
||||||
|
$(INSTALL_BIN) $(CURDIR)/files/ucode/hijack.ut $(1)/etc/nikki/ucode/hijack.ut
|
||||||
|
|
||||||
$(INSTALL_BIN) $(CURDIR)/files/scripts/include.sh $(1)/etc/nikki/scripts/include.sh
|
$(INSTALL_BIN) $(CURDIR)/files/scripts/include.sh $(1)/etc/nikki/scripts/include.sh
|
||||||
$(INSTALL_BIN) $(CURDIR)/files/scripts/firewall_include.sh $(1)/etc/nikki/scripts/firewall_include.sh
|
$(INSTALL_BIN) $(CURDIR)/files/scripts/firewall_include.sh $(1)/etc/nikki/scripts/firewall_include.sh
|
||||||
|
$(INSTALL_BIN) $(CURDIR)/files/scripts/debug.sh $(1)/etc/nikki/scripts/debug.sh
|
||||||
|
|
||||||
$(INSTALL_BIN) $(CURDIR)/files/nftables/hijack.nft $(1)/etc/nikki/nftables/hijack.nft
|
|
||||||
$(INSTALL_BIN) $(CURDIR)/files/nftables/reserved_ip.nft $(1)/etc/nikki/nftables/reserved_ip.nft
|
$(INSTALL_BIN) $(CURDIR)/files/nftables/reserved_ip.nft $(1)/etc/nikki/nftables/reserved_ip.nft
|
||||||
$(INSTALL_BIN) $(CURDIR)/files/nftables/reserved_ip6.nft $(1)/etc/nikki/nftables/reserved_ip6.nft
|
$(INSTALL_BIN) $(CURDIR)/files/nftables/reserved_ip6.nft $(1)/etc/nikki/nftables/reserved_ip6.nft
|
||||||
$(INSTALL_BIN) $(CURDIR)/files/nftables/geoip_cn.nft $(1)/etc/nikki/nftables/geoip_cn.nft
|
$(INSTALL_BIN) $(CURDIR)/files/nftables/geoip_cn.nft $(1)/etc/nikki/nftables/geoip_cn.nft
|
||||||
|
@ -1,243 +0,0 @@
|
|||||||
#!/usr/sbin/nft -f
|
|
||||||
|
|
||||||
table inet nikki {
|
|
||||||
set bypass_user {
|
|
||||||
type uid
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set bypass_group {
|
|
||||||
type gid
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
elements = {
|
|
||||||
$NIKKI_GROUP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set bypass_dscp {
|
|
||||||
type dscp
|
|
||||||
flags interval
|
|
||||||
}
|
|
||||||
|
|
||||||
set dns_hijack_nfproto {
|
|
||||||
type nf_proto
|
|
||||||
flags interval
|
|
||||||
}
|
|
||||||
|
|
||||||
set proxy_nfproto {
|
|
||||||
type nf_proto
|
|
||||||
flags interval
|
|
||||||
}
|
|
||||||
|
|
||||||
set china_ip {
|
|
||||||
type ipv4_addr
|
|
||||||
flags interval
|
|
||||||
}
|
|
||||||
|
|
||||||
set china_ip6 {
|
|
||||||
type ipv6_addr
|
|
||||||
flags interval
|
|
||||||
}
|
|
||||||
|
|
||||||
set reserved_ip {
|
|
||||||
type ipv4_addr
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set reserved_ip6 {
|
|
||||||
type ipv6_addr
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set proxy_dport {
|
|
||||||
type inet_proto . inet_service
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set acl_ip {
|
|
||||||
type ipv4_addr
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set acl_ip6 {
|
|
||||||
type ipv6_addr
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set acl_mac {
|
|
||||||
type ether_addr
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
set acl_interface {
|
|
||||||
type ifname
|
|
||||||
flags interval
|
|
||||||
auto-merge
|
|
||||||
}
|
|
||||||
|
|
||||||
chain router_dns_hijack {
|
|
||||||
meta skuid @bypass_user counter return
|
|
||||||
meta skgid @bypass_group counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain all_dns_hijack {
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain allow_dns_hijack {
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter redirect to :$DNS_PORT
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter redirect to :$DNS_PORT
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter redirect to :$DNS_PORT
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 iifname @acl_interface counter redirect to :$DNS_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain block_dns_hijack {
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 iifname @acl_interface counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :$DNS_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain router_redirect {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp counter redirect to :$REDIR_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain all_redirect {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp counter redirect to :$REDIR_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain allow_redirect {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp ip saddr @acl_ip counter redirect to :$REDIR_PORT
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp ip6 saddr @acl_ip6 counter redirect to :$REDIR_PORT
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp ether saddr @acl_mac counter redirect to :$REDIR_PORT
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp iifname @acl_interface counter redirect to :$REDIR_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain block_redirect {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp ip saddr @acl_ip counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp ip6 saddr @acl_ip6 counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp ether saddr @acl_mac counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp iifname @acl_interface counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto tcp counter redirect to :$REDIR_PORT
|
|
||||||
}
|
|
||||||
|
|
||||||
chain router_tproxy {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter
|
|
||||||
}
|
|
||||||
|
|
||||||
chain all_tproxy {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain allow_tproxy {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set mark ^ $FW_MARK tproxy ip to :$TPROXY_PORT counter accept
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set mark ^ $FW_MARK tproxy ip6 to :$TPROXY_PORT counter accept
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } iifname @acl_interface meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain block_tproxy {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } iifname @acl_interface counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK tproxy to :$TPROXY_PORT counter accept
|
|
||||||
}
|
|
||||||
|
|
||||||
chain router_tun {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter
|
|
||||||
}
|
|
||||||
|
|
||||||
chain all_tun {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter
|
|
||||||
}
|
|
||||||
|
|
||||||
chain allow_tun {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set mark ^ $FW_MARK counter
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set mark ^ $FW_MARK counter
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set mark ^ $FW_MARK counter
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } iifname @acl_interface meta mark set mark ^ $FW_MARK counter
|
|
||||||
}
|
|
||||||
|
|
||||||
chain block_tun {
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip saddr @acl_ip counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } ether saddr @acl_mac counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } iifname @acl_interface counter return
|
|
||||||
meta nfproto @proxy_nfproto meta l4proto { tcp, udp } meta mark set mark ^ $FW_MARK counter
|
|
||||||
}
|
|
||||||
|
|
||||||
chain dstnat {
|
|
||||||
type nat hook prerouting priority dstnat + 1; policy accept;
|
|
||||||
fib daddr type { local, multicast, broadcast, anycast } counter return
|
|
||||||
ct direction reply counter return
|
|
||||||
ip daddr @reserved_ip counter return
|
|
||||||
ip6 daddr @reserved_ip6 counter return
|
|
||||||
ip daddr @china_ip counter return
|
|
||||||
ip6 daddr @china_ip6 counter return
|
|
||||||
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != $FAKE_IP counter return
|
|
||||||
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
|
||||||
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != $FAKE_IP counter return
|
|
||||||
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
|
||||||
}
|
|
||||||
|
|
||||||
chain nat_output {
|
|
||||||
type nat hook output priority filter; policy accept;
|
|
||||||
meta skuid @bypass_user counter return
|
|
||||||
meta skgid @bypass_group counter return
|
|
||||||
fib daddr type { local, multicast, broadcast, anycast } counter return
|
|
||||||
ct direction reply counter return
|
|
||||||
ip daddr @reserved_ip counter return
|
|
||||||
ip6 daddr @reserved_ip6 counter return
|
|
||||||
ip daddr @china_ip counter return
|
|
||||||
ip6 daddr @china_ip6 counter return
|
|
||||||
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != $FAKE_IP counter return
|
|
||||||
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
|
||||||
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != $FAKE_IP counter return
|
|
||||||
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
|
||||||
}
|
|
||||||
|
|
||||||
chain mangle_prerouting {
|
|
||||||
type filter hook prerouting priority mangle; policy accept;
|
|
||||||
meta l4proto { tcp, udp } iifname lo meta mark & $FW_MARK_MASK == $FW_MARK tproxy to :$TPROXY_PORT counter accept
|
|
||||||
meta l4proto { tcp, udp } iifname $TUN_DEVICE counter accept
|
|
||||||
fib daddr type { local, multicast, broadcast, anycast } counter return
|
|
||||||
ct direction reply counter return
|
|
||||||
ip daddr @reserved_ip counter return
|
|
||||||
ip6 daddr @reserved_ip6 counter return
|
|
||||||
ip daddr @china_ip counter return
|
|
||||||
ip6 daddr @china_ip6 counter return
|
|
||||||
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != $FAKE_IP counter return
|
|
||||||
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
|
||||||
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != $FAKE_IP counter return
|
|
||||||
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter return
|
|
||||||
}
|
|
||||||
|
|
||||||
chain mangle_output {
|
|
||||||
type route hook output priority mangle; policy accept;
|
|
||||||
meta skuid @bypass_user counter return
|
|
||||||
meta skgid @bypass_group counter return
|
|
||||||
fib daddr type { local, multicast, broadcast, anycast } counter return
|
|
||||||
ct direction reply counter return
|
|
||||||
ip daddr @reserved_ip counter return
|
|
||||||
ip6 daddr @reserved_ip6 counter return
|
|
||||||
ip daddr @china_ip counter return
|
|
||||||
ip6 daddr @china_ip6 counter return
|
|
||||||
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != $FAKE_IP counter return
|
|
||||||
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
|
||||||
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != $FAKE_IP counter return
|
|
||||||
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
|
||||||
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter return
|
|
||||||
}
|
|
||||||
}
|
|
@ -59,6 +59,7 @@ config mixin 'mixin'
|
|||||||
option 'tcp_concurrent' '1'
|
option 'tcp_concurrent' '1'
|
||||||
option 'tcp_keep_alive_idle' '600'
|
option 'tcp_keep_alive_idle' '600'
|
||||||
option 'tcp_keep_alive_interval' '15'
|
option 'tcp_keep_alive_interval' '15'
|
||||||
|
option 'ui_path' 'ui'
|
||||||
option 'ui_name' ''
|
option 'ui_name' ''
|
||||||
option 'ui_url' 'https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip'
|
option 'ui_url' 'https://github.com/Zephyruso/zashboard/archive/refs/heads/gh-pages.zip'
|
||||||
option 'api_port' '9090'
|
option 'api_port' '9090'
|
||||||
|
@ -51,88 +51,7 @@ start_service() {
|
|||||||
config_get_bool mixin "config" "mixin" 0
|
config_get_bool mixin "config" "mixin" 0
|
||||||
config_get_bool test_profile "config" "test_profile" 0
|
config_get_bool test_profile "config" "test_profile" 0
|
||||||
config_get_bool fast_reload "config" "fast_reload" 0
|
config_get_bool fast_reload "config" "fast_reload" 0
|
||||||
## proxy config
|
|
||||||
### transparent proxy
|
|
||||||
local tcp_transparent_proxy_mode udp_transparent_proxy_mode
|
|
||||||
config_get_bool transparent_proxy "proxy" "transparent_proxy" 0
|
|
||||||
config_get tcp_transparent_proxy_mode "proxy" "tcp_transparent_proxy_mode" "tproxy"
|
|
||||||
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode" "tproxy"
|
|
||||||
## mixin config
|
## mixin config
|
||||||
### general
|
|
||||||
local mode match_process outbound_interface ipv6 unify_delay tcp_concurrent tcp_keep_alive_idle tcp_keep_alive_interval log_level
|
|
||||||
config_get mode "mixin" "mode" "rule"
|
|
||||||
config_get match_process "mixin" "match_process" "off"
|
|
||||||
config_get outbound_interface "mixin" "outbound_interface"
|
|
||||||
config_get_bool ipv6 "mixin" "ipv6" 0
|
|
||||||
config_get_bool unify_delay "mixin" "unify_delay" 0
|
|
||||||
config_get_bool tcp_concurrent "mixin" "tcp_concurrent" 0
|
|
||||||
config_get tcp_keep_alive_idle "mixin" "tcp_keep_alive_idle" 600
|
|
||||||
config_get tcp_keep_alive_interval "mixin" "tcp_keep_alive_interval" 15
|
|
||||||
config_get log_level "mixin" "log_level" "info"
|
|
||||||
### external control
|
|
||||||
local ui_name ui_url api_port api_secret selection_cache
|
|
||||||
config_get ui_name "mixin" "ui_name"
|
|
||||||
config_get ui_url "mixin" "ui_url"
|
|
||||||
config_get api_port "mixin" "api_port" "9090"
|
|
||||||
config_get api_secret "mixin" "api_secret" "666666"
|
|
||||||
config_get_bool selection_cache "mixin" "selection_cache" 0
|
|
||||||
### inbound
|
|
||||||
local allow_lan http_port socks_port mixed_port redir_port tproxy_port authentication
|
|
||||||
config_get_bool allow_lan "mixin" "allow_lan" 0
|
|
||||||
config_get http_port "mixin" "http_port" "8080"
|
|
||||||
config_get socks_port "mixin" "socks_port" "1080"
|
|
||||||
config_get mixed_port "mixin" "mixed_port" "7890"
|
|
||||||
config_get redir_port "mixin" "redir_port" "7891"
|
|
||||||
config_get tproxy_port "mixin" "tproxy_port" "7892"
|
|
||||||
config_get_bool authentication "mixin" "authentication" 0
|
|
||||||
### tun
|
|
||||||
local tun_device tun_stack tun_mtu tun_gso tun_gso_max_size tun_dns_hijack tun_endpoint_independent_nat
|
|
||||||
config_get tun_device "mixin" "tun_device" "nikki"
|
|
||||||
config_get tun_stack "mixin" "tun_stack" "system"
|
|
||||||
config_get tun_mtu "mixin" "tun_mtu" "9000"
|
|
||||||
config_get_bool tun_gso "mixin" "tun_gso" 0
|
|
||||||
config_get tun_gso_max_size "mixin" "tun_gso_max_size" "65536"
|
|
||||||
config_get_bool tun_dns_hijack "mixin" "tun_dns_hijack" 0
|
|
||||||
config_get_bool tun_endpoint_independent_nat "mixin" "tun_endpoint_independent_nat" 0
|
|
||||||
### dns
|
|
||||||
local dns_port dns_mode fake_ip_range fake_ip_filter fake_ip_filter_mode fake_ip_cache dns_respect_rules dns_doh_prefer_http3 dns_ipv6 dns_system_hosts dns_hosts hosts dns_nameserver dns_nameserver_policy
|
|
||||||
config_get dns_port "mixin" "dns_port" "1053"
|
|
||||||
config_get dns_mode "mixin" "dns_mode" "redir-host"
|
|
||||||
config_get fake_ip_range "mixin" "fake_ip_range" "198.18.0.1/16"
|
|
||||||
config_get_bool fake_ip_filter "mixin" "fake_ip_filter" 0
|
|
||||||
config_get fake_ip_filter_mode "mixin" "fake_ip_filter_mode" "blacklist"
|
|
||||||
config_get_bool fake_ip_cache "mixin" "fake_ip_cache" 0
|
|
||||||
config_get_bool dns_respect_rules "mixin" "dns_respect_rules" 0
|
|
||||||
config_get_bool dns_doh_prefer_http3 "mixin" "dns_doh_prefer_http3" 0
|
|
||||||
config_get_bool dns_ipv6 "mixin" "dns_ipv6" 0
|
|
||||||
config_get_bool dns_system_hosts "mixin" "dns_system_hosts" 0
|
|
||||||
config_get_bool dns_hosts "mixin" "dns_hosts" 0
|
|
||||||
config_get_bool hosts "mixin" "hosts" 0
|
|
||||||
config_get_bool dns_nameserver "mixin" "dns_nameserver" 0
|
|
||||||
config_get_bool dns_nameserver_policy "mixin" "dns_nameserver_policy" 0
|
|
||||||
### sniffer
|
|
||||||
local sniffer sniffer_sniff_dns_mapping sniffer_sniff_pure_ip sniffer_overwrite_destination sniffer_force_domain_name sniffer_ignore_domain_name sniffer_sniff
|
|
||||||
config_get_bool sniffer "mixin" sniffer 0
|
|
||||||
config_get_bool sniffer_sniff_dns_mapping "mixin" sniffer_sniff_dns_mapping 0
|
|
||||||
config_get_bool sniffer_sniff_pure_ip "mixin" sniffer_sniff_pure_ip 0
|
|
||||||
config_get_bool sniffer_overwrite_destination "mixin" sniffer_overwrite_destination 0
|
|
||||||
config_get_bool sniffer_force_domain_name "mixin" sniffer_force_domain_name 0
|
|
||||||
config_get_bool sniffer_ignore_domain_name "mixin" sniffer_ignore_domain_name 0
|
|
||||||
config_get_bool sniffer_sniff "mixin" sniffer_sniff 0
|
|
||||||
### rule
|
|
||||||
local rule rule_provider
|
|
||||||
config_get_bool rule "mixin" "rule" 0
|
|
||||||
config_get_bool rule_provider "mixin" "rule_provider" 0
|
|
||||||
### geox
|
|
||||||
local geoip_format geodata_loader geosite_url geoip_mmdb_url geoip_dat_url geoip_asn_url geox_auto_update geox_update_interval
|
|
||||||
config_get geoip_format "mixin" "geoip_format" "mmdb"
|
|
||||||
config_get geodata_loader "mixin" "geodata_loader" "memconservative"
|
|
||||||
config_get geosite_url "mixin" "geosite_url"
|
|
||||||
config_get geoip_mmdb_url "mixin" "geoip_mmdb_url"
|
|
||||||
config_get geoip_dat_url "mixin" "geoip_dat_url"
|
|
||||||
config_get geoip_asn_url "mixin" "geoip_asn_url"
|
|
||||||
config_get_bool geox_auto_update "mixin" "geox_auto_update" 0
|
|
||||||
config_get geox_update_interval "mixin" "geox_update_interval" "24"
|
|
||||||
### mixin file content
|
### mixin file content
|
||||||
local mixin_file_content
|
local mixin_file_content
|
||||||
config_get_bool mixin_file_content "mixin" "mixin_file_content" 0
|
config_get_bool mixin_file_content "mixin" "mixin_file_content" 0
|
||||||
@ -142,15 +61,6 @@ start_service() {
|
|||||||
config_get_bool disable_loopback_detector "env" "disable_loopback_detector" 0
|
config_get_bool disable_loopback_detector "env" "disable_loopback_detector" 0
|
||||||
config_get_bool disable_quic_go_gso "env" "disable_quic_go_gso" 0
|
config_get_bool disable_quic_go_gso "env" "disable_quic_go_gso" 0
|
||||||
config_get_bool disable_quic_go_ecn "env" "disable_quic_go_ecn" 0
|
config_get_bool disable_quic_go_ecn "env" "disable_quic_go_ecn" 0
|
||||||
# prepare
|
|
||||||
local tproxy_enable; tproxy_enable=0
|
|
||||||
if [[ "$tcp_transparent_proxy_mode" == "tproxy" || "$udp_transparent_proxy_mode" == "tproxy" ]]; then
|
|
||||||
tproxy_enable=1
|
|
||||||
fi
|
|
||||||
local tun_enable; tun_enable=0
|
|
||||||
if [[ "$tcp_transparent_proxy_mode" == "tun" || "$udp_transparent_proxy_mode" == "tun" ]]; then
|
|
||||||
tun_enable=1
|
|
||||||
fi
|
|
||||||
# get profile
|
# get profile
|
||||||
if [[ "$profile" == "file:"* ]]; then
|
if [[ "$profile" == "file:"* ]]; then
|
||||||
local profile_name; profile_name=$(basename "${profile/file:/}")
|
local profile_name; profile_name=$(basename "${profile/file:/}")
|
||||||
@ -187,104 +97,16 @@ start_service() {
|
|||||||
if [ "$mixin" == 0 ]; then
|
if [ "$mixin" == 0 ]; then
|
||||||
log "Mixin" "Disabled."
|
log "Mixin" "Disabled."
|
||||||
log "Mixin" "Mixin neccesary config."
|
log "Mixin" "Mixin neccesary config."
|
||||||
# do mixin
|
|
||||||
log_level="$log_level" mode="$mode" match_process="$match_process" ipv6="$ipv6" \
|
|
||||||
ui_path="ui" ui_name="$ui_name" ui_url="$ui_url" api_listen="0.0.0.0:$api_port" api_secret="$api_secret" \
|
|
||||||
allow_lan="$allow_lan" http_port="$http_port" socks_port="$socks_port" mixed_port="$mixed_port" redir_port="$redir_port" tproxy_port="$tproxy_port" \
|
|
||||||
tun_enable="$tun_enable" tun_stack="$tun_stack" tun_device="$tun_device" tun_mtu="$tun_mtu" tun_gso="$tun_gso" tun_gso_max_size="$tun_gso_max_size" tun_endpoint_independent_nat="$tun_endpoint_independent_nat" \
|
|
||||||
dns_enable="true" dns_listen="0.0.0.0:$dns_port" dns_mode="$dns_mode" fake_ip_range="$fake_ip_range" \
|
|
||||||
yq -M -i '
|
|
||||||
.log-level = strenv(log_level) | .mode = strenv(mode) | .find-process-mode = strenv(match_process) | .ipv6 = env(ipv6) == 1 |
|
|
||||||
.external-ui = strenv(ui_path) | .external-ui-name = strenv(ui_name) | .external-ui-url = strenv(ui_url) | .external-controller = strenv(api_listen) | .secret = strenv(api_secret) |
|
|
||||||
.allow-lan = env(allow_lan) == 1 | .port = env(http_port) | .socks-port = env(socks_port) | .mixed-port = env(mixed_port) | .redir-port = env(redir_port) | .tproxy-port = env(tproxy_port) |
|
|
||||||
.tun.enable = env(tun_enable) == 1 | .tun.stack = strenv(tun_stack) | .tun.device = strenv(tun_device) | .tun.mtu = env(tun_mtu) | .tun.gso = env(tun_gso) == 1 | .tun.gso-max-size = env(tun_gso_max_size) | .tun.endpoint-independent-nat = env(tun_endpoint_independent_nat) == 1 |
|
|
||||||
.tun.auto-route = false | .tun.auto-redirect = false | .tun.auto-detect-interface = false |
|
|
||||||
.dns.enable = env(dns_enable) | .dns.listen = strenv(dns_listen) | .dns.enhanced-mode = strenv(dns_mode) | .dns.fake-ip-range = strenv(fake_ip_range)
|
|
||||||
' "$RUN_PROFILE_PATH"
|
|
||||||
else
|
else
|
||||||
log "Mixin" "Enabled."
|
log "Mixin" "Enabled."
|
||||||
log "Mixin" "Mixin all config."
|
log "Mixin" "Mixin all config."
|
||||||
# do mixin
|
|
||||||
log_level="$log_level" mode="$mode" match_process="$match_process" ipv6="$ipv6" unify_delay="$unify_delay" tcp_concurrent="$tcp_concurrent" tcp_keep_alive_idle="$tcp_keep_alive_idle" tcp_keep_alive_interval="$tcp_keep_alive_interval" \
|
|
||||||
ui_path="ui" ui_name="$ui_name" ui_url="$ui_url" api_listen="0.0.0.0:$api_port" api_secret="$api_secret" selection_cache="$selection_cache" \
|
|
||||||
allow_lan="$allow_lan" http_port="$http_port" socks_port="$socks_port" mixed_port="$mixed_port" redir_port="$redir_port" tproxy_port="$tproxy_port" \
|
|
||||||
tun_enable="$tun_enable" tun_stack="$tun_stack" tun_device="$tun_device" tun_mtu="$tun_mtu" tun_gso="$tun_gso" tun_gso_max_size="$tun_gso_max_size" tun_endpoint_independent_nat="$tun_endpoint_independent_nat" \
|
|
||||||
dns_enable="true" dns_listen="0.0.0.0:$dns_port" dns_mode="$dns_mode" fake_ip_range="$fake_ip_range" fake_ip_cache="$fake_ip_cache" \
|
|
||||||
dns_respect_rules="$dns_respect_rules" dns_doh_prefer_http3="$dns_doh_prefer_http3" dns_ipv6="$dns_ipv6" dns_system_hosts="$dns_system_hosts" dns_hosts="$dns_hosts" \
|
|
||||||
sniffer="$sniffer" sniffer_sniff_dns_mapping="$sniffer_sniff_dns_mapping" sniffer_sniff_pure_ip="$sniffer_sniff_pure_ip" sniffer_overwrite_destination="$sniffer_overwrite_destination" \
|
|
||||||
geoip_format="$geoip_format" geodata_loader="$geodata_loader" geosite_url="$geosite_url" geoip_mmdb_url="$geoip_mmdb_url" geoip_dat_url="$geoip_dat_url" geoip_asn_url="$geoip_asn_url" \
|
|
||||||
geox_auto_update="$geox_auto_update" geox_update_interval="$geox_update_interval" \
|
|
||||||
yq -M -i '
|
|
||||||
.log-level = strenv(log_level) | .mode = strenv(mode) | .find-process-mode = strenv(match_process) | .ipv6 = env(ipv6) == 1 | .unified-delay = env(unify_delay) == 1 | .tcp-concurrent = env(tcp_concurrent) == 1 | .keep-alive-idle = env(tcp_keep_alive_idle) | .keep-alive-interval = env(tcp_keep_alive_interval) |
|
|
||||||
.external-ui = strenv(ui_path) | .external-ui-name = strenv(ui_name) | .external-ui-url = strenv(ui_url) | .external-controller = strenv(api_listen) | .secret = strenv(api_secret) | .profile.store-selected = env(selection_cache) == 1 |
|
|
||||||
.allow-lan = env(allow_lan) == 1 | .port = env(http_port) | .socks-port = env(socks_port) | .mixed-port = env(mixed_port) | .redir-port = env(redir_port) | .tproxy-port = env(tproxy_port) |
|
|
||||||
.tun.enable = env(tun_enable) == 1 | .tun.stack = strenv(tun_stack) | .tun.device = strenv(tun_device) | .tun.mtu = env(tun_mtu) | .tun.gso = env(tun_gso) == 1 | .tun.gso-max-size = env(tun_gso_max_size) | .tun.endpoint-independent-nat = env(tun_endpoint_independent_nat) == 1 |
|
|
||||||
.tun.auto-route = false | .tun.auto-redirect = false | .tun.auto-detect-interface = false |
|
|
||||||
.dns.enable = env(dns_enable) | .dns.listen = strenv(dns_listen) | .dns.enhanced-mode = strenv(dns_mode) | .dns.fake-ip-range = strenv(fake_ip_range) | .profile.store-fake-ip = env(fake_ip_cache) == 1 |
|
|
||||||
.dns.respect-rules = env(dns_respect_rules) == 1 | .dns.prefer-h3 = env(dns_doh_prefer_http3) == 1 | .dns.ipv6 = env(dns_ipv6) == 1 | .dns.use-system-hosts = env(dns_system_hosts) == 1 | .dns.use-hosts = env(dns_hosts) == 1 |
|
|
||||||
.sniffer.enable = env(sniffer) == 1 | .sniffer.force-dns-mapping = env(sniffer_sniff_dns_mapping) == 1 | .sniffer.parse-pure-ip = env(sniffer_sniff_pure_ip) == 1 | .sniffer.override-destination = env(sniffer_overwrite_destination) == 1 |
|
|
||||||
.geodata-mode = strenv(geoip_format) == "dat" | .geodata-loader = strenv(geodata_loader) | .geox-url.geosite = strenv(geosite_url) | .geox-url.mmdb = strenv(geoip_mmdb_url) | .geox-url.geoip = strenv(geoip_dat_url) | .geox-url.asn = strenv(geoip_asn_url) |
|
|
||||||
.geo-auto-update = env(geox_auto_update) == 1 | .geo-update-interval = env(geox_update_interval)
|
|
||||||
' "$RUN_PROFILE_PATH"
|
|
||||||
|
|
||||||
if [ "$fake_ip_filter" == 1 ]; then
|
|
||||||
fake_ip_filter_mode="$fake_ip_filter_mode" \
|
|
||||||
yq -M -i 'del(.dns.fake-ip-filter) | .dns.fake-ip-filter-mode = strenv(fake_ip_filter_mode)' "$RUN_PROFILE_PATH"
|
|
||||||
config_list_foreach "mixin" "fake_ip_filters" mixin_fake_ip_filters
|
|
||||||
fi
|
|
||||||
if [ "$hosts" == 1 ]; then
|
|
||||||
yq -M -i 'del(.hosts)' "$RUN_PROFILE_PATH"
|
|
||||||
config_foreach mixin_hosts "hosts"
|
|
||||||
fi
|
|
||||||
if [ "$dns_nameserver" == 1 ]; then
|
|
||||||
yq -M -i 'del(.dns.default-nameserver) | del(.dns.proxy-server-nameserver) | del(.dns.direct-nameserver) | del(.dns.nameserver) | del(.dns.fallback)' "$RUN_PROFILE_PATH"
|
|
||||||
config_foreach mixin_nameservers "nameserver"
|
|
||||||
fi
|
|
||||||
if [ "$dns_nameserver_policy" == 1 ]; then
|
|
||||||
yq -M -i 'del(.dns.nameserver-policy)' "$RUN_PROFILE_PATH"
|
|
||||||
config_foreach mixin_nameserver_policies "nameserver_policy"
|
|
||||||
fi
|
|
||||||
if [ "$sniffer_force_domain_name" == 1 ]; then
|
|
||||||
yq -M -i 'del(.sniffer.force-domain)' "$RUN_PROFILE_PATH"
|
|
||||||
config_list_foreach "mixin" "sniffer_force_domain_names" mixin_sniffer_domain_names "force-domain"
|
|
||||||
fi
|
|
||||||
if [ "$sniffer_ignore_domain_name" == 1 ]; then
|
|
||||||
yq -M -i 'del(.sniffer.skip-domain)' "$RUN_PROFILE_PATH"
|
|
||||||
config_list_foreach "mixin" "sniffer_ignore_domain_names" mixin_sniffer_domain_names "skip-domain"
|
|
||||||
fi
|
|
||||||
if [ "$sniffer_sniff" == 1 ]; then
|
|
||||||
yq -M -i 'del(.sniffer.sniff)' "$RUN_PROFILE_PATH"
|
|
||||||
config_foreach mixin_sniffs "sniff"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
yq -M -i 'del (.bind-address)' "$RUN_PROFILE_PATH"
|
|
||||||
if [ -n "$outbound_interface" ]; then
|
|
||||||
local outbound_device; network_get_device outbound_device "$outbound_interface"
|
|
||||||
if [ -n "$outbound_device" ]; then
|
|
||||||
outbound_device="$outbound_device" yq -M -i '.interface-name = strenv(outbound_device)' "$RUN_PROFILE_PATH"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if [ "$authentication" == 1 ]; then
|
|
||||||
yq -M -i 'del(.authentication)' "$RUN_PROFILE_PATH"
|
|
||||||
config_foreach mixin_authentications "authentication"
|
|
||||||
fi
|
|
||||||
if [ "$tun_dns_hijack" == 1 ]; then
|
|
||||||
yq -M -i 'del(.tun.dns-hijack)' "$RUN_PROFILE_PATH"
|
|
||||||
config_list_foreach "mixin" "tun_dns_hijacks" mixin_tun_dns_hijacks
|
|
||||||
fi
|
|
||||||
if [ "$rule_provider" == 1 ]; then
|
|
||||||
config_foreach mixin_rule_providers "rule_provider"
|
|
||||||
fi
|
|
||||||
if [ "$rule" == 1 ]; then
|
|
||||||
yq -M -i 'del(.nikki-rules)' "$RUN_PROFILE_PATH"
|
|
||||||
config_foreach mixin_rules "rule"
|
|
||||||
yq -M -i '.rules = .nikki-rules + .rules | del(.nikki-rules)' "$RUN_PROFILE_PATH"
|
|
||||||
fi
|
|
||||||
if [ "$mixin_file_content" == 1 ]; then
|
|
||||||
if [ -s "$MIXIN_FILE_PATH" ]; then
|
|
||||||
yq -M -i ea '. as $item ireduce ({}; . * $item ) | ... comments=""' "$RUN_PROFILE_PATH" "$MIXIN_FILE_PATH"
|
|
||||||
fi
|
fi
|
||||||
|
if [ "$mixin_file_content" == 0 ]; then
|
||||||
|
ucode -S "$MIXIN_UC" | yq -M -p json -o yaml | yq -M -i ea '. as $item ireduce ({}; . * $item ) | .rules = .nikki-rules + .rules | del(.nikki-rules)' "$RUN_PROFILE_PATH" -
|
||||||
|
elif [ "$mixin_file_content" == 1 ]; then
|
||||||
|
ucode -S "$MIXIN_UC" | yq -M -p json -o yaml | yq -M -i ea '. as $item ireduce ({}; . * $item ) | .rules = .nikki-rules + .rules | del(.nikki-rules)' "$RUN_PROFILE_PATH" "$MIXIN_FILE_PATH" -
|
||||||
fi
|
fi
|
||||||
|
yq -M -i '... comments=""' "$RUN_PROFILE_PATH"
|
||||||
# test profile
|
# test profile
|
||||||
if [ "$test_profile" == 1 ]; then
|
if [ "$test_profile" == 1 ]; then
|
||||||
log "Profile" "Testing..."
|
log "Profile" "Testing..."
|
||||||
@ -339,17 +161,7 @@ service_started() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
# get config
|
# get config
|
||||||
### inbound
|
## mixin
|
||||||
local http_port socks_port mixed_port redir_port tproxy_port
|
|
||||||
config_get http_port "mixin" "http_port" "8080"
|
|
||||||
config_get socks_port "mixin" "socks_port" "1080"
|
|
||||||
config_get mixed_port "mixin" "mixed_port" "7890"
|
|
||||||
config_get redir_port "mixin" "redir_port" "7891"
|
|
||||||
config_get tproxy_port "mixin" "tproxy_port" "7892"
|
|
||||||
### dns
|
|
||||||
local dns_port fake_ip_range
|
|
||||||
config_get dns_port "mixin" "dns_port" "1053"
|
|
||||||
config_get fake_ip_range "mixin" "fake_ip_range" "198.18.0.1/16"
|
|
||||||
### tun
|
### tun
|
||||||
local tun_device
|
local tun_device
|
||||||
config_get tun_device "mixin" "tun_device" "nikki"
|
config_get tun_device "mixin" "tun_device" "nikki"
|
||||||
@ -365,8 +177,12 @@ service_started() {
|
|||||||
config_get_bool router_proxy "proxy" "router_proxy" 0
|
config_get_bool router_proxy "proxy" "router_proxy" 0
|
||||||
config_get_bool lan_proxy "proxy" "lan_proxy" 0
|
config_get_bool lan_proxy "proxy" "lan_proxy" 0
|
||||||
### access control
|
### access control
|
||||||
local access_control_mode bypass_china_mainland_ip proxy_tcp_dport proxy_udp_dport bypass_dscp
|
local access_control_mode
|
||||||
config_get access_control_mode "proxy" "access_control_mode"
|
config_get access_control_mode "proxy" "access_control_mode"
|
||||||
|
### bypass
|
||||||
|
local bypass_user bypass_group bypass_china_mainland_ip proxy_tcp_dport proxy_udp_dport bypass_dscp
|
||||||
|
config_get bypass_user "proxy" "bypass_user"
|
||||||
|
config_get bypass_group "proxy" "bypass_group"
|
||||||
config_get_bool bypass_china_mainland_ip "proxy" "bypass_china_mainland_ip" 0
|
config_get_bool bypass_china_mainland_ip "proxy" "bypass_china_mainland_ip" 0
|
||||||
config_get proxy_tcp_dport "proxy" "proxy_tcp_dport" "0-65535"
|
config_get proxy_tcp_dport "proxy" "proxy_tcp_dport" "0-65535"
|
||||||
config_get proxy_udp_dport "proxy" "proxy_udp_dport" "0-65535"
|
config_get proxy_udp_dport "proxy" "proxy_udp_dport" "0-65535"
|
||||||
@ -409,72 +225,48 @@ service_started() {
|
|||||||
if [ "$tproxy_enable" == 1 ]; then
|
if [ "$tproxy_enable" == 1 ]; then
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
if [ "$ipv4_proxy" == 1 ]; then
|
||||||
ip -4 route add local default dev lo table "$TPROXY_ROUTE_TABLE"
|
ip -4 route add local default dev lo table "$TPROXY_ROUTE_TABLE"
|
||||||
|
ip -4 rule add pref "$TPROXY_RULE_PREF" fwmark "$TPROXY_FW_MARK" table "$TPROXY_ROUTE_TABLE"
|
||||||
fi
|
fi
|
||||||
if [ "$ipv6_proxy" == 1 ]; then
|
if [ "$ipv6_proxy" == 1 ]; then
|
||||||
ip -6 route add local default dev lo table "$TPROXY_ROUTE_TABLE"
|
ip -6 route add local default dev lo table "$TPROXY_ROUTE_TABLE"
|
||||||
|
ip -4 rule add pref "$TPROXY_RULE_PREF" fwmark "$TPROXY_FW_MARK" table "$TPROXY_ROUTE_TABLE"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$tun_enable" == 1 ]; then
|
if [ "$tun_enable" == 1 ]; then
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
if [ "$ipv4_proxy" == 1 ]; then
|
||||||
ip -4 route add unicast default dev "$tun_device" table "$TUN_ROUTE_TABLE"
|
ip -4 route add unicast default dev "$tun_device" table "$TUN_ROUTE_TABLE"
|
||||||
|
ip -4 rule add pref "$TUN_RULE_PREF" fwmark "$TUN_FW_MARK" table "$TUN_ROUTE_TABLE"
|
||||||
fi
|
fi
|
||||||
if [ "$ipv6_proxy" == 1 ]; then
|
if [ "$ipv6_proxy" == 1 ]; then
|
||||||
ip -6 route add unicast default dev "$tun_device" table "$TUN_ROUTE_TABLE"
|
ip -6 route add unicast default dev "$tun_device" table "$TUN_ROUTE_TABLE"
|
||||||
|
ip -4 rule add pref "$TUN_RULE_PREF" fwmark "$TUN_FW_MARK" table "$TUN_ROUTE_TABLE"
|
||||||
fi
|
fi
|
||||||
$FIREWALL_INCLUDE_SH
|
$FIREWALL_INCLUDE_SH
|
||||||
fi
|
fi
|
||||||
local tcp_route_table
|
utpl -D nikki_group="$NIKKI_GROUP" -D tproxy_fw_mark="$TPROXY_FW_MARK" -D tun_fw_mark="$TUN_FW_MARK" -S "$HIJACK_UT" | nft -f -
|
||||||
if [ "$tcp_transparent_proxy_mode" == "tproxy" ]; then
|
|
||||||
tcp_route_table="$TPROXY_ROUTE_TABLE"
|
|
||||||
elif [ "$tcp_transparent_proxy_mode" == "tun" ]; then
|
|
||||||
tcp_route_table="$TUN_ROUTE_TABLE"
|
|
||||||
fi
|
|
||||||
if [ -n "$tcp_route_table" ]; then
|
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
|
||||||
ip -4 rule add pref "$TCP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto tcp table "$tcp_route_table"
|
|
||||||
fi
|
|
||||||
if [ "$ipv6_proxy" == 1 ]; then
|
|
||||||
ip -6 rule add pref "$TCP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto tcp table "$tcp_route_table"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
local udp_route_table
|
|
||||||
if [ "$udp_transparent_proxy_mode" == "tproxy" ]; then
|
|
||||||
udp_route_table="$TPROXY_ROUTE_TABLE"
|
|
||||||
elif [ "$udp_transparent_proxy_mode" == "tun" ]; then
|
|
||||||
udp_route_table="$TUN_ROUTE_TABLE"
|
|
||||||
fi
|
|
||||||
if [ -n "$udp_route_table" ]; then
|
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
|
||||||
ip -4 rule add pref "$UDP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto udp table "$udp_route_table"
|
|
||||||
fi
|
|
||||||
if [ "$ipv6_proxy" == 1 ]; then
|
|
||||||
ip -6 rule add pref "$UDP_RULE_PREF" fwmark "$FW_MARK/$FW_MARK_MASK" ipproto udp table "$udp_route_table"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
nft -f "$HIJACK_NFT" -D NIKKI_GROUP="$NIKKI_GROUP" -D FW_MARK="$FW_MARK" -D FW_MARK_MASK="$FW_MARK_MASK" -D TUN_DEVICE="$tun_device" -D FAKE_IP="$fake_ip_range" -D DNS_PORT="$dns_port" -D REDIR_PORT="$redir_port" -D TPROXY_PORT="$tproxy_port"
|
|
||||||
nft -f "$RESERVED_IP_NFT"
|
nft -f "$RESERVED_IP_NFT"
|
||||||
nft -f "$RESERVED_IP6_NFT"
|
nft -f "$RESERVED_IP6_NFT"
|
||||||
# dns hijack
|
# dns hijack
|
||||||
if [ "$ipv4_dns_hijack" == 1 ]; then
|
if [ "$ipv4_dns_hijack" == 1 ]; then
|
||||||
log "Transparent Proxy" "Hijack IPv4 dns request."
|
log "Transparent Proxy" "Hijack IPv4 dns request."
|
||||||
nft add element inet "$FW_TABLE" dns_hijack_nfproto \{ ipv4 \}
|
|
||||||
fi
|
fi
|
||||||
if [ "$ipv6_dns_hijack" == 1 ]; then
|
if [ "$ipv6_dns_hijack" == 1 ]; then
|
||||||
log "Transparent Proxy" "Hijack IPv6 dns request."
|
log "Transparent Proxy" "Hijack IPv6 dns request."
|
||||||
nft add element inet "$FW_TABLE" dns_hijack_nfproto \{ ipv6 \}
|
|
||||||
fi
|
fi
|
||||||
# proxy
|
# proxy
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
if [ "$ipv4_proxy" == 1 ]; then
|
||||||
log "Transparent Proxy" "Proxy IPv4 traffic."
|
log "Transparent Proxy" "Proxy IPv4 traffic."
|
||||||
nft add element inet "$FW_TABLE" proxy_nfproto \{ ipv4 \}
|
|
||||||
fi
|
fi
|
||||||
if [ "$ipv6_proxy" == 1 ]; then
|
if [ "$ipv6_proxy" == 1 ]; then
|
||||||
log "Transparent Proxy" "Proxy IPv6 traffic."
|
log "Transparent Proxy" "Proxy IPv6 traffic."
|
||||||
nft add element inet "$FW_TABLE" proxy_nfproto \{ ipv6 \}
|
|
||||||
fi
|
fi
|
||||||
# bypass
|
# bypass
|
||||||
config_list_foreach "proxy" "bypass_user" add_bypass_user
|
if [ -n "$bypass_user" ]; then
|
||||||
config_list_foreach "proxy" "bypass_group" add_bypass_group
|
log "Transparent Proxy" "Bypass user: $bypass_user."
|
||||||
|
fi
|
||||||
|
if [ -n "$bypass_group" ]; then
|
||||||
|
log "Transparent Proxy" "Bypass group: $bypass_group."
|
||||||
|
fi
|
||||||
if [ "$bypass_china_mainland_ip" == 1 ]; then
|
if [ "$bypass_china_mainland_ip" == 1 ]; then
|
||||||
log "Transparent Proxy" "Bypass china mainland ip."
|
log "Transparent Proxy" "Bypass china mainland ip."
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
if [ "$ipv4_proxy" == 1 ]; then
|
||||||
@ -486,32 +278,12 @@ service_started() {
|
|||||||
fi
|
fi
|
||||||
log "Transparent Proxy" "Destination TCP Port to Proxy: $proxy_tcp_dport."
|
log "Transparent Proxy" "Destination TCP Port to Proxy: $proxy_tcp_dport."
|
||||||
log "Transparent Proxy" "Destination UDP Port to Proxy: $proxy_udp_dport."
|
log "Transparent Proxy" "Destination UDP Port to Proxy: $proxy_udp_dport."
|
||||||
local proxy_dport
|
|
||||||
for proxy_dport in $proxy_tcp_dport; do
|
|
||||||
nft add element inet "$FW_TABLE" proxy_dport \{ "tcp" . "$proxy_dport" \}
|
|
||||||
done
|
|
||||||
for proxy_dport in $proxy_udp_dport; do
|
|
||||||
nft add element inet "$FW_TABLE" proxy_dport \{ "udp" . "$proxy_dport" \}
|
|
||||||
done
|
|
||||||
if [ -n "$bypass_dscp" ]; then
|
if [ -n "$bypass_dscp" ]; then
|
||||||
log "Transparent Proxy" "Bypass DSCP: $bypass_dscp."
|
log "Transparent Proxy" "Bypass DSCP: $bypass_dscp."
|
||||||
local dscp
|
|
||||||
for dscp in $bypass_dscp; do
|
|
||||||
nft add element inet "$FW_TABLE" bypass_dscp \{ "$dscp" \}
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
# router proxy
|
# router proxy
|
||||||
if [ "$router_proxy" == 1 ]; then
|
if [ "$router_proxy" == 1 ]; then
|
||||||
log "Transparent Proxy" "Set proxy for router."
|
log "Transparent Proxy" "Set proxy for router."
|
||||||
if [ "$tcp_transparent_proxy_mode" == "redirect" ]; then
|
|
||||||
nft insert rule inet "$FW_TABLE" nat_output jump router_dns_hijack
|
|
||||||
nft add rule inet "$FW_TABLE" nat_output meta l4proto tcp jump "router_${tcp_transparent_proxy_mode}"
|
|
||||||
else
|
|
||||||
nft flush chain inet "$FW_TABLE" nat_output
|
|
||||||
nft add rule inet "$FW_TABLE" nat_output jump router_dns_hijack
|
|
||||||
nft add rule inet "$FW_TABLE" mangle_output meta l4proto tcp jump "router_${tcp_transparent_proxy_mode}"
|
|
||||||
fi
|
|
||||||
nft add rule inet "$FW_TABLE" mangle_output meta l4proto udp jump "router_${udp_transparent_proxy_mode}"
|
|
||||||
fi
|
fi
|
||||||
# lan proxy
|
# lan proxy
|
||||||
if [ "$lan_proxy" == 1 ]; then
|
if [ "$lan_proxy" == 1 ]; then
|
||||||
@ -524,19 +296,6 @@ service_started() {
|
|||||||
elif [ "$access_control_mode" == "block" ]; then
|
elif [ "$access_control_mode" == "block" ]; then
|
||||||
log "Transparent Proxy" "Access Control is using block mode, set proxy for client which is not in acl."
|
log "Transparent Proxy" "Access Control is using block mode, set proxy for client which is not in acl."
|
||||||
fi
|
fi
|
||||||
config_list_foreach "proxy" "acl_ip" add_acl_ip
|
|
||||||
config_list_foreach "proxy" "acl_ip6" add_acl_ip6
|
|
||||||
config_list_foreach "proxy" "acl_mac" add_acl_mac
|
|
||||||
config_list_foreach "proxy" "acl_interface" add_acl_interface
|
|
||||||
if [ "$tcp_transparent_proxy_mode" == "redirect" ]; then
|
|
||||||
nft insert rule inet "$FW_TABLE" dstnat jump "${access_control_mode}_dns_hijack"
|
|
||||||
nft add rule inet "$FW_TABLE" dstnat meta l4proto tcp jump "${access_control_mode}_${tcp_transparent_proxy_mode}"
|
|
||||||
else
|
|
||||||
nft flush chain inet "$FW_TABLE" dstnat
|
|
||||||
nft add rule inet "$FW_TABLE" dstnat jump "${access_control_mode}_dns_hijack"
|
|
||||||
nft add rule inet "$FW_TABLE" mangle_prerouting meta l4proto tcp jump "${access_control_mode}_${tcp_transparent_proxy_mode}"
|
|
||||||
fi
|
|
||||||
nft add rule inet "$FW_TABLE" mangle_prerouting meta l4proto udp jump "${access_control_mode}_${udp_transparent_proxy_mode}"
|
|
||||||
fi
|
fi
|
||||||
# fix compatible between tproxy and dockerd (kmod-br-netfilter)
|
# fix compatible between tproxy and dockerd (kmod-br-netfilter)
|
||||||
if [ "$tproxy_enable" == 1 ] && (lsmod | grep -q br_netfilter); then
|
if [ "$tproxy_enable" == 1 ] && (lsmod | grep -q br_netfilter); then
|
||||||
@ -574,21 +333,17 @@ cleanup() {
|
|||||||
# clear log
|
# clear log
|
||||||
clear_log
|
clear_log
|
||||||
# delete routing policy
|
# delete routing policy
|
||||||
ip -4 rule del ipproto tcp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
ip -4 rule del table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -4 rule del ipproto udp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
ip -4 rule del table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -4 rule del ipproto tcp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
ip -6 rule del table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -4 rule del ipproto udp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
ip -6 rule del table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -6 rule del ipproto tcp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
|
||||||
ip -6 rule del ipproto udp table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
|
||||||
ip -6 rule del ipproto tcp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
|
||||||
ip -6 rule del ipproto udp table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
|
||||||
# delete routing table
|
# delete routing table
|
||||||
ip -4 route flush table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
ip -4 route flush table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -4 route flush table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
ip -4 route flush table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -6 route flush table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
ip -6 route flush table "$TPROXY_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
ip -6 route flush table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
ip -6 route flush table "$TUN_ROUTE_TABLE" > /dev/null 2>&1
|
||||||
# delete hijack
|
# delete hijack
|
||||||
nft delete table inet "$FW_TABLE" > /dev/null 2>&1
|
nft delete table inet nikki > /dev/null 2>&1
|
||||||
local handles handle
|
local handles handle
|
||||||
handles=$(nft --json list table inet fw4 | yq -M '.nftables[] | select(has("rule")) | .rule | select(.chain == "input" and .comment == "nikki") | .handle')
|
handles=$(nft --json list table inet fw4 | yq -M '.nftables[] | select(has("rule")) | .rule | select(.chain == "input" and .comment == "nikki") | .handle')
|
||||||
for handle in $handles; do
|
for handle in $handles; do
|
||||||
@ -614,201 +369,6 @@ cleanup() {
|
|||||||
/etc/init.d/cron restart
|
/etc/init.d/cron restart
|
||||||
}
|
}
|
||||||
|
|
||||||
mixin_authentications() {
|
|
||||||
local section="$1"
|
|
||||||
|
|
||||||
local enabled username password
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
config_get username "$section" "username"
|
|
||||||
config_get password "$section" "password"
|
|
||||||
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
authentication="$username:$password" yq -M -i '.authentication += [strenv(authentication)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_tun_dns_hijacks() {
|
|
||||||
dns_hijack="$1" yq -M -i '.tun.dns-hijack += [strenv(dns_hijack)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_fake_ip_filters() {
|
|
||||||
domain_name="$1" yq -M -i '.dns.fake-ip-filter += [strenv(domain_name)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_hosts() {
|
|
||||||
local section="$1"
|
|
||||||
|
|
||||||
local enabled domain_name
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
config_get domain_name "$section" "domain_name"
|
|
||||||
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_list_foreach "$section" "ip" mixin_host "$domain_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_host() {
|
|
||||||
ip="$1" domain_name="$2" yq -M -i '.hosts.[strenv(domain_name)] += [strenv(ip)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_nameservers() {
|
|
||||||
local section="$1"
|
|
||||||
|
|
||||||
local enabled type
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
config_get type "$section" "type"
|
|
||||||
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_list_foreach "$section" "nameserver" mixin_nameserver "$type"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_nameserver() {
|
|
||||||
nameserver="$1" type="$2" yq -M -i '.dns.[strenv(type)] += [strenv(nameserver)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_nameserver_policies() {
|
|
||||||
local section="$1"
|
|
||||||
|
|
||||||
local enabled matcher
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
config_get matcher "$section" "matcher"
|
|
||||||
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
config_list_foreach "$section" "nameserver" mixin_nameserver_policy "$matcher"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_nameserver_policy() {
|
|
||||||
nameserver="$1" matcher="$2" yq -M -i '.dns.nameserver-policy.[strenv(matcher)] += [strenv(nameserver)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_sniffer_domain_names() {
|
|
||||||
domain_name="$1" type="$2" yq -M -i '.sniffer.[strenv(type)] += [strenv(domain_name)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_sniffs() {
|
|
||||||
local section="$1"
|
|
||||||
local enabled protocol overwrite_destination
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
config_get protocol "$section" "protocol"
|
|
||||||
config_get_bool overwrite_destination "$section" "overwrite_destination" 0
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
protocol="$protocol" overwrite_destination="$overwrite_destination" yq -M -i '.sniffer.sniff.[strenv(protocol)].override-destination = env(overwrite_destination) == 1' "$RUN_PROFILE_PATH"
|
|
||||||
config_list_foreach "$section" "port" mixin_sniff "$protocol"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_sniff() {
|
|
||||||
port="$1" protocol="$2" yq -M -i '.sniffer.sniff.[strenv(protocol)].ports += [env(port)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_rule_providers() {
|
|
||||||
local section="$1"
|
|
||||||
local enabled
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
local name type url node file_size_limit file_path file_format behavior update_interval
|
|
||||||
config_get name "$section" "name"
|
|
||||||
config_get type "$section" "type"
|
|
||||||
config_get url "$section" "url"
|
|
||||||
config_get node "$section" "node"
|
|
||||||
config_get file_size_limit "$section" "file_size_limit" 0
|
|
||||||
config_get file_path "$section" "file_path"
|
|
||||||
config_get file_format "$section" "file_format"
|
|
||||||
config_get behavior "$section" "behavior"
|
|
||||||
config_get update_interval "$section" "update_interval" 0
|
|
||||||
if [ "$type" == "http" ]; then
|
|
||||||
name="$name" type="$type" url="$url" node="$node" file_size_limit="$file_size_limit" file_format="$file_format" behavior="$behavior" update_interval="$update_interval" \
|
|
||||||
yq -M -i '
|
|
||||||
.rule-providers.[strenv(name)].type = strenv(type) |
|
|
||||||
.rule-providers.[strenv(name)].url = strenv(url) |
|
|
||||||
.rule-providers.[strenv(name)].proxy = strenv(node) |
|
|
||||||
.rule-providers.[strenv(name)].size_limit = env(file_size_limit) |
|
|
||||||
.rule-providers.[strenv(name)].format = strenv(file_format) |
|
|
||||||
.rule-providers.[strenv(name)].behavior = strenv(behavior) |
|
|
||||||
.rule-providers.[strenv(name)].interval = env(update_interval)
|
|
||||||
' "$RUN_PROFILE_PATH"
|
|
||||||
elif [ "$type" == "file" ]; then
|
|
||||||
name="$name" type="$type" file_path="$file_path" file_format="$file_format" behavior="$behavior" \
|
|
||||||
yq -M -i '
|
|
||||||
.rule-providers.[strenv(name)].type = strenv(type) |
|
|
||||||
.rule-providers.[strenv(name)].path = strenv(file_path) |
|
|
||||||
.rule-providers.[strenv(name)].format = strenv(file_format) |
|
|
||||||
.rule-providers.[strenv(name)].behavior = strenv(behavior)
|
|
||||||
' "$RUN_PROFILE_PATH"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
mixin_rules() {
|
|
||||||
local section="$1"
|
|
||||||
local enabled
|
|
||||||
config_get_bool enabled "$section" "enabled" 0
|
|
||||||
if [ "$enabled" == 0 ]; then
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
local type match node no_resolve
|
|
||||||
config_get type "$section" "type"
|
|
||||||
config_get match "$section" "match"
|
|
||||||
config_get node "$section" "node"
|
|
||||||
config_get_bool no_resolve "$section" "no_resolve" 0
|
|
||||||
local rule
|
|
||||||
if [ -z "$type" ]; then
|
|
||||||
rule="$match,$node"
|
|
||||||
else
|
|
||||||
rule="$type,$match,$node"
|
|
||||||
fi
|
|
||||||
if [ "$no_resolve" == 1 ]; then
|
|
||||||
rule="$rule,no-resolve"
|
|
||||||
fi
|
|
||||||
rule="$rule" yq -M -i '.nikki-rules += [strenv(rule)]' "$RUN_PROFILE_PATH"
|
|
||||||
}
|
|
||||||
|
|
||||||
add_bypass_user() {
|
|
||||||
local user; user="$1"
|
|
||||||
if [ "$user" != "root" ] && (cut -d ':' -f 1 < /etc/passwd | grep -q "$user"); then
|
|
||||||
nft add element inet "$FW_TABLE" bypass_user \{ "$user" \}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
add_bypass_group() {
|
|
||||||
local group; group="$1"
|
|
||||||
if [ "$group" != "root" ] && (cut -d ':' -f 1 < /etc/group | grep -q "$group"); then
|
|
||||||
nft add element inet "$FW_TABLE" bypass_group \{ "$group" \}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
add_acl_ip() {
|
|
||||||
nft add element inet "$FW_TABLE" acl_ip \{ "$1" \}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_acl_ip6() {
|
|
||||||
nft add element inet "$FW_TABLE" acl_ip6 \{ "$1" \}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_acl_mac() {
|
|
||||||
nft add element inet "$FW_TABLE" acl_mac \{ "$1" \}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_acl_interface() {
|
|
||||||
local interface; interface="$1"
|
|
||||||
local device; network_get_device device "$interface"
|
|
||||||
if [ -n "$device" ]; then
|
|
||||||
nft add element inet "$FW_TABLE" acl_interface \{ "$device" \}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
update_subscription() {
|
update_subscription() {
|
||||||
local subscription_section; subscription_section="$1"
|
local subscription_section; subscription_section="$1"
|
||||||
if [ -z "$subscription_section" ]; then
|
if [ -z "$subscription_section" ]; then
|
||||||
|
73
nikki/files/scripts/debug.sh
Normal file
73
nikki/files/scripts/debug.sh
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo \
|
||||||
|
"
|
||||||
|
# Nikki Debug Info
|
||||||
|
## system
|
||||||
|
\`\`\`shell
|
||||||
|
$(cat /etc/openwrt_release)
|
||||||
|
\`\`\`
|
||||||
|
## kernel
|
||||||
|
\`\`\`
|
||||||
|
$(uname -a)
|
||||||
|
\`\`\`
|
||||||
|
## application
|
||||||
|
\`\`\`
|
||||||
|
`
|
||||||
|
if [ -x "/bin/opkg" ]; then
|
||||||
|
opkg list-installed "nikki"
|
||||||
|
opkg list-installed "luci-app-nikki"
|
||||||
|
elif [ -x "/usr/bin/apk" ]; then
|
||||||
|
apk list -I "nikki"
|
||||||
|
apk list -I "luci-app-nikki"
|
||||||
|
fi
|
||||||
|
`
|
||||||
|
\`\`\`
|
||||||
|
## config
|
||||||
|
\`\`\`
|
||||||
|
$(uci show nikki)
|
||||||
|
\`\`\`
|
||||||
|
## profile
|
||||||
|
\`\`\`yaml
|
||||||
|
$(cat /etc/nikki/run/config.yaml)
|
||||||
|
\`\`\`
|
||||||
|
## ip rule
|
||||||
|
\`\`\`
|
||||||
|
$(ip rule list)
|
||||||
|
\`\`\`
|
||||||
|
## ip route
|
||||||
|
\`\`\`
|
||||||
|
TPROXY:
|
||||||
|
$(ip route list table 80)
|
||||||
|
|
||||||
|
TUN:
|
||||||
|
$(ip route list table 81)
|
||||||
|
\`\`\`
|
||||||
|
## ip6 rule
|
||||||
|
\`\`\`
|
||||||
|
$(ip -6 rule list)
|
||||||
|
\`\`\`
|
||||||
|
## ip6 route
|
||||||
|
\`\`\`
|
||||||
|
TPROXY:
|
||||||
|
$(ip -6 route list table 80)
|
||||||
|
TUN:
|
||||||
|
$(ip -6 route list table 81)
|
||||||
|
\`\`\`
|
||||||
|
## nftables
|
||||||
|
\`\`\`
|
||||||
|
$(nft list ruleset)
|
||||||
|
\`\`\`
|
||||||
|
## service
|
||||||
|
\`\`\`json
|
||||||
|
$(service nikki info)
|
||||||
|
\`\`\`
|
||||||
|
## process
|
||||||
|
\`\`\`
|
||||||
|
$(ps | grep mihomo)
|
||||||
|
\`\`\`
|
||||||
|
## netstat
|
||||||
|
\`\`\`
|
||||||
|
$(netstat -nalp | grep mihomo)
|
||||||
|
\`\`\`
|
||||||
|
"
|
@ -5,11 +5,10 @@ NIKKI_USER="root"
|
|||||||
NIKKI_GROUP="nikki"
|
NIKKI_GROUP="nikki"
|
||||||
|
|
||||||
# routing
|
# routing
|
||||||
FW_TABLE="nikki"
|
TPROXY_FW_MARK="0x80"
|
||||||
FW_MARK="0x80"
|
TUN_FW_MARK="0x81"
|
||||||
FW_MARK_MASK="0xFF"
|
TPROXY_RULE_PREF="1024"
|
||||||
TCP_RULE_PREF="1024"
|
TUN_RULE_PREF="1025"
|
||||||
UDP_RULE_PREF="1025"
|
|
||||||
TPROXY_ROUTE_TABLE="80"
|
TPROXY_ROUTE_TABLE="80"
|
||||||
TUN_ROUTE_TABLE="81"
|
TUN_ROUTE_TABLE="81"
|
||||||
|
|
||||||
@ -24,7 +23,6 @@ RUN_PROFILE_PATH="$RUN_DIR/config.yaml"
|
|||||||
PROVIDERS_DIR="$RUN_DIR/providers"
|
PROVIDERS_DIR="$RUN_DIR/providers"
|
||||||
RULE_PROVIDERS_DIR="$PROVIDERS_DIR/rule"
|
RULE_PROVIDERS_DIR="$PROVIDERS_DIR/rule"
|
||||||
PROXY_PROVIDERS_DIR="$PROVIDERS_DIR/proxy"
|
PROXY_PROVIDERS_DIR="$PROVIDERS_DIR/proxy"
|
||||||
RUN_UI_DIR="$RUN_DIR/ui"
|
|
||||||
|
|
||||||
# log
|
# log
|
||||||
LOG_DIR="/var/log/nikki"
|
LOG_DIR="/var/log/nikki"
|
||||||
@ -37,6 +35,12 @@ STARTED_FLAG="$FLAG_DIR/started.flag"
|
|||||||
BRIDGE_NF_CALL_IPTABLES_FLAG="$FLAG_DIR/bridge_nf_call_iptables.flag"
|
BRIDGE_NF_CALL_IPTABLES_FLAG="$FLAG_DIR/bridge_nf_call_iptables.flag"
|
||||||
BRIDGE_NF_CALL_IP6TABLES_FLAG="$FLAG_DIR/bridge_nf_call_ip6tables.flag"
|
BRIDGE_NF_CALL_IP6TABLES_FLAG="$FLAG_DIR/bridge_nf_call_ip6tables.flag"
|
||||||
|
|
||||||
|
# ucode
|
||||||
|
UCODE_DIR="$HOME_DIR/ucode"
|
||||||
|
INCLUDE_UCODE="$UCODE_DIR/include.uc"
|
||||||
|
MIXIN_UC="$UCODE_DIR/mixin.uc"
|
||||||
|
HIJACK_UT="$UCODE_DIR/hijack.ut"
|
||||||
|
|
||||||
# scripts
|
# scripts
|
||||||
SH_DIR="$HOME_DIR/scripts"
|
SH_DIR="$HOME_DIR/scripts"
|
||||||
INCLUDE_SH="$SH_DIR/include.sh"
|
INCLUDE_SH="$SH_DIR/include.sh"
|
||||||
@ -44,7 +48,6 @@ FIREWALL_INCLUDE_SH="$SH_DIR/firewall_include.sh"
|
|||||||
|
|
||||||
# nftables
|
# nftables
|
||||||
NFT_DIR="$HOME_DIR/nftables"
|
NFT_DIR="$HOME_DIR/nftables"
|
||||||
HIJACK_NFT="$NFT_DIR/hijack.nft"
|
|
||||||
RESERVED_IP_NFT="$NFT_DIR/reserved_ip.nft"
|
RESERVED_IP_NFT="$NFT_DIR/reserved_ip.nft"
|
||||||
RESERVED_IP6_NFT="$NFT_DIR/reserved_ip6.nft"
|
RESERVED_IP6_NFT="$NFT_DIR/reserved_ip6.nft"
|
||||||
GEOIP_CN_NFT="$NFT_DIR/geoip_cn.nft"
|
GEOIP_CN_NFT="$NFT_DIR/geoip_cn.nft"
|
||||||
|
@ -8,6 +8,12 @@ mixin_rule=$(uci -q get nikki.mixin.rule); [ -z "$mixin_rule" ] && uci set nikki
|
|||||||
|
|
||||||
mixin_rule_provider=$(uci -q get nikki.mixin.rule_provider); [ -z "$mixin_rule_provider" ] && uci set nikki.mixin.rule_provider=0
|
mixin_rule_provider=$(uci -q get nikki.mixin.rule_provider); [ -z "$mixin_rule_provider" ] && uci set nikki.mixin.rule_provider=0
|
||||||
|
|
||||||
|
# since v1.19.0
|
||||||
|
|
||||||
|
mixin_ui_path=$(uci -q get nikki.mixin.ui_path); [ -z "$mixin_ui_path" ] && uci set nikki.mixin.ui_path=ui
|
||||||
|
|
||||||
|
uci show nikki | grep -E 'nikki.@rule\[[[:digit:]]+\]=rule' | sed 's/nikki.@rule\[\([[:digit:]]\+\)\]=rule/rename nikki.@rule[\1].match=matcher/' | uci batch
|
||||||
|
|
||||||
# commit
|
# commit
|
||||||
uci commit nikki
|
uci commit nikki
|
||||||
|
|
||||||
|
403
nikki/files/ucode/hijack.ut
Normal file
403
nikki/files/ucode/hijack.ut
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
#!/usr/bin/utpl
|
||||||
|
|
||||||
|
{%-
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { readfile } from 'fs';
|
||||||
|
import { cursor } from 'uci';
|
||||||
|
import { ensure_array } from '/etc/nikki/ucode/include.uc';
|
||||||
|
|
||||||
|
let users = map(split(readfile('/etc/passwd'), '\n'), (x) => split(x, ':')[0]);
|
||||||
|
let groups = map(split(readfile('/etc/group'), '\n'), (x) => split(x, ':')[0]);
|
||||||
|
|
||||||
|
const uci = cursor();
|
||||||
|
|
||||||
|
uci.load('nikki');
|
||||||
|
|
||||||
|
const redir_port = uci.get('nikki', 'mixin', 'redir_port');
|
||||||
|
const tproxy_port = uci.get('nikki', 'mixin', 'tproxy_port');
|
||||||
|
|
||||||
|
const dns_port = uci.get('nikki', 'mixin', 'dns_port');
|
||||||
|
const fake_ip_range = uci.get('nikki', 'mixin', 'fake_ip_range');
|
||||||
|
|
||||||
|
const tun_device = uci.get('nikki', 'mixin', 'tun_device');
|
||||||
|
|
||||||
|
const tcp_transparent_proxy_mode = uci.get('nikki', 'proxy', 'tcp_transparent_proxy_mode');
|
||||||
|
const udp_transparent_proxy_mode = uci.get('nikki', 'proxy', 'udp_transparent_proxy_mode');
|
||||||
|
const ipv4_dns_hijack = uci.get('nikki', 'proxy', 'ipv4_dns_hijack');
|
||||||
|
const ipv6_dns_hijack = uci.get('nikki', 'proxy', 'ipv6_dns_hijack');
|
||||||
|
const ipv4_proxy = uci.get('nikki', 'proxy', 'ipv4_proxy');
|
||||||
|
const ipv6_proxy = uci.get('nikki', 'proxy', 'ipv6_proxy');
|
||||||
|
const router_proxy = uci.get('nikki', 'proxy', 'router_proxy');
|
||||||
|
const lan_proxy = uci.get('nikki', 'proxy', 'lan_proxy');
|
||||||
|
|
||||||
|
const access_control_mode = uci.get('nikki', 'proxy', 'access_control_mode');
|
||||||
|
const acl_ip = ensure_array(uci.get('nikki', 'proxy', 'acl_ip'));
|
||||||
|
const acl_ip6 = ensure_array(uci.get('nikki', 'proxy', 'acl_ip6'));
|
||||||
|
const acl_mac = ensure_array(uci.get('nikki', 'proxy', 'acl_mac'));
|
||||||
|
const acl_interface = ensure_array(uci.get('nikki', 'proxy', 'acl_interface'));
|
||||||
|
|
||||||
|
const bypass_user = filter(ensure_array(uci.get('nikki', 'proxy', 'bypass_user')), (x) => x != "root" && index(users, x) >= 0);
|
||||||
|
const bypass_group = filter(ensure_array(uci.get('nikki', 'proxy', 'bypass_group')), (x) => x != "root" && index(groups, x) >= 0);
|
||||||
|
const proxy_tcp_dport = ensure_array(uci.get('nikki', 'proxy', 'proxy_tcp_dport'));
|
||||||
|
const proxy_udp_dport = ensure_array(uci.get('nikki', 'proxy', 'proxy_udp_dport'));
|
||||||
|
const bypass_dscp = ensure_array(uci.get('nikki', 'proxy', 'bypass_dscp'));
|
||||||
|
|
||||||
|
const dns_hijack_nfproto = [];
|
||||||
|
if (ipv4_dns_hijack == '1') {
|
||||||
|
push(dns_hijack_nfproto, 'ipv4')
|
||||||
|
}
|
||||||
|
if (ipv6_dns_hijack == '1') {
|
||||||
|
push(dns_hijack_nfproto, 'ipv6')
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxy_nfproto = [];
|
||||||
|
if (ipv4_proxy == '1') {
|
||||||
|
push(proxy_nfproto, 'ipv4')
|
||||||
|
}
|
||||||
|
if (ipv6_proxy == '1') {
|
||||||
|
push(proxy_nfproto, 'ipv6')
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxy_dport = [];
|
||||||
|
for (let port in proxy_tcp_dport) {
|
||||||
|
push(proxy_dport, `tcp . ${port}`)
|
||||||
|
}
|
||||||
|
for (let port in proxy_udp_dport) {
|
||||||
|
push(proxy_dport, `udp . ${port}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
push(bypass_group, nikki_group);
|
||||||
|
-%}
|
||||||
|
|
||||||
|
table inet nikki {
|
||||||
|
set bypass_user {
|
||||||
|
type uid
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(bypass_user) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in bypass_user): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set bypass_group {
|
||||||
|
type gid
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(bypass_group) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in bypass_group): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set bypass_dscp {
|
||||||
|
type dscp
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(bypass_dscp) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in bypass_dscp): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set dns_hijack_nfproto {
|
||||||
|
type nf_proto
|
||||||
|
flags interval
|
||||||
|
{% if (length(dns_hijack_nfproto) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in dns_hijack_nfproto): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set proxy_nfproto {
|
||||||
|
type nf_proto
|
||||||
|
flags interval
|
||||||
|
{% if (length(proxy_nfproto) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in proxy_nfproto): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set china_ip {
|
||||||
|
type ipv4_addr
|
||||||
|
flags interval
|
||||||
|
}
|
||||||
|
|
||||||
|
set china_ip6 {
|
||||||
|
type ipv6_addr
|
||||||
|
flags interval
|
||||||
|
}
|
||||||
|
|
||||||
|
set reserved_ip {
|
||||||
|
type ipv4_addr
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
}
|
||||||
|
|
||||||
|
set reserved_ip6 {
|
||||||
|
type ipv6_addr
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
}
|
||||||
|
|
||||||
|
set proxy_dport {
|
||||||
|
type inet_proto . inet_service
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(proxy_dport) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in proxy_dport): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set acl_ip {
|
||||||
|
type ipv4_addr
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(acl_ip) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in acl_ip): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set acl_ip6 {
|
||||||
|
type ipv6_addr
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(acl_ip6) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in acl_ip6): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set acl_mac {
|
||||||
|
type ether_addr
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(acl_mac) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in acl_mac): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
set acl_interface {
|
||||||
|
type ifname
|
||||||
|
flags interval
|
||||||
|
auto-merge
|
||||||
|
{% if (length(acl_interface) > 0): %}
|
||||||
|
elements = {
|
||||||
|
{% for (let x in acl_interface): %}
|
||||||
|
{{ x }},
|
||||||
|
{% endfor %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain all_dns_hijack {
|
||||||
|
meta l4proto { tcp, udp } th dport 53 counter redirect to :{{ dns_port }}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain allow_dns_hijack {
|
||||||
|
meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter redirect to :{{ dns_port }}
|
||||||
|
meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter redirect to :{{ dns_port }}
|
||||||
|
meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter redirect to :{{ dns_port }}
|
||||||
|
meta l4proto { tcp, udp } th dport 53 iifname @acl_interface counter redirect to :{{ dns_port }}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain block_dns_hijack {
|
||||||
|
meta l4proto { tcp, udp } th dport 53 ip saddr @acl_ip counter return
|
||||||
|
meta l4proto { tcp, udp } th dport 53 ip6 saddr @acl_ip6 counter return
|
||||||
|
meta l4proto { tcp, udp } th dport 53 ether saddr @acl_mac counter return
|
||||||
|
meta l4proto { tcp, udp } th dport 53 iifname @acl_interface counter return
|
||||||
|
meta l4proto { tcp, udp } th dport 53 counter redirect to :{{ dns_port }}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain all_redirect {
|
||||||
|
meta l4proto tcp counter redirect to :{{ redir_port }}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain allow_redirect {
|
||||||
|
meta l4proto tcp ip saddr @acl_ip counter redirect to :{{ redir_port }}
|
||||||
|
meta l4proto tcp ip6 saddr @acl_ip6 counter redirect to :{{ redir_port }}
|
||||||
|
meta l4proto tcp ether saddr @acl_mac counter redirect to :{{ redir_port }}
|
||||||
|
meta l4proto tcp iifname @acl_interface counter redirect to :{{ redir_port }}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain block_redirect {
|
||||||
|
meta l4proto tcp ip saddr @acl_ip counter return
|
||||||
|
meta l4proto tcp ip6 saddr @acl_ip6 counter return
|
||||||
|
meta l4proto tcp ether saddr @acl_mac counter return
|
||||||
|
meta l4proto tcp iifname @acl_interface counter return
|
||||||
|
meta l4proto tcp counter redirect to :{{ redir_port }}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain all_tproxy {
|
||||||
|
meta l4proto { tcp, udp } meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
|
||||||
|
}
|
||||||
|
|
||||||
|
chain allow_tproxy {
|
||||||
|
meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set {{ tproxy_fw_mark }} tproxy ip to :{{ tproxy_port }} counter accept
|
||||||
|
meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set {{ tproxy_fw_mark }} tproxy ip6 to :{{ tproxy_port }} counter accept
|
||||||
|
meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
|
||||||
|
meta l4proto { tcp, udp } iifname @acl_interface meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
|
||||||
|
}
|
||||||
|
|
||||||
|
chain block_tproxy {
|
||||||
|
meta l4proto { tcp, udp } ip saddr @acl_ip counter return
|
||||||
|
meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
|
||||||
|
meta l4proto { tcp, udp } ether saddr @acl_mac counter return
|
||||||
|
meta l4proto { tcp, udp } iifname @acl_interface counter return
|
||||||
|
meta l4proto { tcp, udp } meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
|
||||||
|
}
|
||||||
|
|
||||||
|
chain all_tun {
|
||||||
|
meta l4proto { tcp, udp } meta mark set {{ tun_fw_mark }} counter
|
||||||
|
}
|
||||||
|
|
||||||
|
chain allow_tun {
|
||||||
|
meta l4proto { tcp, udp } ip saddr @acl_ip meta mark set {{ tun_fw_mark }} counter
|
||||||
|
meta l4proto { tcp, udp } ip6 saddr @acl_ip6 meta mark set {{ tun_fw_mark }} counter
|
||||||
|
meta l4proto { tcp, udp } ether saddr @acl_mac meta mark set {{ tun_fw_mark }} counter
|
||||||
|
meta l4proto { tcp, udp } iifname @acl_interface meta mark set {{ tun_fw_mark }} counter
|
||||||
|
}
|
||||||
|
|
||||||
|
chain block_tun {
|
||||||
|
meta l4proto { tcp, udp } ip saddr @acl_ip counter return
|
||||||
|
meta l4proto { tcp, udp } ip6 saddr @acl_ip6 counter return
|
||||||
|
meta l4proto { tcp, udp } ether saddr @acl_mac counter return
|
||||||
|
meta l4proto { tcp, udp } iifname @acl_interface counter return
|
||||||
|
meta l4proto { tcp, udp } meta mark set {{ tun_fw_mark }} counter
|
||||||
|
}
|
||||||
|
|
||||||
|
{% if (router_proxy == '1'): %}
|
||||||
|
chain nat_output {
|
||||||
|
type nat hook output priority filter; policy accept;
|
||||||
|
meta skuid @bypass_user counter return
|
||||||
|
meta skgid @bypass_group counter return
|
||||||
|
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter redirect to :{{ dns_port }}
|
||||||
|
{% if (tcp_transparent_proxy_mode == 'redirect'): %}
|
||||||
|
fib daddr type { local, multicast, broadcast, anycast } counter return
|
||||||
|
ct direction reply counter return
|
||||||
|
ip daddr @reserved_ip counter return
|
||||||
|
ip6 daddr @reserved_ip6 counter return
|
||||||
|
ip daddr @china_ip counter return
|
||||||
|
ip6 daddr @china_ip6 counter return
|
||||||
|
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
||||||
|
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto tcp counter redirect to :{{ redir_port }}
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain mangle_output {
|
||||||
|
type route hook output priority mangle; policy accept;
|
||||||
|
meta skuid @bypass_user counter return
|
||||||
|
meta skgid @bypass_group counter return
|
||||||
|
fib daddr type { local, multicast, broadcast, anycast } counter return
|
||||||
|
ct direction reply counter return
|
||||||
|
ip daddr @reserved_ip counter return
|
||||||
|
ip6 daddr @reserved_ip6 counter return
|
||||||
|
ip daddr @china_ip counter return
|
||||||
|
ip6 daddr @china_ip6 counter return
|
||||||
|
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
||||||
|
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
||||||
|
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter return
|
||||||
|
{% if (tcp_transparent_proxy_mode == 'tproxy'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto tcp meta mark set {{ tproxy_fw_mark }} counter
|
||||||
|
{% elif (tcp_transparent_proxy_mode == 'tun'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto tcp meta mark set {{ tun_fw_mark }} counter
|
||||||
|
{% endif %}
|
||||||
|
{% if (udp_transparent_proxy_mode == 'tproxy'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto udp meta mark set {{ tproxy_fw_mark }} counter
|
||||||
|
{% elif (udp_transparent_proxy_mode == 'tun'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto udp meta mark set {{ tun_fw_mark }} counter
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain mangle_prerouting_router {
|
||||||
|
type filter hook prerouting priority mangle - 1; policy accept;
|
||||||
|
{% if (tcp_transparent_proxy_mode == 'tproxy' || udp_transparent_proxy_mode == 'tproxy'): %}
|
||||||
|
meta l4proto { tcp, udp } iifname lo meta mark {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
|
||||||
|
{% endif %}
|
||||||
|
{% if (tcp_transparent_proxy_mode == 'tun' || udp_transparent_proxy_mode == 'tun'): %}
|
||||||
|
meta l4proto { tcp, udp } iifname {{ tun_device }} counter accept
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if (lan_proxy == '1'): %}
|
||||||
|
chain dstnat {
|
||||||
|
type nat hook prerouting priority dstnat + 1; policy accept;
|
||||||
|
meta nfproto @dns_hijack_nfproto jump {{ access_control_mode }}_dns_hijack
|
||||||
|
{% if (tcp_transparent_proxy_mode == 'redirect'): %}
|
||||||
|
fib daddr type { local, multicast, broadcast, anycast } counter return
|
||||||
|
ct direction reply counter return
|
||||||
|
ip daddr @reserved_ip counter return
|
||||||
|
ip6 daddr @reserved_ip6 counter return
|
||||||
|
ip daddr @china_ip counter return
|
||||||
|
ip6 daddr @china_ip6 counter return
|
||||||
|
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
||||||
|
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
||||||
|
meta nfproto @proxy_nfproto jump {{ access_control_mode }}_redirect
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
chain mangle_prerouting_lan {
|
||||||
|
type filter hook prerouting priority mangle; policy accept;
|
||||||
|
fib daddr type { local, multicast, broadcast, anycast } counter return
|
||||||
|
ct direction reply counter return
|
||||||
|
ip daddr @reserved_ip counter return
|
||||||
|
ip6 daddr @reserved_ip6 counter return
|
||||||
|
ip daddr @china_ip counter return
|
||||||
|
ip6 daddr @china_ip6 counter return
|
||||||
|
meta nfproto ipv4 meta l4proto . th dport != @proxy_dport ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta nfproto ipv6 meta l4proto . th dport != @proxy_dport counter return
|
||||||
|
meta l4proto { tcp, udp } ip dscp == @bypass_dscp ip daddr != {{ fake_ip_range }} counter return
|
||||||
|
meta l4proto { tcp, udp } ip6 dscp == @bypass_dscp counter return
|
||||||
|
meta nfproto @dns_hijack_nfproto meta l4proto { tcp, udp } th dport 53 counter return
|
||||||
|
{% if (tcp_transparent_proxy_mode == 'tproxy'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto tcp jump {{ access_control_mode }}_tproxy
|
||||||
|
{% elif (tcp_transparent_proxy_mode == 'tun'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto tcp jump {{ access_control_mode }}_tun
|
||||||
|
{% endif %}
|
||||||
|
{% if (udp_transparent_proxy_mode == 'tproxy'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto udp jump {{ access_control_mode }}_tproxy
|
||||||
|
{% elif (udp_transparent_proxy_mode == 'tun'): %}
|
||||||
|
meta nfproto @proxy_nfproto meta l4proto udp jump {{ access_control_mode }}_tun
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
{% endif %}
|
||||||
|
}
|
9
nikki/files/ucode/include.uc
Normal file
9
nikki/files/ucode/include.uc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export function ensure_array(obj) {
|
||||||
|
if (obj == null) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (type(obj) == 'array') {
|
||||||
|
return uniq(obj);
|
||||||
|
}
|
||||||
|
return [obj];
|
||||||
|
};
|
191
nikki/files/ucode/mixin.uc
Normal file
191
nikki/files/ucode/mixin.uc
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
#!/usr/bin/ucode
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { cursor } from 'uci';
|
||||||
|
import { connect } from 'ubus';
|
||||||
|
import { ensure_array } from '/etc/nikki/ucode/include.uc';
|
||||||
|
|
||||||
|
const uci = cursor();
|
||||||
|
const ubus = connect();
|
||||||
|
|
||||||
|
const config = {};
|
||||||
|
|
||||||
|
const mixin = uci.get('nikki', 'config', 'mixin') == '1';
|
||||||
|
|
||||||
|
config['log-level'] = uci.get('nikki', 'mixin', 'log_level') || 'info';
|
||||||
|
config['mode'] = uci.get('nikki', 'mixin', 'mode') || 'rule';
|
||||||
|
config['find-process-mode'] = uci.get('nikki', 'mixin', 'match_process') || 'off';
|
||||||
|
config['interface-name'] = ubus.call('network.interface', 'status', {'interface': uci.get('nikki', 'mixin', 'outbound_interface')})?.l3_device || '';
|
||||||
|
config['ipv6'] = uci.get('nikki', 'mixin', 'ipv6') == '1';
|
||||||
|
if (mixin) {
|
||||||
|
config['unified-delay'] = uci.get('nikki', 'mixin', 'unify_delay') == '1';
|
||||||
|
config['tcp-concurrent'] = uci.get('nikki', 'mixin', 'tcp_concurrent') == '1';
|
||||||
|
config['keep-alive-idle'] = int(uci.get('nikki', 'mixin', 'tcp_keep_alive_idle') || '600');
|
||||||
|
config['keep-alive-interval'] = int(uci.get('nikki', 'mixin', 'tcp_keep_alive_interval') || '15');
|
||||||
|
}
|
||||||
|
|
||||||
|
config['external-ui'] = uci.get('nikki', 'mixin', 'ui_path') || 'ui';
|
||||||
|
config['external-ui-name'] = uci.get('nikki', 'mixin', 'ui_name') || '';
|
||||||
|
config['external-ui-url'] = uci.get('nikki', 'mixin', 'ui_url');
|
||||||
|
config['external-controller'] = '0.0.0.0' + ':' + (uci.get('nikki', 'mixin', 'api_port') || '9090');
|
||||||
|
config['secret'] = uci.get('nikki', 'mixin', 'api_secret') || '666666';
|
||||||
|
config['profile'] = {};
|
||||||
|
config['profile']['store-selected'] = uci.get('nikki', 'mixin', 'selection_cache') == '1';
|
||||||
|
config['profile']['store-fake-ip'] = uci.get('nikki', 'mixin', 'fake_ip_cache') == '1';
|
||||||
|
|
||||||
|
config['allow-lan'] = uci.get('nikki', 'mixin', 'allow_lan') == '1';
|
||||||
|
config['port'] = int(uci.get('nikki', 'mixin', 'http_port') || '8080');
|
||||||
|
config['socks-port'] = int(uci.get('nikki', 'mixin', 'socks_port') || '1080');
|
||||||
|
config['mixed-port'] = int(uci.get('nikki', 'mixin', 'mixed_port') || '7890');
|
||||||
|
config['redir-port'] = int(uci.get('nikki', 'mixin', 'redir_port') || '7891');
|
||||||
|
config['tproxy-port'] = int(uci.get('nikki', 'mixin', 'tproxy_port') || '7892');
|
||||||
|
|
||||||
|
if (uci.get('nikki', 'mixin', 'authentication') == '1') {
|
||||||
|
config['authentication'] = [];
|
||||||
|
uci.foreach('nikki', 'authentication', (section) => {
|
||||||
|
if (section.enabled == '1') {
|
||||||
|
push(config['authentication'], `${section.username}:${section.password}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
config['tun'] = {};
|
||||||
|
if (uci.get('nikki', 'proxy', 'tcp_transparent_proxy_mode') == 'tun' || uci.get('nikki', 'proxy', 'udp_transparent_proxy_mode') == 'tun') {
|
||||||
|
config['tun']['enable'] = true;
|
||||||
|
config['tun']['device'] = uci.get('nikki', 'mixin', 'tun_device') || 'nikki';
|
||||||
|
config['tun']['stack'] = uci.get('nikki', 'mixin', 'tun_stack') || 'system';
|
||||||
|
config['tun']['mtu'] = int(uci.get('nikki', 'mixin', 'tun_mtu') || '9000');
|
||||||
|
config['tun']['gso'] = uci.get('nikki', 'mixin', 'tun_gso') == '1';
|
||||||
|
config['tun']['gso-max-size'] = int(uci.get('nikki', 'mixin', 'tun_gso_max_size') || '65536');
|
||||||
|
config['tun']['endpoint-independent-nat'] = uci.get('nikki', 'mixin', 'tun_endpoint_independent_nat') == '1';
|
||||||
|
config['tun']['auto-route'] = false;
|
||||||
|
config['tun']['auto-redirect'] = false;
|
||||||
|
config['tun']['auto-detect-interface'] = false;
|
||||||
|
if (uci.get('nikki', 'mixin', 'tun_dns_hijack') == '1') {
|
||||||
|
config['tun']['dns-hijack'] = ensure_array(uci.get('nikki', 'mixin', 'tun_dns_hijacks'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
config['tun']['enable'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
config['dns'] = {};
|
||||||
|
config['dns']['listen'] = '0.0.0.0' + ':' + (uci.get('nikki', 'mixin', 'dns_port') || '1053');
|
||||||
|
config['dns']['enhanced-mode'] = uci.get('nikki', 'mixin', 'dns_mode') || 'redir-host';
|
||||||
|
config['dns']['fake-ip-range'] = uci.get('nikki', 'mixin', 'fake_ip_range') || '198.18.0.1/16';
|
||||||
|
if (uci.get('nikki', 'mixin', 'fake_ip_filter') == '1') {
|
||||||
|
config['dns']['fake-ip-filter'] = ensure_array(uci.get('nikki', 'mixin', 'fake_ip_filters'));
|
||||||
|
config['dns']['fake-ip-filter-mode'] = uci.get('nikki', 'mixin', 'fake_ip_filter_mode') || 'blacklist';
|
||||||
|
}
|
||||||
|
if (mixin) {
|
||||||
|
config['dns']['respect-rules'] = uci.get('nikki', 'mixin', 'dns_respect_rules') == '1';
|
||||||
|
config['dns']['prefer-h3'] = uci.get('nikki', 'mixin', 'dns_doh_prefer_http3') == '1';
|
||||||
|
config['dns']['ipv6'] = uci.get('nikki', 'mixin', 'dns_ipv6') == '1';
|
||||||
|
config['dns']['use-system-hosts'] = uci.get('nikki', 'mixin', 'dns_system_hosts') == '1';
|
||||||
|
config['dns']['use-hosts'] = uci.get('nikki', 'mixin', 'dns_hosts') == '1';
|
||||||
|
if (uci.get('nikki', 'mixin', 'hosts') == '1') {
|
||||||
|
config['hosts'] = {};
|
||||||
|
uci.foreach('nikki', 'hosts', (section) => {
|
||||||
|
if (section.enabled == '1') {
|
||||||
|
config['hosts'][section.domain_name] = ensure_array(section.ip);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (uci.get('nikki', 'mixin', 'dns_nameserver') == '1') {
|
||||||
|
config['dns']['default-nameserver'] = [];
|
||||||
|
config['dns']['proxy-server-nameserver'] = [];
|
||||||
|
config['dns']['direct-nameserver'] = [];
|
||||||
|
config['dns']['nameserver'] = [];
|
||||||
|
config['dns']['fallback'] = [];
|
||||||
|
uci.foreach('nikki', 'nameserver', (section) => {
|
||||||
|
push(config['dns'][section.type], ...ensure_array(section.nameserver));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (uci.get('nikki', 'mixin', 'dns_nameserver_policy') == '1') {
|
||||||
|
config['dns']['nameserver-policy'] = {};
|
||||||
|
uci.foreach('nikki', 'nameserver_policy', (section) => {
|
||||||
|
if (section.enabled == '1') {
|
||||||
|
config['dns']['nameserver-policy'][section.matcher] = ensure_array(section.nameserver);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mixin) {
|
||||||
|
config['sniffer'] = {};
|
||||||
|
config['sniffer']['enable'] = uci.get('nikki', 'mixin', 'sniffer') == '1';
|
||||||
|
config['sniffer']['force-dns-mapping'] = uci.get('nikki', 'mixin', 'sniffer_sniff_dns_mapping') == '1';
|
||||||
|
config['sniffer']['parse-pure-ip'] = uci.get('nikki', 'mixin', 'sniffer_sniff_pure_ip') == '1';
|
||||||
|
config['sniffer']['override-destination'] = uci.get('nikki', 'mixin', 'sniffer_overwrite_destination') == '1';
|
||||||
|
if (uci.get('nikki', 'mixin', 'sniffer_force_domain_name') == '1') {
|
||||||
|
config['sniffer']['force-domain'] = uci.get('nikki', 'mixin', 'sniffer_force_domain_names');
|
||||||
|
}
|
||||||
|
if (uci.get('nikki', 'mixin', 'sniffer_ignore_domain_name') == '1') {
|
||||||
|
config['sniffer']['skip-domain'] = uci.get('nikki', 'mixin', 'sniffer_ignore_domain_names');
|
||||||
|
}
|
||||||
|
if (uci.get('nikki', 'mixin', 'sniffer_sniff') == '1') {
|
||||||
|
config['sniffer']['sniff'] = {};
|
||||||
|
config['sniffer']['sniff']['HTTP'] = {};
|
||||||
|
config['sniffer']['sniff']['TLS'] = {};
|
||||||
|
config['sniffer']['sniff']['QUIC'] = {};
|
||||||
|
uci.foreach('nikki', 'sniff', (section) => {
|
||||||
|
if (section.enabled == '1') {
|
||||||
|
config['sniffer']['sniff'][section.protocol]['port'] = ensure_array(section.port);
|
||||||
|
config['sniffer']['sniff'][section.protocol]['override-destination'] = section.overwrite_destination == '1';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uci.get('nikki', 'mixin', 'rule_provider') == '1') {
|
||||||
|
config['rule-providers'] = {};
|
||||||
|
uci.foreach('nikki', 'rule_provider', (section) => {
|
||||||
|
if (section.type == 'http') {
|
||||||
|
config['rule-providers'][section.name] = {
|
||||||
|
type: section.type,
|
||||||
|
url: section.url,
|
||||||
|
proxy: section.node,
|
||||||
|
size_limit: section.file_size_limit,
|
||||||
|
format: section.file_format,
|
||||||
|
behavior: section.behavior,
|
||||||
|
interval: section.update_interval,
|
||||||
|
}
|
||||||
|
} else if (section.type == 'file') {
|
||||||
|
config['rule-providers'][section.name] = {
|
||||||
|
type: section.type,
|
||||||
|
path: section.file_path,
|
||||||
|
format: section.file_format,
|
||||||
|
behavior: section.behavior,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (uci.get('nikki', 'mixin', 'rule') == '1') {
|
||||||
|
config['nikki-rules'] = [];
|
||||||
|
uci.foreach('nikki', 'rule', (section) => {
|
||||||
|
let rule;
|
||||||
|
if (section.type == null || section.type == '') {
|
||||||
|
rule = `${section.matcher},${section.node}`;
|
||||||
|
} else {
|
||||||
|
rule = `${section.type},${section.matcher},${section.node}`;
|
||||||
|
}
|
||||||
|
if (section.no_resolve == '1') {
|
||||||
|
rule += ',no_resolve';
|
||||||
|
}
|
||||||
|
push(config['nikki-rules'], rule);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mixin) {
|
||||||
|
config['geodata-mode'] = (uci.get('nikki', 'mixin', 'geoip_format') || 'mmdb') == 'dat';
|
||||||
|
config['geodata-loader'] = uci.get('nikki', 'mixin', 'geodata_loader') || 'memconservative';
|
||||||
|
config['geox-url'] = {};
|
||||||
|
config['geox-url']['geosite'] = uci.get('nikki', 'mixin', 'geosite_url');
|
||||||
|
config['geox-url']['mmdb'] = uci.get('nikki', 'mixin', 'geoip_mmdb_url');
|
||||||
|
config['geox-url']['geoip'] = uci.get('nikki', 'mixin', 'geoip_dat_url');
|
||||||
|
config['geox-url']['asn'] = uci.get('nikki', 'mixin', 'geoip_asn_url');
|
||||||
|
config['geo-auto-update'] = uci.get('nikki', 'mixin', 'geox_auto_update') == '1';
|
||||||
|
config['geo-update-interval'] = int(uci.get('nikki', 'mixin', 'geox_update_interval') || '24');
|
||||||
|
}
|
||||||
|
|
||||||
|
print(config);
|
Loading…
Reference in New Issue
Block a user