Compare commits

...

14 Commits

Author SHA1 Message Date
itdoginfo
ca7bb77356 Fix 2025-02-16 16:57:16 +03:00
itdoginfo
da8195b795 Fix migrate 2025-02-16 15:59:07 +03:00
itdoginfo
98129720bb rm until 2025-02-16 14:29:50 +03:00
itdoginfo
3c1865c8a3 Expanding checkes. DNS 127.0.0.42. QUIC disable. Some fixes 2025-02-16 14:18:19 +03:00
itdoginfo
77ac728d47 Check sing-box 2025-02-16 12:16:43 +03:00
itdoginfo
1b5cfa3371 Move check sing-box to start 2025-02-15 23:32:18 +03:00
itdoginfo
590e040958 v0.3.4 2025-02-15 22:23:55 +03:00
itdoginfo
2323d426dd tmp check br-lan 2025-02-15 22:12:25 +03:00
itdoginfo
9bcc80f2be Checking file uploads 2025-02-15 19:17:59 +03:00
itdoginfo
bfde7518fb Merge pull request #20 from VizzleTF/main
feat(podkop): add show config + version features
2025-02-15 18:21:47 +03:00
Ivan K
18d466e166 feat(podkop): add version display in UI
- Added version display in Podkop UI
- Updated init script to fetch and display version
2025-02-15 17:58:39 +03:00
Ivan K
a30752d2e9 fix(init.d): decode URL-encoded characters in get_param
- Replaced `uhttpd` with `sed` for URL decoding
2025-02-15 17:47:09 +03:00
Ivan K
eb18537370 feat(podkop): add show_version command
- Update init script to include show_version command
- Add show_version function to display current version
- Update EXTRA_COMMANDS to include show_version
- Remove version from web and config
2025-02-15 17:30:14 +03:00
Ivan K
aa86445332 feat(podkop): add show config feature
- Add new button to show config with masked sensitive data
- Update init script with new command `show_config`
- Implement `show_config` function to mask sensitive data
- Update version in config file to 0.3.3
- Update proxy check logic for better error handling
2025-02-15 16:55:51 +03:00
7 changed files with 253 additions and 51 deletions

View File

@@ -148,6 +148,7 @@ Luci: Services/podkop
- [ ] Диагностика: podkop_domains: 0 elements как проверять что доходят запросы при fakeip? Мб врубать логи dnsmasq и их чекать.
- [ ] Сделать галку запрещающую подкопу редачить dhcp. Допилить в исключение вместе с пустыми полями proxy и vpn
- [ ] Валидации предустановленных значений. Если прописаны другие, то вывод в лог о неизвестной переменной и продолжение работы
- [ ] Добавление в список доменов домены первого уровня (LuCI)
Приоритет 2
- [x] Списки доменов и подсетей с роутера

View File

