From 48716e71562d6659a6e4d11bad75fb2afc181f6e Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 17:18:07 +0300 Subject: [PATCH 1/7] Enhance Podkop functionality with global check feature and improved diagnostics. Added support for FakeIP tests in both browser and router contexts. Updated UI elements for better status reporting and added localization for new messages. --- .../resources/view/podkop/podkop.js | 326 +++++++++++++----- luci-app-podkop/po/ru/podkop.po | 24 ++ luci-app-podkop/po/templates/podkop.pot | 24 ++ podkop/files/usr/bin/podkop | 200 +++++------ 4 files changed, 391 insertions(+), 183 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 5fe0886..27f6a67 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 @@ -63,20 +63,20 @@ function getNetworkInterfaces(o, section_id, excludeInterfaces = []) { } function getNetworkNetworks(o, section_id, excludeInterfaces = []) { - return network.getNetworks().then(networks => { - o.keylist = []; - o.vallist = []; + return network.getNetworks().then(networks => { + o.keylist = []; + o.vallist = []; - networks.forEach(net => { - const name = net.getName(); - const ifname = net.getIfname(); - if (name && !excludeInterfaces.includes(name)) { - o.value(name, ifname ? `${name} (${ifname})` : name); - } - }); - }).catch(error => { - console.error('Failed to get networks:', error); - }); + networks.forEach(net => { + const name = net.getName(); + const ifname = net.getIfname(); + if (name && !excludeInterfaces.includes(name)) { + o.value(name, ifname ? `${name} (${ifname})` : name); + } + }); + }).catch(error => { + console.error('Failed to get networks:', error); + }); } function createConfigSection(section, map, network) { @@ -623,7 +623,33 @@ const createModalContent = (title, content) => { const showConfigModal = async (command, title) => { const res = await safeExec('/usr/bin/podkop', [command]); - const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); + let formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); + + if (command === 'global_check') { + try { + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); + + const response = await fetch('https://fakeip.tech-domain.club/check', { signal: controller.signal }); + const data = await response.json(); + clearTimeout(timeoutId); + + formattedOutput += '\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'; + formattedOutput += ' ' + _('FAKEIP BROWSER TEST') + '\n'; + formattedOutput += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n'; + + if (data.fakeip === true) { + formattedOutput += '✅ ' + _('FakeIP is working in browser!') + '\n'; + } else { + formattedOutput += '❌ ' + _('FakeIP is not working in browser') + '\n'; + formattedOutput += _('Check DNS server on current device (PC, phone)') + '\n'; + formattedOutput += _('Its must be router!') + '\n'; + } + } catch (error) { + formattedOutput += '\n❌ ' + _('Check failed: ') + (error.name === 'AbortError' ? _('timeout') : error.message) + '\n'; + } + } + ui.showModal(_(title), createModalContent(_(title), formattedOutput)); }; @@ -672,11 +698,18 @@ const createStatusPanel = (title, status, buttons) => { E('strong', {}, _(title)), status && E('br'), status && E('span', { - 'style': `color: ${status.running ? STATUS_COLORS.SUCCESS : STATUS_COLORS.ERROR}` + 'style': `color: ${title === 'Sing-box Status' ? + (status.running && !status.enabled ? STATUS_COLORS.SUCCESS : STATUS_COLORS.ERROR) : + title === 'Podkop Status' ? + (status.enabled ? STATUS_COLORS.SUCCESS : STATUS_COLORS.ERROR) : + (status.running ? STATUS_COLORS.SUCCESS : STATUS_COLORS.ERROR) + }` }, [ - status.running ? '✔' : '✘', - ' ', - status.status + title === 'Sing-box Status' ? + (status.running && !status.enabled ? '✔ running' : '✘ ' + status.status) : + title === 'Podkop Status' ? + (status.enabled ? '✔ enabled' : '✘ disabled') : + (status.running ? '✔' : '✘') + ' ' + status.status ]) ].filter(Boolean); @@ -688,7 +721,80 @@ const createStatusPanel = (title, status, buttons) => { E('div', { 'class': 'panel-body', 'style': 'display: flex; flex-direction: column; gap: 8px;' - }, buttons) + }, title === 'Podkop Status' ? [ + ButtonFactory.createActionButton({ + label: 'Restart Podkop', + type: 'apply', + action: 'restart', + reload: true + }), + ButtonFactory.createInitActionButton({ + label: status.enabled ? 'Disable Podkop' : 'Enable Podkop', + type: status.enabled ? 'remove' : 'apply', + action: status.enabled ? 'disable' : 'enable', + reload: true + }), + ButtonFactory.createModalButton({ + label: _('Global check'), + command: 'global_check', + title: _('Click here for all the info') + }), + ButtonFactory.createModalButton({ + label: 'View Logs', + command: 'check_logs', + title: 'Podkop Logs' + }), + ButtonFactory.createModalButton({ + label: _('Update Lists'), + command: 'list_update', + title: _('Lists Update Results') + }) + ] : title === 'FakeIP Status' ? [ + E('div', { style: 'margin-bottom: 10px;' }, [ + E('div', { style: 'margin-bottom: 5px;' }, [ + E('span', { style: `color: ${fakeipStatus.color}` }, [ + fakeipStatus.state === 'working' ? '✔' : fakeipStatus.state === 'not_working' ? '✘' : '!', + ' ', + fakeipStatus.state === 'working' ? _('works in browser') : _('not works in browser') + ]) + ]), + E('div', {}, [ + E('span', { style: `color: ${fakeipCLIStatus.color}` }, [ + fakeipCLIStatus.state === 'working' ? '✔' : fakeipCLIStatus.state === 'not_working' ? '✘' : '!', + ' ', + fakeipCLIStatus.state === 'working' ? _('works on router') : _('not works on router') + ]) + ]) + ]), + E('div', { style: 'margin-bottom: 10px;' }, [ + E('div', { style: 'margin-bottom: 5px;' }, [ + E('strong', {}, _('DNS Status')), + E('br'), + E('span', { style: `color: ${dnsStatus.remote.color}` }, [ + dnsStatus.remote.state === 'available' ? '✔' : dnsStatus.remote.state === 'unavailable' ? '✘' : '!', + ' ', + dnsStatus.remote.message + ]), + E('br'), + E('span', { style: `color: ${dnsStatus.local.color}` }, [ + dnsStatus.local.state === 'available' ? '✔' : dnsStatus.local.state === 'unavailable' ? '✘' : '!', + ' ', + dnsStatus.local.message + ]) + ]) + ]), + E('div', { style: 'margin-bottom: 10px;' }, [ + E('div', { style: 'margin-bottom: 5px;' }, [ + E('strong', {}, configName), + E('br'), + E('span', { style: `color: ${bypassStatus.color}` }, [ + bypassStatus.state === 'working' ? '✔' : bypassStatus.state === 'not_working' ? '✘' : '!', + ' ', + bypassStatus.message + ]) + ]) + ]) + ] : buttons) ]); }; @@ -717,9 +823,9 @@ let createStatusSection = function (podkopStatus, singboxStatus, podkop, luci, s reload: true }), ButtonFactory.createModalButton({ - label: 'Show Config', - command: 'show_config', - title: 'Podkop Configuration' + label: _('Global check'), + command: 'global_check', + title: _('Click here for all the info') }), ButtonFactory.createModalButton({ label: 'View Logs', @@ -807,12 +913,7 @@ let createStatusSection = function (podkopStatus, singboxStatus, podkop, luci, s bypassStatus.message ]) ]) - ]), - ButtonFactory.createModalButton({ - label: _('Global check'), - command: 'global_check', - title: _('Click here for all the info') - }) + ]) ]), // Version Information Panel @@ -1350,32 +1451,67 @@ return view.extend({ async function updateDiagnostics() { try { - const [ - podkopStatus, - singboxStatus, - podkop, - luci, - singbox, - system, - fakeipStatus, - fakeipCLIStatus, - dnsStatus, - bypassStatus - ] = await Promise.all([ - safeExec('/usr/bin/podkop', ['get_status']), - safeExec('/usr/bin/podkop', ['get_sing_box_status']), - safeExec('/usr/bin/podkop', ['show_version']), - safeExec('/usr/bin/podkop', ['show_luci_version']), - safeExec('/usr/bin/podkop', ['show_sing_box_version']), - safeExec('/usr/bin/podkop', ['show_system_info']), - checkFakeIP(), - checkFakeIPCLI(), - checkDNSAvailability(), - checkBypass() - ]); + const results = { + podkopStatus: null, + singboxStatus: null, + podkop: null, + luci: null, + singbox: null, + system: null, + fakeipStatus: null, + fakeipCLIStatus: null, + dnsStatus: null, + bypassStatus: null + }; - const parsedPodkopStatus = JSON.parse(podkopStatus.stdout || '{"running":0,"enabled":0,"status":"unknown"}'); - const parsedSingboxStatus = JSON.parse(singboxStatus.stdout || '{"running":0,"enabled":0,"status":"unknown"}'); + // Выполняем все проверки независимо друг от друга + const checks = [ + safeExec('/usr/bin/podkop', ['get_status']) + .then(result => results.podkopStatus = result) + .catch(() => results.podkopStatus = { stdout: '{"enabled":0,"status":"error"}' }), + + safeExec('/usr/bin/podkop', ['get_sing_box_status']) + .then(result => results.singboxStatus = result) + .catch(() => results.singboxStatus = { stdout: '{"running":0,"enabled":0,"status":"error"}' }), + + safeExec('/usr/bin/podkop', ['show_version']) + .then(result => results.podkop = result) + .catch(() => results.podkop = { stdout: 'error' }), + + safeExec('/usr/bin/podkop', ['show_luci_version']) + .then(result => results.luci = result) + .catch(() => results.luci = { stdout: 'error' }), + + safeExec('/usr/bin/podkop', ['show_sing_box_version']) + .then(result => results.singbox = result) + .catch(() => results.singbox = { stdout: 'error' }), + + safeExec('/usr/bin/podkop', ['show_system_info']) + .then(result => results.system = result) + .catch(() => results.system = { stdout: 'error' }), + + checkFakeIP() + .then(result => results.fakeipStatus = result) + .catch(() => results.fakeipStatus = { state: 'error', message: 'check error', color: STATUS_COLORS.WARNING }), + + checkFakeIPCLI() + .then(result => results.fakeipCLIStatus = result) + .catch(() => results.fakeipCLIStatus = { state: 'error', message: 'check error', color: STATUS_COLORS.WARNING }), + + checkDNSAvailability() + .then(result => results.dnsStatus = result) + .catch(() => results.dnsStatus = { + remote: { state: 'error', message: 'check error', color: STATUS_COLORS.WARNING }, + local: { state: 'error', message: 'check error', color: STATUS_COLORS.WARNING } + }), + + checkBypass() + .then(result => results.bypassStatus = result) + .catch(() => results.bypassStatus = { state: 'error', message: 'check error', color: STATUS_COLORS.WARNING }) + ]; + + // Ждем завершения всех проверок + await Promise.allSettled(checks); const container = document.getElementById('diagnostics-status'); if (!container) return; @@ -1395,11 +1531,7 @@ return view.extend({ const label = activeConfig.split('#').pop(); if (label && label.trim()) { configName = _('Config: ') + decodeURIComponent(label); - } else { - configName = _('Main config'); } - } else { - configName = _('Main config'); } } } @@ -1407,42 +1539,62 @@ return view.extend({ console.error('Error getting config name from UCI:', e); } - // Create a modified statusSection function with the configName - const statusSection = createStatusSection(parsedPodkopStatus, parsedSingboxStatus, podkop, luci, singbox, system, fakeipStatus, fakeipCLIStatus, dnsStatus, bypassStatus, configName); + const parsedPodkopStatus = JSON.parse(results.podkopStatus.stdout || '{"enabled":0,"status":"error"}'); + const parsedSingboxStatus = JSON.parse(results.singboxStatus.stdout || '{"running":0,"enabled":0,"status":"error"}'); + + const statusSection = createStatusSection( + parsedPodkopStatus, + parsedSingboxStatus, + results.podkop, + results.luci, + results.singbox, + results.system, + results.fakeipStatus, + results.fakeipCLIStatus, + results.dnsStatus, + results.bypassStatus, + configName + ); + container.innerHTML = ''; container.appendChild(statusSection); - const fakeipElement = document.getElementById('fakeip-status'); - if (fakeipElement) { - fakeipElement.innerHTML = E('span', { 'style': `color: ${fakeipStatus.color}` }, [ - fakeipStatus.state === 'working' ? '✔ ' : fakeipStatus.state === 'not_working' ? '✘ ' : '! ', - fakeipStatus.message - ]).outerHTML; - } + // Обновляем отдельные элементы статуса + const updateStatusElement = (elementId, status, template) => { + const element = document.getElementById(elementId); + if (element) { + element.innerHTML = template(status); + } + }; - const fakeipCLIElement = document.getElementById('fakeip-cli-status'); - if (fakeipCLIElement) { - fakeipCLIElement.innerHTML = E('span', { 'style': `color: ${fakeipCLIStatus.color}` }, [ - fakeipCLIStatus.state === 'working' ? '✔ ' : fakeipCLIStatus.state === 'not_working' ? '✘ ' : '! ', - fakeipCLIStatus.message - ]).outerHTML; - } + updateStatusElement('fakeip-status', results.fakeipStatus, + status => E('span', { 'style': `color: ${status.color}` }, [ + status.state === 'working' ? '✔ ' : status.state === 'not_working' ? '✘ ' : '! ', + status.message + ]).outerHTML + ); - const dnsRemoteElement = document.getElementById('dns-remote-status'); - if (dnsRemoteElement) { - dnsRemoteElement.innerHTML = E('span', { 'style': `color: ${dnsStatus.remote.color}` }, [ - dnsStatus.remote.state === 'available' ? '✔ ' : dnsStatus.remote.state === 'unavailable' ? '✘ ' : '! ', - dnsStatus.remote.message - ]).outerHTML; - } + updateStatusElement('fakeip-cli-status', results.fakeipCLIStatus, + status => E('span', { 'style': `color: ${status.color}` }, [ + status.state === 'working' ? '✔ ' : status.state === 'not_working' ? '✘ ' : '! ', + status.message + ]).outerHTML + ); + + updateStatusElement('dns-remote-status', results.dnsStatus.remote, + status => E('span', { 'style': `color: ${status.color}` }, [ + status.state === 'available' ? '✔ ' : status.state === 'unavailable' ? '✘ ' : '! ', + status.message + ]).outerHTML + ); + + updateStatusElement('dns-local-status', results.dnsStatus.local, + status => E('span', { 'style': `color: ${status.color}` }, [ + status.state === 'available' ? '✔ ' : status.state === 'unavailable' ? '✘ ' : '! ', + status.message + ]).outerHTML + ); - const dnsLocalElement = document.getElementById('dns-local-status'); - if (dnsLocalElement) { - dnsLocalElement.innerHTML = E('span', { 'style': `color: ${dnsStatus.local.color}` }, [ - dnsStatus.local.state === 'available' ? '✔ ' : dnsStatus.local.state === 'unavailable' ? '✘ ' : '! ', - dnsStatus.local.message - ]).outerHTML; - } } catch (e) { const container = document.getElementById('diagnostics-status'); if (container) { diff --git a/luci-app-podkop/po/ru/podkop.po b/luci-app-podkop/po/ru/podkop.po index 6b1ff8e..b1ba065 100644 --- a/luci-app-podkop/po/ru/podkop.po +++ b/luci-app-podkop/po/ru/podkop.po @@ -819,3 +819,27 @@ msgstr "недоступен" msgid "Apply for SS2022" msgstr "Применить для SS2022" + +msgid "PODKOP CONFIGURATION" +msgstr "КОНФИГУРАЦИЯ PODKOP" + +msgid "FAKEIP ROUTER TEST" +msgstr "ПРОВЕРКА FAKEIP НА РОУТЕРЕ" + +msgid "FAKEIP BROWSER TEST" +msgstr "ПРОВЕРКА FAKEIP В БРАУЗЕРЕ" + +msgid "FakeIP is working correctly on router (198.18.x.x)" +msgstr "FakeIP работает корректно на роутере (198.18.x.x)" + +msgid "Click here for all the info" +msgstr "Нажмите для просмотра всей информации" + +msgid "Check DNS server on current device (PC, phone)" +msgstr "Проверьте DNS сервер на текущем устройстве (ПК, телефон)" + +msgid "Its must be router!" +msgstr "Это должен быть роутер!" + +msgid "Global check" +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 c017151..f668555 100644 --- a/luci-app-podkop/po/templates/podkop.pot +++ b/luci-app-podkop/po/templates/podkop.pot @@ -1169,4 +1169,28 @@ msgid "available" msgstr "" msgid "unavailable" +msgstr "" + +msgid "PODKOP CONFIGURATION" +msgstr "" + +msgid "FAKEIP ROUTER TEST" +msgstr "" + +msgid "FAKEIP BROWSER TEST" +msgstr "" + +msgid "FakeIP is working correctly on router (198.18.x.x)" +msgstr "" + +msgid "Click here for all the info" +msgstr "" + +msgid "Check DNS server on current device (PC, phone)" +msgstr "" + +msgid "Its must be router!" +msgstr "" + +msgid "Global check" msgstr "" \ No newline at end of file diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 52f2779..c4953f6 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -1953,9 +1953,7 @@ show_sing_box_config() { )' "$SING_BOX_CONFIG" } -show_config() { - nolog "📄 Current podkop configuration:" - +show_config() { if [ ! -f /etc/config/podkop ]; then nolog "Configuration file not found" return 1 @@ -2046,36 +2044,18 @@ get_sing_box_status() { } get_status() { - local running=0 local enabled=0 local status="" # Check if service is enabled if [ -x /etc/rc.d/S99podkop ]; then enabled=1 - fi - - # Check if service is running - if pgrep -f "sing-box" >/dev/null; then - running=1 - fi - - # Format status message - if [ $running -eq 1 ]; then - if [ $enabled -eq 1 ]; then - status="running & enabled" - else - status="running but disabled" - fi + status="enabled" else - if [ $enabled -eq 1 ]; then - status="stopped but enabled" - else - status="stopped & disabled" - fi + status="disabled" fi - echo "{\"running\":$running,\"enabled\":$enabled,\"status\":\"$status\"}" + echo "{\"enabled\":$enabled,\"status\":\"$status\"}" } check_dns_available() { @@ -2171,71 +2151,39 @@ sing_box_add_secure_dns_probe_domain() { log "DNS probe domain ${domain} configured with override to port ${override_port}" } +print_global() { + local message="$1" + echo "$message" +} + global_check() { - nolog "📡 Global check run!" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " SYSTEM INFO" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "📦 Podkop: $(opkg list-installed podkop | awk '{print $3}')" + print_global "📦 LuCI App: $(opkg list-installed luci-app-podkop | awk '{print $3}')" + print_global "📦 Sing-box: $(sing-box version | head -n 1 | awk '{print $3}')" + print_global "🔧 OpenWrt: $(grep OPENWRT_RELEASE /etc/os-release | cut -d'"' -f2)" + print_global "💻 Device: $(cat /tmp/sysinfo/model)" + print_global "" - nolog "Podkop $(opkg list-installed podkop | awk '{print $3}')" - nolog "LuCi App $(opkg list-installed luci-app-podkop | awk '{print $3}')" - nolog "Sing-box $(sing-box version | head -n 1 | awk '{print $3}')" - nolog "$(grep OPENWRT_RELEASE /etc/os-release | cut -d'"' -f2)" - nolog "Device: $(cat /tmp/sysinfo/model)" - - printf "\n" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " PODKOP CONFIGURATION" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" show_config - printf "\n" + print_global "" - nolog "Checking fakeip functionality..." - - nolog "➡️ DNS resolution: system DNS server" - nslookup -timeout=2 $TEST_DOMAIN - - local working_resolver=$(find_working_resolver) - if [ -z "$working_resolver" ]; then - nolog "❌ No working resolver found, skipping resolver check" - else - nolog "➡️ DNS resolution: external resolver ($working_resolver)" - nslookup -timeout=2 $TEST_DOMAIN $working_resolver - fi - - # Main FakeIP check - nolog "➡️ DNS resolution: sing-box DNS server (127.0.0.42)" - local result=$(nslookup -timeout=2 $TEST_DOMAIN 127.0.0.42 2>&1) - echo "$result" - - if echo "$result" | grep -q "198.18"; then - nolog "✅ FakeIP is working correctly! Domain resolved to FakeIP range (198.18.x.x)" - else - nolog "❌ FakeIP test failed. Domain did not resolve to FakeIP range" - nolog "Checking if sing-box is running..." - - if ! pgrep -f "sing-box" >/dev/null; then - nolog "sing-box is not running" - else - nolog "sing-box is running, but FakeIP might not be configured correctly" - nolog "Checking DNS configuration in sing-box..." - - if [ -f "$SING_BOX_CONFIG" ]; then - local fakeip_enabled=$(jq -r '.dns.fakeip.enabled' "$SING_BOX_CONFIG") - local fakeip_range=$(jq -r '.dns.fakeip.inet4_range' "$SING_BOX_CONFIG") - - nolog "FakeIP enabled: $fakeip_enabled" - nolog "FakeIP range: $fakeip_range" - - local dns_rules=$(jq -r '.dns.rules[] | select(.server == "fakeip-server") | .domain' "$SING_BOX_CONFIG") - nolog "FakeIP domain: $dns_rules" - else - nolog "sing-box config file not found" - fi - fi - fi - printf "\n" + print_global "" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " SYSTEM CHECKS" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" if grep -E "^nameserver\s+([0-9]{1,3}\.){3}[0-9]{1,3}" "$RESOLV_CONF" | grep -vqE "127\.0\.0\.1|0\.0\.0\.0"; then - nolog "❌ /etc/resolv.conf contains an external nameserver:" - cat /etc/resolv.conf + print_global "❌ /etc/resolv.conf contains external nameserver:" + cat /etc/resolv.conf | sed 's/^/ /' echo "" else - nolog "✅ /etc/resolv.conf OK" + print_global "✅ /etc/resolv.conf - OK" fi cachesize="$(uci get dhcp.@dnsmasq[0].cachesize 2>/dev/null)" @@ -2243,29 +2191,35 @@ global_check() { server="$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)" if [ "$cachesize" != "0" ] || [ "$noresolv" != "1" ] || [ "$server" != "127.0.0.42" ]; then - nolog "❌ The configuration differs from the template. 📄 DHCP config:" - awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp + print_global "❌ DHCP configuration differs from template:" + awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp | sed 's/^/ /' elif [ "$(uci get podkop.main.dont_touch_dhcp 2>/dev/null)" = "1" ]; then - nolog "⚠️ Enable dont_touch_dhcp. 📄 DHCP config:" - awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp + print_global "⚠️ dont_touch_dhcp is enabled:" + awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp | sed 's/^/ /' else - nolog "✅ /etc/config/dhcp" + print_global "✅ DHCP configuration - OK" fi if ! pgrep -f "sing-box" >/dev/null; then - nolog "❌ sing-box is not running" + print_global "❌ sing-box process - not running" else - nolog "✅ sing-box is running" + print_global "✅ sing-box process - running" fi - nolog "📄 NFT Table Podkop" + print_global "" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " NFT RULES" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" if ! nft list table inet PodkopTable >/dev/null 2>&1; then - nolog "PodkopTable not found" + print_global "❌ PodkopTable not found" else - nft list table inet PodkopTable + nft list table inet PodkopTable | sed 's/^/ /' fi - nolog "📄 WAN config" + print_global "" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " WAN CONFIG" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" if uci show network.wan >/dev/null 2>&1; then awk ' /^config / { @@ -2284,28 +2238,82 @@ global_check() { print } } - ' /etc/config/network + ' /etc/config/network | sed 's/^/ /' else - nolog "WAN not exists" + print_global "❌ WAN configuration not found" fi + print_global "" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " WARP DETECTION" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + CLOUDFLARE_OCTETS="103.21 103.22 103.31 104.16 104.17 104.18 104.19 104.20 104.21 104.22 104.23 \ 104.24 104.25 104.26 104.27 104.28 108.162 131.0 141.101 162.158 162.159 172.64 172.65 172.66 \ 172.67 172.68 172.69 172.70 172.71 173.245 188.114 190.93 197.234 198.41" + local warp_found=0 if uci show network | grep -q endpoint_host; then uci show network | grep endpoint_host | cut -d'=' -f2 | tr -d "'\" " | while read -r host; do if [ "$host" = "engage.cloudflareclient.com" ]; then - nolog "⚠️ WARP detected ($host)" + print_global "⚠️ WARP detected: $host" + warp_found=1 continue fi ip_prefix=$(echo "$host" | cut -d'.' -f1,2) if echo "$CLOUDFLARE_OCTETS" | grep -wq "$ip_prefix"; then - nolog "⚠️ WARP detected ($host)" + print_global "⚠️ WARP detected: $host" + warp_found=1 fi done fi + + if [ "$warp_found" -eq 0 ]; then + print_global "✅ No WARP configurations detected" + fi + + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " FAKEIP ROUTER TEST" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + print_global "🔍 Testing system DNS resolver..." + nslookup -timeout=2 $TEST_DOMAIN + + local working_resolver=$(find_working_resolver) + if [ -z "$working_resolver" ]; then + print_global "❌ No working external resolver found" + else + print_global "🔍 Testing external resolver ($working_resolver)..." + nslookup -timeout=2 $TEST_DOMAIN $working_resolver + fi + + print_global "🔍 Testing sing-box DNS server (127.0.0.42)..." + local result=$(nslookup -timeout=2 $TEST_DOMAIN 127.0.0.42 2>&1) + echo "$result" + + if echo "$result" | grep -q "198.18"; then + print_global "✅ FakeIP is working correctly on router (198.18.x.x)" + else + print_global "❌ FakeIP test failed - domain did not resolve to FakeIP range" + if ! pgrep -f "sing-box" >/dev/null; then + print_global " └─ sing-box is not running" + else + print_global " └─ sing-box is running, checking configuration..." + + if [ -f "$SING_BOX_CONFIG" ]; then + local fakeip_enabled=$(jq -r '.dns.fakeip.enabled' "$SING_BOX_CONFIG") + local fakeip_range=$(jq -r '.dns.fakeip.inet4_range' "$SING_BOX_CONFIG") + local dns_rules=$(jq -r '.dns.rules[] | select(.server == "fakeip-server") | .domain' "$SING_BOX_CONFIG") + + print_global " ├─ FakeIP enabled: $fakeip_enabled" + print_global " ├─ FakeIP range: $fakeip_range" + print_global " └─ FakeIP domain: $dns_rules" + else + print_global " └─ sing-box config file not found" + fi + fi + fi } case "$1" in From 05272de650ba5e11d69da9c99fdb0f1ab0abb1bf Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 17:48:25 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=F0=9F=92=84=20style(podkop):=20update=20fo?= =?UTF-8?q?rmatting=20and=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/view/podkop/podkop.js | 5 +- podkop/files/usr/bin/podkop | 63 +++++++------------ 2 files changed, 23 insertions(+), 45 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 27f6a67..66af555 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 @@ -634,9 +634,8 @@ const showConfigModal = async (command, title) => { const data = await response.json(); clearTimeout(timeoutId); - formattedOutput += '\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'; - formattedOutput += ' ' + _('FAKEIP BROWSER TEST') + '\n'; - formattedOutput += '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n'; + formattedOutput += '\n━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'; + formattedOutput += ' ➡️ ' + _('FAKEIP BROWSER TEST') + '\n'; if (data.fakeip === true) { formattedOutput += '✅ ' + _('FakeIP is working in browser!') + '\n'; diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index c4953f6..3908f50 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -24,6 +24,7 @@ TEST_DOMAIN="fakeip.tech-domain.club" INTERFACES_LIST="" SRC_INTERFACE="" RESOLV_CONF="/etc/resolv.conf" +CLOUDFLARE_OCTETS="103.21 103.22 103.31 104.16 104.17 104.18 104.19 104.20 104.21 104.22 104.23 104.24 104.25 104.26 104.27 104.28 108.162 131.0 141.101 162.158 162.159 172.64 172.65 172.66 172.67 172.68 172.69 172.70 172.71 173.245 188.114 190.93 197.234 198.41" log() { local message="$1" @@ -2157,26 +2158,20 @@ print_global() { } global_check() { - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " SYSTEM INFO" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ➡️ SYSTEM INFO" print_global "📦 Podkop: $(opkg list-installed podkop | awk '{print $3}')" print_global "📦 LuCI App: $(opkg list-installed luci-app-podkop | awk '{print $3}')" print_global "📦 Sing-box: $(sing-box version | head -n 1 | awk '{print $3}')" print_global "🔧 OpenWrt: $(grep OPENWRT_RELEASE /etc/os-release | cut -d'"' -f2)" print_global "💻 Device: $(cat /tmp/sysinfo/model)" - print_global "" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " PODKOP CONFIGURATION" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ➡️ CONFIGURATION" show_config - print_global "" - print_global "" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " SYSTEM CHECKS" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ➡️ SYSTEM CHECKS" if grep -E "^nameserver\s+([0-9]{1,3}\.){3}[0-9]{1,3}" "$RESOLV_CONF" | grep -vqE "127\.0\.0\.1|0\.0\.0\.0"; then print_global "❌ /etc/resolv.conf contains external nameserver:" @@ -2206,20 +2201,16 @@ global_check() { print_global "✅ sing-box process - running" fi - print_global "" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " NFT RULES" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ➡️ NFT RULES" if ! nft list table inet PodkopTable >/dev/null 2>&1; then print_global "❌ PodkopTable not found" else nft list table inet PodkopTable | sed 's/^/ /' fi - print_global "" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " WAN CONFIG" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ➡️ WAN CONFIG" if uci show network.wan >/dev/null 2>&1; then awk ' /^config / { @@ -2243,15 +2234,6 @@ global_check() { print_global "❌ WAN configuration not found" fi - print_global "" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " WARP DETECTION" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - - CLOUDFLARE_OCTETS="103.21 103.22 103.31 104.16 104.17 104.18 104.19 104.20 104.21 104.22 104.23 \ - 104.24 104.25 104.26 104.27 104.28 108.162 131.0 141.101 162.158 162.159 172.64 172.65 172.66 \ - 172.67 172.68 172.69 172.70 172.71 173.245 188.114 190.93 197.234 198.41" - local warp_found=0 if uci show network | grep -q endpoint_host; then uci show network | grep endpoint_host | cut -d'=' -f2 | tr -d "'\" " | while read -r host; do @@ -2263,19 +2245,16 @@ global_check() { ip_prefix=$(echo "$host" | cut -d'.' -f1,2) if echo "$CLOUDFLARE_OCTETS" | grep -wq "$ip_prefix"; then + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ⚡ WARP DETECTION" print_global "⚠️ WARP detected: $host" warp_found=1 fi done fi - - if [ "$warp_found" -eq 0 ]; then - print_global "✅ No WARP configurations detected" - fi - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " FAKEIP ROUTER TEST" - print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" + print_global " ➡️ FAKEIP ROUTER TEST" print_global "🔍 Testing system DNS resolver..." nslookup -timeout=2 $TEST_DOMAIN @@ -2297,20 +2276,20 @@ global_check() { else print_global "❌ FakeIP test failed - domain did not resolve to FakeIP range" if ! pgrep -f "sing-box" >/dev/null; then - print_global " └─ sing-box is not running" + print_global " └─ sing-box is not running" else - print_global " └─ sing-box is running, checking configuration..." + print_global " └─ sing-box is running, checking configuration..." if [ -f "$SING_BOX_CONFIG" ]; then local fakeip_enabled=$(jq -r '.dns.fakeip.enabled' "$SING_BOX_CONFIG") local fakeip_range=$(jq -r '.dns.fakeip.inet4_range' "$SING_BOX_CONFIG") local dns_rules=$(jq -r '.dns.rules[] | select(.server == "fakeip-server") | .domain' "$SING_BOX_CONFIG") - print_global " ├─ FakeIP enabled: $fakeip_enabled" - print_global " ├─ FakeIP range: $fakeip_range" - print_global " └─ FakeIP domain: $dns_rules" + print_global " ├─ FakeIP enabled: $fakeip_enabled" + print_global " ├─ FakeIP range: $fakeip_range" + print_global " └─ FakeIP domain: $dns_rules" else - print_global " └─ sing-box config file not found" + print_global " └─ sing-box config file not found" fi fi fi From e59ef6dd6f233b4ae5e95825a3e5bcf8d600b729 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 17:57:51 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=92=84=20style(podkop):=20remove=20un?= =?UTF-8?q?necessary=20sed=20commands=20in=20global=5Fcheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- podkop/files/usr/bin/podkop | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 3908f50..e36c365 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -2175,7 +2175,7 @@ global_check() { if grep -E "^nameserver\s+([0-9]{1,3}\.){3}[0-9]{1,3}" "$RESOLV_CONF" | grep -vqE "127\.0\.0\.1|0\.0\.0\.0"; then print_global "❌ /etc/resolv.conf contains external nameserver:" - cat /etc/resolv.conf | sed 's/^/ /' + cat /etc/resolv.conf echo "" else print_global "✅ /etc/resolv.conf - OK" @@ -2187,18 +2187,18 @@ global_check() { if [ "$cachesize" != "0" ] || [ "$noresolv" != "1" ] || [ "$server" != "127.0.0.42" ]; then print_global "❌ DHCP configuration differs from template:" - awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp | sed 's/^/ /' + awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp elif [ "$(uci get podkop.main.dont_touch_dhcp 2>/dev/null)" = "1" ]; then print_global "⚠️ dont_touch_dhcp is enabled:" - awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp | sed 's/^/ /' + awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp else print_global "✅ DHCP configuration - OK" fi if ! pgrep -f "sing-box" >/dev/null; then - print_global "❌ sing-box process - not running" + print_global "❌ sing-box is not running" else - print_global "✅ sing-box process - running" + print_global "✅ sing-box is running" fi print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" @@ -2206,7 +2206,7 @@ global_check() { if ! nft list table inet PodkopTable >/dev/null 2>&1; then print_global "❌ PodkopTable not found" else - nft list table inet PodkopTable | sed 's/^/ /' + nft list table inet PodkopTable fi print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" @@ -2229,7 +2229,7 @@ global_check() { print } } - ' /etc/config/network | sed 's/^/ /' + ' /etc/config/network else print_global "❌ WAN configuration not found" fi From 65f72e1e041078a4aefb672d0cd7597ba27772c9 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 18:29:42 +0300 Subject: [PATCH 4/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(podkop):=20up?= =?UTF-8?q?date=20WARP=20detection=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- podkop/files/usr/bin/podkop | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index e36c365..7283c8f 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -2234,21 +2234,18 @@ global_check() { print_global "❌ WAN configuration not found" fi - local warp_found=0 if uci show network | grep -q endpoint_host; then uci show network | grep endpoint_host | cut -d'=' -f2 | tr -d "'\" " | while read -r host; do if [ "$host" = "engage.cloudflareclient.com" ]; then print_global "⚠️ WARP detected: $host" - warp_found=1 continue fi ip_prefix=$(echo "$host" | cut -d'.' -f1,2) if echo "$CLOUDFLARE_OCTETS" | grep -wq "$ip_prefix"; then print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━" - print_global " ⚡ WARP DETECTION" + print_global " ➡️ WARP DETECTION" print_global "⚠️ WARP detected: $host" - warp_found=1 fi done fi From b364363b1bbfbc660561a777ea754b083227b75d Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 19:20:36 +0300 Subject: [PATCH 5/7] =?UTF-8?q?=E2=9C=A8=20feat(dns):=20add=20DoH=20URL=20?= =?UTF-8?q?resolution=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- podkop/files/usr/bin/podkop | 81 ++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 24 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 7283c8f..1b5014a 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -688,6 +688,46 @@ sing_box_inbound_proxy() { }' > $SING_BOX_CONFIG } +get_doh_url() { + local dns_server="$1" + local url="" + + # Special case for Quad9 servers + if echo "$dns_server" | grep -q "quad9.net" || \ + echo "$dns_server" | grep -qE "^9\.9\.9\.(9|10|11)$|^149\.112\.112\.(112|10|11)$|^2620:fe::(fe|9|10|11)$|^2620:fe::fe:(10|11)$"; then + url="https://$dns_server:5053/dns-query" + if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then + echo "$url" + return 0 + fi + fi + + # Try standard DoH path first (most common) + url="https://$dns_server/dns-query" + if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then + echo "$url" + return 0 + fi + + # Try alternative path + url="https://$dns_server/resolve" + if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then + echo "$url" + return 0 + fi + + # Try root path + url="https://$dns_server" + if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then + echo "$url" + return 0 + fi + + # If no paths worked, return error + echo "error: no working DoH endpoint found for $dns_server" + return 1 +} + sing_box_dns() { local dns_type local dns_server @@ -711,25 +751,30 @@ sing_box_dns() { fi log "Configure DNS in sing-box" + + local dns_address="" + if [ "$dns_type" = "doh" ]; then + dns_address=$(get_doh_url "$dns_server") + if [ $? -ne 0 ] || [ "${dns_address#error:}" != "$dns_address" ]; then + log "[critical] Failed to get working DoH URL for $dns_server" + exit 1 + fi + elif [ "$dns_type" = "dot" ]; then + dns_address="tls://$dns_server" + else + dns_address="$dns_server" + fi server_json=$(jq -n \ --arg type "$dns_type" \ - --arg server "$dns_server" \ + --arg address "$dns_address" \ --arg resolver "$resolver_tag" \ --arg is_ip "$is_ip" \ '{ "servers": [ { "tag": "dns-server", - "address": ( - if $type == "doh" then - "https://" + $server + "/dns-query" - elif $type == "dot" then - "tls://" + $server - else - $server - end - ), + "address": $address, "detour": "direct-out" } + ( if $is_ip == "0" then @@ -2078,20 +2123,8 @@ check_dns_available() { fi if [ "$dns_type" = "doh" ]; then - local result="" - - if echo "$dns_server" | grep -q "quad9.net" || \ - echo "$dns_server" | grep -qE "^9\.9\.9\.(9|10|11)$|^149\.112\.112\.(112|10|11)$|^2620:fe::(fe|9|10|11)$|^2620:fe::fe:(10|11)$"; then - result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server:5053/dns-query?name=itdog.info&type=A") - else - result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/dns-query?name=itdog.info&type=A") - if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then - is_available=1 - status="available" - else - result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/resolve?name=itdog.info&type=A") - fi - fi + local doh_url=$(get_doh_url "$dns_server") + local result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "$doh_url?name=itdog.info&type=A") if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then is_available=1 From 26c3d0bc7e8121113196cbab5b3617cbb93881fb Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 19:26:21 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(podkop):=20si?= =?UTF-8?q?mplify=20DoH=20URL=20determination=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- podkop/files/usr/bin/podkop | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 1b5014a..92eb9a9 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -702,20 +702,6 @@ get_doh_url() { fi fi - # Try standard DoH path first (most common) - url="https://$dns_server/dns-query" - if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then - echo "$url" - return 0 - fi - - # Try alternative path - url="https://$dns_server/resolve" - if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then - echo "$url" - return 0 - fi - # Try root path url="https://$dns_server" if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then @@ -723,9 +709,10 @@ get_doh_url() { return 0 fi - # If no paths worked, return error - echo "error: no working DoH endpoint found for $dns_server" - return 1 + # Try standard DoH path first (most common) + url="https://$dns_server/dns-query" + echo "$url" + return 0 } sing_box_dns() { @@ -755,10 +742,6 @@ sing_box_dns() { local dns_address="" if [ "$dns_type" = "doh" ]; then dns_address=$(get_doh_url "$dns_server") - if [ $? -ne 0 ] || [ "${dns_address#error:}" != "$dns_address" ]; then - log "[critical] Failed to get working DoH URL for $dns_server" - exit 1 - fi elif [ "$dns_type" = "dot" ]; then dns_address="tls://$dns_server" else From 2939229df30f5b73e4959fcdea49f92f14148998 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Thu, 1 May 2025 19:30:05 +0300 Subject: [PATCH 7/7] back to the future --- podkop/files/usr/bin/podkop | 64 ++++++++++++++----------------------- 1 file changed, 24 insertions(+), 40 deletions(-) diff --git a/podkop/files/usr/bin/podkop b/podkop/files/usr/bin/podkop index 92eb9a9..7283c8f 100755 --- a/podkop/files/usr/bin/podkop +++ b/podkop/files/usr/bin/podkop @@ -688,33 +688,6 @@ sing_box_inbound_proxy() { }' > $SING_BOX_CONFIG } -get_doh_url() { - local dns_server="$1" - local url="" - - # Special case for Quad9 servers - if echo "$dns_server" | grep -q "quad9.net" || \ - echo "$dns_server" | grep -qE "^9\.9\.9\.(9|10|11)$|^149\.112\.112\.(112|10|11)$|^2620:fe::(fe|9|10|11)$|^2620:fe::fe:(10|11)$"; then - url="https://$dns_server:5053/dns-query" - if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then - echo "$url" - return 0 - fi - fi - - # Try root path - url="https://$dns_server" - if curl --connect-timeout 3 -s -o /dev/null -w "%{http_code}" -H "accept: application/dns-json" "$url?name=example.com&type=A" 2>/dev/null | grep -q "200"; then - echo "$url" - return 0 - fi - - # Try standard DoH path first (most common) - url="https://$dns_server/dns-query" - echo "$url" - return 0 -} - sing_box_dns() { local dns_type local dns_server @@ -738,26 +711,25 @@ sing_box_dns() { fi log "Configure DNS in sing-box" - - local dns_address="" - if [ "$dns_type" = "doh" ]; then - dns_address=$(get_doh_url "$dns_server") - elif [ "$dns_type" = "dot" ]; then - dns_address="tls://$dns_server" - else - dns_address="$dns_server" - fi server_json=$(jq -n \ --arg type "$dns_type" \ - --arg address "$dns_address" \ + --arg server "$dns_server" \ --arg resolver "$resolver_tag" \ --arg is_ip "$is_ip" \ '{ "servers": [ { "tag": "dns-server", - "address": $address, + "address": ( + if $type == "doh" then + "https://" + $server + "/dns-query" + elif $type == "dot" then + "tls://" + $server + else + $server + end + ), "detour": "direct-out" } + ( if $is_ip == "0" then @@ -2106,8 +2078,20 @@ check_dns_available() { fi if [ "$dns_type" = "doh" ]; then - local doh_url=$(get_doh_url "$dns_server") - local result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "$doh_url?name=itdog.info&type=A") + local result="" + + if echo "$dns_server" | grep -q "quad9.net" || \ + echo "$dns_server" | grep -qE "^9\.9\.9\.(9|10|11)$|^149\.112\.112\.(112|10|11)$|^2620:fe::(fe|9|10|11)$|^2620:fe::fe:(10|11)$"; then + result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server:5053/dns-query?name=itdog.info&type=A") + else + result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/dns-query?name=itdog.info&type=A") + if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then + is_available=1 + status="available" + else + result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/resolve?name=itdog.info&type=A") + fi + fi if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then is_available=1