parent
c725691965
commit
cdcbb246ef
@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=nikki
|
PKG_NAME:=nikki
|
||||||
PKG_RELEASE:=7
|
PKG_RELEASE:=8
|
||||||
|
|
||||||
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
|
||||||
|
@ -8,7 +8,6 @@ config config 'config'
|
|||||||
option 'scheduled_restart' '0'
|
option 'scheduled_restart' '0'
|
||||||
option 'cron_expression' '0 3 * * *'
|
option 'cron_expression' '0 3 * * *'
|
||||||
option 'test_profile' '1'
|
option 'test_profile' '1'
|
||||||
option 'mixin' '1'
|
|
||||||
|
|
||||||
config proxy 'proxy'
|
config proxy 'proxy'
|
||||||
option 'transparent_proxy' '1'
|
option 'transparent_proxy' '1'
|
||||||
@ -17,8 +16,8 @@ config proxy 'proxy'
|
|||||||
option 'ipv4_dns_hijack' '1'
|
option 'ipv4_dns_hijack' '1'
|
||||||
option 'ipv6_dns_hijack' '1'
|
option 'ipv6_dns_hijack' '1'
|
||||||
option 'ipv4_proxy' '1'
|
option 'ipv4_proxy' '1'
|
||||||
option 'ipv6_proxy' '0'
|
option 'ipv6_proxy' '1'
|
||||||
option 'fake_ip_ping_hijack' '0'
|
option 'fake_ip_ping_hijack' '1'
|
||||||
option 'router_proxy' '1'
|
option 'router_proxy' '1'
|
||||||
option 'lan_proxy' '1'
|
option 'lan_proxy' '1'
|
||||||
option 'access_control_mode' 'all'
|
option 'access_control_mode' 'all'
|
||||||
@ -55,17 +54,10 @@ config mixin 'mixin'
|
|||||||
option 'log_level' 'warning'
|
option 'log_level' 'warning'
|
||||||
option 'mode' 'rule'
|
option 'mode' 'rule'
|
||||||
option 'match_process' 'off'
|
option 'match_process' 'off'
|
||||||
option 'outbound_interface' ''
|
option 'ipv6' '1'
|
||||||
option 'ipv6' '0'
|
|
||||||
option 'unify_delay' '1'
|
|
||||||
option 'tcp_concurrent' '1'
|
|
||||||
option 'tcp_keep_alive_idle' '600'
|
|
||||||
option 'tcp_keep_alive_interval' '15'
|
|
||||||
option 'ui_path' 'ui'
|
option 'ui_path' 'ui'
|
||||||
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_listen' '[::]:9090'
|
||||||
option 'api_secret' ''
|
|
||||||
option 'selection_cache' '1'
|
option 'selection_cache' '1'
|
||||||
option 'allow_lan' '1'
|
option 'allow_lan' '1'
|
||||||
option 'http_port' '8080'
|
option 'http_port' '8080'
|
||||||
@ -76,14 +68,10 @@ config mixin 'mixin'
|
|||||||
option 'authentication' '1'
|
option 'authentication' '1'
|
||||||
option 'tun_device' 'nikki'
|
option 'tun_device' 'nikki'
|
||||||
option 'tun_stack' 'system'
|
option 'tun_stack' 'system'
|
||||||
option 'tun_mtu' '9000'
|
|
||||||
option 'tun_gso' '1'
|
|
||||||
option 'tun_gso_max_size' '65536'
|
|
||||||
option 'tun_dns_hijack' '0'
|
option 'tun_dns_hijack' '0'
|
||||||
list 'tun_dns_hijacks' 'tcp://any:53'
|
list 'tun_dns_hijacks' 'tcp://any:53'
|
||||||
list 'tun_dns_hijacks' 'udp://any:53'
|
list 'tun_dns_hijacks' 'udp://any:53'
|
||||||
option 'tun_endpoint_independent_nat' '0'
|
option 'dns_listen' '[::]:1053'
|
||||||
option 'dns_port' '1053'
|
|
||||||
option 'dns_ipv6' '1'
|
option 'dns_ipv6' '1'
|
||||||
option 'dns_mode' 'fake-ip'
|
option 'dns_mode' 'fake-ip'
|
||||||
option 'fake_ip_range' '198.18.0.1/16'
|
option 'fake_ip_range' '198.18.0.1/16'
|
||||||
@ -91,32 +79,14 @@ config mixin 'mixin'
|
|||||||
list 'fake_ip_filters' '+.lan'
|
list 'fake_ip_filters' '+.lan'
|
||||||
list 'fake_ip_filters' '+.local'
|
list 'fake_ip_filters' '+.local'
|
||||||
option 'fake_ip_cache' '1'
|
option 'fake_ip_cache' '1'
|
||||||
option 'dns_respect_rules' '0'
|
|
||||||
option 'dns_doh_prefer_http3' '0'
|
|
||||||
option 'dns_system_hosts' '0'
|
|
||||||
option 'dns_hosts' '1'
|
|
||||||
option 'hosts' '0'
|
option 'hosts' '0'
|
||||||
option 'dns_nameserver' '0'
|
option 'dns_nameserver' '0'
|
||||||
option 'dns_nameserver_policy' '0'
|
option 'dns_nameserver_policy' '0'
|
||||||
option 'sniffer' '0'
|
|
||||||
option 'sniffer_sniff_dns_mapping' '1'
|
|
||||||
option 'sniffer_sniff_pure_ip' '1'
|
|
||||||
option 'sniffer_overwrite_destination' '0'
|
|
||||||
option 'sniffer_force_domain_name' '0'
|
option 'sniffer_force_domain_name' '0'
|
||||||
option 'sniffer_force_domain_names' ''
|
|
||||||
option 'sniffer_ignore_domain_name' '0'
|
option 'sniffer_ignore_domain_name' '0'
|
||||||
option 'sniffer_ignore_domain_names' ''
|
|
||||||
option 'sniffer_sniff' '0'
|
option 'sniffer_sniff' '0'
|
||||||
option 'rule' '0'
|
option 'rule' '0'
|
||||||
option 'rule_provider' '0'
|
option 'rule_provider' '0'
|
||||||
option 'geoip_format' 'dat'
|
|
||||||
option 'geodata_loader' 'memconservative'
|
|
||||||
option 'geosite_url' 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat'
|
|
||||||
option 'geoip_mmdb_url' 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.metadb'
|
|
||||||
option 'geoip_dat_url' 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip-lite.dat'
|
|
||||||
option 'geoip_asn_url' 'https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/GeoLite2-ASN.mmdb'
|
|
||||||
option 'geox_auto_update' '0'
|
|
||||||
option 'geox_update_interval' '24'
|
|
||||||
option 'mixin_file_content' '0'
|
option 'mixin_file_content' '0'
|
||||||
|
|
||||||
config env 'env'
|
config env 'env'
|
||||||
|
@ -44,11 +44,10 @@ start_service() {
|
|||||||
log "App" "Start."
|
log "App" "Start."
|
||||||
# get config
|
# get config
|
||||||
## app config
|
## app config
|
||||||
local scheduled_restart cron_expression profile mixin test_profile fast_reload
|
local scheduled_restart cron_expression profile test_profile fast_reload
|
||||||
config_get_bool scheduled_restart "config" "scheduled_restart" 0
|
config_get_bool scheduled_restart "config" "scheduled_restart" 0
|
||||||
config_get cron_expression "config" "cron_expression"
|
config_get cron_expression "config" "cron_expression"
|
||||||
config_get profile "config" "profile"
|
config_get profile "config" "profile"
|
||||||
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
|
||||||
## mixin config
|
## mixin config
|
||||||
@ -94,13 +93,7 @@ start_service() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
# mixin
|
# mixin
|
||||||
if [ "$mixin" == 0 ]; then
|
log "Mixin" "Mixin config."
|
||||||
log "Mixin" "Disabled."
|
|
||||||
log "Mixin" "Mixin neccesary config."
|
|
||||||
else
|
|
||||||
log "Mixin" "Enabled."
|
|
||||||
log "Mixin" "Mixin all config."
|
|
||||||
fi
|
|
||||||
if [ "$mixin_file_content" == 0 ]; then
|
if [ "$mixin_file_content" == 0 ]; then
|
||||||
ucode -S "$MIXIN_UC" | yq -M -p json -o yaml | yq -M -i ea '... comments="" | . as $item ireduce ({}; . * $item ) | .rules = .nikki-rules + .rules | del(.nikki-rules)' "$RUN_PROFILE_PATH" -
|
ucode -S "$MIXIN_UC" | yq -M -p json -o yaml | yq -M -i ea '... comments="" | . as $item ireduce ({}; . * $item ) | .rules = .nikki-rules + .rules | del(.nikki-rules)' "$RUN_PROFILE_PATH" -
|
||||||
elif [ "$mixin_file_content" == 1 ]; then
|
elif [ "$mixin_file_content" == 1 ]; then
|
||||||
@ -110,9 +103,9 @@ start_service() {
|
|||||||
if [ "$test_profile" == 1 ]; then
|
if [ "$test_profile" == 1 ]; then
|
||||||
log "Profile" "Testing..."
|
log "Profile" "Testing..."
|
||||||
if ($PROG -d "$RUN_DIR" -t >> "$CORE_LOG_PATH" 2>&1); then
|
if ($PROG -d "$RUN_DIR" -t >> "$CORE_LOG_PATH" 2>&1); then
|
||||||
log "Profile" "Test passed!"
|
log "Profile" "Test passed."
|
||||||
else
|
else
|
||||||
log "Profile" "Test failed!"
|
log "Profile" "Test failed."
|
||||||
log "Profile" "Please check the core log to find out the problem."
|
log "Profile" "Please check the core log to find out the problem."
|
||||||
log "App" "Exit."
|
log "App" "Exit."
|
||||||
return
|
return
|
||||||
@ -166,26 +159,11 @@ service_started() {
|
|||||||
config_get tun_device "mixin" "tun_device" "nikki"
|
config_get tun_device "mixin" "tun_device" "nikki"
|
||||||
## proxy config
|
## proxy config
|
||||||
### transparent proxy
|
### transparent proxy
|
||||||
local tcp_transparent_proxy_mode udp_transparent_proxy_mode ipv4_dns_hijack ipv6_dns_hijack ipv4_proxy ipv6_proxy router_proxy lan_proxy
|
local tcp_transparent_proxy_mode udp_transparent_proxy_mode ipv4_proxy ipv6_proxy
|
||||||
config_get tcp_transparent_proxy_mode "proxy" "tcp_transparent_proxy_mode" "redirect"
|
config_get tcp_transparent_proxy_mode "proxy" "tcp_transparent_proxy_mode" "redirect"
|
||||||
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode" "tun"
|
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode" "tun"
|
||||||
config_get_bool ipv4_dns_hijack "proxy" "ipv4_dns_hijack" 0
|
|
||||||
config_get_bool ipv6_dns_hijack "proxy" "ipv6_dns_hijack" 0
|
|
||||||
config_get_bool ipv4_proxy "proxy" "ipv4_proxy" 0
|
config_get_bool ipv4_proxy "proxy" "ipv4_proxy" 0
|
||||||
config_get_bool ipv6_proxy "proxy" "ipv6_proxy" 0
|
config_get_bool ipv6_proxy "proxy" "ipv6_proxy" 0
|
||||||
config_get_bool router_proxy "proxy" "router_proxy" 0
|
|
||||||
config_get_bool lan_proxy "proxy" "lan_proxy" 0
|
|
||||||
### access control
|
|
||||||
local 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 proxy_tcp_dport "proxy" "proxy_tcp_dport" "0-65535"
|
|
||||||
config_get proxy_udp_dport "proxy" "proxy_udp_dport" "0-65535"
|
|
||||||
config_get bypass_dscp "proxy" "bypass_dscp"
|
|
||||||
# prepare
|
# prepare
|
||||||
local tproxy_enable; tproxy_enable=0
|
local tproxy_enable; tproxy_enable=0
|
||||||
if [[ "$tcp_transparent_proxy_mode" == "tproxy" || "$udp_transparent_proxy_mode" == "tproxy" ]]; then
|
if [[ "$tcp_transparent_proxy_mode" == "tproxy" || "$udp_transparent_proxy_mode" == "tproxy" ]]; then
|
||||||
@ -197,12 +175,10 @@ service_started() {
|
|||||||
fi
|
fi
|
||||||
# transparent proxy
|
# transparent proxy
|
||||||
log "Transparent Proxy" "Enabled."
|
log "Transparent Proxy" "Enabled."
|
||||||
log "Transparent Proxy" "TCP Mode: $tcp_transparent_proxy_mode."
|
|
||||||
log "Transparent Proxy" "UDP Mode: $udp_transparent_proxy_mode."
|
|
||||||
# wait for tun device online
|
# wait for tun device online
|
||||||
if [ "$tun_enable" == 1 ]; then
|
if [ "$tun_enable" == 1 ]; then
|
||||||
log "Transparent Proxy" "Waiting for tun device online..."
|
log "Transparent Proxy" "Waiting for tun device online..."
|
||||||
local tun_timeout; tun_timeout=60
|
local tun_timeout; tun_timeout=15
|
||||||
local tun_interval; tun_interval=1
|
local tun_interval; tun_interval=1
|
||||||
while [ "$tun_timeout" -gt 0 ]; do
|
while [ "$tun_timeout" -gt 0 ]; do
|
||||||
if (ip link show dev "$tun_device" > /dev/null 2>&1); then
|
if (ip link show dev "$tun_device" > /dev/null 2>&1); then
|
||||||
@ -242,51 +218,14 @@ service_started() {
|
|||||||
fi
|
fi
|
||||||
$FIREWALL_INCLUDE_SH
|
$FIREWALL_INCLUDE_SH
|
||||||
fi
|
fi
|
||||||
|
# hijack
|
||||||
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 -
|
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 -
|
||||||
# dns hijack
|
# check hijack
|
||||||
if [ "$ipv4_dns_hijack" == 1 ]; then
|
if (nft list tables | grep -q nikki); then
|
||||||
log "Transparent Proxy" "Hijack IPv4 dns request."
|
log "Transparent Proxy" "Hijack successful."
|
||||||
fi
|
else
|
||||||
if [ "$ipv6_dns_hijack" == 1 ]; then
|
log "Transparent Proxy" "Hijack failed."
|
||||||
log "Transparent Proxy" "Hijack IPv6 dns request."
|
log "App" "Exit."
|
||||||
fi
|
|
||||||
# proxy
|
|
||||||
if [ "$ipv4_proxy" == 1 ]; then
|
|
||||||
log "Transparent Proxy" "Proxy IPv4 traffic."
|
|
||||||
fi
|
|
||||||
if [ "$ipv6_proxy" == 1 ]; then
|
|
||||||
log "Transparent Proxy" "Proxy IPv6 traffic."
|
|
||||||
fi
|
|
||||||
# bypass
|
|
||||||
if [ -n "$bypass_user" ]; then
|
|
||||||
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
|
|
||||||
log "Transparent Proxy" "Bypass china mainland ip."
|
|
||||||
fi
|
|
||||||
log "Transparent Proxy" "Destination TCP Port to Proxy: $proxy_tcp_dport."
|
|
||||||
log "Transparent Proxy" "Destination UDP Port to Proxy: $proxy_udp_dport."
|
|
||||||
if [ -n "$bypass_dscp" ]; then
|
|
||||||
log "Transparent Proxy" "Bypass DSCP: $bypass_dscp."
|
|
||||||
fi
|
|
||||||
# router proxy
|
|
||||||
if [ "$router_proxy" == 1 ]; then
|
|
||||||
log "Transparent Proxy" "Set proxy for router."
|
|
||||||
fi
|
|
||||||
# lan proxy
|
|
||||||
if [ "$lan_proxy" == 1 ]; then
|
|
||||||
log "Transparent Proxy" "Set proxy for lan."
|
|
||||||
# access control
|
|
||||||
if [ "$access_control_mode" == "all" ]; then
|
|
||||||
log "Transparent Proxy" "Access Control is using all mode, set proxy for all client."
|
|
||||||
elif [ "$access_control_mode" == "allow" ]; then
|
|
||||||
log "Transparent Proxy" "Access Control is using allow mode, set proxy for client which is in acl."
|
|
||||||
elif [ "$access_control_mode" == "block" ]; then
|
|
||||||
log "Transparent Proxy" "Access Control is using block mode, set proxy for client which is not in acl."
|
|
||||||
fi
|
|
||||||
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
|
||||||
|
@ -16,7 +16,52 @@ uci show nikki | grep -E 'nikki.@rule\[[[:digit:]]+\].match=' | sed 's/nikki.@ru
|
|||||||
|
|
||||||
# since v1.19.1
|
# since v1.19.1
|
||||||
|
|
||||||
fake_ip_ping_hijack=$(uci -q get nikki.proxy.fake_ip_ping_hijack); [ -z "$fake_ip_ping_hijack" ] && uci set nikki.proxy.fake_ip_ping_hijack=0
|
proxy_fake_ip_ping_hijack=$(uci -q get nikki.proxy.fake_ip_ping_hijack); [ -z "$proxy_fake_ip_ping_hijack" ] && uci set nikki.proxy.fake_ip_ping_hijack=0
|
||||||
|
|
||||||
|
# since v1.20.0
|
||||||
|
|
||||||
|
mixin=$(uci -q get nikki.config.mixin); [ -n "$mixin" ] && {
|
||||||
|
uci del nikki.config.mixin
|
||||||
|
[ "$mixin" == "0" ] && {
|
||||||
|
uci del nikki.mixin.unify_delay
|
||||||
|
uci del nikki.mixin.tcp_concurrent
|
||||||
|
uci del nikki.mixin.tcp_keep_alive_idle
|
||||||
|
uci del nikki.mixin.tcp_keep_alive_interval
|
||||||
|
uci set nikki.mixin.fake_ip_filter=0
|
||||||
|
uci del nikki.mixin.fake_ip_filter_mode
|
||||||
|
uci del nikki.mixin.dns_respect_rules
|
||||||
|
uci del nikki.mixin.dns_doh_prefer_http3
|
||||||
|
uci del nikki.mixin.dns_system_hosts
|
||||||
|
uci del nikki.mixin.dns_hosts
|
||||||
|
uci set nikki.mixin.hosts=0
|
||||||
|
uci set nikki.mixin.dns_nameserver=0
|
||||||
|
uci set nikki.mixin.dns_nameserver_policy=0
|
||||||
|
uci del nikki.mixin.sniffer
|
||||||
|
uci del nikki.mixin.sniffer_sniff_dns_mapping
|
||||||
|
uci del nikki.mixin.sniffer_sniff_pure_ip
|
||||||
|
uci set nikki.mixin.sniffer_force_domain_name=0
|
||||||
|
uci set nikki.mixin.sniffer_ignore_domain_name=0
|
||||||
|
uci set nikki.mixin.sniffer_sniff=0
|
||||||
|
uci del nikki.mixin.geoip_format
|
||||||
|
uci del nikki.mixin.geodata_loader
|
||||||
|
uci del nikki.mixin.geosite_url
|
||||||
|
uci del nikki.mixin.geoip_mmdb_url
|
||||||
|
uci del nikki.mixin.geoip_dat_url
|
||||||
|
uci del nikki.mixin.geoip_asn_url
|
||||||
|
uci del nikki.mixin.geox_auto_update
|
||||||
|
uci del nikki.mixin.geox_update_interval
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin_api_port=$(uci -q get nikki.mixin.api_port); [ -n "$mixin_api_port" ] && {
|
||||||
|
uci del nikki.mixin.api_port
|
||||||
|
uci set nikki.mixin.api_listen=[::]:$mixin_api_port
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin_dns_port=$(uci -q get nikki.mixin.dns_port); [ -n "$mixin_dns_port" ] && {
|
||||||
|
uci del nikki.mixin.dns_port
|
||||||
|
uci set nikki.mixin.dns_listen=[::]:$mixin_dns_port
|
||||||
|
}
|
||||||
|
|
||||||
# commit
|
# commit
|
||||||
uci commit nikki
|
uci commit nikki
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
import { connect } from 'ubus';
|
import { connect } from 'ubus';
|
||||||
import { uci_bool, uci_array } from '/etc/nikki/ucode/include.uc';
|
import { uci_bool, uci_array } from '/etc/nikki/ucode/include.uc';
|
||||||
|
|
||||||
let users = map(split(readfile('/etc/passwd'), '\n'), (x) => split(x, ':')[0]);
|
const users = map(split(readfile('/etc/passwd'), '\n'), (x) => split(x, ':')[0]);
|
||||||
let groups = map(split(readfile('/etc/group'), '\n'), (x) => split(x, ':')[0]);
|
const groups = map(split(readfile('/etc/group'), '\n'), (x) => split(x, ':')[0]);
|
||||||
|
|
||||||
const uci = cursor();
|
const uci = cursor();
|
||||||
const ubus = connect();
|
const ubus = connect();
|
||||||
@ -19,7 +19,8 @@
|
|||||||
const redir_port = uci.get('nikki', 'mixin', 'redir_port');
|
const redir_port = uci.get('nikki', 'mixin', 'redir_port');
|
||||||
const tproxy_port = uci.get('nikki', 'mixin', 'tproxy_port');
|
const tproxy_port = uci.get('nikki', 'mixin', 'tproxy_port');
|
||||||
|
|
||||||
const dns_port = uci.get('nikki', 'mixin', 'dns_port');
|
const dns_listen = uci.get('nikki', 'mixin', 'dns_listen');
|
||||||
|
const dns_port = substr(dns_listen, rindex(dns_listen, ':') + 1);
|
||||||
const fake_ip_range = uci.get('nikki', 'mixin', 'fake_ip_range');
|
const fake_ip_range = uci.get('nikki', 'mixin', 'fake_ip_range');
|
||||||
|
|
||||||
const tun_device = uci.get('nikki', 'mixin', 'tun_device');
|
const tun_device = uci.get('nikki', 'mixin', 'tun_device');
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
export function uci_bool(obj) {
|
export function uci_bool(obj) {
|
||||||
return obj == '1';
|
return obj == null ? null : obj == '1';
|
||||||
|
};
|
||||||
|
|
||||||
|
export function uci_int(obj) {
|
||||||
|
return obj == null ? null : int(obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function uci_array(obj) {
|
export function uci_array(obj) {
|
||||||
@ -36,7 +40,7 @@ export function trim_all(obj) {
|
|||||||
delete obj[key];
|
delete obj[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (length(obj_keys) == 0) {
|
if (length(keys(obj)) == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -4,39 +4,35 @@
|
|||||||
|
|
||||||
import { cursor } from 'uci';
|
import { cursor } from 'uci';
|
||||||
import { connect } from 'ubus';
|
import { connect } from 'ubus';
|
||||||
import { uci_bool, uci_array, trim_all } from '/etc/nikki/ucode/include.uc';
|
import { uci_bool, uci_int, uci_array, trim_all } from '/etc/nikki/ucode/include.uc';
|
||||||
|
|
||||||
const uci = cursor();
|
const uci = cursor();
|
||||||
const ubus = connect();
|
const ubus = connect();
|
||||||
|
|
||||||
const config = {};
|
const config = {};
|
||||||
|
|
||||||
const mixin = uci_bool(uci.get('nikki', 'config', 'mixin'));
|
config['log-level'] = uci.get('nikki', 'mixin', 'log_level');
|
||||||
|
config['mode'] = uci.get('nikki', 'mixin', 'mode');
|
||||||
config['log-level'] = uci.get('nikki', 'mixin', 'log_level') ?? 'info';
|
config['find-process-mode'] = uci.get('nikki', 'mixin', 'match_process');
|
||||||
config['mode'] = uci.get('nikki', 'mixin', 'mode') ?? 'rule';
|
config['interface-name'] = ubus.call('network.interface', 'status', {'interface': uci.get('nikki', 'mixin', 'outbound_interface')})?.l3_device;
|
||||||
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_bool(uci.get('nikki', 'mixin', 'ipv6'));
|
config['ipv6'] = uci_bool(uci.get('nikki', 'mixin', 'ipv6'));
|
||||||
if (mixin) {
|
config['unified-delay'] = uci_bool(uci.get('nikki', 'mixin', 'unify_delay'));
|
||||||
config['unified-delay'] = uci_bool(uci.get('nikki', 'mixin', 'unify_delay'));
|
config['tcp-concurrent'] = uci_bool(uci.get('nikki', 'mixin', 'tcp_concurrent'));
|
||||||
config['tcp-concurrent'] = uci_bool(uci.get('nikki', 'mixin', 'tcp_concurrent'));
|
config['keep-alive-idle'] = uci_int(uci.get('nikki', 'mixin', 'tcp_keep_alive_idle'));
|
||||||
config['keep-alive-idle'] = int(uci.get('nikki', 'mixin', 'tcp_keep_alive_idle') ?? '600');
|
config['keep-alive-interval'] = uci_int(uci.get('nikki', 'mixin', 'tcp_keep_alive_interval'));
|
||||||
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'] = uci.get('nikki', 'mixin', 'ui_path');
|
||||||
config['external-ui-name'] = uci.get('nikki', 'mixin', 'ui_name') ?? '';
|
config['external-ui-name'] = uci.get('nikki', 'mixin', 'ui_name');
|
||||||
config['external-ui-url'] = uci.get('nikki', 'mixin', 'ui_url');
|
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['external-controller'] = uci.get('nikki', 'mixin', 'api_listen');
|
||||||
config['secret'] = uci.get('nikki', 'mixin', 'api_secret') ?? '666666';
|
config['secret'] = uci.get('nikki', 'mixin', 'api_secret');
|
||||||
|
|
||||||
config['allow-lan'] = uci_bool(uci.get('nikki', 'mixin', 'allow_lan'));
|
config['allow-lan'] = uci_bool(uci.get('nikki', 'mixin', 'allow_lan'));
|
||||||
config['port'] = int(uci.get('nikki', 'mixin', 'http_port') ?? '8080');
|
config['port'] = uci_int(uci.get('nikki', 'mixin', 'http_port'));
|
||||||
config['socks-port'] = int(uci.get('nikki', 'mixin', 'socks_port') ?? '1080');
|
config['socks-port'] = uci_int(uci.get('nikki', 'mixin', 'socks_port'));
|
||||||
config['mixed-port'] = int(uci.get('nikki', 'mixin', 'mixed_port') ?? '7890');
|
config['mixed-port'] = uci_int(uci.get('nikki', 'mixin', 'mixed_port'));
|
||||||
config['redir-port'] = int(uci.get('nikki', 'mixin', 'redir_port') ?? '7891');
|
config['redir-port'] = uci_int(uci.get('nikki', 'mixin', 'redir_port'));
|
||||||
config['tproxy-port'] = int(uci.get('nikki', 'mixin', 'tproxy_port') ?? '7892');
|
config['tproxy-port'] = uci_int(uci.get('nikki', 'mixin', 'tproxy_port'));
|
||||||
|
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'authentication'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'authentication'))) {
|
||||||
config['authentication'] = [];
|
config['authentication'] = [];
|
||||||
@ -54,11 +50,11 @@ if (uci.get('nikki', 'proxy', 'tcp_transparent_proxy_mode') == 'tun' || uci.get(
|
|||||||
config['tun']['auto-route'] = false;
|
config['tun']['auto-route'] = false;
|
||||||
config['tun']['auto-redirect'] = false;
|
config['tun']['auto-redirect'] = false;
|
||||||
config['tun']['auto-detect-interface'] = false;
|
config['tun']['auto-detect-interface'] = false;
|
||||||
config['tun']['device'] = uci.get('nikki', 'mixin', 'tun_device') ?? 'nikki';
|
config['tun']['device'] = uci.get('nikki', 'mixin', 'tun_device');
|
||||||
config['tun']['stack'] = uci.get('nikki', 'mixin', 'tun_stack') ?? 'system';
|
config['tun']['stack'] = uci.get('nikki', 'mixin', 'tun_stack');
|
||||||
config['tun']['mtu'] = int(uci.get('nikki', 'mixin', 'tun_mtu') ?? '9000');
|
config['tun']['mtu'] = uci_int(uci.get('nikki', 'mixin', 'tun_mtu'));
|
||||||
config['tun']['gso'] = uci_bool(uci.get('nikki', 'mixin', 'tun_gso'));
|
config['tun']['gso'] = uci_bool(uci.get('nikki', 'mixin', 'tun_gso'));
|
||||||
config['tun']['gso-max-size'] = int(uci.get('nikki', 'mixin', 'tun_gso_max_size') ?? '65536');
|
config['tun']['gso-max-size'] = uci_int(uci.get('nikki', 'mixin', 'tun_gso_max_size'));
|
||||||
config['tun']['endpoint-independent-nat'] = uci_bool(uci.get('nikki', 'mixin', 'tun_endpoint_independent_nat'));
|
config['tun']['endpoint-independent-nat'] = uci_bool(uci.get('nikki', 'mixin', 'tun_endpoint_independent_nat'));
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'tun_dns_hijack'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'tun_dns_hijack'))) {
|
||||||
config['tun']['dns-hijack'] = uci_array(uci.get('nikki', 'mixin', 'tun_dns_hijacks'));
|
config['tun']['dns-hijack'] = uci_array(uci.get('nikki', 'mixin', 'tun_dns_hijacks'));
|
||||||
@ -69,20 +65,20 @@ if (uci.get('nikki', 'proxy', 'tcp_transparent_proxy_mode') == 'tun' || uci.get(
|
|||||||
|
|
||||||
config['dns'] = {};
|
config['dns'] = {};
|
||||||
config['dns']['enable'] = true;
|
config['dns']['enable'] = true;
|
||||||
config['dns']['listen'] = '0.0.0.0' + ':' + (uci.get('nikki', 'mixin', 'dns_port') ?? '1053');
|
config['dns']['listen'] = uci.get('nikki', 'mixin', 'dns_listen');
|
||||||
config['dns']['ipv6'] = uci_bool(uci.get('nikki', 'mixin', 'dns_ipv6'));
|
config['dns']['ipv6'] = uci_bool(uci.get('nikki', 'mixin', 'dns_ipv6'));
|
||||||
config['dns']['enhanced-mode'] = uci.get('nikki', 'mixin', 'dns_mode') ?? 'redir-host';
|
config['dns']['enhanced-mode'] = uci.get('nikki', 'mixin', 'dns_mode');
|
||||||
config['dns']['fake-ip-range'] = uci.get('nikki', 'mixin', 'fake_ip_range') ?? '198.18.0.1/16';
|
config['dns']['fake-ip-range'] = uci.get('nikki', 'mixin', 'fake_ip_range');
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'fake_ip_filter'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'fake_ip_filter'))) {
|
||||||
config['dns']['fake-ip-filter'] = uci_array(uci.get('nikki', 'mixin', 'fake_ip_filters'));
|
config['dns']['fake-ip-filter'] = uci_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']['fake-ip-filter-mode'] = uci.get('nikki', 'mixin', 'fake_ip_filter_mode');
|
||||||
config['dns']['respect-rules'] = uci_bool(uci.get('nikki', 'mixin', 'dns_respect_rules'));
|
|
||||||
config['dns']['prefer-h3'] = uci_bool(uci.get('nikki', 'mixin', 'dns_doh_prefer_http3'));
|
config['dns']['respect-rules'] = uci_bool(uci.get('nikki', 'mixin', 'dns_respect_rules'));
|
||||||
config['dns']['use-system-hosts'] = uci_bool(uci.get('nikki', 'mixin', 'dns_system_hosts'));
|
config['dns']['prefer-h3'] = uci_bool(uci.get('nikki', 'mixin', 'dns_doh_prefer_http3'));
|
||||||
config['dns']['use-hosts'] = uci_bool(uci.get('nikki', 'mixin', 'dns_hosts'));
|
config['dns']['use-system-hosts'] = uci_bool(uci.get('nikki', 'mixin', 'dns_system_hosts'));
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'hosts'))) {
|
config['dns']['use-hosts'] = uci_bool(uci.get('nikki', 'mixin', 'dns_hosts'));
|
||||||
|
if (uci_bool(uci.get('nikki', 'mixin', 'hosts'))) {
|
||||||
config['hosts'] = {};
|
config['hosts'] = {};
|
||||||
uci.foreach('nikki', 'hosts', (section) => {
|
uci.foreach('nikki', 'hosts', (section) => {
|
||||||
if (!uci_bool(section.enabled)) {
|
if (!uci_bool(section.enabled)) {
|
||||||
@ -90,8 +86,8 @@ if (mixin) {
|
|||||||
}
|
}
|
||||||
config['hosts'][section.domain_name] = uci_array(section.ip);
|
config['hosts'][section.domain_name] = uci_array(section.ip);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'dns_nameserver'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'dns_nameserver'))) {
|
||||||
config['dns']['default-nameserver'] = [];
|
config['dns']['default-nameserver'] = [];
|
||||||
config['dns']['proxy-server-nameserver'] = [];
|
config['dns']['proxy-server-nameserver'] = [];
|
||||||
config['dns']['direct-nameserver'] = [];
|
config['dns']['direct-nameserver'] = [];
|
||||||
@ -103,8 +99,8 @@ if (mixin) {
|
|||||||
}
|
}
|
||||||
push(config['dns'][section.type], ...uci_array(section.nameserver));
|
push(config['dns'][section.type], ...uci_array(section.nameserver));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'dns_nameserver_policy'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'dns_nameserver_policy'))) {
|
||||||
config['dns']['nameserver-policy'] = {};
|
config['dns']['nameserver-policy'] = {};
|
||||||
uci.foreach('nikki', 'nameserver_policy', (section) => {
|
uci.foreach('nikki', 'nameserver_policy', (section) => {
|
||||||
if (!uci_bool(section.enabled)) {
|
if (!uci_bool(section.enabled)) {
|
||||||
@ -112,22 +108,19 @@ if (mixin) {
|
|||||||
}
|
}
|
||||||
config['dns']['nameserver-policy'][section.matcher] = uci_array(section.nameserver);
|
config['dns']['nameserver-policy'][section.matcher] = uci_array(section.nameserver);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mixin) {
|
config['sniffer'] = {};
|
||||||
config['sniffer'] = {};
|
config['sniffer']['enable'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer'));
|
||||||
config['sniffer']['enable'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer'));
|
config['sniffer']['force-dns-mapping'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer_sniff_dns_mapping'));
|
||||||
config['sniffer']['force-dns-mapping'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer_sniff_dns_mapping'));
|
config['sniffer']['parse-pure-ip'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer_sniff_pure_ip'));
|
||||||
config['sniffer']['parse-pure-ip'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer_sniff_pure_ip'));
|
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_force_domain_name'))) {
|
||||||
config['sniffer']['override-destination'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer_overwrite_destination'));
|
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_force_domain_name'))) {
|
|
||||||
config['sniffer']['force-domain'] = uci_array(uci.get('nikki', 'mixin', 'sniffer_force_domain_names'));
|
config['sniffer']['force-domain'] = uci_array(uci.get('nikki', 'mixin', 'sniffer_force_domain_names'));
|
||||||
}
|
}
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_ignore_domain_name'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_ignore_domain_name'))) {
|
||||||
config['sniffer']['skip-domain'] = uci_array(uci.get('nikki', 'mixin', 'sniffer_ignore_domain_names'));
|
config['sniffer']['skip-domain'] = uci_array(uci.get('nikki', 'mixin', 'sniffer_ignore_domain_names'));
|
||||||
}
|
}
|
||||||
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_sniff'))) {
|
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_sniff'))) {
|
||||||
config['sniffer']['sniff'] = {};
|
config['sniffer']['sniff'] = {};
|
||||||
config['sniffer']['sniff']['HTTP'] = {};
|
config['sniffer']['sniff']['HTTP'] = {};
|
||||||
config['sniffer']['sniff']['TLS'] = {};
|
config['sniffer']['sniff']['TLS'] = {};
|
||||||
@ -139,7 +132,6 @@ if (mixin) {
|
|||||||
config['sniffer']['sniff'][section.protocol]['port'] = uci_array(section.port);
|
config['sniffer']['sniff'][section.protocol]['port'] = uci_array(section.port);
|
||||||
config['sniffer']['sniff'][section.protocol]['override-destination'] = uci_bool(section.overwrite_destination);
|
config['sniffer']['sniff'][section.protocol]['override-destination'] = uci_bool(section.overwrite_destination);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
config['profile'] = {};
|
config['profile'] = {};
|
||||||
@ -178,29 +170,19 @@ if (uci_bool(uci.get('nikki', 'mixin', 'rule'))) {
|
|||||||
if (!uci_bool(section.enabled)) {
|
if (!uci_bool(section.enabled)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let rule;
|
push(config['nikki-rules'], `${section.type},${section.matcher},${section.node}` + (uci_bool(section.no_resolve) ? ',no_resolve' : ''));
|
||||||
if (length(section.type) > 0) {
|
|
||||||
rule = `${section.type},${section.matcher},${section.node}`;
|
|
||||||
} else {
|
|
||||||
rule = `${section.matcher},${section.node}`;
|
|
||||||
}
|
|
||||||
if (uci_bool(section.no_resolve)) {
|
|
||||||
rule += ',no_resolve';
|
|
||||||
}
|
|
||||||
push(config['nikki-rules'], rule);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mixin) {
|
const geoip_format = uci.get('nikki', 'mixin', 'geoip_format');
|
||||||
config['geodata-mode'] = uci.get('nikki', 'mixin', 'geoip_format') == 'dat';
|
config['geodata-mode'] = geoip_format == null ? null : geoip_format == 'dat';
|
||||||
config['geodata-loader'] = uci.get('nikki', 'mixin', 'geodata_loader') ?? 'memconservative';
|
config['geodata-loader'] = uci.get('nikki', 'mixin', 'geodata_loader');
|
||||||
config['geox-url'] = {};
|
config['geox-url'] = {};
|
||||||
config['geox-url']['geosite'] = uci.get('nikki', 'mixin', 'geosite_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']['mmdb'] = uci.get('nikki', 'mixin', 'geoip_mmdb_url');
|
||||||
config['geox-url']['geoip'] = uci.get('nikki', 'mixin', 'geoip_dat_url');
|
config['geox-url']['geoip'] = uci.get('nikki', 'mixin', 'geoip_dat_url');
|
||||||
config['geox-url']['asn'] = uci.get('nikki', 'mixin', 'geoip_asn_url');
|
config['geox-url']['asn'] = uci.get('nikki', 'mixin', 'geoip_asn_url');
|
||||||
config['geo-auto-update'] = uci_bool(uci.get('nikki', 'mixin', 'geox_auto_update'));
|
config['geo-auto-update'] = uci_bool(uci.get('nikki', 'mixin', 'geox_auto_update'));
|
||||||
config['geo-update-interval'] = int(uci.get('nikki', 'mixin', 'geox_update_interval') ?? '24');
|
config['geo-update-interval'] = uci_int(uci.get('nikki', 'mixin', 'geox_update_interval'));
|
||||||
}
|
|
||||||
|
|
||||||
print(trim_all(config));
|
print(trim_all(config));
|
Loading…
Reference in New Issue
Block a user