@@ -4,15 +4,38 @@ REPO="https://api.github.com/repos/itdoginfo/podkop/releases/latest"
IS_SHOULD_RESTART_NETWORK=
DOWNLOAD_DIR="/tmp/podkop"
COUNT=3
rm -rf "$DOWNLOAD_DIR"
mkdir -p "$DOWNLOAD_DIR"
main() {
check_system
wget -qO- "$REPO" | grep -o 'https://[^"]*\.ipk' | while read -r url; do
sing_box
wget -qO- "$REPO" | grep -o 'https://[^"[:space:]]*\.ipk' | while read -r url; do
filename=$(basename "$url")
echo "Download $filename..."
wget -q -O "$DOWNLOAD_DIR/$filename" "$url"
filepath="$DOWNLOAD_DIR/$filename"
attempt=0
while [ $attempt -lt $COUNT ]; do
if [ -f "$filepath" ] && [ -s "$filepath" ]; then
echo "$filename has already been uploaded"
break
fi
echo "Download $filename (count $((attempt+1)))..."
wget -q -O "$filepath" "$url"
if [ -s "$filepath" ]; then
echo "$filename successfully downloaded"
break
else
echo "Download error $filename. Retry..."
rm -f "$filepath"
fi
attempt=$((attempt+1))
done
done
echo "opkg update"
@@ -49,6 +72,7 @@ main() {
opkg install $DOWNLOAD_DIR/podkop*.ipk
opkg install $DOWNLOAD_DIR/luci-app-podkop*.ipk
echo "Русский язык интерфейса ставим? y/n (Need a Russian translation?)"
while true; do
read -r -p '' RUS
@@ -378,6 +402,15 @@ check_system() {
echo "Available: $((AVAILABLE_SPACE/1024))MB"
echo "Required: $((REQUIRED_SPACE/1024))MB"
exit 1
fi
}
sing_box() {
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
opkg remove sing-box
fi
}

View File

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

View File

@@ -7,10 +7,20 @@
return view.extend({
async render() {
document.getElementsByTagName('head')[0].insertAdjacentHTML('beforeend', `
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
`);
var m, s, o;
m = new form.Map('podkop', _('Podkop configuration'), null, ['main', 'second']);
fs.exec('/etc/init.d/podkop', ['show_version']).then(function (res) {
if (res.stdout) {
m.title = _('Podkop') + ' v' + res.stdout.trim();
}
});
s = m.section(form.TypedSection, 'main');
s.anonymous = true;
@@ -394,13 +404,16 @@ return view.extend({
o = s.taboption('additional', form.Flag, 'yacd', _('Yacd enable'), _('http://openwrt.lan:9090/ui'));
o.default = '0';
o.depends('mode', 'proxy');
o.rmempty = false;
o.ucisection = 'main';
o = s.taboption('additional', form.Flag, 'exclude_ntp', _('Exclude NTP'), _('For issues with open connections sing-box'));
o.default = '0';
o.depends('mode', 'proxy');
o.rmempty = false;
o.ucisection = 'main';
o = s.taboption('additional', form.Flag, 'quic_disable', _('QUIC disable'), _('For issues with the video stream'));
o.default = '0';
o.rmempty = false;
o.ucisection = 'main';
@@ -552,6 +565,50 @@ return view.extend({
});
};
o = s.taboption('diagnostics', form.Button, '_show_config');
o.title = _('Show Config');
o.description = _('Show current podkop configuration with masked sensitive data');
o.inputtitle = _('Show Config');
o.inputstyle = 'apply';
o.onclick = function () {
return fs.exec('/etc/init.d/podkop', ['show_config'])
.then(function (res) {
const formattedOutput = formatDiagnosticOutput(res.stdout || _('No output'));
const modalElement = ui.showModal(_('Podkop Configuration'), [
E('div', { class: 'cbi-section' }, [
E('pre', { class: 'cbi-value-field' }, formattedOutput)
]),
E('div', { style: 'display: flex; justify-content: space-between; margin-top: 1em;' }, [
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.title = _('Update lists');
o.description = _('Update all lists in config');

View File

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

View File

@@ -28,5 +28,6 @@ config main 'main'
option yacd '0'
option socks5 '0'
option exclude_ntp '0'
option quic_disable '0'
option update_interval '1d'
option custom_domains_text

View File

@@ -7,7 +7,7 @@ script=$(readlink "$initscript")
NAME="$(basename ${script:-$initscript})"
config_load "$NAME"
EXTRA_COMMANDS="list_update check_proxy check_nft check_github check_logs check_all check_three main"
EXTRA_COMMANDS="list_update check_proxy check_nft check_github check_logs check_all check_three main show_config show_version"
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
@@ -16,7 +16,9 @@ EXTRA_HELP=" list_update Updating domain and subnet lists
check_logs Show podkop logs from system journal
check_all Run all checks
check_three Run check_proxy, check_nft and check_github
main Main function"
main Main function
show_config Show current configuration with masked sensitive data
show_version Show current version"
[ ! -L /usr/sbin/podkop ] && ln -s /etc/init.d/podkop /usr/sbin/podkop
@@ -37,6 +39,26 @@ FAKEIP="198.18.0.0/15"
start_service() {
log "Start podkop"
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
echo "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 -qE "iptables|kmod-ipt"; then
echo "Found incompatible iptables packages. If you're using FriendlyWrt: https://t.me/itdogchat/44512/181082"
exit 1
fi
if ! ip addr | grep -q "br-lan"; then
log "Interface br-lan not found"
exit 1
fi
migration
procd_open_instance
procd_set_param command /bin/sh -c "/etc/init.d/podkop main &"
procd_set_param stdout 1
@@ -109,22 +131,12 @@ nolog() {
}
main() {
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
echo "The version of sing-box ($sing_box_version) is lower than the minimum version. Update sing-box: opkg update && opkg install sing-box"
exit 1
fi
migration
sleep 5
config_foreach wget_github
mkdir -p /tmp/podkop
# base
route_table_rule_mark
create_nft_table
@@ -172,6 +184,12 @@ main() {
nft insert rule inet PodkopTable mangle udp dport 123 return
fi
config_get_bool quic_disable "main" "quic_disable" "0"
if [ "$quic_disable" -eq 1 ]; then
log "Rule for disable QUIC"
sing_box_quic_reject
fi
sing_box_config_check
/etc/init.d/sing-box restart
/etc/init.d/sing-box enable
@@ -187,15 +205,46 @@ main() {
# Migrations funcs
migration() {
# list migrate
grep -q "list domain_list 'ru_inside'" /etc/config/podkop && sed -i "s/list domain_list 'ru_inside'/list domain_list 'russia_inside'/" /etc/config/podkop
grep -q "list domain_list 'ru_outside'" /etc/config/podkop && sed -i "s/list domain_list 'ru_outside'/list domain_list 'russia_outside'/" /etc/config/podkop
grep -q "list domain_list 'ua'" /etc/config/podkop && sed -i "s/list domain_list 'ua'/list domain_list 'ukraine_inside'/" /etc/config/podkop
local CONFIG="/etc/config/podkop"
if grep -q "ru_inside" $CONFIG; then
log "Depricated list found: ru_inside"
sed -i '/ru_inside/d' $CONFIG
fi
if grep -q "list domain_list 'ru_outside'" $CONFIG; then
log "Depricated list found: sru_outside"
sed -i '/ru_outside/d' $CONFIG
fi
if grep -q "list domain_list 'ua'" $CONFIG; then
log "Depricated list found: ua"
sed -i '/ua/d' $CONFIG
fi
# Subnet list
if grep -q "list subnets" $CONFIG; then
log "Depricated second section found"
sed -i '/list subnets/d' $CONFIG
fi
# second remove
grep -q "config second 'second'" /etc/config/podkop && sed -i '/second/d' /etc/config/podkop
if grep -q "config second 'second'" $CONFIG; then
log "Depricated second section found"
sed -i '/second/d' $CONFIG
fi
# cron update
grep -qE "^\s*option update_interval '[0-9*/,-]+( [0-9*/,-]+){4}'" /etc/config/podkop && sed -i "s|^\(\s*option update_interval\) '[0-9*/,-]\+\( [0-9*/,-]\+\)\{4\}'|\1 '1d'|" /etc/config/podkop
if grep -qE "^\s*option update_interval '[0-9*/,-]+( [0-9*/,-]+){4}'" $CONFIG; then
log "Depricated update_interval"
sed -i "s|^\(\s*option update_interval\) '[0-9*/,-]\+\( [0-9*/,-]\+\)\{4\}'|\1 '1d'|" $CONFIG
fi
# dnsmasq https
if grep -q "^filter-rr=HTTPS" "/etc/dnsmasq.conf"; then
log "Found and removed filter-rr=HTTPS in dnsmasq config"
sed -i '/^filter-rr=HTTPS/d' "/etc/dnsmasq.conf"
fi
}
# Main funcs
@@ -246,12 +295,10 @@ dnsmasq_add() {
uci set dhcp.@dnsmasq[0].filter_aaaa="1"
uci set dhcp.@dnsmasq[0].cachesize="0"
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server="127.0.0.1#5353"
uci add_list dhcp.@dnsmasq[0].server="127.0.0.42"
uci add_list dhcp.@dnsmasq[0].server='/use-application-dns.net/'
uci commit dhcp
grep -q "filter-rr=HTTPS" /etc/dnsmasq.conf || echo "filter-rr=HTTPS" >> /etc/dnsmasq.conf
/etc/init.d/dnsmasq restart
}
@@ -263,8 +310,6 @@ dnsmasq_rm() {
uci -q delete dhcp.@dnsmasq[0].server
uci commit dhcp
sed -i '/filter-rr=HTTPS/d' /etc/dnsmasq.conf
/etc/init.d/dnsmasq restart
}
@@ -478,8 +523,8 @@ sing_box_inbound_proxy() {
{
"tag": "dns-in",
"type": "direct",
"listen": "127.0.0.1",
"listen_port": 5353
"listen": "127.0.0.42",
"listen_port": 53
}
],
"outbounds": [
@@ -520,6 +565,12 @@ sing_box_dns_rule_fakeip() {
jq \
'.dns += {
"rules": [
{
"query_type": [
"HTTPS"
],
"action": "reject"
},
{
"server": "fakeip-server",
"rule_set": []
@@ -680,8 +731,8 @@ sing_box_config_outbound_json() {
{
"tag": "dns-in",
"type": "direct",
"listen": "127.0.0.1",
"listen_port": 5353
"listen": "127.0.0.42",
"listen_port": 53
}
],
"outbounds": [],
@@ -1081,7 +1132,7 @@ sing_box_rules() {
local rule_set="$1"
local outbound="$2"
# Check if there is an outbound rule for tproxy-in
# Check if there is an outbound rule for "tproxy-in"
local rule_exists=$(jq -r '.route.rules[] | select(.outbound == "'"$outbound"'" and .inbound == ["tproxy-in"])' "$SING_BOX_CONFIG")
if [[ -n "$rule_exists" ]]; then
@@ -1105,6 +1156,25 @@ sing_box_rules() {
fi
}
sing_box_quic_reject() {
local quic_rule_exists=$(jq -e '.route.rules[] | select(.protocol == "quic" and .action == "reject")' "$SING_BOX_CONFIG")
if [[ -z "$quic_rule_exists" ]]; then
jq '
.route.rules |= (
reduce .[] as $rule ([];
if $rule.protocol == "dns" and $rule.action == "hijack-dns" then
. + [$rule, {"protocol": "quic", "action": "reject"}]
else
. + [$rule]
end
)
)' "$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
log "QUIC reject rule added successfully"
fi
}
process_remote_ruleset() {
config_get_bool domain_list_enabled "$section" "domain_list_enabled" "0"
if [ "$domain_list_enabled" -eq 1 ]; then
@@ -1309,18 +1379,31 @@ check_proxy() {
nolog "Checking proxy connection..."
for attempt in `seq 1 5`; do
response=$(sing-box tools fetch ifconfig.me -D /etc/sing-box 2>/dev/null)
if ! echo "$response" | grep -q "403 Forbidden"; then
nolog "Proxy check completed successfully"
#echo "$response" | sed 's/\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)\.\([0-9]\+\)/XXX.\2.\3.\4/'
echo "$response" | sed -n 's/^[0-9]\+\.[0-9]\+\.[0-9]\+\.\([0-9]\+\)$/X.X.X.\1/p'
return 0
fi
done
nolog "Failed to get a non-403 response after 5 attempts"
return 1
for attempt in `seq 1 5`; do
response=$(sing-box tools fetch ifconfig.me -D /etc/sing-box 2>/dev/null)
if echo "$response" | grep -q "^<html\|403 Forbidden"; then
continue
fi
if [[ $response =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
ip=$(echo "$response" | sed -n 's/^[0-9]\+\.[0-9]\+\.[0-9]\+\.\([0-9]\+\)$/X.X.X.\1/p')
nolog "$ip - should match proxy IP"
return 0
elif echo "$response" | grep -q "^[0-9a-fA-F:]*::[0-9a-fA-F:]*$\|^[0-9a-fA-F:]\+$"; then
ip=$(echo "$response" | sed 's/\([0-9a-fA-F]\+:[0-9a-fA-F]\+:[0-9a-fA-F]\+\):.*/\1:XXXX:XXXX:XXXX/')
nolog "$ip - should match proxy IP"
return 0
fi
if [ $attempt -eq 5 ]; then
nolog "Failed to get valid IP address after 5 attempts"
if [ -z "$response" ]; then
nolog "Error: Empty response"
else
nolog "Error response: $response"
fi
return 1
fi
done
}
check_nft() {
@@ -1331,7 +1414,6 @@ check_nft() {
nolog "Checking PodkopTable rules..."
# Список всех возможных сетов
local sets="podkop_domains podkop_subnets podkop_subnets_discord localv4"
nolog "Sets statistics:"
@@ -1344,7 +1426,6 @@ check_nft() {
fi
done
# Показываем правила с счетчиками
nolog "Current chains and rules:"
nft list table inet PodkopTable | grep "chain\|counter"
@@ -1377,7 +1458,6 @@ check_logs() {
nolog "Showing podkop logs from system journal..."
if command -v logread >/dev/null 2>&1; then
# Попытка получить последние 50 записей
logread -e "podkop" | tail -n 50
else
nolog "Error: logread command not found"
@@ -1406,3 +1486,33 @@ check_all() {
check_three
}
show_config() {
nolog "Current podkop configuration:"
if [ ! -f /etc/config/podkop ]; then
nolog "Configuration file not found"
return 1
fi
tmp_config=$(mktemp)
cat /etc/config/podkop | sed \
-e 's/\(option proxy_string\).*/\1 '\''MASKED'\''/g' \
-e 's/\(option outbound_json\).*/\1 '\''MASKED'\''/g' \
-e 's/\(option second_proxy_string\).*/\1 '\''MASKED'\''/g' \
-e 's/\(option second_outbound_json\).*/\1 '\''MASKED'\''/g' \
-e 's/\(vless:\/\/[^@]*@\)/vless:\/\/MASKED@/g' \
-e 's/\(ss:\/\/[^@]*@\)/ss:\/\/MASKED@/g' \
-e 's/\(pbk=[^&]*\)/pbk=MASKED/g' \
-e 's/\(sid=[^&]*\)/sid=MASKED/g' \
> "$tmp_config"
cat "$tmp_config"
rm -f "$tmp_config"
}
show_version() {
local version=$(opkg info podkop | grep -m 1 "Version:" | cut -d' ' -f2)
echo "$version"
}