Merge pull request #27 from VizzleTF/main

Поправил диагностику
This commit is contained in:
itdoginfo
2025-02-17 19:41:26 +03:00
committed by GitHub
4 changed files with 532 additions and 122 deletions

View File

@@ -442,18 +442,17 @@ return view.extend({
`: ${status === 'available' ? '✓' : '✗'}`); `: ${status === 'available' ? '✓' : '✗'}`);
} }
// Check All - full diagnostic // Connection Checks Section
o = s.taboption('diagnostics', form.Button, '_check_all'); o = s.taboption('diagnostics', form.Button, '_check_nft');
o.title = _('Main Check'); o.title = _('NFT Rules');
o.description = _('Run a comprehensive diagnostic check of all components'); o.description = _('Show current nftables rules and statistics');
o.inputtitle = _('Run Check'); o.inputtitle = _('Check Rules');
o.inputstyle = 'apply'; o.inputstyle = 'apply';
o.onclick = function () { o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['check_three']) return fs.exec('/etc/init.d/podkop', ['check_nft'])
.then(function (res) { .then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('NFT Rules'), [
const modalElement = ui.showModal(_('Full Diagnostic Results'), [
E('div', { E('div', {
style: style:
'max-height: 70vh;' + 'max-height: 70vh;' +
@@ -478,7 +477,7 @@ return view.extend({
'class': 'btn', 'class': 'btn',
'click': function () { 'click': function () {
const textarea = document.createElement('textarea'); const textarea = document.createElement('textarea');
textarea.value = '```txt\n' + formattedOutput + '\n```'; textarea.value = formattedOutput;
document.body.appendChild(textarea); document.body.appendChild(textarea);
textarea.select(); textarea.select();
try { try {
@@ -494,27 +493,77 @@ return view.extend({
'click': ui.hideModal 'click': ui.hideModal
}, _('Close')) }, _('Close'))
]) ])
], 'large'); ]);
});
};
if (modalElement && modalElement.parentElement) {
modalElement.parentElement.style.width = '90%';
modalElement.parentElement.style.maxWidth = '1200px'; // Logs Section
modalElement.parentElement.style.margin = '2rem auto'; o = s.taboption('diagnostics', form.Button, '_check_sing_box_logs');
} o.title = _('Sing-Box Logs');
o.description = _('View recent sing-box logs from system journal');
o.inputtitle = _('View Sing-Box Logs');
o.inputstyle = 'apply';
o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['check_sing_box_logs'])
.then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('Sing-Box Logs'), [
E('div', {
style:
'max-height: 70vh;' +
'overflow-y: auto;' +
'margin: 1em 0;' +
'padding: 1.5em;' +
'background: #f8f9fa;' +
'border: 1px solid #e9ecef;' +
'border-radius: 4px;' +
'font-family: monospace;' +
'white-space: pre-wrap;' +
'word-wrap: break-word;' +
'line-height: 1.5;' +
'font-size: 14px;'
}, [
E('pre', { style: 'margin: 0;' }, formattedOutput)
]),
E('div', {
style: 'display: flex; justify-content: space-between; margin-top: 1em;'
}, [
E('button', {
'class': 'btn',
'click': function () {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
document.body.removeChild(textarea);
}
}, _('Copy to Clipboard')),
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Close'))
])
]);
}); });
}; };
o = s.taboption('diagnostics', form.Button, '_check_logs'); o = s.taboption('diagnostics', form.Button, '_check_logs');
o.title = _('System Logs'); o.title = _('Podkop Logs');
o.description = _('View recent system logs related to Podkop'); o.description = _('View recent podkop logs from system journal');
o.inputtitle = _('View Logs'); o.inputtitle = _('View Podkop Logs');
o.inputstyle = 'apply'; o.inputstyle = 'apply';
o.onclick = function () { o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['check_logs']) return fs.exec('/etc/init.d/podkop', ['check_logs'])
.then(function (res) { .then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('Podkop Logs'), [
const modalElement = ui.showModal(_('System Logs'), [
E('div', { E('div', {
style: style:
'max-height: 70vh;' + 'max-height: 70vh;' +
@@ -539,7 +588,7 @@ return view.extend({
'class': 'btn', 'class': 'btn',
'click': function () { 'click': function () {
const textarea = document.createElement('textarea'); const textarea = document.createElement('textarea');
textarea.value = '```txt\n' + formattedOutput + '\n```'; textarea.value = formattedOutput;
document.body.appendChild(textarea); document.body.appendChild(textarea);
textarea.select(); textarea.select();
try { try {
@@ -555,18 +604,175 @@ return view.extend({
'click': ui.hideModal 'click': ui.hideModal
}, _('Close')) }, _('Close'))
]) ])
], 'large'); ]);
});
};
if (modalElement && modalElement.parentElement) { // Configurations Section
modalElement.parentElement.style.width = '90%'; o = s.taboption('diagnostics', form.Button, '_check_sing_box_connections');
modalElement.parentElement.style.maxWidth = '1200px'; o.title = _('Active Connections');
modalElement.parentElement.style.margin = '2rem auto'; o.description = _('View active sing-box network connections');
} o.inputtitle = _('Check Connections');
o.inputstyle = 'apply';
o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['check_sing_box_connections'])
.then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('Active Connections'), [
E('div', {
style:
'max-height: 70vh;' +
'overflow-y: auto;' +
'margin: 1em 0;' +
'padding: 1.5em;' +
'background: #f8f9fa;' +
'border: 1px solid #e9ecef;' +
'border-radius: 4px;' +
'font-family: monospace;' +
'white-space: pre-wrap;' +
'word-wrap: break-word;' +
'line-height: 1.5;' +
'font-size: 14px;'
}, [
E('pre', { style: 'margin: 0;' }, formattedOutput)
]),
E('div', {
style: 'display: flex; justify-content: space-between; margin-top: 1em;'
}, [
E('button', {
'class': 'btn',
'click': function () {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
document.body.removeChild(textarea);
}
}, _('Copy to Clipboard')),
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Close'))
])
]);
});
};
o = s.taboption('diagnostics', form.Button, '_check_dnsmasq');
o.title = _('DNSMasq Configuration');
o.description = _('View current DNSMasq configuration settings');
o.inputtitle = _('Check DNSMasq');
o.inputstyle = 'apply';
o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['check_dnsmasq'])
.then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('DNSMasq Configuration'), [
E('div', {
style:
'max-height: 70vh;' +
'overflow-y: auto;' +
'margin: 1em 0;' +
'padding: 1.5em;' +
'background: #f8f9fa;' +
'border: 1px solid #e9ecef;' +
'border-radius: 4px;' +
'font-family: monospace;' +
'white-space: pre-wrap;' +
'word-wrap: break-word;' +
'line-height: 1.5;' +
'font-size: 14px;'
}, [
E('pre', { style: 'margin: 0;' }, formattedOutput)
]),
E('div', {
style: 'display: flex; justify-content: space-between; margin-top: 1em;'
}, [
E('button', {
'class': 'btn',
'click': function () {
const textarea = document.createElement('textarea');
textarea.value = formattedOutput;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
document.body.removeChild(textarea);
}
}, _('Copy to Clipboard')),
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Close'))
])
]);
});
};
o = s.taboption('diagnostics', form.Button, '_show_sing_box_config');
o.title = _('Sing-Box Configuration');
o.description = _('Show current sing-box configuration');
o.inputtitle = _('Show Sing-Box Config');
o.inputstyle = 'apply';
o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['show_sing_box_config'])
.then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('Sing-Box Configuration'), [
E('div', {
style:
'max-height: 70vh;' +
'overflow-y: auto;' +
'margin: 1em 0;' +
'padding: 1.5em;' +
'background: #f8f9fa;' +
'border: 1px solid #e9ecef;' +
'border-radius: 4px;' +
'font-family: monospace;' +
'white-space: pre-wrap;' +
'word-wrap: break-word;' +
'line-height: 1.5;' +
'font-size: 14px;'
}, [
E('pre', { style: 'margin: 0;' }, formattedOutput)
]),
E('div', {
style: 'display: flex; justify-content: space-between; margin-top: 1em;'
}, [
E('button', {
'class': 'btn',
'click': function () {
const textarea = document.createElement('textarea');
textarea.value = '```json\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
document.body.removeChild(textarea);
}
}, _('Copy to Clipboard')),
E('button', {
'class': 'btn',
'click': ui.hideModal
}, _('Close'))
])
]);
}); });
}; };
o = s.taboption('diagnostics', form.Button, '_show_config'); o = s.taboption('diagnostics', form.Button, '_show_config');
o.title = _('Show Config'); o.title = _('Podkop Configuration');
o.description = _('Show current podkop configuration with masked sensitive data'); o.description = _('Show current podkop configuration with masked sensitive data');
o.inputtitle = _('Show Config'); o.inputtitle = _('Show Config');
o.inputstyle = 'apply'; o.inputstyle = 'apply';
@@ -574,58 +780,33 @@ return view.extend({
return fs.exec('/etc/init.d/podkop', ['show_config']) return fs.exec('/etc/init.d/podkop', ['show_config'])
.then(function (res) { .then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output')); const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
ui.showModal(_('Podkop Configuration'), [
const modalElement = ui.showModal(_('Podkop Configuration'), [ E('div', { style: 'white-space:pre-wrap;padding:5px' }, formattedOutput),
E('div', { class: 'cbi-section' }, [ E('div', { class: 'right' }, E('button', {
E('pre', { class: 'cbi-value-field' }, formattedOutput) class: 'btn',
]), click: ui.hideModal
E('div', { style: 'display: flex; justify-content: space-between; margin-top: 1em;' }, [ }, _('Close')))
E('button', { ]);
'class': 'btn cbi-button-save',
'click': function () {
const textarea = document.createElement('textarea');
textarea.value = '```\n' + formattedOutput + '\n```';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
ui.hideModal();
} catch (err) {
ui.addNotification(null, E('p', {}, _('Failed to copy: ') + err.message));
}
document.body.removeChild(textarea);
}
}, _('Copy to Clipboard')),
E('button', {
'class': 'btn cbi-button-neutral',
'click': ui.hideModal
}, _('Close'))
])
], 'large');
if (modalElement && modalElement.parentElement) {
modalElement.parentElement.classList.add('modal-overlay-large');
}
}); });
}; };
o = s.taboption('diagnostics', form.Button, '_list_update'); o = s.taboption('diagnostics', form.Button, '_list_update');
o.title = _('Update lists'); o.title = _('Update Lists');
o.description = _('Update all lists in config'); o.description = _('Update all lists in config');
o.inputtitle = _('Update lists'); o.inputtitle = _('Update Lists');
o.inputstyle = 'apply'; o.inputstyle = 'apply';
o.onclick = function () { o.onclick = function () {
fs.exec('/etc/init.d/podkop', ['list_update']); return fs.exec('/etc/init.d/podkop', ['list_update'])
.then(function (res) {
ui.showModal(_('List Update'), [ const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
E('p', {}, _('Lists will be updated in background. You can check the progress in system logs.')), ui.showModal(_('Lists Update Results'), [
E('div', { class: 'right' }, [ E('div', { style: 'white-space:pre-wrap;padding:5px' }, formattedOutput),
E('button', { E('div', { class: 'right' }, E('button', {
'class': 'btn', class: 'btn',
'click': ui.hideModal click: ui.hideModal
}, _('Close')) }, _('Close')))
]) ]);
]); });
}; };

