nikki: sync upstream

last commit: 1bb4fcdd4b
This commit is contained in:
gitea-action 2025-03-03 22:30:24 +08:00
parent c725691965
commit cdcbb246ef
7 changed files with 169 additions and 228 deletions

View File

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

View File

@ -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'

View File

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

View File

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

View File

@ -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');

View File

@ -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;

View File

@ -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'] = int(uci.get('nikki', 'mixin', 'tcp_keep_alive_idle') ?? '600'); config['keep-alive-idle'] = uci_int(uci.get('nikki', 'mixin', 'tcp_keep_alive_idle'));
config['keep-alive-interval'] = int(uci.get('nikki', 'mixin', 'tcp_keep_alive_interval') ?? '15'); config['keep-alive-interval'] = uci_int(uci.get('nikki', 'mixin', 'tcp_keep_alive_interval'));
}
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,15 +65,15 @@ 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']['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']['prefer-h3'] = uci_bool(uci.get('nikki', 'mixin', 'dns_doh_prefer_http3'));
config['dns']['use-system-hosts'] = uci_bool(uci.get('nikki', 'mixin', 'dns_system_hosts')); config['dns']['use-system-hosts'] = uci_bool(uci.get('nikki', 'mixin', 'dns_system_hosts'));
@ -113,14 +109,11 @@ 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'));
config['sniffer']['override-destination'] = uci_bool(uci.get('nikki', 'mixin', 'sniffer_overwrite_destination'));
if (uci_bool(uci.get('nikki', 'mixin', 'sniffer_force_domain_name'))) { 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'));
} }
@ -140,7 +133,6 @@ if (mixin) {
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'] = {};
config['profile']['store-selected'] = uci_bool(uci.get('nikki', 'mixin', 'selection_cache')); config['profile']['store-selected'] = uci_bool(uci.get('nikki', 'mixin', 'selection_cache'));
@ -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));