Compare commits

..

16 Commits

Author SHA1 Message Date
itdoginfo
0a7efb3169 Fix 2025-04-03 17:53:21 +03:00
itdoginfo
468e51ee8e v0.3.35 2025-04-03 17:42:45 +03:00
itdoginfo
3b93a914de v0.3.34 2025-04-03 17:27:35 +03:00
itdoginfo
76c5baf1e2 Fix tailscale smartdns in resolve.conf 2025-04-03 17:27:13 +03:00
itdoginfo
c752c46abf Fix resolv_conf value 2025-04-03 17:24:57 +03:00
itdoginfo
1df1defa5e Check curl 2025-04-03 17:24:31 +03:00
itdoginfo
3cb4be6427 v0.3.33 2025-04-03 16:47:47 +03:00
itdoginfo
25bfdce5ce Added critical log. Rm friendlywrt check. Added iptables check 2025-04-03 16:47:26 +03:00
itdoginfo
6d0f097a07 Merge pull request #75 from itdoginfo/feature/error-notification (#47)
Feature/error notification
2025-04-03 14:52:00 +03:00
Ivan K
5f780955eb 💄 style(podkop): update error log filtering criteria 2025-04-03 13:42:55 +03:00
Ivan K
389def9056 ♻️ refactor(podkop): remove unused createErrorModal function 2025-04-03 13:40:41 +03:00
Ivan K
e816da5133 feat(podkop): add error logging and notification system 2025-04-03 13:36:22 +03:00
Ivan K
e57adbe042 🔒 refactor(config): Mask NextDNS server address in config output 2025-03-30 20:36:49 +03:00
itdoginfo
d78c51360d Merge pull request #73 from itdoginfo/feature/no-more-cache
🐛 fix(doh): Improve DoH server compatibility detection for quad9
2025-03-30 18:44:26 +03:00
Ivan K
c2357337fc 🐛 fix(dns): improve DoH server compatibility and error handling 2025-03-30 17:20:06 +03:00
Ivan K
bc6490b56e 🐛 fix(doh): Improve DoH server compatibility detection for quad9 2025-03-30 17:04:30 +03:00
6 changed files with 161 additions and 31 deletions

View File