View File

@@ -380,4 +380,85 @@ msgid "Local Domain Lists Path"
msgstr "Путь к локальным спискам доменов" msgstr "Путь к локальным спискам доменов"
msgid "Enter to the list file path" msgid "Enter to the list file path"
msgstr "Введите путь к файлу списка" msgstr "Введите путь к файлу списка"
msgid "Proxy Check"
msgstr "Проверка прокси"
msgid "Check if sing-box proxy works correctly"
msgstr "Проверить корректность работы прокси sing-box"
msgid "Check Proxy"
msgstr "Проверить прокси"
msgid "Proxy Check Results"
msgstr "Результаты проверки прокси"
msgid "NFT Rules"
msgstr "Правила NFT"
msgid "Show current nftables rules and statistics"
msgstr "Показать текущие правила и статистику nftables"
msgid "Check Rules"
msgstr "Проверить правила"
msgid "GitHub Connectivity"
msgstr "Подключение к GitHub"
msgid "Check GitHub connectivity and lists availability"
msgstr "Проверить подключение к GitHub и доступность списков"
msgid "Check GitHub"
msgstr "Проверить GitHub"
msgid "GitHub Connectivity Results"
msgstr "Результаты проверки подключения к GitHub"
msgid "Sing-Box Logs"
msgstr "Логи Sing-Box"
msgid "View recent sing-box logs from system journal"
msgstr "Просмотр последних логов sing-box из системного журнала"
msgid "View Sing-Box Logs"
msgstr "Просмотр логов Sing-Box"
msgid "Podkop Logs"
msgstr "Логи Podkop"
msgid "View recent podkop logs from system journal"
msgstr "Просмотр последних логов podkop из системного журнала"
msgid "View Podkop Logs"
msgstr "Просмотр логов Podkop"
msgid "Active Connections"
msgstr "Активные соединения"
msgid "View active sing-box network connections"
msgstr "Просмотр активных сетевых соединений sing-box"
msgid "Check Connections"
msgstr "Проверить соединения"
msgid "DNSMasq Configuration"
msgstr "Конфигурация DNSMasq"
msgid "View current DNSMasq configuration settings"
msgstr "Просмотр текущих настроек конфигурации DNSMasq"
msgid "Check DNSMasq"
msgstr "Проверить DNSMasq"
msgid "Sing-Box Configuration"
msgstr "Конфигурация Sing-Box"
msgid "Show current sing-box configuration"
msgstr "Показать текущую конфигурацию sing-box"
msgid "Show Sing-Box Config"
msgstr "Показать конфигурацию Sing-Box"
msgid "Lists Update Results"
msgstr "Результаты обновления списков"

