From c31df68bec3dbaaaa496f4a26d42d020e4727eef Mon Sep 17 00:00:00 2001 From: Andrey Petelin Date: Thu, 25 Sep 2025 11:11:41 +0500 Subject: [PATCH 1/5] refactor: Add version checks and service existence validation for required packages before starting podkop --- podkop/files/usr/bin/podkop | 80 ++++++++++++++++++++++++------- podkop/files/usr/lib/constants.sh | 3 ++ podkop/files/usr/lib/helpers.sh | 27 +++++++++++ 3 files changed, 92 insertions(+), 18 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index cc1f22a..1424156 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -29,22 +29,77 @@ check_required_file "$PODKOP_LIB/logging.sh" config_load "$PODKOP_CONFIG" -start_main() { - log "Starting podkop" +check_requirements() { + log "Check Requirements" - # checking - sing_box_version=$(sing-box version | head -n 1 | awk '{print $3}') - required_version="1.12.0" + local sing_box_version curl_version jq_version kmod_nft_tproxy_version coreutils_base64_version + sing_box_version="$(get_package_version "sing-box")" + curl_version="$(get_package_version "curl")" + jq_version="$(get_package_version "jq")" + kmod_nft_tproxy_version="$(get_package_version "kmod-nft-tproxy")" + coreutils_base64_version="$(get_package_version "coreutils-base64")" - if [ "$(echo -e "$sing_box_version\n$required_version" | sort -V | head -n 1)" != "$required_version" ]; then - log "The version of sing-box ($sing_box_version) is lower than the minimum version. Update sing-box: opkg update && opkg remove sing-box && opkg install sing-box" "critical" + if [ -z "$sing_box_version" ]; then + log "Package 'sing-box' is not installed." "error" exit 1 + else + if ! is_min_package_version "$sing_box_version" "$SB_REQUIRED_VERSION"; then + log "Package 'sing-box' version ($sing_box_version) is lower than the required minimum ($SB_REQUIRED_VERSION). Update sing-box: opkg update && opkg remove sing-box && opkg install sing-box" "error" + exit 1 + fi + + if ! service_exists "sing-box"; then + log "Service 'sing-box' is missing. Please install the official package to ensure the service is available." "error" + exit 1 + fi + fi + + if [ -z "$curl_version" ]; then + log "Package 'curl' is not installed." "error" + exit 1 + fi + + if [ -z "$jq_version" ]; then + log "Package 'jq' is not installed." "error" + exit 1 + elif ! is_min_package_version "$jq_version" "$JQ_REQUIRED_VERSION"; then + log "Package 'jq' version ($jq_version) is lower than the required minimum ($JQ_REQUIRED_VERSION)." "error" + exit 1 + fi + + if [ -z "$kmod_nft_tproxy_version" ]; then + log "Package 'kmod-nft-tproxy' is not installed." "error" + exit 1 + fi + + if [ -z "$coreutils_base64_version" ]; then + log "Package 'coreutils-base64' is not installed." "error" + exit 1 + elif ! is_min_package_version "$coreutils_base64_version" "$COREUTILS_BASE64_REQUIRED_VERSION"; then + log "Package 'coreutils-base64' version ($coreutils_base64_version) is lower than the required minimum ($COREUTILS_BASE64_REQUIRED_VERSION). This may cause issues when decoding base64 streams with missing padding, as automatic padding support is not available in older versions." "warn" fi if grep -qE 'doh_backup_noresolv|doh_backup_server|doh_server' /etc/config/dhcp; then log "Detected https-dns-proxy in dhcp config. Edit /etc/config/dhcp" "warn" fi + local proxy_string interface outbound_json urltest_proxy_links dont_touch_dhcp + config_get proxy_string "main" "proxy_string" + config_get interface "main" "interface" + config_get outbound_json "main" "outbound_json" + config_get urltest_proxy_links "main" "urltest_proxy_links" + + if [ -z "$proxy_string" ] && [ -z "$interface" ] && [ -z "$outbound_json" ] && [ -z "$urltest_proxy_links" ]; then + log "Required options (proxy_string, interface, outbound_json, urltest_proxy_links) are missing in 'main' section. Aborted." "error" + exit 1 + fi +} + +start_main() { + log "Starting podkop" + + check_requirements + migration config_foreach process_validate_service @@ -82,17 +137,6 @@ start_main() { } start() { - local proxy_string interface outbound_json urltest_proxy_links dont_touch_dhcp - config_get proxy_string "main" "proxy_string" - config_get interface "main" "interface" - config_get outbound_json "main" "outbound_json" - config_get urltest_proxy_links "main" "urltest_proxy_links" - - if [ -z "$proxy_string" ] && [ -z "$interface" ] && [ -z "$outbound_json" ] && [ -z "$urltest_proxy_links" ]; then - log "Required options (proxy_string, interface, outbound_json, urltest_proxy_links) are missing in 'main' section. Aborted." "fatal" - exit 1 - fi - start_main config_get_bool dont_touch_dhcp "main" "dont_touch_dhcp" 0 if [ "$dont_touch_dhcp" -eq 0 ]; then diff --git a/podkop/files/usr/lib/constants.sh b/podkop/files/usr/lib/constants.sh index 8114154..f4ce74f 100644 --- a/podkop/files/usr/lib/constants.sh +++ b/podkop/files/usr/lib/constants.sh @@ -9,6 +9,8 @@ FAKEIP_TEST_DOMAIN="fakeip.podkop.fyi" TMP_SING_BOX_FOLDER="/tmp/sing-box" TMP_RULESET_FOLDER="$TMP_SING_BOX_FOLDER/rulesets" CLOUDFLARE_OCTETS="8.47 162.159 188.114" # Endpoints https://github.com/ampetelin/warp-endpoint-checker +JQ_REQUIRED_VERSION="1.7.1" +COREUTILS_BASE64_REQUIRED_VERSION="9.7" ## nft NFT_TABLE_NAME="PodkopTable" @@ -18,6 +20,7 @@ NFT_DISCORD_SET_NAME="podkop_discord_subnets" NFT_INTERFACE_SET_NAME="interfaces" ## sing-box +SB_REQUIRED_VERSION="1.12.0" # Log SB_DEFAULT_LOG_LEVEL="warn" # DNS diff --git a/podkop/files/usr/lib/helpers.sh b/podkop/files/usr/lib/helpers.sh index b6bee7d..ecb3b29 100644 --- a/podkop/files/usr/lib/helpers.sh +++ b/podkop/files/usr/lib/helpers.sh @@ -48,6 +48,15 @@ is_shadowsocks_userinfo_format() { [[ "$str" =~ $regex ]] } +# Compares the current package version with the required minimum +is_min_package_version() { + local current="$1" + local required="$2" + + lowest="$(printf '%s\n' "$current" "$required" | sort -V | head -n1)" + [ "$lowest" = "$required" ] +} + # Checks if the given file exists file_exists() { local filepath="$1" @@ -59,6 +68,17 @@ file_exists() { fi } +# Checks if a service script exists in /etc/init.d +service_exists() { + local service="$1" + + if [ -x "/etc/init.d/$service" ]; then + return 0 + else + return 1 + fi +} + # Returns the inbound tag name by appending the postfix to the given section get_inbound_tag_by_section() { local section="$1" @@ -106,6 +126,13 @@ get_ruleset_format_by_file_extension() { echo "$format" } +# Retrieves the installed package version from opkg +get_package_version() { + local package="$1" + + opkg status "$package" 2>/dev/null | awk '/^Version:/ {print $2}' | cut -d'-' -f1 +} + # Converts a comma-separated string into a JSON array string comma_string_to_json_array() { local input="$1" From 5b15a56502bdb918e819e055832acb59b3a5113c Mon Sep 17 00:00:00 2001 From: Andrey Petelin Date: Thu, 25 Sep 2025 11:43:03 +0500 Subject: [PATCH 2/5] fix: Add local declaration for lowest variable and improve opkg status error redirection spacing --- podkop/files/usr/lib/helpers.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/podkop/files/usr/lib/helpers.sh b/podkop/files/usr/lib/helpers.sh index ecb3b29..aa94339 100644 --- a/podkop/files/usr/lib/helpers.sh +++ b/podkop/files/usr/lib/helpers.sh @@ -53,7 +53,9 @@ is_min_package_version() { local current="$1" local required="$2" + local lowest lowest="$(printf '%s\n' "$current" "$required" | sort -V | head -n1)" + [ "$lowest" = "$required" ] } @@ -130,7 +132,7 @@ get_ruleset_format_by_file_extension() { get_package_version() { local package="$1" - opkg status "$package" 2>/dev/null | awk '/^Version:/ {print $2}' | cut -d'-' -f1 + opkg status "$package" 2> /dev/null | awk '/^Version:/ {print $2}' | cut -d'-' -f1 } # Converts a comma-separated string into a JSON array string From 927b8a53b0115c4a3ceffaba62d58fe938a482b2 Mon Sep 17 00:00:00 2001 From: Andrey Petelin Date: Sat, 27 Sep 2025 11:47:01 +0500 Subject: [PATCH 3/5] fix: restore default resolvfile in DNS settings if backup servers are missing to prevent resolution issues --- podkop/files/usr/bin/podkop | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 1424156..f9028db 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -444,7 +444,7 @@ dnsmasq_restore() { return 0 fi - local cachesize noresolv backup_servers + local cachesize noresolv backup_servers resolvfile log "Restoring cachesize" "debug" cachesize="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_cachesize")" if [ -z "$cachesize" ]; then @@ -465,12 +465,18 @@ dnsmasq_restore() { 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" + else + log "Backup DNS servers and default resolvfile not found, possible resolving issues" "warn" fi uci_commit "dhcp" From dd44e0156e7f17af70b6b657dc9de687f8ec105c Mon Sep 17 00:00:00 2001 From: Andrey Petelin Date: Sat, 27 Sep 2025 12:22:50 +0500 Subject: [PATCH 4/5] fix: restore default cachesize and noresolv values in dnsmasq configuration if unset --- podkop/files/usr/bin/podkop | 2 ++ 1 file changed, 2 insertions(+) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index f9028db..bdc95c1 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -449,6 +449,7 @@ dnsmasq_restore() { 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" @@ -458,6 +459,7 @@ dnsmasq_restore() { noresolv="$(uci_get "dhcp" "@dnsmasq[0]" "podkop_noresolv")" if [ -z "$noresolv" ]; then uci_remove "dhcp" "@dnsmasq[0]" "noresolv" + uci_set "dhcp" "@dnsmasq[0]" "noresolv" 0 else uci_set "dhcp" "@dnsmasq[0]" "noresolv" "$noresolv" uci_remove "dhcp" "@dnsmasq[0]" "podkop_noresolv" From 759b6748c6743ff2c139c98f5bcff0aaefe0956e Mon Sep 17 00:00:00 2001 From: Andrey Petelin Date: Tue, 30 Sep 2025 19:55:25 +0500 Subject: [PATCH 5/5] refactor: Replace opkg version checks with direct command execution --- podkop/files/usr/bin/podkop | 20 ++++---------------- podkop/files/usr/lib/helpers.sh | 7 ------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index bdc95c1..42c1f22 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -32,12 +32,10 @@ config_load "$PODKOP_CONFIG" check_requirements() { log "Check Requirements" - local sing_box_version curl_version jq_version kmod_nft_tproxy_version coreutils_base64_version - sing_box_version="$(get_package_version "sing-box")" - curl_version="$(get_package_version "curl")" - jq_version="$(get_package_version "jq")" - kmod_nft_tproxy_version="$(get_package_version "kmod-nft-tproxy")" - coreutils_base64_version="$(get_package_version "coreutils-base64")" + local sing_box_version jq_version coreutils_base64_version + sing_box_version="$(sing-box version | head -n1 | awk '{print $3}')" + jq_version="$(jq --version | awk -F- '{print $2}')" + coreutils_base64_version="$(base64 --version | head -n1 | awk '{print $4}')" if [ -z "$sing_box_version" ]; then log "Package 'sing-box' is not installed." "error" @@ -54,11 +52,6 @@ check_requirements() { fi fi - if [ -z "$curl_version" ]; then - log "Package 'curl' is not installed." "error" - exit 1 - fi - if [ -z "$jq_version" ]; then log "Package 'jq' is not installed." "error" exit 1 @@ -67,11 +60,6 @@ check_requirements() { exit 1 fi - if [ -z "$kmod_nft_tproxy_version" ]; then - log "Package 'kmod-nft-tproxy' is not installed." "error" - exit 1 - fi - if [ -z "$coreutils_base64_version" ]; then log "Package 'coreutils-base64' is not installed." "error" exit 1 diff --git a/podkop/files/usr/lib/helpers.sh b/podkop/files/usr/lib/helpers.sh index aa94339..b0cfb22 100644 --- a/podkop/files/usr/lib/helpers.sh +++ b/podkop/files/usr/lib/helpers.sh @@ -128,13 +128,6 @@ get_ruleset_format_by_file_extension() { echo "$format" } -# Retrieves the installed package version from opkg -get_package_version() { - local package="$1" - - opkg status "$package" 2> /dev/null | awk '/^Version:/ {print $2}' | cut -d'-' -f1 -} - # Converts a comma-separated string into a JSON array string comma_string_to_json_array() { local input="$1"