nikki: sync upstream

last commit: 0df3fc2941
This commit is contained in:
gitea-action 2025-04-12 13:30:27 +08:00
parent 30cf173156
commit 73586f1afa
7 changed files with 382 additions and 267 deletions

View File

@ -5,9 +5,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git
PKG_SOURCE_DATE:=2025-04-06
PKG_SOURCE_VERSION:=9e8f4ada4754ae95b002535acbeb457e40b06731
PKG_MIRROR_HASH:=1c8a7d70de0cb903b58eca1937b6561003cae7e76f9f021fd3eb9007b6a1f65f
PKG_SOURCE_DATE:=2025-04-12
PKG_SOURCE_VERSION:=cedb36df5fe58d5d972b1507c1ab656aca5f046d
PKG_MIRROR_HASH:=b2f9fe4e2ebd38036eac0f2c5af79362cb2afbb780c36c236259ecace9db11da
PKG_LICENSE:=GPL3.0+
PKG_MAINTAINER:=Joseph Mory <morytyann@gmail.com>
@ -16,7 +16,7 @@ PKG_BUILD_DEPENDS:=golang/host
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=no-mips16
PKG_BUILD_VERSION:=alpha-9e8f4ad
PKG_BUILD_VERSION:=alpha-cedb36d
PKG_BUILD_TIME:=$(shell date -u -Iseconds)
GO_PKG:=github.com/metacubex/mihomo

View File

@ -10,9 +10,9 @@ config config 'config'
option 'test_profile' '1'
config proxy 'proxy'
option 'transparent_proxy' '1'
option 'tcp_transparent_proxy_mode' 'redirect'
option 'udp_transparent_proxy_mode' 'tun'
option 'enabled' '1'
option 'tcp_mode' 'redirect'
option 'udp_mode' 'tun'
option 'ipv4_dns_hijack' '1'
option 'ipv6_dns_hijack' '1'
option 'ipv4_proxy' '1'
@ -20,30 +20,7 @@ config proxy 'proxy'
option 'fake_ip_ping_hijack' '1'
option 'router_proxy' '1'
option 'lan_proxy' '1'
option 'access_control_mode' 'all'
option 'acl_ip' ''
option 'acl_ip6' ''
option 'acl_mac' ''
option 'acl_interface' ''
list 'bypass_user' 'dnsmasq'
list 'bypass_user' 'ftp'
list 'bypass_user' 'logd'
list 'bypass_user' 'nobody'
list 'bypass_user' 'ntp'
list 'bypass_user' 'ubus'
list 'bypass_group' 'dnsmasq'
list 'bypass_group' 'ftp'
list 'bypass_group' 'logd'
list 'bypass_group' 'nogroup'
list 'bypass_group' 'ntp'
list 'bypass_group' 'ubus'
list 'bypass_cgroup' 'adguardhome'
list 'bypass_cgroup' 'aria2'
list 'bypass_cgroup' 'dnsmasq'
list 'bypass_cgroup' 'netbird'
list 'bypass_cgroup' 'qbittorrent'
list 'bypass_cgroup' 'tailscale'
list 'bypass_cgroup' 'zerotier'
list 'lan_inbound_interface' 'lan'
list 'bypass_dscp' '4'
option 'bypass_china_mainland_ip' '0'
option 'proxy_tcp_dport' '0-65535'
@ -100,6 +77,38 @@ config env 'env'
option 'disable_quic_go_gso' '0'
option 'disable_quic_go_ecn' '0'
config router_access_control
option 'enabled' '1'
list 'user' 'dnsmasq'
list 'user' 'ftp'
list 'user' 'logd'
list 'user' 'nobody'
list 'user' 'ntp'
list 'user' 'ubus'
list 'group' 'dnsmasq'
list 'group' 'ftp'
list 'group' 'logd'
list 'group' 'nogroup'
list 'group' 'ntp'
list 'group' 'ubus'
list 'cgroup' 'adguardhome'
list 'cgroup' 'aria2'
list 'cgroup' 'dnsmasq'
list 'cgroup' 'netbird'
list 'cgroup' 'qbittorrent'
list 'cgroup' 'sysntpd'
list 'cgroup' 'tailscale'
list 'cgroup' 'zerotier'
option 'proxy' '0'
config router_access_control
option 'enabled' '1'
option 'proxy' '1'
config lan_access_control
option 'enabled' '1'
option 'proxy' '1'
config authentication
option 'enabled' '1'
option 'username' 'nikki'