View File

@@ -380,4 +380,85 @@ msgid "Local Domain Lists Path"
msgstr "" msgstr ""
msgid "Enter to the list file path" msgid "Enter to the list file path"
msgstr ""
msgid "Proxy Check"
msgstr ""
msgid "Check if sing-box proxy works correctly"
msgstr ""
msgid "Check Proxy"
msgstr ""
msgid "Proxy Check Results"
msgstr ""
msgid "NFT Rules"
msgstr ""
msgid "Show current nftables rules and statistics"
msgstr ""
msgid "Check Rules"
msgstr ""
msgid "GitHub Connectivity"
msgstr ""
msgid "Check GitHub connectivity and lists availability"
msgstr ""
msgid "Check GitHub"
msgstr ""
msgid "GitHub Connectivity Results"
msgstr ""
msgid "Sing-Box Logs"
msgstr ""
msgid "View recent sing-box logs from system journal"
msgstr ""
msgid "View Sing-Box Logs"
msgstr ""
msgid "Podkop Logs"
msgstr ""
msgid "View recent podkop logs from system journal"
msgstr ""
msgid "View Podkop Logs"
msgstr ""
msgid "Active Connections"
msgstr ""
msgid "View active sing-box network connections"
msgstr ""
msgid "Check Connections"
msgstr ""
msgid "DNSMasq Configuration"
msgstr ""
msgid "View current DNSMasq configuration settings"
msgstr ""
msgid "Check DNSMasq"
msgstr ""
msgid "Sing-Box Configuration"
msgstr ""
msgid "Show current sing-box configuration"
msgstr ""
msgid "Show Sing-Box Config"
msgstr ""
msgid "Lists Update Results"
msgstr "" msgstr ""

