From 6ba2681cf208f327c671be3ff5f4010bf7968336 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 12:32:30 +0300 Subject: [PATCH 1/8] feat: Add diagnostic checks --- podkop/files/etc/init.d/podkop | 141 ++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 4 deletions(-) diff --git a/podkop/files/etc/init.d/podkop b/podkop/files/etc/init.d/podkop index 9d05307..a417fc5 100755 --- a/podkop/files/etc/init.d/podkop +++ b/podkop/files/etc/init.d/podkop @@ -7,10 +7,17 @@ script=$(readlink "$initscript") NAME="$(basename ${script:-$initscript})" config_load "$NAME" -EXTRA_COMMANDS="list_update add_route_interface" +EXTRA_COMMANDS="list_update add_route_interface check_proxy check_nft check_github check_logs check_all" EXTRA_HELP=" list_update Updating domain and subnet lists add_route_interface Adding route for interface - sing_box_config_vless For test vless string" + sing_box_config_vless For test vless string + check_proxy Check if sing-box proxy works correctly + check_nft Show PodkopTable nftables rules + check_github Check GitHub connectivity and lists availability + check_logs Show podkop logs from system journal + check_all Run all checks" + +[ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop config_get update_interval "main" "update_interval" "0 4 * * *" cron_job="${update_interval} /etc/init.d/podkop list_update" @@ -352,6 +359,16 @@ log() { logger -t "podkop" "$timestamp $message" } +nolog() { + local message="$1" + local timestamp=$(date +"%Y-%m-%d %H:%M:%S") + local CYAN="\033[0;36m" + local GREEN="\033[0;32m" + local RESET="\033[0m" + + echo -e "${CYAN}[$timestamp]${RESET} ${GREEN}$message${RESET}" +} + add_cron_job() { remove_cron_job crontab -l | { @@ -778,7 +795,7 @@ list_custom_local_domains_create() { local filename=$(basename "$local_file" | cut -d. -f1) local config="/tmp/dnsmasq.d/${name}-${filename}.lst" - rm -f $config + rm -f "$config" while IFS= read -r domain; do echo "nftset=/$domain/4#inet#PodkopTable#${name}_domains" >>$config done <"$local_file" @@ -791,7 +808,7 @@ list_custom_download_domains_create() { local filename=$(basename "$URL") local config="/tmp/dnsmasq.d/${name}-${filename}.lst" - rm -f $config + rm -f "$config" curl -f "$URL" --output "/tmp/podkop/${filename}" while IFS= read -r domain; do echo "nftset=/$domain/4#inet#PodkopTable#${name}_domains" >>$config @@ -1089,6 +1106,122 @@ sing_box_config_check() { fi } +check_proxy() { + if ! command -v sing-box >/dev/null 2>&1; then + nolog "sing-box is not installed" + return 1 + fi + + # Проверка конфигурации + if [ ! -f /etc/sing-box/config.json ]; then + nolog "Configuration file not found" + return 1 + fi + + # Проверка валидности конфига + if ! sing-box -c /etc/sing-box/config.json check; then + nolog "Invalid configuration" + return 1 + fi + + nolog "Checking sing-box proxy connection..." + if ! sing-box tools fetch ifconfig.me -D /etc/sing-box; then + nolog "Failed to check proxy connection" + return 1 + fi + + nolog "Proxy check completed successfully" +} + +check_nft() { + if ! command -v nft >/dev/null 2>&1; then + nolog "nft is not installed" + return 1 + fi + + nolog "Checking PodkopTable rules..." + + # Список всех возможных сетов + local sets="podkop_domains podkop_subnets podkop2_domains podkop2_subnets localv4" + + nolog "Sets statistics:" + for set_name in $sets; do + if nft list set inet PodkopTable $set_name >/dev/null 2>&1; then + local count=$(nft list set inet PodkopTable $set_name 2>/dev/null | grep -c ",") + nolog "- $set_name: $count elements" + else + nolog "- $set_name: not found" + fi + done + + # Показываем правила с счетчиками + nolog "Current chains and rules:" + nft list table inet PodkopTable | grep "chain\|counter" + + nolog "NFT check completed" +} + +check_github() { + nolog "Checking GitHub connectivity..." + + # Проверка базового соединения с GitHub + if ! curl -m 3 -sf https://github.com >/dev/null 2>&1; then + nolog "Error: Cannot connect to GitHub" + return 1 + fi + nolog "GitHub is accessible" + + # Список URL для проверки + local urls=" + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/inside-dnsmasq-nfset.lst + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/outside-dnsmasq-nfset.lst + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Ukraine/inside-dnsmasq-nfset.lst + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Services/youtube.lst + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Twitter.lst + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Meta.lst + https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Discord.lst" + + nolog "Checking lists availability:" + for url in $urls; do + local list_name=$(basename "$url") + if curl -m 5 -sf "$url" >/dev/null 2>&1; then + nolog "- $list_name: available" + else + nolog "- $list_name: not available" + fi + done +} + +check_logs() { + nolog "Showing podkop logs from system journal..." + + if command -v logread >/dev/null 2>&1; then + # Попытка получить последние 50 записей + logread -e "podkop" | tail -n 50 + else + nolog "Error: logread command not found" + return 1 + fi +} + +check_all() { + nolog "Starting full diagnostic check..." + + nolog "\n=== Checking recent logs ===" + check_logs + + nolog "\n=== Checking GitHub connectivity ===" + check_github + + nolog "\n=== Checking proxy settings ===" + check_proxy + + nolog "\n=== Checking NFT rules ===" + check_nft + + nolog "\nFull diagnostic check completed" +} + process_domains_text() { local text="$1" local name="$2" From 86dafabee93d769eefcbaae22c41f09cdfdedd55 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 14:12:03 +0300 Subject: [PATCH 2/8] feat: Add diagnostics tab --- .../resources/view/podkop/podkop.js | 146 ++++++++++++++++++ podkop/files/etc/init.d/podkop | 39 +++-- 2 files changed, 172 insertions(+), 13 deletions(-) diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index 72e09ae..eda6fd7 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -3,6 +3,7 @@ 'require form'; 'require ui'; 'require network'; +'require fs'; return view.extend({ async render() { @@ -626,6 +627,151 @@ return view.extend({ return true; }; + // Добавьте новую вкладку Diagnostics (оставьте весь существующий код и добавьте это перед return m.render()) + + // Добавляем вкладку диагностики + o = s.tab('diagnostics', _('Diagnostics')); + + // Функция форматирования вывода для модального окна + function formatDiagnosticOutput(output) { + if (!output) return ''; + + return output + .replace(/\x1B\[[0-9;]*[mK]/g, '') + .replace(/\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\] /g, '') + .replace(/\n{3,}/g, '\n\n') + .replace(/===\s+(.*?)\s+===/g, (_, title) => `\n${title}\n${'─'.repeat(title.length)}`) + .replace(/^Checking\s+(.+)\.{3}/gm, '► Checking $1...') + .replace(/:\s+(available|not found)$/gm, (_, status) => + `: ${status === 'available' ? '✓' : '✗'}`); + } + + // Check All - полная диагностика + o = s.taboption('diagnostics', form.Button, '_check_all'); + o.title = _('Main Check'); + o.description = _('Run a comprehensive diagnostic check of all components'); + o.inputtitle = _('Run Check'); + o.inputstyle = 'apply'; + o.onclick = function () { + return fs.exec('/etc/init.d/podkop', ['check_three']) + .then(function (res) { + const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); + + const modalElement = ui.showModal(_('Full Diagnostic Results'), [ + E('div', { + style: + 'max-height: 70vh;' + + 'overflow-y: auto;' + + 'margin: 1em 0;' + + 'padding: 1.5em;' + + 'background: #f8f9fa;' + + 'border: 1px solid #e9ecef;' + + 'border-radius: 4px;' + + 'font-family: monospace;' + + 'white-space: pre-wrap;' + + 'word-wrap: break-word;' + + 'line-height: 1.5;' + + 'font-size: 14px;' + }, [ + E('pre', { style: 'margin: 0;' }, formattedOutput) + ]), + E('div', { + style: 'display: flex; justify-content: space-between; margin-top: 1em;' + }, [ + E('button', { + 'class': 'btn', + 'click': function () { + const textarea = document.createElement('textarea'); + textarea.value = '```txt\n' + formattedOutput + '\n```'; + document.body.appendChild(textarea); + textarea.select(); + try { + document.execCommand('copy'); + ui.addNotification(null, E('p', {}, _('Results copied to clipboard'))); + } catch (err) { + ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message)); + } + document.body.removeChild(textarea); + } + }, _('Copy to Clipboard')), + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Close')) + ]) + ], 'large'); + + if (modalElement && modalElement.parentElement) { + modalElement.parentElement.style.width = '90%'; + modalElement.parentElement.style.maxWidth = '1200px'; + modalElement.parentElement.style.margin = '2rem auto'; + } + }); + }; + + // Check Logs - проверка логов + o = s.taboption('diagnostics', form.Button, '_check_logs'); + o.title = _('System Logs'); + o.description = _('View recent system logs related to Podkop'); + o.inputtitle = _('View Logs'); + o.inputstyle = 'apply'; + o.onclick = function () { + return fs.exec('/etc/init.d/podkop', ['check_logs']) + .then(function (res) { + const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); + + const modalElement = ui.showModal(_('System Logs'), [ + E('div', { + style: + 'max-height: 70vh;' + + 'overflow-y: auto;' + + 'margin: 1em 0;' + + 'padding: 1.5em;' + + 'background: #f8f9fa;' + + 'border: 1px solid #e9ecef;' + + 'border-radius: 4px;' + + 'font-family: monospace;' + + 'white-space: pre-wrap;' + + 'word-wrap: break-word;' + + 'line-height: 1.5;' + + 'font-size: 14px;' + }, [ + E('pre', { style: 'margin: 0;' }, formattedOutput) + ]), + E('div', { + style: 'display: flex; justify-content: space-between; margin-top: 1em;' + }, [ + E('button', { + 'class': 'btn', + 'click': function () { + const textarea = document.createElement('textarea'); + textarea.value = '```txt\n' + formattedOutput + '\n```'; + document.body.appendChild(textarea); + textarea.select(); + try { + document.execCommand('copy'); + ui.addNotification(null, E('p', {}, _('Logs copied to clipboard'))); + } catch (err) { + ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message)); + } + document.body.removeChild(textarea); + } + }, _('Copy to Clipboard')), + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Close')) + ]) + ], 'large'); + + if (modalElement && modalElement.parentElement) { + modalElement.parentElement.style.width = '90%'; + modalElement.parentElement.style.maxWidth = '1200px'; + modalElement.parentElement.style.margin = '2rem auto'; + } + }); + }; + return m.render(); } }); \ No newline at end of file diff --git a/podkop/files/etc/init.d/podkop b/podkop/files/etc/init.d/podkop index a417fc5..b624fd7 100755 --- a/podkop/files/etc/init.d/podkop +++ b/podkop/files/etc/init.d/podkop @@ -7,7 +7,7 @@ script=$(readlink "$initscript") NAME="$(basename ${script:-$initscript})" config_load "$NAME" -EXTRA_COMMANDS="list_update add_route_interface check_proxy check_nft check_github check_logs check_all" +EXTRA_COMMANDS="list_update add_route_interface check_proxy check_nft check_github check_logs check_all check_three" EXTRA_HELP=" list_update Updating domain and subnet lists add_route_interface Adding route for interface sing_box_config_vless For test vless string @@ -15,7 +15,8 @@ EXTRA_HELP=" list_update Updating domain and subnet lists check_nft Show PodkopTable nftables rules check_github Check GitHub connectivity and lists availability check_logs Show podkop logs from system journal - check_all Run all checks" + check_all Run all checks + check_three Run check_proxy, check_nft and check_github" [ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop @@ -1125,12 +1126,20 @@ check_proxy() { fi nolog "Checking sing-box proxy connection..." - if ! sing-box tools fetch ifconfig.me -D /etc/sing-box; then - nolog "Failed to check proxy connection" - return 1 - fi - nolog "Proxy check completed successfully" + for attempt in `seq 1 5`; do + response=$(sing-box tools fetch ifconfig.me -D /etc/sing-box) + if echo "$response" | grep -q "403 Forbidden"; then + : + else + nolog "Proxy check completed successfully" + echo "$response" + return 0 + fi + done + + nolog "Failed to get a non-403 response after 5 attempts" + return 1 } check_nft() { @@ -1204,12 +1213,7 @@ check_logs() { fi } -check_all() { - nolog "Starting full diagnostic check..." - - nolog "\n=== Checking recent logs ===" - check_logs - +check_three() { nolog "\n=== Checking GitHub connectivity ===" check_github @@ -1222,6 +1226,15 @@ check_all() { nolog "\nFull diagnostic check completed" } +check_all() { + nolog "Starting full diagnostic check..." + + nolog "\n=== Checking recent logs ===" + check_logs + + check_three +} + process_domains_text() { local text="$1" local name="$2" From 8b1da669bd7d437a57a6335181acbff109222606 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 14:14:04 +0300 Subject: [PATCH 3/8] Add diagnostic tab --- .../htdocs/luci-static/resources/view/podkop/podkop.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index eda6fd7..6c3cb4f 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -627,12 +627,8 @@ return view.extend({ return true; }; - // Добавьте новую вкладку Diagnostics (оставьте весь существующий код и добавьте это перед return m.render()) - - // Добавляем вкладку диагностики o = s.tab('diagnostics', _('Diagnostics')); - // Функция форматирования вывода для модального окна function formatDiagnosticOutput(output) { if (!output) return ''; @@ -709,7 +705,6 @@ return view.extend({ }); }; - // Check Logs - проверка логов o = s.taboption('diagnostics', form.Button, '_check_logs'); o.title = _('System Logs'); o.description = _('View recent system logs related to Podkop'); From 7373b76a8ee8024d50050aa82a8093cb0e4eabca Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 16:04:06 +0300 Subject: [PATCH 4/8] feat: Add translate for new functions --- .../resources/view/podkop/podkop.js | 2 - luci-app-podkop/po/ru/podkop.po | 41 ++++++++++++++++++- luci-app-podkop/po/templates/podkop.pot | 39 ++++++++++++++++++ 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index 6c3cb4f..49c52cb 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -683,7 +683,6 @@ return view.extend({ textarea.select(); try { document.execCommand('copy'); - ui.addNotification(null, E('p', {}, _('Results copied to clipboard'))); } catch (err) { ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message)); } @@ -745,7 +744,6 @@ return view.extend({ textarea.select(); try { document.execCommand('copy'); - ui.addNotification(null, E('p', {}, _('Logs copied to clipboard'))); } catch (err) { ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message)); } diff --git a/luci-app-podkop/po/ru/podkop.po b/luci-app-podkop/po/ru/podkop.po index fb3775b..af7d0f0 100644 --- a/luci-app-podkop/po/ru/podkop.po +++ b/luci-app-podkop/po/ru/podkop.po @@ -290,4 +290,43 @@ msgid "JSON must contain at least type, server and server_port fields" msgstr "JSON должен содержать как минимум поля type, server и server_port" msgid "Invalid JSON format" -msgstr "Неверный формат JSON" \ No newline at end of file +msgstr "Неверный формат JSON" + +msgid "Diagnostics" +msgstr "Диагностика" + +msgid "Main Check" +msgstr "Основная проверка" + +msgid "Run a comprehensive diagnostic check of all components" +msgstr "Запустить комплексную диагностическую проверку всех компонентов" + +msgid "Run Check" +msgstr "Запустить проверку" + +msgid "Full Diagnostic Results" +msgstr "Полные результаты диагностики" + +msgid "Failed to copy: " +msgstr "Ошибка копирования: " + +msgid "Copy to Clipboard" +msgstr "Скопировать в буфер" + +msgid "Close" +msgstr "Закрыть" + +msgid "No output" +msgstr "Нет данных" + +msgid "System Logs" +msgstr "Системные логи" + +msgid "View recent system logs related to Podkop" +msgstr "Просмотр недавних системных логов, связанных с Podkop" + +msgid "View Logs" +msgstr "Просмотр логов" + +msgid "Failed to copy logs: " +msgstr "Ошибка копирования логов: " \ No newline at end of file diff --git a/luci-app-podkop/po/templates/podkop.pot b/luci-app-podkop/po/templates/podkop.pot index d04a25f..2bb1775 100644 --- a/luci-app-podkop/po/templates/podkop.pot +++ b/luci-app-podkop/po/templates/podkop.pot @@ -290,4 +290,43 @@ msgid "JSON must contain at least type, server and server_port fields" msgstr "" msgid "Invalid JSON format" +msgstr "" + +msgid "Diagnostics" +msgstr "" + +msgid "Main Check" +msgstr "" + +msgid "Run a comprehensive diagnostic check of all components" +msgstr "" + +msgid "Run Check" +msgstr "" + +msgid "Full Diagnostic Results" +msgstr "" + +msgid "Failed to copy: " +msgstr "" + +msgid "Copy to Clipboard" +msgstr "" + +msgid "Close" +msgstr "" + +msgid "No output" +msgstr "" + +msgid "System Logs" +msgstr "" + +msgid "View recent system logs related to Podkop" +msgstr "" + +msgid "View Logs" +msgstr "" + +msgid "Failed to copy logs: " msgstr "" \ No newline at end of file From 7ba5ed6347d7df971656ce67c2feff8465390d05 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 17:41:04 +0300 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=D0=9A=D0=BD=D0=BE=D0=BF=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BE=D0=B2=20=D0=B8=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D1=81=D0=B5=D1=82=D0=B5=D0=B9=20refactor:=20=D0=9F=D0=BE=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=8F=D1=82=D1=8C=20curl=20=D0=BD=D0=B0=20wget,=20?= =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D1=82=D1=8C=20=D0=B7=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.sh | 22 ++++ .../resources/view/podkop/podkop.js | 19 +++ podkop/files/etc/init.d/podkop | 122 +++++++++--------- 3 files changed, 105 insertions(+), 58 deletions(-) diff --git a/install.sh b/install.sh index bba883f..52fc4b8 100755 --- a/install.sh +++ b/install.sh @@ -7,6 +7,8 @@ DOWNLOAD_DIR="/tmp/podkop" mkdir -p "$DOWNLOAD_DIR" main() { + check_system + wget -qO- "$REPO" | grep -o 'https://[^"]*\.ipk' | while read -r url; do filename=$(basename "$url") echo "Download $filename..." @@ -384,4 +386,24 @@ wg_awg_setup() { handler_network_restart } +check_system() { + # Get router model + MODEL=$(cat /tmp/sysinfo/model) + echo "Router model: $MODEL" + + # Check available space + AVAILABLE_SPACE=$(df /tmp | awk 'NR==2 {print $4}') + REQUIRED_SPACE=20480 # 20MB in KB + + echo "Available space: $((AVAILABLE_SPACE/1024))MB" + echo "Required space: $((REQUIRED_SPACE/1024))MB" + + if [ "$AVAILABLE_SPACE" -lt "$REQUIRED_SPACE" ]; then + echo "Error: Insufficient space in /tmp" + echo "Available: $((AVAILABLE_SPACE/1024))MB" + echo "Required: $((REQUIRED_SPACE/1024))MB" + exit 1 + fi +} + main \ No newline at end of file diff --git a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js index 49c52cb..c7ff872 100644 --- a/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js +++ b/luci-app-podkop/htdocs/luci-static/resources/view/podkop/podkop.js @@ -765,6 +765,25 @@ return view.extend({ }); }; + o = s.taboption('diagnostics', form.Button, '_list_update'); + o.title = _('Update lists'); + o.description = _('Update all lists in config'); + o.inputtitle = _('Update lists'); + o.inputstyle = 'apply'; + o.onclick = function () { + fs.exec('/etc/init.d/podkop', ['list_update']); + + ui.showModal(_('List Update'), [ + E('p', {}, _('Lists will be updated in background. You can check the progress in system logs.')), + E('div', { class: 'right' }, [ + E('button', { + 'class': 'btn', + 'click': ui.hideModal + }, _('Close')) + ]) + ]); + }; + return m.render(); } }); \ No newline at end of file diff --git a/podkop/files/etc/init.d/podkop b/podkop/files/etc/init.d/podkop index b624fd7..18c5e78 100755 --- a/podkop/files/etc/init.d/podkop +++ b/podkop/files/etc/init.d/podkop @@ -20,6 +20,16 @@ EXTRA_HELP=" list_update Updating domain and subnet lists [ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop +GITHUB_RAW_URL="https://raw.githubusercontent.com/itdoginfo/allow-domains/main" +DOMAINS_RU_INSIDE="${GITHUB_RAW_URL}/Russia/inside-dnsmasq-nfset.lst" +DOMAINS_RU_OUTSIDE="${GITHUB_RAW_URL}/Russia/outside-dnsmasq-nfset.lst" +DOMAINS_UA="${GITHUB_RAW_URL}/Ukraine/inside-dnsmasq-nfset.lst" +DOMAINS_YOUTUBE="${GITHUB_RAW_URL}/Services/youtube.lst" +SUBNETS_TWITTER="${GITHUB_RAW_URL}/Subnets/IPv4/Twitter.lst" +SUBNETS_META="${GITHUB_RAW_URL}/Subnets/IPv4/Meta.lst" +SUBNETS_DISCORD="${GITHUB_RAW_URL}/Subnets/IPv4/Discord.lst" +SING_BOX_CONFIG="/etc/sing-box/config.json" + config_get update_interval "main" "update_interval" "0 4 * * *" cron_job="${update_interval} /etc/init.d/podkop list_update" @@ -116,10 +126,10 @@ start_service() { config_get proxy_string main "proxy_string" if [[ "$proxy_string" =~ ^ss:// ]]; then sing_box_config_shadowsocks "$proxy_string" "1602" - jq '.outbounds[0] + {tag: "main"} | {outbounds: [.]}' /etc/sing-box/config.json > "$outbound_main" + jq '.outbounds[0] + {tag: "main"} | {outbounds: [.]}' $SING_BOX_CONFIG > "$outbound_main" elif [[ "$proxy_string" =~ ^vless:// ]]; then sing_box_config_vless "$proxy_string" "1602" - jq '.outbounds[0] + {tag: "main"} | {outbounds: [.]}' /etc/sing-box/config.json > "$outbound_main" + jq '.outbounds[0] + {tag: "main"} | {outbounds: [.]}' $SING_BOX_CONFIG > "$outbound_main" else log "Unsupported proxy type or missing configuration for main" rm -f "$outbound_main" "$outbound_second" @@ -144,10 +154,10 @@ start_service() { config_get proxy_string "second" "second_proxy_string" if [[ "$proxy_string" =~ ^ss:// ]]; then sing_box_config_shadowsocks "$proxy_string" "1603" - jq '.outbounds[0] + {tag: "second"} | {outbounds: [.]}' /etc/sing-box/config.json > "$outbound_second" + jq '.outbounds[0] + {tag: "second"} | {outbounds: [.]}' $SING_BOX_CONFIG > "$outbound_second" elif [[ "$proxy_string" =~ ^vless:// ]]; then sing_box_config_vless "$proxy_string" "1603" - jq '.outbounds[0] + {tag: "second"} | {outbounds: [.]}' /etc/sing-box/config.json > "$outbound_second" + jq '.outbounds[0] + {tag: "second"} | {outbounds: [.]}' $SING_BOX_CONFIG > "$outbound_second" else log "Unsupported proxy type or missing configuration for second" rm -f "$outbound_main" "$outbound_second" @@ -187,7 +197,7 @@ start_service() { ], "auto_detect_interface": true } - }' "$outbound_main" "$outbound_second" > /etc/sing-box/config.json + }' "$outbound_main" "$outbound_second" > $SING_BOX_CONFIG rm -f "$outbound_main" "$outbound_second" @@ -273,7 +283,7 @@ start_service() { jq '.experimental.clash_api = { "external_ui": "ui", "external_controller": "0.0.0.0:9090" - }' /etc/sing-box/config.json >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json /etc/sing-box/config.json + }' $SING_BOX_CONFIG >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json $SING_BOX_CONFIG /etc/init.d/sing-box restart fi @@ -285,7 +295,7 @@ start_service() { "listen": "0.0.0.0", "listen_port": 2080, "set_system_proxy": false - }]' /etc/sing-box/config.json >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json /etc/sing-box/config.json + }]' $SING_BOX_CONFIG >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json $SING_BOX_CONFIG /etc/init.d/sing-box restart fi @@ -664,19 +674,15 @@ add_mark() { lists_domains_download() { local URL="$1" - RU_INSIDE_DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/inside-dnsmasq-nfset.lst - RU_OUTSIDE_DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/outside-dnsmasq-nfset.lst - UA_DOMAINS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Ukraine/inside-dnsmasq-nfset.lst - case "$URL" in "ru_inside") - URL=$RU_INSIDE_DOMAINS + URL=$DOMAINS_RU_INSIDE ;; "ru_outside") - URL=$RU_OUTSIDE_DOMAINS + URL=$DOMAINS_RU_OUTSIDE ;; "ua") - URL=$UA_DOMAINS + URL=$DOMAINS_UA ;; *) log "Unidentified list of domains" @@ -686,10 +692,12 @@ lists_domains_download() { count=0 while true; do - if curl -m 3 github.com; then - curl -f $URL --output /tmp/dnsmasq.d/podkop-domains.lst - sed -i 's/fw4#vpn_domains/PodkopTable#podkop_domains/g' /tmp/dnsmasq.d/podkop-domains.lst - return 0 + if ping -c 1 -W 3 github.com >/dev/null 2>&1; then + wget -q -O /tmp/dnsmasq.d/podkop-domains.lst $URL + if [ $? -eq 0 ]; then + sed -i 's/fw4#vpn_domains/PodkopTable#podkop_domains/g' /tmp/dnsmasq.d/podkop-domains.lst + return 0 + fi else log "GitHub is not available. Check the internet availability [$count sec]" count=$((count + 1)) @@ -712,11 +720,9 @@ lists_domains_download() { lists_services_download() { local URL="$1" - YOUTUBE=https://raw.githubusercontent.com/itdoginfo/allow-domains/refs/heads/main/Services/youtube.lst - case "$URL" in "youtube") - URL=$YOUTUBE + URL=$DOMAINS_YOUTUBE ;; *) log "Unidentified list of domains" @@ -726,11 +732,13 @@ lists_services_download() { count=0 while true; do - if curl -m 3 github.com; then - curl -f $URL --output /tmp/dnsmasq.d/podkop2-domains.lst - delist_downloaded_domains - sed -i 's/.*/nftset=\/&\/4#inet#PodkopTable#podkop2_domains/g' /tmp/dnsmasq.d/podkop2-domains.lst - return 0 + if ping -c 1 -W 3 github.com >/dev/null 2>&1; then + wget -q -O /tmp/dnsmasq.d/podkop2-domains.lst $URL + if [ $? -eq 0 ]; then + delist_downloaded_domains + sed -i 's/.*/nftset=\/&\/4#inet#PodkopTable#podkop2_domains/g' /tmp/dnsmasq.d/podkop2-domains.lst + return 0 + fi else log "GitHub is not available. Check the internet availability [$count sec]" count=$((count + 1)) @@ -751,33 +759,31 @@ lists_services_download() { } list_subnets_download() { - TWITTER_SUBNETS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Twitter.lst - META_SUBNETS=https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Meta.lst - DISCORD_SUBNETS=https://raw.githubusercontent.com/itdoginfo/allow-domains/refs/heads/main/Subnets/IPv4/Discord.lst local URL="$1" case "$URL" in "twitter") - URL=$TWITTER_SUBNETS + URL=$SUBNETS_TWITTER ;; "meta") - URL=$META_SUBNETS + URL=$SUBNETS_META ;; "discord") - URL=$DISCORD_SUBNETS + URL=$SUBNETS_DISCORD ;; *) log "Custom URL for subnet" - if curl --output /dev/null --silent --head --fail "$URL"; then + if wget -q --spider "$URL"; then log "URL is valid" else log "URL $URL is not valid" + return fi ;; esac local filename=$(basename "$URL") - curl -f "$URL" --output "/tmp/podkop/$filename" + wget -q -O "/tmp/podkop/$filename" "$URL" while IFS= read -r subnet; do nft add element inet PodkopTable podkop_subnets { $subnet } done <"/tmp/podkop/$filename" @@ -810,7 +816,7 @@ list_custom_download_domains_create() { local config="/tmp/dnsmasq.d/${name}-${filename}.lst" rm -f "$config" - curl -f "$URL" --output "/tmp/podkop/${filename}" + wget -q -O "/tmp/podkop/${filename}" "$URL" while IFS= read -r domain; do echo "nftset=/$domain/4#inet#PodkopTable#${name}_domains" >>$config done <"/tmp/podkop/$filename" @@ -915,7 +921,7 @@ sing_box_config_outbound_json() { } EOF - jq --argjson outbound "$json_config" '.outbounds += [$outbound]' /tmp/base_config.json > /etc/sing-box/config.json + jq --argjson outbound "$json_config" '.outbounds += [$outbound]' /tmp/base_config.json > $SING_BOX_CONFIG rm -f /tmp/base_config.json } @@ -990,7 +996,7 @@ sing_box_config_shadowsocks() { } EOF - mv /tmp/ss_config.json /etc/sing-box/config.json + mv /tmp/ss_config.json $SING_BOX_CONFIG } sing_box_config_vless() { @@ -1090,7 +1096,7 @@ sing_box_config_vless() { "short_id": $sid } else . end - else . end' > /etc/sing-box/config.json + else . end' > $SING_BOX_CONFIG if [ $? -eq 0 ]; then echo "Config created successfully" @@ -1101,7 +1107,7 @@ sing_box_config_vless() { } sing_box_config_check() { - if ! sing-box -c /etc/sing-box/config.json check >/dev/null 2>&1; then + if ! sing-box -c $SING_BOX_CONFIG check >/dev/null 2>&1; then log "Sing-box configuration is invalid" return fi @@ -1113,18 +1119,26 @@ check_proxy() { return 1 fi - # Проверка конфигурации - if [ ! -f /etc/sing-box/config.json ]; then + if [ ! -f $SING_BOX_CONFIG ]; then nolog "Configuration file not found" return 1 fi - # Проверка валидности конфига - if ! sing-box -c /etc/sing-box/config.json check; then + if ! sing-box -c $SING_BOX_CONFIG check; then nolog "Invalid configuration" return 1 fi + nolog "\nCurrent sing-box configuration (sensitive data masked):" + + jq ' + .outbounds[].uuid |= "MASKED-UUID" | + .outbounds[].server |= "MASKED-SERVER" | + if .outbounds[].tls.reality.public_key then + .outbounds[].tls.reality.public_key |= "MASKED-PUBLIC-KEY" + else . end + ' $SING_BOX_CONFIG + nolog "Checking sing-box proxy connection..." for attempt in `seq 1 5`; do @@ -1133,7 +1147,8 @@ check_proxy() { : else nolog "Proxy check completed successfully" - echo "$response" + masked_ip=$(echo "$response" | sed 's/\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/XXX.\2.\3.\4/') + echo "$masked_ip" return 0 fi done @@ -1173,27 +1188,18 @@ check_nft() { check_github() { nolog "Checking GitHub connectivity..." - # Проверка базового соединения с GitHub - if ! curl -m 3 -sf https://github.com >/dev/null 2>&1; then + if ! ping -c 1 -W 3 github.com >/dev/null 2>&1; then nolog "Error: Cannot connect to GitHub" return 1 fi nolog "GitHub is accessible" - # Список URL для проверки - local urls=" - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/inside-dnsmasq-nfset.lst - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Russia/outside-dnsmasq-nfset.lst - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Ukraine/inside-dnsmasq-nfset.lst - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Services/youtube.lst - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Twitter.lst - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Meta.lst - https://raw.githubusercontent.com/itdoginfo/allow-domains/main/Subnets/IPv4/Discord.lst" - nolog "Checking lists availability:" - for url in $urls; do + for url in "$DOMAINS_RU_INSIDE" "$DOMAINS_RU_OUTSIDE" "$DOMAINS_UA" "$DOMAINS_YOUTUBE" \ + "$SUBNETS_TWITTER" "$SUBNETS_META" "$SUBNETS_DISCORD"; do local list_name=$(basename "$url") - if curl -m 5 -sf "$url" >/dev/null 2>&1; then + wget -q -O /dev/null "$url" + if [ $? -eq 0 ]; then nolog "- $list_name: available" else nolog "- $list_name: not available" From 2fb89b34b57a76956e27951647d5c98476aa8fe8 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 17:49:16 +0300 Subject: [PATCH 6/8] chore: small rename --- podkop/files/etc/init.d/podkop | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/podkop/files/etc/init.d/podkop b/podkop/files/etc/init.d/podkop index 18c5e78..daac780 100755 --- a/podkop/files/etc/init.d/podkop +++ b/podkop/files/etc/init.d/podkop @@ -1129,7 +1129,7 @@ check_proxy() { return 1 fi - nolog "\nCurrent sing-box configuration (sensitive data masked):" + nolog "Checking sing-box configuration..." jq ' .outbounds[].uuid |= "MASKED-UUID" | @@ -1138,7 +1138,7 @@ check_proxy() { .outbounds[].tls.reality.public_key |= "MASKED-PUBLIC-KEY" else . end ' $SING_BOX_CONFIG - + nolog "Checking sing-box proxy connection..." for attempt in `seq 1 5`; do From ab5e0afb9287256022991fd65c34fa0390b6215a Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 18:07:01 +0300 Subject: [PATCH 7/8] fix: jq double output with 2 outputs in sing-box config --- podkop/files/etc/init.d/podkop | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/podkop/files/etc/init.d/podkop b/podkop/files/etc/init.d/podkop index daac780..80db37d 100755 --- a/podkop/files/etc/init.d/podkop +++ b/podkop/files/etc/init.d/podkop @@ -1124,31 +1124,28 @@ check_proxy() { return 1 fi - if ! sing-box -c $SING_BOX_CONFIG check; then + nolog "Checking sing-box configuration..." + + if ! sing-box -c $SING_BOX_CONFIG check >/dev/null; then nolog "Invalid configuration" return 1 fi - nolog "Checking sing-box configuration..." - jq ' - .outbounds[].uuid |= "MASKED-UUID" | - .outbounds[].server |= "MASKED-SERVER" | - if .outbounds[].tls.reality.public_key then - .outbounds[].tls.reality.public_key |= "MASKED-PUBLIC-KEY" - else . end + .outbounds |= map(. + { + uuid: "MASKED-UUID", + server: "MASKED-SERVER", + tls: (if .tls.reality then .tls + {reality: (.reality + {public_key: "MASKED-PUBLIC-KEY"})} else .tls end) + }) ' $SING_BOX_CONFIG - nolog "Checking sing-box proxy connection..." + nolog "Checking proxy connection..." for attempt in `seq 1 5`; do - response=$(sing-box tools fetch ifconfig.me -D /etc/sing-box) - if echo "$response" | grep -q "403 Forbidden"; then - : - else + response=$(sing-box tools fetch ifconfig.me -D /etc/sing-box 2>/dev/null) + if ! echo "$response" | grep -q "403 Forbidden"; then nolog "Proxy check completed successfully" - masked_ip=$(echo "$response" | sed 's/\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/XXX.\2.\3.\4/') - echo "$masked_ip" + echo "$response" | sed 's/\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/XXX.\2.\3.\4/' return 0 fi done From e31b8b79a4252be6c36ed1c77b1aaf393e05eb32 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Fri, 13 Dec 2024 19:28:34 +0300 Subject: [PATCH 8/8] refactor: Improve proxy config masking --- podkop/files/etc/init.d/podkop | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/podkop/files/etc/init.d/podkop b/podkop/files/etc/init.d/podkop index 80db37d..4df7664 100755 --- a/podkop/files/etc/init.d/podkop +++ b/podkop/files/etc/init.d/podkop @@ -1132,12 +1132,15 @@ check_proxy() { fi jq ' - .outbounds |= map(. + { - uuid: "MASKED-UUID", - server: "MASKED-SERVER", - tls: (if .tls.reality then .tls + {reality: (.reality + {public_key: "MASKED-PUBLIC-KEY"})} else .tls end) - }) - ' $SING_BOX_CONFIG + walk( + if type == "object" then + with_entries( + if [.key] | inside(["uuid", "server", "server_name", "password", "public_key", "short_id"]) then + .value = "MASKED" + else . end + ) + else . end + )' $SING_BOX_CONFIG nolog "Checking proxy connection..."