Scope Podkop DNS to source interfaces

This commit is contained in:
ushan0v
2026-05-01 14:20:13 +03:00
parent b591524269
commit 5873b32ede
+190 -71
View File
@@ -436,7 +436,7 @@ get_remote_ruleset_update_interval() {
} }
capture_reload_state() { capture_reload_state() {
config_load "$PODKOP_CONFIG" config_load "$PODKOP_CONFIG_NAME"
RELOAD_STATE_RESTART_SIGNATURE="$(build_restart_signature)" RELOAD_STATE_RESTART_SIGNATURE="$(build_restart_signature)"
RELOAD_STATE_DNSMASQ_SIGNATURE="$(build_dnsmasq_signature)" RELOAD_STATE_DNSMASQ_SIGNATURE="$(build_dnsmasq_signature)"
RELOAD_STATE_SING_BOX_SIGNATURE="$(build_sing_box_signature)" RELOAD_STATE_SING_BOX_SIGNATURE="$(build_sing_box_signature)"
@@ -1030,7 +1030,7 @@ reload() {
[ "$reload_reason" = "on_config_change" ] || force_runtime_reload=1 [ "$reload_reason" = "on_config_change" ] || force_runtime_reload=1
migration migration
config_load "$PODKOP_CONFIG" config_load "$PODKOP_CONFIG_NAME"
check_requirements check_requirements
config_foreach process_validate_rule "rule" config_foreach process_validate_rule "rule"
ensure_runtime_dirs ensure_runtime_dirs
@@ -1088,11 +1088,10 @@ reload() {
needs_zapret_restart=1 needs_zapret_restart=1
fi fi
if [ "$RELOAD_STATE_DNSMASQ_SIGNATURE" != "$previous_dnsmasq_signature" ] && if [ "$RELOAD_STATE_DNSMASQ_SIGNATURE" != "$previous_dnsmasq_signature" ]; then
[ "$RELOAD_STATE_DONT_TOUCH_DHCP" != "$previous_dont_touch_dhcp" ]; then
if [ "$RELOAD_STATE_DONT_TOUCH_DHCP" -eq 0 ]; then if [ "$RELOAD_STATE_DONT_TOUCH_DHCP" -eq 0 ]; then
needs_dnsmasq_configure=1 needs_dnsmasq_configure=1
else elif [ "$previous_dont_touch_dhcp" = "0" ]; then
needs_dnsmasq_restore=1 needs_dnsmasq_restore=1
fi fi
fi fi
@@ -1790,8 +1789,153 @@ backup_dnsmasq_config_option() {
fi fi
} }
list_has_item() {
local list="$1"
local needle="$2"
local item
for item in $list; do
[ "$item" = "$needle" ] && return 0
done
return 1
}
uci_add_list_unique() {
local package="$1"
local section="$2"
local option="$3"
local value="$4"
local current_values
current_values="$(uci_get "$package" "$section" "$option")"
list_has_item "$current_values" "$value" && return 0
uci_add_list "$package" "$section" "$option" "$value"
}
backup_dnsmasq_config_list_option() {
local key="$1"
local backup_key="$2"
local value
for value in $(uci_get "dhcp" "@dnsmasq[0]" "$key"); do
uci_add_list_unique "dhcp" "@dnsmasq[0]" "$backup_key" "$value"
done
}
restore_dnsmasq_config_option() {
local key="$1"
local backup_key="$2"
local default_value="${3:-}"
local value
value="$(uci_get "dhcp" "@dnsmasq[0]" "$backup_key")"
if [ -n "$value" ]; then
uci_set "dhcp" "@dnsmasq[0]" "$key" "$value"
uci_remove "dhcp" "@dnsmasq[0]" "$backup_key"
elif [ -n "$default_value" ]; then
uci_set "dhcp" "@dnsmasq[0]" "$key" "$default_value"
else
uci_remove "dhcp" "@dnsmasq[0]" "$key"
fi
}
restore_dnsmasq_config_list_option() {
local key="$1"
local backup_key="$2"
local value
uci_remove "dhcp" "@dnsmasq[0]" "$key"
for value in $(uci_get "dhcp" "@dnsmasq[0]" "$backup_key"); do
uci_add_list "dhcp" "@dnsmasq[0]" "$key" "$value"
done
uci_remove "dhcp" "@dnsmasq[0]" "$backup_key"
}
dnsmasq_server_list_has_podkop_dns() {
local server_list="$1"
local server
for server in $server_list; do
[ "$server" = "$SB_DNS_INBOUND_ADDRESS" ] && return 0
done
return 1
}
dnsmasq_default_has_podkop_dns() {
dnsmasq_server_list_has_podkop_dns "$(uci_get "dhcp" "@dnsmasq[0]" "server")"
}
dnsmasq_split_has_podkop_dns() {
dnsmasq_server_list_has_podkop_dns "$(uci_get "dhcp" "$PODKOP_DNSMASQ_SECTION" "server")"
}
dnsmasq_has_podkop_dns() { dnsmasq_has_podkop_dns() {
uci -q show dhcp | grep -F ".server='$SB_DNS_INBOUND_ADDRESS'" >/dev/null 2>&1 dnsmasq_split_has_podkop_dns || dnsmasq_default_has_podkop_dns
}
dnsmasq_restore_default_instance() {
local server_list backup_servers server legacy_global_dns noresolv cachesize
server_list="$(uci_get "dhcp" "@dnsmasq[0]" "server")"
backup_servers="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_server")"
legacy_global_dns=0
dnsmasq_server_list_has_podkop_dns "$server_list" && legacy_global_dns=1
uci_remove "dhcp" "@dnsmasq[0]" "server"
if [ -n "$backup_servers" ]; then
for server in $backup_servers; do
uci_add_list "dhcp" "@dnsmasq[0]" "server" "$server"
done
uci_remove "dhcp" "@dnsmasq[0]" "podkop_server"
else
for server in $server_list; do
[ "$server" = "$SB_DNS_INBOUND_ADDRESS" ] && continue
uci_add_list "dhcp" "@dnsmasq[0]" "server" "$server"
done
fi
noresolv="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_noresolv")"
if [ -n "$noresolv" ]; then
restore_dnsmasq_config_option "noresolv" "podkop_noresolv"
elif [ "$legacy_global_dns" -eq 1 ]; then
uci_set "dhcp" "@dnsmasq[0]" "noresolv" 0
fi
cachesize="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_cachesize")"
if [ -n "$cachesize" ]; then
restore_dnsmasq_config_option "cachesize" "podkop_cachesize"
elif [ "$legacy_global_dns" -eq 1 ]; then
uci_set "dhcp" "@dnsmasq[0]" "cachesize" 150
fi
}
dnsmasq_configure_split_instance() {
local source_network_interfaces interface
config_get source_network_interfaces "settings" "source_network_interfaces" "br-lan"
backup_dnsmasq_config_list_option "notinterface" "podkop_notinterface"
for interface in $source_network_interfaces; do
uci_add_list_unique "dhcp" "@dnsmasq[0]" "notinterface" "$interface"
done
uci -q delete "dhcp.$PODKOP_DNSMASQ_SECTION"
uci set "dhcp.$PODKOP_DNSMASQ_SECTION=dnsmasq"
uci_set "dhcp" "$PODKOP_DNSMASQ_SECTION" "noresolv" 1
uci_set "dhcp" "$PODKOP_DNSMASQ_SECTION" "cachesize" 0
uci_add_list "dhcp" "$PODKOP_DNSMASQ_SECTION" "server" "$SB_DNS_INBOUND_ADDRESS"
for interface in $source_network_interfaces; do
uci_add_list "dhcp" "$PODKOP_DNSMASQ_SECTION" "interface" "$interface"
done
}
dnsmasq_restore_split_instance() {
uci -q delete "dhcp.$PODKOP_DNSMASQ_SECTION"
restore_dnsmasq_config_list_option "notinterface" "podkop_notinterface"
} }
dnsmasq_configure() { dnsmasq_configure() {
@@ -1799,7 +1943,7 @@ dnsmasq_configure() {
local shutdown_correctly local shutdown_correctly
config_get shutdown_correctly "settings" "shutdown_correctly" config_get shutdown_correctly "settings" "shutdown_correctly"
if [ "$force" != "force" ] && [ "$shutdown_correctly" -eq 0 ]; then if [ "$force" != "force" ] && [ "$shutdown_correctly" -eq 0 ]; then
if dnsmasq_has_podkop_dns; then if dnsmasq_split_has_podkop_dns; then
log "Previous shutdown of podkop was not correct, dnsmasq is already configured" log "Previous shutdown of podkop was not correct, dnsmasq is already configured"
return 0 return 0
fi fi
@@ -1807,24 +1951,16 @@ dnsmasq_configure() {
log "Previous shutdown of podkop was not correct, but dnsmasq is not configured. Applying Podkop DNS settings" log "Previous shutdown of podkop was not correct, but dnsmasq is not configured. Applying Podkop DNS settings"
fi fi
log "Backup dnsmasq configuration"
current_servers="$(uci_get "dhcp" "@dnsmasq[0]" "server")"
if [ -n "$current_servers" ]; then
for server in $(uci_get "dhcp" "@dnsmasq[0]" "server"); do
if ! [ "$server" == "$SB_DNS_INBOUND_ADDRESS" ]; then
uci_add_list "dhcp" "@dnsmasq[0]" "podkop_server" "$server"
fi
done
uci_remove "dhcp" "@dnsmasq[0]" "server"
fi
backup_dnsmasq_config_option "noresolv" "podkop_noresolv"
backup_dnsmasq_config_option "cachesize" "podkop_cachesize"
log "Configure dnsmasq for sing-box" log "Configure dnsmasq for sing-box"
uci_add_list "dhcp" "@dnsmasq[0]" "server" "$SB_DNS_INBOUND_ADDRESS" if dnsmasq_split_has_podkop_dns; then
uci_set "dhcp" "@dnsmasq[0]" "noresolv" 1 log "Refreshing existing interface-scoped Podkop DNS settings"
uci_set "dhcp" "@dnsmasq[0]" "cachesize" 0 dnsmasq_restore_split_instance
fi
if dnsmasq_default_has_podkop_dns; then
log "Migrating legacy global dnsmasq DNS settings to interface-scoped Podkop DNS"
dnsmasq_restore_default_instance
fi
dnsmasq_configure_split_instance
uci_commit "dhcp" uci_commit "dhcp"
/etc/init.d/dnsmasq restart /etc/init.d/dnsmasq restart
@@ -1844,45 +1980,8 @@ dnsmasq_restore() {
log "Previous shutdown of podkop was correct, but Podkop DNS is still present. Restoring dnsmasq" log "Previous shutdown of podkop was correct, but Podkop DNS is still present. Restoring dnsmasq"
fi fi
local cachesize noresolv backup_servers resolvfile dnsmasq_restore_split_instance
log "Restoring cachesize" "debug" dnsmasq_restore_default_instance
cachesize="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_cachesize")"
if [ -z "$cachesize" ]; then
uci_remove "dhcp" "@dnsmasq[0]" "cachesize"
uci_set "dhcp" "@dnsmasq[0]" "cachesize" 150
else
uci_set "dhcp" "@dnsmasq[0]" "cachesize" "$cachesize"
uci_remove "dhcp" "@dnsmasq[0]" "podkop_cachesize"
fi
log "Restoring noresolv" "debug"
noresolv="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_noresolv")"
if [ -z "$noresolv" ]; then
uci_set "dhcp" "@dnsmasq[0]" "noresolv" 0
else
uci_set "dhcp" "@dnsmasq[0]" "noresolv" "$noresolv"
uci_remove "dhcp" "@dnsmasq[0]" "podkop_noresolv"
fi
log "Restoring DNS servers" "debug"
uci_remove "dhcp" "@dnsmasq[0]" "server"
resolvfile="/tmp/resolv.conf.d/resolv.conf.auto"
backup_servers="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_server")"
if [ -n "$backup_servers" ]; then
for server in $backup_servers; do
uci_add_list "dhcp" "@dnsmasq[0]" "server" "$server"
done
uci_remove "dhcp" "@dnsmasq[0]" "podkop_server"
elif file_exists "$resolvfile"; then
log "Backup DNS servers not found, using default resolvfile" "debug"
uci_set "dhcp" "@dnsmasq[0]" "resolvfile" "$resolvfile"
if [ -n "$noresolv" ] && [ "$noresolv" -eq 1 ]; then
log "Disabling noresolv option to use system resolvfile" "debug"
uci_set "dhcp" "@dnsmasq[0]" "noresolv" 0
fi
else
log "Backup DNS servers and default resolvfile not found, possible resolving issues" "warn"
fi
uci_commit "dhcp" uci_commit "dhcp"
@@ -4388,25 +4487,32 @@ check_dns_available() {
fi fi
fi fi
# Check if /etc/config/dhcp has server 127.0.0.42 # Check if dnsmasq sends only selected source interfaces through Podkop DNS.
config_load dhcp config_load dhcp
config_foreach check_dhcp_has_podkop_dns dnsmasq check_dhcp_has_podkop_dns
config_load "$PODKOP_CONFIG" config_load "$PODKOP_CONFIG_NAME"
echo "{\"dns_type\":\"$dns_type\",\"dns_server\":\"$display_dns_server\",\"dns_status\":$dns_status,\"dns_on_router\":$dns_on_router,\"bootstrap_dns_server\":\"$bootstrap_dns_server\",\"bootstrap_dns_status\":$bootstrap_dns_status,\"dhcp_config_status\":$dhcp_config_status}" | jq . echo "{\"dns_type\":\"$dns_type\",\"dns_server\":\"$display_dns_server\",\"dns_status\":$dns_status,\"dns_on_router\":$dns_on_router,\"bootstrap_dns_server\":\"$bootstrap_dns_server\",\"bootstrap_dns_status\":$bootstrap_dns_status,\"dhcp_config_status\":$dhcp_config_status}" | jq .
} }
check_dhcp_has_podkop_dns() { check_dhcp_has_podkop_dns() {
local server_list cachesize noresolv server_found local source_network_interfaces podkop_interfaces default_notinterfaces server_list cachesize noresolv
config_get server_list "$1" "server" local server server_found interface
config_get cachesize "$1" "cachesize"
config_get noresolv "$1" "noresolv" source_network_interfaces="$(uci_get "$PODKOP_CONFIG_NAME" "settings" "source_network_interfaces")"
[ -n "$source_network_interfaces" ] || source_network_interfaces="br-lan"
server_list="$(uci_get "dhcp" "$PODKOP_DNSMASQ_SECTION" "server")"
cachesize="$(uci_get "dhcp" "$PODKOP_DNSMASQ_SECTION" "cachesize")"
noresolv="$(uci_get "dhcp" "$PODKOP_DNSMASQ_SECTION" "noresolv")"
podkop_interfaces="$(uci_get "dhcp" "$PODKOP_DNSMASQ_SECTION" "interface")"
default_notinterfaces="$(uci_get "dhcp" "@dnsmasq[0]" "notinterface")"
server_found=0 server_found=0
if [ -n "$server_list" ]; then if [ -n "$server_list" ]; then
for server in $server_list; do for server in $server_list; do
if [ "$server" = "127.0.0.42" ]; then if [ "$server" = "$SB_DNS_INBOUND_ADDRESS" ]; then
server_found=1 server_found=1
break break
fi fi
@@ -4415,6 +4521,19 @@ check_dhcp_has_podkop_dns() {
if [ "$cachesize" != "0" ] || [ "$noresolv" != "1" ] || [ "$server_found" != "1" ]; then if [ "$cachesize" != "0" ] || [ "$noresolv" != "1" ] || [ "$server_found" != "1" ]; then
dhcp_config_status=0 dhcp_config_status=0
return 0
fi
for interface in $source_network_interfaces; do
if ! list_has_item "$podkop_interfaces" "$interface" ||
! list_has_item "$default_notinterfaces" "$interface"; then
dhcp_config_status=0
return 0
fi
done
if dnsmasq_default_has_podkop_dns; then
dhcp_config_status=0
fi fi
} }