View File

@@ -7,18 +7,18 @@ script=$(readlink "$initscript")
NAME="$(basename ${script:-$initscript})" NAME="$(basename ${script:-$initscript})"
config_load "$NAME" config_load "$NAME"
EXTRA_COMMANDS="list_update check_proxy check_nft check_github check_logs check_all check_three main show_config show_version" EXTRA_COMMANDS="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"
EXTRA_HELP=" list_update Updating domain and subnet lists EXTRA_HELP=" list_update Updating domain and subnet lists
sing_box_config_vless For test vless string
check_proxy Check if sing-box proxy works correctly check_proxy Check if sing-box proxy works correctly
check_nft Show PodkopTable nftables rules check_nft Show PodkopTable nftables rules
check_github Check GitHub connectivity and lists availability check_github Check GitHub connectivity and lists availability
check_logs Show podkop logs from system journal check_logs Show podkop logs from system journal
check_all Run all checks check_sing_box_connections Show active sing-box network connections
check_three Run check_proxy, check_nft and check_github check_sing_box_logs Show recent sing-box logs
main Main function check_dnsmasq Show current DNSMasq configuration
show_config Show current configuration with masked sensitive data show_config Show current configuration with masked sensitive data
show_version Show current version" show_version Show current version
show_sing_box_config Show current sing-box configuration"
[ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop [ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop
@@ -1390,15 +1390,29 @@ check_proxy() {
fi fi
jq ' jq '
walk( walk(
if type == "object" then if type == "object" then
with_entries( with_entries(
if [.key] | inside(["uuid", "server", "server_name", "password", "public_key", "short_id"]) then if .key == "uuid" then
.value = "MASKED" .value = "MASKED"
else . end elif .key == "server" then
) .value = "MASKED"
else . end elif .key == "server_name" then
)' $SING_BOX_CONFIG .value = "MASKED"
elif .key == "password" then
.value = "MASKED"
elif .key == "public_key" then
.value = "MASKED"
elif .key == "short_id" then
.value = "MASKED"
elif .key == "fingerprint" then
.value = "MASKED"
elif .key == "server_port" then
.value = "MASKED"
else . end
)
else . end
)' $SING_BOX_CONFIG
nolog "Checking proxy connection..." nolog "Checking proxy connection..."
@@ -1437,22 +1451,18 @@ check_nft() {
nolog "Checking PodkopTable rules..." nolog "Checking PodkopTable rules..."
local sets="podkop_domains podkop_subnets podkop_subnets_discord localv4" # Check if table exists
if ! nft list table inet PodkopTable >/dev/null 2>&1; then
nolog "Sets statistics:" nolog "PodkopTable not found"
for set_name in $sets; do return 1
if nft list set inet PodkopTable $set_name >/dev/null 2>&1; then fi
local count=$(nft list set inet PodkopTable $set_name 2>/dev/null | grep -c ",")
nolog "- $set_name: $count elements"
else
nolog "- $set_name: not found"
fi
done
nolog "Current chains and rules:" # Get all sets
nft list table inet PodkopTable | grep "chain\|counter" nolog "\nSets configuration:"
nolog "NFT check completed" nft list table inet PodkopTable
nolog "\nNFT check completed"
} }
check_github() { check_github() {
@@ -1477,37 +1487,94 @@ check_github() {
done done
} }
check_dnsmasq() {
nolog "Checking dnsmasq configuration..."
local config=$(uci show dhcp.@dnsmasq[0])
if [ -z "$config" ]; then
nolog "No dnsmasq configuration found"
return 1
fi
echo "$config" | while IFS='=' read -r key value; do
nolog "$key = $value"
done
}
check_sing_box_connections() {
nolog "Checking sing-box connections..."
if ! command -v netstat >/dev/null 2>&1; then
nolog "netstat is not installed"
return 1
fi
local connections=$(netstat -tuanp | grep sing-box)
if [ -z "$connections" ]; then
nolog "No active sing-box connections found"
return 1
fi
echo "$connections" | while read -r line; do
nolog "$line"
done
}
check_sing_box_logs() {
nolog "Showing sing-box logs from system journal..."
local logs=$(logread -e sing-box | tail -n 50)
if [ -z "$logs" ]; then
nolog "No sing-box logs found"
return 1
fi
echo "$logs"
}
check_logs() { check_logs() {
nolog "Showing podkop logs from system journal..." nolog "Showing podkop logs from system journal..."
if command -v logread >/dev/null 2>&1; then if command -v logread >/dev/null 2>&1; then
logread -e "podkop" | tail -n 50 logread -e podkop | tail -n 50
else else
nolog "Error: logread command not found" nolog "Error: logread command not found"
return 1 return 1
fi fi
} }
check_three() { show_sing_box_config() {
nolog "\n=== Checking GitHub connectivity ===" nolog "Current sing-box configuration:"
check_github
nolog "\n=== Checking proxy settings ===" if [ ! -f "$SING_BOX_CONFIG" ]; then
check_proxy nolog "Configuration file not found"
return 1
nolog "\n=== Checking NFT rules ===" fi
check_nft
nolog "\nFull diagnostic check completed"
}
check_all() { jq '
nolog "Starting full diagnostic check..." walk(
if type == "object" then
nolog "\n=== Checking recent logs ===" with_entries(
check_logs if .key == "uuid" then
.value = "MASKED"
check_three elif .key == "server" then
.value = "MASKED"
elif .key == "server_name" then
.value = "MASKED"
elif .key == "password" then
.value = "MASKED"
elif .key == "public_key" then
.value = "MASKED"
elif .key == "short_id" then
.value = "MASKED"
elif .key == "fingerprint" then
.value = "MASKED"
elif .key == "server_port" then
.value = "MASKED"
else . end
)
else . end
)' "$SING_BOX_CONFIG"
} }
show_config() { show_config() {