mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 11:36:50 +03:00
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.
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 "Глобальная проверка"
|
||||
@@ -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 ""
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user