Compare commits

...

4 Commits

Author SHA1 Message Date
itdoginfo
251f94cb88 v0.3.26 2025-03-12 14:59:03 +03:00
itdoginfo
44936c698e Merge pull request #62 from itdoginfo/chore/fakeip-method
feat: add CLI check for FakeIP functionality and update status display
2025-03-12 14:57:41 +03:00
Ivan K
0faaca12fc сhore: remove tabs 2025-03-12 14:54:56 +03:00
Ivan K
c6d1f05916 feat: add CLI check for FakeIP functionality and update status display 2025-03-11 19:14:21 +03:00
6 changed files with 211 additions and 42 deletions

View File

@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-podkop PKG_NAME:=luci-app-podkop
PKG_VERSION:=0.3.25 PKG_VERSION:=0.3.26
PKG_RELEASE:=1 PKG_RELEASE:=1
LUCI_TITLE:=LuCI podkop app LUCI_TITLE:=LuCI podkop app

View File

@@ -591,7 +591,7 @@ const createModalContent = (title, content) => {
const showConfigModal = async (command, title) => { const showConfigModal = async (command, title) => {
const res = await safeExec('/usr/bin/podkop', [command]); const res = await safeExec('/usr/bin/podkop', [command]);
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_(title), createModalContent(title, formattedOutput)); ui.showModal(_(title), createModalContent(_(title), formattedOutput));
}; };
// Button Factory // Button Factory
@@ -650,7 +650,7 @@ const createStatusPanel = (title, status, buttons) => {
}; };
// Update the status section creation // Update the status section creation
let createStatusSection = function (podkopStatus, singboxStatus, podkop, luci, singbox, system, fakeipStatus) { let createStatusSection = function (podkopStatus, singboxStatus, podkop, luci, singbox, system, fakeipStatus, fakeipCLIStatus) {
return E('div', { 'class': 'cbi-section' }, [ return E('div', { 'class': 'cbi-section' }, [
E('h3', {}, _('Service Status')), E('h3', {}, _('Service Status')),
E('div', { 'class': 'table', style: 'display: flex; gap: 20px;' }, [ E('div', { 'class': 'table', style: 'display: flex; gap: 20px;' }, [
@@ -712,36 +712,54 @@ let createStatusSection = function (podkopStatus, singboxStatus, podkop, luci, s
}) })
]), ]),
// FakeIP Status Panel with dynamic status // FakeIP Status Panel with both browser and router checks
createStatusPanel('FakeIP Status', { createStatusPanel(_('FakeIP Status'), null, [
running: fakeipStatus.state === 'working', E('div', { style: 'margin-bottom: 10px;' }, [
status: fakeipStatus.message 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')
])
])
]),
ButtonFactory.createModalButton({ ButtonFactory.createModalButton({
label: 'Check NFT Rules', label: _('Check NFT Rules'),
command: 'check_nft', command: 'check_nft',
title: 'NFT Rules' title: _('NFT Rules')
}), }),
ButtonFactory.createModalButton({ ButtonFactory.createModalButton({
label: 'Check DNSMasq', label: _('Check DNSMasq'),
command: 'check_dnsmasq', command: 'check_dnsmasq',
title: 'DNSMasq Configuration' title: _('DNSMasq Configuration')
}), }),
ButtonFactory.createModalButton({ ButtonFactory.createModalButton({
label: 'Update Lists', label: _('Update Lists'),
command: 'list_update', command: 'list_update',
title: 'Lists Update Results' title: _('Lists Update Results')
}),
ButtonFactory.createModalButton({
label: _('Check Router FakeIP'),
command: 'check_fakeip',
title: _('FakeIP Router Check')
}) })
]), ]),
// Version Information Panel // Version Information Panel
createStatusPanel('Version Information', null, [ createStatusPanel(_('Version Information'), null, [
E('div', { 'style': 'margin-top: 10px; font-family: monospace; white-space: pre-wrap;' }, [ E('div', { 'style': 'margin-top: 10px; font-family: monospace; white-space: pre-wrap;' }, [
E('strong', {}, 'Podkop: '), podkop.stdout ? podkop.stdout.trim() : _('Unknown'), '\n', E('strong', {}, _('Podkop: ')), podkop.stdout ? podkop.stdout.trim() : _('Unknown'), '\n',
E('strong', {}, 'LuCI App: '), luci.stdout ? luci.stdout.trim() : _('Unknown'), '\n', E('strong', {}, _('LuCI App: ')), luci.stdout ? luci.stdout.trim() : _('Unknown'), '\n',
E('strong', {}, 'Sing-box: '), singbox.stdout ? singbox.stdout.trim() : _('Unknown'), '\n', E('strong', {}, _('Sing-box: ')), singbox.stdout ? singbox.stdout.trim() : _('Unknown'), '\n',
E('strong', {}, 'OpenWrt Version: '), system.stdout ? system.stdout.split('\n')[1].trim() : _('Unknown'), '\n', E('strong', {}, _('OpenWrt Version: ')), system.stdout ? system.stdout.split('\n')[1].trim() : _('Unknown'), '\n',
E('strong', {}, 'Device Model: '), system.stdout ? system.stdout.split('\n')[4].trim() : _('Unknown') E('strong', {}, _('Device Model: ')), system.stdout ? system.stdout.split('\n')[4].trim() : _('Unknown')
]) ])
]) ])
]) ])
@@ -957,17 +975,15 @@ return view.extend({
const timeoutId = setTimeout(() => controller.abort(), 10000); const timeoutId = setTimeout(() => controller.abort(), 10000);
try { try {
const response = await fetch('http://httpbin.org/ip', { signal: controller.signal }); const response = await fetch('https://fakeip.tech-domain.club/check', { signal: controller.signal });
const text = await response.text(); const data = await response.json();
clearTimeout(timeoutId); clearTimeout(timeoutId);
if (text.includes('Cannot GET /ip')) { if (data.fakeip === true) {
return resolve(createStatus('working', 'working', 'SUCCESS')); return resolve(createStatus('working', 'working', 'SUCCESS'));
} } else {
if (text.includes('"origin":')) {
return resolve(createStatus('not_working', 'not working', 'ERROR')); return resolve(createStatus('not_working', 'not working', 'ERROR'));
} }
return resolve(createStatus('error', 'check error', 'WARNING'));
} catch (fetchError) { } catch (fetchError) {
clearTimeout(timeoutId); clearTimeout(timeoutId);
const message = fetchError.name === 'AbortError' ? 'timeout' : 'check error'; const message = fetchError.name === 'AbortError' ? 'timeout' : 'check error';
@@ -980,6 +996,39 @@ return view.extend({
}); });
} }
function checkFakeIPCLI() {
const createStatus = (state, message, color) => ({
state,
message: _(message),
color: STATUS_COLORS[color]
});
return new Promise(async (resolve) => {
try {
const singboxStatusResult = await safeExec('/usr/bin/podkop', ['get_sing_box_status']);
const singboxStatus = JSON.parse(singboxStatusResult.stdout || '{"running":0,"dns_configured":0}');
if (!singboxStatus.running) {
return resolve(createStatus('not_working', 'sing-box not running', 'ERROR'));
}
if (!singboxStatus.dns_configured) {
return resolve(createStatus('not_working', 'DNS not configured', 'ERROR'));
}
const fakeipResult = await safeExec('/usr/bin/podkop', ['check_fakeip']);
if (fakeipResult.stdout && fakeipResult.stdout.includes('198.18')) {
return resolve(createStatus('working', 'FakeIP working (CLI)', 'SUCCESS'));
} else {
return resolve(createStatus('not_working', 'FakeIP not working (CLI)', 'ERROR'));
}
} catch (error) {
console.error('Error in checkFakeIPCLI:', error);
return resolve(createStatus('error', 'CLI check error', 'WARNING'));
}
});
}
async function updateDiagnostics() { async function updateDiagnostics() {
try { try {
const [ const [
@@ -989,7 +1038,8 @@ return view.extend({
luci, luci,
singbox, singbox,
system, system,
fakeipStatus fakeipStatus,
fakeipCLIStatus
] = await Promise.all([ ] = await Promise.all([
safeExec('/usr/bin/podkop', ['get_status']), safeExec('/usr/bin/podkop', ['get_status']),
safeExec('/usr/bin/podkop', ['get_sing_box_status']), safeExec('/usr/bin/podkop', ['get_sing_box_status']),
@@ -997,7 +1047,8 @@ return view.extend({
safeExec('/usr/bin/podkop', ['show_luci_version']), safeExec('/usr/bin/podkop', ['show_luci_version']),
safeExec('/usr/bin/podkop', ['show_sing_box_version']), safeExec('/usr/bin/podkop', ['show_sing_box_version']),
safeExec('/usr/bin/podkop', ['show_system_info']), safeExec('/usr/bin/podkop', ['show_system_info']),
checkFakeIP() checkFakeIP(),
checkFakeIPCLI()
]); ]);
const parsedPodkopStatus = JSON.parse(podkopStatus.stdout || '{"running":0,"enabled":0,"status":"unknown"}'); const parsedPodkopStatus = JSON.parse(podkopStatus.stdout || '{"running":0,"enabled":0,"status":"unknown"}');
@@ -1006,7 +1057,7 @@ return view.extend({
const container = document.getElementById('diagnostics-status'); const container = document.getElementById('diagnostics-status');
if (!container) return; if (!container) return;
const statusSection = createStatusSection(parsedPodkopStatus, parsedSingboxStatus, podkop, luci, singbox, system, fakeipStatus); const statusSection = createStatusSection(parsedPodkopStatus, parsedSingboxStatus, podkop, luci, singbox, system, fakeipStatus, fakeipCLIStatus);
container.innerHTML = ''; container.innerHTML = '';
container.appendChild(statusSection); container.appendChild(statusSection);
@@ -1017,6 +1068,14 @@ return view.extend({
fakeipStatus.message fakeipStatus.message
]).outerHTML; ]).outerHTML;
} }
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;
}
} catch (e) { } catch (e) {
console.error('Error updating diagnostics:', e); console.error('Error updating diagnostics:', e);
const container = document.getElementById('diagnostics-status'); const container = document.getElementById('diagnostics-status');
@@ -1049,6 +1108,7 @@ return view.extend({
const singboxStatusResult = await safeExec('/usr/bin/podkop', ['get_sing_box_status']); const singboxStatusResult = await safeExec('/usr/bin/podkop', ['get_sing_box_status']);
const singboxStatus = JSON.parse(singboxStatusResult.stdout || '{"running":0,"dns_configured":0}'); const singboxStatus = JSON.parse(singboxStatusResult.stdout || '{"running":0,"dns_configured":0}');
const fakeipStatus = await checkFakeIP(); const fakeipStatus = await checkFakeIP();
const fakeipCLIStatus = await checkFakeIPCLI();
titleDiv.textContent = versionText + (!singboxStatus.running || !singboxStatus.dns_configured === 'not_working' ? ' (not working)' : ''); titleDiv.textContent = versionText + (!singboxStatus.running || !singboxStatus.dns_configured === 'not_working' ? ' (not working)' : '');

View File

@@ -723,3 +723,27 @@ msgstr "остановлен, но активирован"
msgid "stopped & disabled" msgid "stopped & disabled"
msgstr "остановлен и деактивирован" msgstr "остановлен и деактивирован"
msgid "works in browser"
msgstr "работает в браузере"
msgid "works on router"
msgstr "работает на роутере"
msgid "Check Router FakeIP"
msgstr "Проверить FakeIP на роутере"
msgid "FakeIP Router Check"
msgstr "Проверка FakeIP на роутере"
msgid "FakeIP CLI Check"
msgstr "Проверка FakeIP через CLI"
msgid "FakeIP CLI Check Results"
msgstr "Результаты проверки FakeIP через CLI"
msgid "not works in browser"
msgstr "не работает в браузере"
msgid "not works on router"
msgstr "не работает на роутере"

View File

@@ -1077,3 +1077,27 @@ msgstr ""
msgid "stopped & disabled" msgid "stopped & disabled"
msgstr "" msgstr ""
msgid "works in browser"
msgstr ""
msgid "works on router"
msgstr ""
msgid "Check Router FakeIP"
msgstr ""
msgid "FakeIP Router Check"
msgstr ""
msgid "FakeIP CLI Check"
msgstr ""
msgid "FakeIP CLI Check Results"
msgstr ""
msgid "not works in browser"
msgstr ""
msgid "not works on router"
msgstr ""

View File

@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=podkop PKG_NAME:=podkop
PKG_VERSION:=0.3.25 PKG_VERSION:=0.3.26
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_MAINTAINER:=ITDog <podkop@itdog.info> PKG_MAINTAINER:=ITDog <podkop@itdog.info>

View File

@@ -1709,6 +1709,69 @@ check_sing_box_logs() {
echo "$logs" echo "$logs"
} }
check_fakeip() {
nolog "Checking fakeip functionality..."
if ! command -v nslookup >/dev/null 2>&1; then
nolog "nslookup is not installed"
return 1
fi
local test_domain="fakeip.tech-domain.club"
# Additional DNS checks with different servers
nolog "Testing DNS resolution with default DNS server"
echo "=== Testing with default DNS server ==="
nslookup $test_domain
echo ""
nolog "Testing DNS resolution with Google DNS (8.8.8.8)"
echo "=== Testing with Google DNS (8.8.8.8) ==="
nslookup $test_domain 8.8.8.8
echo ""
nolog "Testing DNS resolution with Cloudflare DNS (1.1.1.1)"
echo "=== Testing with Cloudflare DNS (1.1.1.1) ==="
nslookup $test_domain 1.1.1.1
echo ""
# Main FakeIP check
nolog "Testing DNS resolution for $test_domain using 127.0.0.42"
echo "=== Testing with FakeIP DNS (127.0.0.42) ==="
local result=$(nslookup $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)"
return 0
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
return 1
fi
}
check_logs() { check_logs() {
nolog "Showing podkop logs from system journal..." nolog "Showing podkop logs from system journal..."
@@ -1878,19 +1941,14 @@ get_status() {
} }
sing_box_add_secure_dns_probe_domain() { sing_box_add_secure_dns_probe_domain() {
local domain="httpbin.org" local domain="fakeip.tech-domain.club"
local override_address="numbersapi.com" local override_port=8443
if [ -z "$override_address" ]; then
log "Error: Could not get br-lan IP address"
return 1
fi
log "Adding DNS probe domain ${domain} to fakeip-server configuration" log "Adding DNS probe domain ${domain} to fakeip-server configuration"
jq \ jq \
--arg domain "$domain" \ --arg domain "$domain" \
--arg override "$override_address" \ --argjson override_port "$override_port" \
'.dns.rules |= map( '.dns.rules |= map(
if .server == "fakeip-server" then if .server == "fakeip-server" then
. + { . + {
@@ -1904,11 +1962,11 @@ sing_box_add_secure_dns_probe_domain() {
{ {
"domain": $domain, "domain": $domain,
"action": "route-options", "action": "route-options",
"override_address": $override "override_port": $override_port
} }
]' "$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG" ]' "$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
log "DNS probe domain ${domain} configured with override to ${override_address}" log "DNS probe domain ${domain} configured with override to port ${override_port}"
} }
case "$1" in case "$1" in
@@ -1946,6 +2004,9 @@ case "$1" in
check_sing_box_logs) check_sing_box_logs)
check_sing_box_logs check_sing_box_logs
;; ;;
check_fakeip)
check_fakeip
;;
check_dnsmasq) check_dnsmasq)
check_dnsmasq check_dnsmasq
;; ;;
@@ -1974,7 +2035,7 @@ case "$1" in
get_sing_box_status get_sing_box_status
;; ;;
*) *)
echo "Usage: $0 {start|stop|restart|reload|enable|disable|main|list_update|check_proxy|check_nft|check_github|check_logs|check_sing_box_connections|check_sing_box_logs|check_dnsmasq|show_config|show_version|show_sing_box_config|show_luci_version|show_sing_box_version|show_system_info|get_status|get_sing_box_status}" echo "Usage: $0 {start|stop|restart|reload|enable|disable|main|list_update|check_proxy|check_nft|check_github|check_logs|check_sing_box_connections|check_sing_box_logs|check_fakeip|check_dnsmasq|show_config|show_version|show_sing_box_config|show_luci_version|show_sing_box_version|show_system_info|get_status|get_sing_box_status}"
exit 1 exit 1
;; ;;
esac esac