View File

@ -143,11 +143,11 @@ service_started() {
fi
# load config
config_load nikki
# check if transparent proxy enabled
local transparent_proxy
config_get_bool transparent_proxy "proxy" "transparent_proxy" 0
if [ "$transparent_proxy" == 0 ]; then
log "Transparent Proxy" "Disabled."
# check if proxy enabled
local enabled
config_get_bool enabled "proxy" "enabled" 0
if [ "$enabled" == 0 ]; then
log "Proxy" "Disabled."
return
fi
# get config
@ -156,19 +156,19 @@ service_started() {
local tun_device
config_get tun_device "mixin" "tun_device" "nikki"
## proxy config
### transparent 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"
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode"
### general
local tcp_mode udp_mode ipv4_proxy ipv6_proxy
config_get tcp_mode "proxy" "tcp_mode"
config_get udp_mode "proxy" "udp_mode"
config_get_bool ipv4_proxy "proxy" "ipv4_proxy" 0
config_get_bool ipv6_proxy "proxy" "ipv6_proxy" 0
# prepare config
local tproxy_enable; tproxy_enable=0
if [[ "$tcp_transparent_proxy_mode" == "tproxy" || "$udp_transparent_proxy_mode" == "tproxy" ]]; then
if [[ "$tcp_mode" == "tproxy" || "$udp_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
if [[ "$tcp_mode" == "tun" || "$udp_mode" == "tun" ]]; then
tun_enable=1
fi
# fix compatible with dockerd
@ -197,17 +197,17 @@ service_started() {
fi
fi
fi
# transparent proxy
log "Transparent Proxy" "Enabled."
# proxy
log "Proxy" "Enabled."
# wait for tun device online
if [ "$tun_enable" == 1 ]; then
log "Transparent Proxy" "Waiting for tun device online..."
log "Proxy" "Waiting for tun device online..."
local tun_timeout; tun_timeout=15
local tun_interval; tun_interval=1
while [ "$tun_timeout" -gt 0 ]; do
if (ip link show dev "$tun_device" > /dev/null 2>&1); then
if [ $(ip -json addr show dev "$tun_device" | tun_device="$tun_device" yq -M '.[] | select(.ifname = strenv(tun_device)) | .addr_info | length') -gt 0 ]; then
log "Transparent Proxy" "Tun device is online."
log "Proxy" "Tun device is online."
break
fi
fi
@ -215,7 +215,7 @@ service_started() {
sleep "$tun_interval"
done
if [ "$tun_timeout" -le 0 ]; then
log "Transparent Proxy" "Waiting timeout, tun device is not online."
log "Proxy" "Waiting timeout, tun device is not online."
log "App" "Exit."
return
fi
@ -246,9 +246,9 @@ service_started() {
utpl -D cgroup_name="$CGROUP_NAME" -D cgroup_id="$CGROUP_ID" -D tproxy_fw_mark="$TPROXY_FW_MARK" -D tun_fw_mark="$TUN_FW_MARK" -S "$HIJACK_UT" | nft -f -
# check hijack
if (nft list tables | grep -q nikki); then
log "Transparent Proxy" "Hijack successful."
log "Proxy" "Hijack successful."
else
log "Transparent Proxy" "Hijack failed."
log "Proxy" "Hijack failed."
log "App" "Exit."
fi
}

View File

@ -5,11 +5,11 @@
config_load nikki
config_get enabled "config" "enabled" 0
config_get tcp_transparent_proxy_mode "proxy" "tcp_transparent_proxy_mode"
config_get udp_transparent_proxy_mode "proxy" "udp_transparent_proxy_mode"
config_get tcp_mode "proxy" "tcp_mode"
config_get udp_mode "proxy" "udp_mode"
config_get tun_device "mixin" "tun_device"
if [ "$enabled" == 1 ] && [[ "$tcp_transparent_proxy_mode" == "tun" || "$udp_transparent_proxy_mode" == "tun" ]]; then
if [ "$enabled" == 1 ] && [[ "$tcp_mode" == "tun" || "$udp_mode" == "tun" ]]; then
nft insert rule inet fw4 input iifname "$tun_device" counter accept comment "nikki"
nft insert rule inet fw4 forward oifname "$tun_device" counter accept comment "nikki"
nft insert rule inet fw4 forward iifname "$tun_device" counter accept comment "nikki"

View File

@ -30,6 +30,82 @@ mixin_dns_port=$(uci -q get nikki.mixin.dns_port); [ -n "$mixin_dns_port" ] && {
uci set nikki.mixin.dns_listen=[::]:$mixin_dns_port
}
# since v1.22.0
proxy_transparent_proxy=$(uci -q get nikki.proxy.transparent_proxy); [ -n "$proxy_transparent_proxy" ] && {
uci rename nikki.proxy.transparent_proxy=enabled
uci rename nikki.proxy.tcp_transparent_proxy_mode=tcp_mode
uci rename nikki.proxy.udp_transparent_proxy_mode=udp_mode
uci add nikki router_access_control
uci set nikki.@router_access_control[-1].enabled=1
proxy_bypass_user=$(uci -q get nikki.proxy.bypass_user); [ -n "$proxy_bypass_user" ] && {
for user in $proxy_bypass_user; do
uci add_list nikki.@router_access_control[-1].user="$user"
done
}
proxy_bypass_group=$(uci -q get nikki.proxy.bypass_group); [ -n "$proxy_bypass_group" ] && {
for group in $proxy_bypass_group; do
uci add_list nikki.@router_access_control[-1].group="$group"
done
}
proxy_bypass_cgroup=$(uci -q get nikki.proxy.bypass_cgroup); [ -n "$proxy_bypass_cgroup" ] && {
for cgroup in $proxy_bypass_cgroup; do
uci add_list nikki.@router_access_control[-1].cgroup="$cgroup"
done
}
uci set nikki.@router_access_control[-1].proxy=0
uci add nikki router_access_control
uci set nikki.@router_access_control[-1].enabled=1
uci set nikki.@router_access_control[-1].proxy=1
uci add_list nikki.proxy.lan_inbound_interface=lan
proxy_access_control_mode=$(uci -q get nikki.proxy.access_control_mode); [ "$proxy_access_control_mode" != "all" ] && {
proxy_acl_ip=$(uci -q get nikki.proxy.acl_ip); [ -n "$proxy_acl_ip" ] && {
for ip in $proxy_acl_ip; do
uci add nikki lan_access_control
uci set nikki.@lan_access_control[-1].enabled=1
uci add_list nikki.@lan_access_control[-1].ip="$ip"
[ "$proxy_access_control_mode" == "allow" ] && uci set nikki.@lan_access_control[-1].proxy=1
[ "$proxy_access_control_mode" == "block" ] && uci set nikki.@lan_access_control[-1].proxy=0
done
}
proxy_acl_ip6=$(uci -q get nikki.proxy.acl_ip6); [ -n "$proxy_acl_ip6" ] && {
for ip6 in $proxy_acl_ip6; do
uci add nikki lan_access_control
uci set nikki.@lan_access_control[-1].enabled=1
uci add_list nikki.@lan_access_control[-1].ip6="$ip6"
[ "$proxy_access_control_mode" == "allow" ] && uci set nikki.@lan_access_control[-1].proxy=1
[ "$proxy_access_control_mode" == "block" ] && uci set nikki.@lan_access_control[-1].proxy=0
done
}
proxy_acl_mac=$(uci -q get nikki.proxy.acl_mac); [ -n "$proxy_acl_mac" ] && {
for mac in $proxy_acl_mac; do
uci add nikki lan_access_control
uci set nikki.@lan_access_control[-1].enabled=1
uci add_list nikki.@lan_access_control[-1].mac="$mac"
[ "$proxy_access_control_mode" == "allow" ] && uci set nikki.@lan_access_control[-1].proxy=1
[ "$proxy_access_control_mode" == "block" ] && uci set nikki.@lan_access_control[-1].proxy=0
done
}
[ "$proxy_access_control_mode" == "block" ] && {
uci add nikki lan_access_control
uci set nikki.@lan_access_control[-1].enabled=1
uci set nikki.@lan_access_control[-1].proxy=1
}
}
uci del nikki.proxy.access_control_mode
uci del nikki.proxy.acl_ip
uci del nikki.proxy.acl_ip6
uci del nikki.proxy.acl_mac
uci del nikki.proxy.acl_interface
uci del nikki.proxy.bypass_user
uci del nikki.proxy.bypass_group
uci del nikki.proxy.bypass_cgroup
}
# commit
uci commit nikki

View File

@ -27,32 +27,43 @@
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 tcp_mode = uci.get('nikki', 'proxy', 'tcp_mode');
const udp_mode = uci.get('nikki', 'proxy', 'udp_mode');
const ipv4_dns_hijack = uci_bool(uci.get('nikki', 'proxy', 'ipv4_dns_hijack'));
const ipv6_dns_hijack = uci_bool(uci.get('nikki', 'proxy', 'ipv6_dns_hijack'));
const ipv4_proxy = uci_bool(uci.get('nikki', 'proxy', 'ipv4_proxy'));
const ipv6_proxy = uci_bool(uci.get('nikki', 'proxy', 'ipv6_proxy'));
const fake_ip_ping_hijack = uci_bool(uci.get('nikki', 'proxy', 'fake_ip_ping_hijack'));
const router_proxy = uci_bool(uci.get('nikki', 'proxy', 'router_proxy'));
const router_access_control = [];
uci.foreach('nikki', 'router_access_control', (access_control) => {
access_control['enabled'] = uci_bool(access_control['enabled']);
access_control['user'] = filter(uci_array(access_control['user']), (x) => index(users, x) >= 0);
access_control['group'] = filter(uci_array(access_control['group']), (x) => index(groups, x) >= 0);
access_control['cgroup'] = filter(uci_array(access_control['cgroup']), (x) => index(cgroups, x) >= 0);
access_control['proxy'] = uci_bool(access_control['proxy']);
push(router_access_control, access_control);
});
const lan_proxy = uci_bool(uci.get('nikki', 'proxy', 'lan_proxy'));
const access_control_mode = uci.get('nikki', 'proxy', 'access_control_mode');
const acl_ip = uci_array(uci.get('nikki', 'proxy', 'acl_ip'));
const acl_ip6 = uci_array(uci.get('nikki', 'proxy', 'acl_ip6'));
const acl_mac = uci_array(uci.get('nikki', 'proxy', 'acl_mac'));
const acl_interface = uci_array(uci.get('nikki', 'proxy', 'acl_interface'));
const bypass_user = filter(uci_array(uci.get('nikki', 'proxy', 'bypass_user')), (x) => x != 'root' && index(users, x) >= 0);
const bypass_group = filter(uci_array(uci.get('nikki', 'proxy', 'bypass_group')), (x) => x != 'root' && index(groups, x) >= 0);
let bypass_cgroup = [];
if (cgroups_version == 1) {
push(bypass_cgroup, cgroup_id);
} else if (cgroups_version == 2) {
bypass_cgroup = filter(uci_array(uci.get('nikki', 'proxy', 'bypass_cgroup')), (x) => x != 'nikki' && index(cgroups, x) >= 0);
push(bypass_cgroup, cgroup_name);
const lan_inbound_interface = uci_array(uci.get('nikki', 'proxy', 'lan_inbound_interface'));
const lan_inbound_device = [];
for (let interface in lan_inbound_interface) {
const device = ubus.call('network.interface', 'status', {'interface': interface})?.l3_device ?? '';
if (device != '') {
push(lan_inbound_device, device);
}
}
const lan_access_control = [];
uci.foreach('nikki', 'lan_access_control', (access_control) => {
access_control['enabled'] = uci_bool(access_control['enabled']);
access_control['ip'] = uci_array(access_control['ip']);
access_control['ip6'] = uci_array(access_control['ip6']);
access_control['mac'] = uci_array(access_control['mac']);
access_control['proxy'] = uci_bool(access_control['proxy']);
push(lan_access_control, access_control);
});
const bypass_dscp = uci_array(uci.get('nikki', 'proxy', 'bypass_dscp'));
const bypass_china_mainland_ip = uci_bool(uci.get('nikki', 'proxy', 'bypass_china_mainland_ip'));
@ -67,14 +78,6 @@
push(dns_hijack_nfproto, 'ipv6');
}
const acl_device = [];
for (let i = 0; i < length(acl_interface); i++) {
const device = ubus.call('network.interface', 'status', {'interface': acl_interface[i]})?.l3_device ?? '';
if (device != '') {
push(acl_device, device);
}
}
const proxy_nfproto = [];
if (ipv4_proxy) {
push(proxy_nfproto, 'ipv4');
@ -98,8 +101,8 @@ table inet nikki {
flags interval
{% if (length(dns_hijack_nfproto) > 0): %}
elements = {
{% for (let x in dns_hijack_nfproto): %}
{{ x }},
{% for (let nfproto in dns_hijack_nfproto): %}
{{ nfproto }},
{% endfor %}
}
{% endif %}
@ -110,67 +113,13 @@ table inet nikki {
flags interval
{% if (length(proxy_nfproto) > 0): %}
elements = {
{% for (let x in proxy_nfproto): %}
{{ x }},
{% for (let nfproto in proxy_nfproto): %}
{{ nfproto }},
{% endfor %}
}
{% endif %}
}
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 %}
}
{% if (cgroups_version == 1): %}
set bypass_cgroup {
typeof meta cgroup
flags interval
auto-merge
{% if (length(bypass_cgroup) > 0): %}
elements = {
{% for (let x in bypass_cgroup): %}
{{ x }},
{% endfor %}
}
{% endif %}
}
{% elif (cgroups_version == 2): %}
set bypass_cgroup {
type cgroupsv2
flags interval
auto-merge
{% if (length(bypass_cgroup) > 0): %}
elements = {
{% for (let x in bypass_cgroup): %}
services/{{ x }},
{% endfor %}
}
{% endif %}
}
{% endif %}
set reserved_ip {
type ipv4_addr
flags interval
@ -183,6 +132,19 @@ table inet nikki {
auto-merge
}
set lan_inbound_device {
type ifname
flags interval
auto-merge
{% if (length(lan_inbound_device) > 0): %}
elements = {
{% for (let device in lan_inbound_device): %}
{{ device }},
{% endfor %}
}
{% endif %}
}
set china_ip {
type ipv4_addr
flags interval
@ -199,8 +161,8 @@ table inet nikki {
auto-merge
{% if (length(proxy_dport) > 0): %}
elements = {
{% for (let x in proxy_dport): %}
{{ x }},
{% for (let dport in proxy_dport): %}
{{ dport }},
{% endfor %}
}
{% endif %}
@ -212,145 +174,215 @@ table inet nikki {
auto-merge
{% if (length(bypass_dscp) > 0): %}
elements = {
{% for (let x in bypass_dscp): %}
{{ x }},
{% for (let dscp in bypass_dscp): %}
{{ dscp }},
{% 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 %}
}
chain router_dns_hijack {
{% for (let access_control in router_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['user']) == 0 && length(access_control['group']) == 0 && length(access_control['cgroup']) == 0): %}
meta l4proto { tcp, udp } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% else %}
{% if (length(access_control['user']) > 0): %}
meta l4proto { tcp, udp } meta skuid { {% for (let user in access_control['user']): %} {{ user }}, {% endfor %} } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% endif %}
{% if (length(access_control['group']) > 0): %}
meta l4proto { tcp, udp } meta skgid { {% for (let group in access_control['group']): %} {{ group }}, {% endfor %} } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% endif %}
{% if (cgroups_version == 2 && length(access_control['cgroup']) > 0): %}
meta l4proto { tcp, udp } socket cgroupv2 level 2 { {% for (let cgroup in access_control['cgroup']): %} services/{{ cgroup }}, {% endfor %} } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
set acl_ip6 {
type ipv6_addr
flags interval
auto-merge
{% if (length(acl_ip6) > 0): %}
elements = {
{% for (let x in acl_ip6): %}
{{ x }},
{% endfor %}
}
chain router_redirect {
{% for (let access_control in router_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['user']) == 0 && length(access_control['group']) == 0 && length(access_control['cgroup']) == 0): %}
meta l4proto tcp counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% else %}
{% if (length(access_control['user']) > 0): %}
meta l4proto tcp meta skuid { {% for (let user in access_control['user']): %} {{ user }}, {% endfor %} } counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% endif %}
{% if (length(access_control['group']) > 0): %}
meta l4proto tcp meta skgid { {% for (let group in access_control['group']): %} {{ group }}, {% endfor %} } counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% endif %}
{% if (cgroups_version == 2 && length(access_control['cgroup']) > 0): %}
meta l4proto tcp socket cgroupv2 level 2 { {% for (let cgroup in access_control['cgroup']): %} services/{{ cgroup }}, {% endfor %} } counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
set acl_mac {
type ether_addr
flags interval
auto-merge
{% if (length(acl_mac) > 0): %}
elements = {
{% for (let x in acl_mac): %}
{{ x }},
{% endfor %}
}
chain router_tproxy {
{% for (let access_control in router_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['user']) == 0 && length(access_control['group']) == 0 && length(access_control['cgroup']) == 0): %}
meta l4proto { tcp, udp } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% else %}
{% if (length(access_control['user']) > 0): %}
meta l4proto { tcp, udp } meta skuid { {% for (let user in access_control['user']): %} {{ user }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% if (length(access_control['group']) > 0): %}
meta l4proto { tcp, udp } meta skgid { {% for (let group in access_control['group']): %} {{ group }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% if (cgroups_version == 2 && length(access_control['cgroup']) > 0): %}
meta l4proto { tcp, udp } socket cgroupv2 level 2 { {% for (let cgroup in access_control['cgroup']): %} services/{{ cgroup }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
set acl_device {
type ifname
flags interval
auto-merge
{% if (length(acl_device) > 0): %}
elements = {
{% for (let x in acl_device): %}
{{ x }},
{% endfor %}
}
chain router_tun {
{% for (let access_control in router_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['user']) == 0 && length(access_control['group']) == 0 && length(access_control['cgroup']) == 0): %}
meta l4proto { tcp, udp } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %} counter return {% endif %}
{% else %}
{% if (length(access_control['user']) > 0): %}
meta l4proto { tcp, udp } meta skuid { {% for (let user in access_control['user']): %} {{ user }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% if (length(access_control['group']) > 0): %}
meta l4proto { tcp, udp } meta skgid { {% for (let group in access_control['group']): %} {{ group }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% if (cgroups_version == 2 && length(access_control['cgroup']) > 0): %}
meta l4proto { tcp, udp } socket cgroupv2 level 2 { {% for (let cgroup in access_control['cgroup']): %} services/{{ cgroup }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
chain lan_dns_hijack {
{% if (access_control_mode == 'all'): %}
meta l4proto { tcp, udp } th dport 53 counter redirect to :{{ dns_port }}
{% elif (access_control_mode == 'allow'): %}
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_device counter redirect to :{{ dns_port }}
{% elif (access_control_mode == 'block'): %}
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_device counter return
meta l4proto { tcp, udp } th dport 53 counter redirect to :{{ dns_port }}
{% for (let access_control in lan_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['ip']) == 0 && length(access_control['ip6']) == 0 && length(access_control['mac']) == 0): %}
meta l4proto { tcp, udp } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% else %}
{% if (length(access_control['ip']) > 0): %}
meta l4proto { tcp, udp } ip saddr { {% for (let ip in access_control['ip']): %} {{ ip }}, {% endfor %} } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% endif %}
{% if (length(access_control['ip6']) > 0): %}
meta l4proto { tcp, udp } ip6 saddr { {% for (let ip6 in access_control['ip6']): %} {{ ip6 }}, {% endfor %} } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% endif %}
{% if (length(access_control['mac']) > 0): %}
meta l4proto { tcp, udp } ether saddr { {% for (let mac in access_control['mac']): %} {{ mac }}, {% endfor %} } th dport 53 counter {% if (access_control.proxy == '1'): %} redirect to :{{ dns_port }} {% else %} return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
chain lan_redirect {
{% if (access_control_mode == 'all'): %}
meta l4proto tcp counter redirect to :{{ redir_port }}
{% elif (access_control_mode == 'allow'): %}
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_device counter redirect to :{{ redir_port }}
{% elif (access_control_mode == 'block'): %}
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_device counter return
meta l4proto tcp counter redirect to :{{ redir_port }}
{% for (let access_control in lan_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['ip']) == 0 && length(access_control['ip6']) == 0 && length(access_control['mac']) == 0): %}
meta l4proto tcp tcp counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} counter return {% endif %}
{% else %}
{% if (length(access_control['ip']) > 0): %}
meta l4proto tcp ip saddr { {% for (let ip in access_control['ip']): %} {{ ip }}, {% endfor %} } counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% endif %}
{% if (length(access_control['ip6']) > 0): %}
meta l4proto tcp ip6 saddr { {% for (let ip6 in access_control['ip6']): %} {{ ip6 }}, {% endfor %} } counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% endif %}
{% if (length(access_control['mac']) > 0): %}
meta l4proto tcp ether saddr { {% for (let mac in access_control['mac']): %} {{ mac }}, {% endfor %} } counter {% if (access_control.proxy == '1'): %} redirect to :{{ redir_port }} {% else %} return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
chain lan_tproxy {
{% if (access_control_mode == 'all'): %}
meta l4proto { tcp, udp } meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
{% elif (access_control_mode == 'allow'): %}
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_device meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
{% elif (access_control_mode == 'block'): %}
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_device counter return
meta l4proto { tcp, udp } meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept
{% for (let access_control in lan_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['ip']) == 0 && length(access_control['ip6']) == 0 && length(access_control['mac']) == 0): %}
meta l4proto { tcp, udp } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% else %}
{% if (length(access_control['ip']) > 0): %}
meta l4proto { tcp, udp } ip saddr { {% for (let ip in access_control['ip']): %} {{ ip }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy ip to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% if (length(access_control['ip6']) > 0): %}
meta l4proto { tcp, udp } ip6 saddr { {% for (let ip6 in access_control['ip6']): %} {{ ip6 }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy ip6 to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% if (length(access_control['mac']) > 0): %}
meta l4proto { tcp, udp } ether saddr { {% for (let mac in access_control['mac']): %} {{ mac }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tproxy_fw_mark }} tproxy to :{{ tproxy_port }} counter accept {% else %} counter return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
chain lan_tun {
{% if (access_control_mode == 'all'): %}
meta l4proto { tcp, udp } meta mark set {{ tun_fw_mark }} counter
{% elif (access_control_mode == 'allow'): %}
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_device meta mark set {{ tun_fw_mark }} counter
{% elif (access_control_mode == 'block'): %}
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_device counter return
meta l4proto { tcp, udp } meta mark set {{ tun_fw_mark }} counter
{% for (let access_control in lan_access_control): %}
{% if (access_control['enabled']): %}
{% if (length(access_control['ip']) == 0 && length(access_control['ip6']) == 0 && length(access_control['mac']) == 0): %}
meta l4proto { tcp, udp } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %}counter return {% endif %}
{% else %}
{% if (length(access_control['ip']) > 0): %}
meta l4proto { tcp, udp } ip saddr { {% for (let ip in access_control['ip']): %} {{ ip }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %}counter return {% endif %}
{% endif %}
{% if (length(access_control['ip6']) > 0): %}
meta l4proto { tcp, udp } ip6 saddr { {% for (let ip6 in access_control['ip6']): %} {{ ip6 }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %}counter return {% endif %}
{% endif %}
{% if (length(access_control['mac']) > 0): %}
meta l4proto { tcp, udp } ether saddr { {% for (let mac in access_control['mac']): %} {{ mac }}, {% endfor %} } {% if (access_control.proxy == '1'): %} meta mark set {{ tun_fw_mark }} counter accept {% else %}counter return {% endif %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
}
{% if (router_proxy): %}
chain nat_output {
type nat hook output priority filter; policy accept;
{% if (cgroups_version == 1): %}
meta cgroup @bypass_cgroup counter return
meta cgroup {{ cgroup_id }} counter return
{% elif (cgroups_version == 2): %}
socket cgroupv2 level 2 @bypass_cgroup counter return
socket cgroupv2 level 2 services/{{ cgroup_name }} counter return
{% endif %}
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'): %}
meta nfproto @dns_hijack_nfproto jump router_dns_hijack
{% if (tcp_mode == 'redirect'): %}
fib daddr type { local, multicast, broadcast, anycast } counter return
ct direction reply counter return
ip daddr @reserved_ip counter return
@ -361,7 +393,7 @@ table inet nikki {
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 }}
meta nfproto @proxy_nfproto jump router_redirect
{% endif %}
{% if (fake_ip_ping_hijack): %}
ip protocol icmp icmp type echo-request ip daddr {{ fake_ip_range }} counter redirect
@ -371,12 +403,10 @@ table inet nikki {
chain mangle_output {
type route hook output priority mangle; policy accept;
{% if (cgroups_version == 1): %}
meta cgroup @bypass_cgroup counter return
meta cgroup {{ cgroup_id }} counter return
{% elif (cgroups_version == 2): %}
socket cgroupv2 level 2 @bypass_cgroup counter return
socket cgroupv2 level 2 services/{{ cgroup_name }} counter return
{% endif %}
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
@ -388,25 +418,25 @@ table inet nikki {
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
{% if (tcp_mode == 'tproxy'): %}
meta nfproto @proxy_nfproto meta l4proto tcp jump router_tproxy
{% elif (tcp_mode == 'tun'): %}
meta nfproto @proxy_nfproto meta l4proto tcp jump router_tun
{% 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
{% if (udp_mode == 'tproxy'): %}
meta nfproto @proxy_nfproto meta l4proto udp jump router_tproxy
{% elif (udp_mode == 'tun'): %}
meta nfproto @proxy_nfproto meta l4proto udp jump router_tun
{% 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
{% if (tcp_mode == 'tproxy' || udp_mode == 'tproxy'): %}
iifname lo meta l4proto { tcp, udp } 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
{% if (tcp_mode == 'tun' || udp_mode == 'tun'): %}
iifname {{ tun_device }} meta l4proto { icmp, tcp, udp } counter accept
{% endif %}
}
{% endif %}
@ -414,8 +444,8 @@ table inet nikki {
{% if (lan_proxy): %}
chain dstnat {
type nat hook prerouting priority dstnat + 1; policy accept;
meta nfproto @dns_hijack_nfproto jump lan_dns_hijack
{% if (tcp_transparent_proxy_mode == 'redirect'): %}
iifname @lan_inbound_device meta nfproto @dns_hijack_nfproto jump lan_dns_hijack
{% if (tcp_mode == 'redirect'): %}
fib daddr type { local, multicast, broadcast, anycast } counter return
ct direction reply counter return
ip daddr @reserved_ip counter return
@ -426,7 +456,7 @@ table inet nikki {
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 lan_redirect
iifname @lan_inbound_device meta nfproto @proxy_nfproto jump lan_redirect
{% endif %}
{% if (fake_ip_ping_hijack): %}
ip protocol icmp icmp type echo-request ip daddr {{ fake_ip_range }} counter redirect
@ -446,15 +476,15 @@ table inet nikki {
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 lan_tproxy
{% elif (tcp_transparent_proxy_mode == 'tun'): %}
meta nfproto @proxy_nfproto meta l4proto tcp jump lan_tun
{% if (tcp_mode == 'tproxy'): %}
iifname @lan_inbound_device meta nfproto @proxy_nfproto meta l4proto tcp jump lan_tproxy
{% elif (tcp_mode == 'tun'): %}
iifname @lan_inbound_device meta nfproto @proxy_nfproto meta l4proto tcp jump lan_tun
{% endif %}
{% if (udp_transparent_proxy_mode == 'tproxy'): %}
meta nfproto @proxy_nfproto meta l4proto udp jump lan_tproxy
{% elif (udp_transparent_proxy_mode == 'tun'): %}
meta nfproto @proxy_nfproto meta l4proto udp jump lan_tun
{% if (udp_mode == 'tproxy'): %}
iifname @lan_inbound_device meta nfproto @proxy_nfproto meta l4proto udp jump lan_tproxy
{% elif (udp_mode == 'tun'): %}
iifname @lan_inbound_device meta nfproto @proxy_nfproto meta l4proto udp jump lan_tun
{% endif %}
}
{% endif %}

View File

@ -47,7 +47,7 @@ if (uci_bool(uci.get('nikki', 'mixin', 'authentication'))) {
}
config['tun'] = {};
if (uci.get('nikki', 'proxy', 'tcp_transparent_proxy_mode') == 'tun' || uci.get('nikki', 'proxy', 'udp_transparent_proxy_mode') == 'tun') {
if (uci.get('nikki', 'proxy', 'tcp_mode') == 'tun' || uci.get('nikki', 'proxy', 'udp_mode') == 'tun') {
config['tun']['enable'] = true;
config['tun']['auto-route'] = false;
config['tun']['auto-redirect'] = false;