Merge pull request #96 from itdoginfo/chore/sing-box-status
Issue #91 , Issue #94
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,32 @@ 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';
|
||||
formattedOutput += ' ➡️ ' + _('FAKEIP BROWSER TEST') + '\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 +697,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 +720,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 +822,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 +912,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 +1450,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 +1530,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 +1538,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 ""
|
||||
@@ -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"
|
||||
@@ -1953,9 +1954,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 +2045,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 +2152,33 @@ 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 "📦 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)"
|
||||
|
||||
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 " ➡️ CONFIGURATION"
|
||||
show_config
|
||||
printf "\n"
|
||||
|
||||
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 " ➡️ 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
|
||||
nolog "❌ /etc/resolv.conf contains an external nameserver:"
|
||||
print_global "❌ /etc/resolv.conf contains external nameserver:"
|
||||
cat /etc/resolv.conf
|
||||
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 +2186,31 @@ 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:"
|
||||
print_global "❌ DHCP configuration differs from template:"
|
||||
awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp
|
||||
elif [ "$(uci get podkop.main.dont_touch_dhcp 2>/dev/null)" = "1" ]; then
|
||||
nolog "⚠️ Enable dont_touch_dhcp. 📄 DHCP config:"
|
||||
print_global "⚠️ dont_touch_dhcp is enabled:"
|
||||
awk '/^config /{p=($2=="dnsmasq")} p' /etc/config/dhcp
|
||||
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 is not running"
|
||||
else
|
||||
nolog "✅ sing-box is running"
|
||||
print_global "✅ sing-box is running"
|
||||
fi
|
||||
|
||||
nolog "📄 NFT Table Podkop"
|
||||
print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
print_global " ➡️ NFT RULES"
|
||||
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
|
||||
fi
|
||||
|
||||
nolog "📄 WAN config"
|
||||
print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
print_global " ➡️ WAN CONFIG"
|
||||
if uci show network.wan >/dev/null 2>&1; then
|
||||
awk '
|
||||
/^config / {
|
||||
@@ -2286,26 +2231,65 @@ global_check() {
|
||||
}
|
||||
' /etc/config/network
|
||||
else
|
||||
nolog "WAN not exists"
|
||||
print_global "❌ WAN configuration not found"
|
||||
fi
|
||||
|
||||
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"
|
||||
|
||||
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"
|
||||
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 "━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
print_global " ➡️ WARP DETECTION"
|
||||
print_global "⚠️ WARP detected: $host"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
print_global "━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
print_global " ➡️ FAKEIP ROUTER TEST"
|
||||
|
||||
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