@@ -42,12 +42,14 @@ main() {
echo "Installed podkop..."
add_tunnel
fi
if command -v curl &> /dev/null; then
check_response=$(curl -s "https://api.github.com/repos/itdoginfo/podkop/releases/latest")
check_response=$(curl -s "https://api.github.com/repos/itdoginfo/podkop/releases/latest")
if echo "$check_response" | grep -q 'API rate limit '; then
echo "You've reached rate limit from GitHub. Repeat in five minutes."
exit 1
if echo "$check_response" | grep -q 'API rate limit '; then
echo "You've reached rate limit from GitHub. Repeat in five minutes."
exit 1
fi
fi
download_success=0

View File

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

View File

@@ -12,6 +12,8 @@ const STATUS_COLORS = {
WARNING: '#ff9800'
};
const ERROR_POLL_INTERVAL = 5000; // 5 seconds
async function safeExec(command, args = [], timeout = 7000) {
try {
const controller = new AbortController();
@@ -850,6 +852,84 @@ function checkDNSAvailability() {
});
}
async function getPodkopErrors() {
try {
const result = await safeExec('/usr/bin/podkop', ['check_logs']);
if (!result || !result.stdout) return [];
const logs = result.stdout.split('\n');
const errors = logs.filter(log =>
// log.includes('saved for future filters') ||
log.includes('[critical]')
);
console.log('Found errors:', errors);
return errors;
} catch (error) {
console.error('Error getting podkop logs:', error);
return [];
}
}
let errorPollTimer = null;
let lastErrorsSet = new Set();
let isInitialCheck = true;
function showErrorNotification(error, isMultiple = false) {
const notificationContent = E('div', { 'class': 'alert-message error' }, [
E('pre', { 'class': 'error-log' }, error)
]);
ui.addNotification(null, notificationContent);
}
function startErrorPolling() {
if (errorPollTimer) {
clearInterval(errorPollTimer);
}
async function checkErrors() {
const result = await safeExec('/usr/bin/podkop', ['check_logs']);
if (!result || !result.stdout) return;
const logs = result.stdout;
const errorLines = logs.split('\n').filter(line =>
// line.includes('saved for future filters') ||
line.includes('[critical]')
);
if (errorLines.length > 0) {
const currentErrors = new Set(errorLines);
if (isInitialCheck) {
if (errorLines.length > 0) {
showErrorNotification(errorLines.join('\n'), true);
}
isInitialCheck = false;
} else {
const newErrors = [...currentErrors].filter(error => !lastErrorsSet.has(error));
newErrors.forEach(error => {
showErrorNotification(error, false);
});
}
lastErrorsSet = currentErrors;
}
}
checkErrors();
errorPollTimer = setInterval(checkErrors, ERROR_POLL_INTERVAL);
}
function stopErrorPolling() {
if (errorPollTimer) {
clearInterval(errorPollTimer);
errorPollTimer = null;
}
}
return view.extend({
async render() {
document.head.insertAdjacentHTML('beforeend', `
@@ -1348,8 +1428,10 @@ return view.extend({
const diagnosticsContainer = document.getElementById('diagnostics-status');
if (document.hidden) {
stopDiagnosticsUpdates();
stopErrorPolling();
} else if (diagnosticsContainer && diagnosticsContainer.hasAttribute('data-loading')) {
startDiagnosticsUpdates();
startErrorPolling();
}
});
@@ -1360,6 +1442,7 @@ return view.extend({
if (!this.hasAttribute('data-loading')) {
this.setAttribute('data-loading', 'true');
startDiagnosticsUpdates();
startErrorPolling();
}
});
}
@@ -1375,9 +1458,11 @@ return view.extend({
if (container && !container.hasAttribute('data-loading')) {
container.setAttribute('data-loading', 'true');
startDiagnosticsUpdates();
startErrorPolling();
}
} else {
stopDiagnosticsUpdates();
stopErrorPolling();
}
}
});
@@ -1388,6 +1473,7 @@ return view.extend({
if (container && !container.hasAttribute('data-loading')) {
container.setAttribute('data-loading', 'true');
startDiagnosticsUpdates();
startErrorPolling();
}
}
}

View File

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

View File

@@ -6,7 +6,7 @@ USE_PROCD=1
script=$(readlink "$initscript")
NAME="$(basename ${script:-$initscript})"
config_load "$NAME"
resolv_conf="/etc/resolv.conf"
RESOLV_CONF="/etc/resolv.conf"
start_service() {
echo "Start podkop"
@@ -19,20 +19,19 @@ start_service() {
exit 1
fi
if grep -q FriendlyWrt /etc/banner; then
printf "\033[31;1mYou use FriendlyWrt. If you have problems, check out: https://t.me/itdogchat/44512/181082\033[0m\n"
if opkg list-installed | grep -q iptables-mod-extra; then
echo "Conflicting package detected: iptables-mod-extra"
fi
if opkg list-installed | grep -q kmod-ipt-nat; then
echo "Conflicting package detected: kmod-ipt-nat"
fi
if grep -qE 'doh_backup_noresolv|doh_backup_server|doh_server' /etc/config/dhcp; then
printf "\033[31;1mDetected https-dns-proxy. Disable or uninstall it for correct functionality.\033[0m\n"
fi
if ! ip addr | grep -q "br-lan"; then
echo "Interface br-lan not found"
exit 1
fi
if ! grep -q "search lan" "$resolv_conf" || ! grep -q "nameserver 127.0.0.1" "$resolv_conf"; then
if { ! grep -q "search lan" "$RESOLV_CONF" || ! grep -q "nameserver 127.0.0.1" "$RESOLV_CONF"; } && ! grep -q "search tail" "$RESOLV_CONF"; then
echo "/etc/resolv.conf does not contain 'search lan' or 'nameserver 127.0.0.1' entries"
fi

View File

@@ -22,6 +22,7 @@ DNS_RESOLVERS="1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 9.9.9.9 9.9.9.11 94.140.14.14 94.
TEST_DOMAIN="fakeip.tech-domain.club"
INTERFACES_LIST=""
SRC_INTERFACE=""
RESOLV_CONF="/etc/resolv.conf"
log() {
local message="$1"
@@ -45,6 +46,33 @@ nolog() {
}
start() {
log "Starting podkop"
# checking
sing_box_version=$(sing-box version | head -n 1 | awk '{print $3}')
required_version="1.11.1"
if [ "$(echo -e "$sing_box_version\n$required_version" | sort -V | head -n 1)" != "$required_version" ]; then
log "[critical] The version of sing-box ($sing_box_version) is lower than the minimum version. Update sing-box: opkg update && opkg remove sing-box && opkg install sing-box"
exit 1
fi
if opkg list-installed | grep -q iptables-mod-extra; then
log "[critical] Conflicting package detected: iptables-mod-extra"
fi
if opkg list-installed | grep -q kmod-ipt-nat; then
log "[critical] Conflicting package detected: kmod-ipt-nat"
fi
if grep -qE 'doh_backup_noresolv|doh_backup_server|doh_server' /etc/config/dhcp; then
log "[critical] Detected https-dns-proxy. Disable or uninstall it for correct functionality."
fi
if { ! grep -q "search lan" "$RESOLV_CONF" || ! grep -q "nameserver 127.0.0.1" "$RESOLV_CONF"; } && ! grep -q "search tail" "$RESOLV_CONF"; then
log "[critical] /etc/resolv.conf does not contain 'search lan' or 'nameserver 127.0.0.1' entries"
fi
migration
config_foreach process_validate_service
@@ -842,7 +870,7 @@ sing_box_outdound() {
config_get interface "$section" "interface"
if [ -z "$interface" ]; then
log "VPN interface is not set. Exit"
log "[critical] VPN interface is not set. Exit"
exit 1
fi
@@ -868,7 +896,7 @@ sing_box_outdound() {
active_proxy_string=$(echo "$proxy_string" | grep -v "^[[:space:]]*\/\/" | head -n 1)
if [ -z "$active_proxy_string" ]; then
log "Proxy string is not set. Exit"
log "[critical] Proxy string is not set. Exit"
exit 1
fi
@@ -941,7 +969,7 @@ sing_box_rule_dns() {
sing_box_config_check() {
if ! sing-box -c $SING_BOX_CONFIG check >/dev/null 2>&1; then
log "Sing-box configuration is invalid"
log "[critical] Sing-box configuration is invalid"
exit 1
fi
}
@@ -1857,12 +1885,24 @@ check_fakeip() {
check_logs() {
nolog "Showing podkop logs from system journal..."
if command -v logread >/dev/null 2>&1; then
logread -e podkop | tail -n 50
else
if ! command -v logread >/dev/null 2>&1; then
nolog "Error: logread command not found"
return 1
fi
# Get all logs first
local all_logs=$(logread)
# Find the last occurrence of "Starting podkop"
local start_line=$(echo "$all_logs" | grep -n "podkop.*Starting podkop" | tail -n 1 | cut -d: -f1)
if [ -z "$start_line" ]; then
nolog "No 'Starting podkop' message found in logs"
return 1
fi
# Output all logs from the last start
echo "$all_logs" | tail -n +"$start_line"
}
show_sing_box_config() {
@@ -1918,6 +1958,7 @@ show_config() {
-e 's/\(ss:\/\/[^@]*@\)/ss:\/\/MASKED@/g' \
-e 's/\(pbk=[^&]*\)/pbk=MASKED/g' \
-e 's/\(sid=[^&]*\)/sid=MASKED/g' \
-e 's/\(option dns_server '\''[^'\'']*\.dns\.nextdns\.io'\''\)/option dns_server '\''MASKED.dns.nextdns.io'\''/g' \
> "$tmp_config"
cat "$tmp_config"
@@ -2038,23 +2079,25 @@ check_dns_available() {
fi
if [ "$dns_type" = "doh" ]; then
# Different DoH providers use different endpoints and formats
local result=""
# Try common DoH endpoints and check for valid responses
# First try /dns-query endpoint (Cloudflare, AdGuard DNS, etc.)
result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/dns-query?name=itdog.info&type=A")
if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then
is_available=1
status="available"
if echo "$dns_server" | grep -q "quad9.net" || \
echo "$dns_server" | grep -qE "^9\.9\.9\.(9|10|11)$|^149\.112\.112\.(112|10|11)$|^2620:fe::(fe|9|10|11)$|^2620:fe::fe:(10|11)$"; then
result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server:5053/dns-query?name=itdog.info&type=A")
else
# If that fails, try /resolve endpoint (Google DNS)
result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/resolve?name=itdog.info&type=A")
result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/dns-query?name=itdog.info&type=A")
if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then
is_available=1
status="available"
else
result=$(curl --connect-timeout 5 -s -H "accept: application/dns-json" "https://$dns_server/resolve?name=itdog.info&type=A")
fi
fi
if [ $? -eq 0 ] && echo "$result" | grep -q "data"; then
is_available=1
status="available"
fi
elif [ "$dns_type" = "dot" ]; then
(nc "$dns_server" 853 </dev/null >/dev/null 2>&1) & pid=$!
sleep 2