Compare commits

..

15 Commits

Author SHA1 Message Date
itdoginfo
19541f8bb3 v0.3.38. fix reload config luci 2025-04-26 22:35:11 +03:00
itdoginfo
aa42c707fe v0.3.37 2025-04-26 17:49:28 +03:00
itdoginfo
bf96f93987 Fix kill stderr. Return if 127.0.0.42 exists 2025-04-26 17:49:04 +03:00
itdoginfo
ff9aad8947 Option enable iface mon 2025-04-26 17:47:52 +03:00
itdoginfo
d9718617bd Option enable iface mon 2025-04-26 17:47:42 +03:00
itdoginfo
e865c9f324 Validate raw network. Path for DoH. Bool for iface monitoring 2025-04-26 17:47:08 +03:00
itdoginfo
7df8bb5826 rmempty proxy url string 2025-04-25 19:29:31 +03:00
itdoginfo
f960358eb6 0.3.36 2025-04-25 10:57:59 +03:00
itdoginfo
ba44966c02 Interface trigger. Disable sing-box autostart. dont touch dhcp. reload without dnsmasq restart 2025-04-24 19:25:08 +03:00
itdoginfo
615241aa37 Merge pull request #88 from Davoyan/patch-1
Update localisation
2025-04-22 11:36:38 +03:00
Davoyan
9a3220d226 Update localisation 2025-04-22 11:24:54 +03:00
itdoginfo
ec8d28857e #82 and #83 2025-04-15 00:42:16 +03:00
itdoginfo
26b49f5bbb Check fix 2025-04-15 00:15:28 +03:00
itdoginfo
0a7efb3169 Fix 2025-04-03 17:53:21 +03:00
itdoginfo
468e51ee8e v0.3.35 2025-04-03 17:42:45 +03:00
9 changed files with 145 additions and 76 deletions

View File

@@ -80,9 +80,18 @@ Luci: Services/podkop
# ToDo
Этот раздел не означает задачи, которые нужно брать и делать. Это общий список хотелок. Если вы хотите помочь, пожалуйста, спросите сначала в телеграмме.
- [ ] Сделать галку запрещающую подкопу редачить dhcp. Допилить в исключение вместе с пустыми полями proxy и vpn (нужно wiki)
- [ ] Рестарт сервиса без рестарта dnsmasq
- [ ] `ash: can't kill pid 9848: No such process` при обновлении
- [x] Interface trigger
- [x] Управление sing-box с помощью podkop. sing-box disable
- [x] Сделать галку запрещающую подкопу редачить dhcp. Допилить в исключение вместе с пустыми полями proxy и vpn (нужно wiki)
- [x] Рестарт сервиса без рестарта dnsmasq
- [x] `ash: can't kill pid 9848: No such process` при обновлении
- [x] Luci: Добавить валидацию "Proxy Configuration URL". Если пустое, то ошибка. Как с интерфейсом.
- [ ] Не грузится диагностика полностью при одной нерабочей комманде. Подумать как это можно дебажить легко. https://t.me/itdogchat/142500/378956
- [x] DoH возможность добавлять сервера c path. Взять пример из NextDNS
- [ ] При добавлении github ломается скачивание скрипта установки и любые другие скрипты с github соотвественно. Скорее всего нужно делать опцией добавление в nft самого роутера как src.
Диагностика
- [ ] Используется ли warp. Сравнивать endpoint с префиксами CF
Низкий приоритет
- [ ] Галочка, которая режет доступ к doh серверам
@@ -94,6 +103,23 @@ Luci: Services/podkop
- [ ] Unit тесты (BATS)
- [ ] Интеграционые тесты бекенда (OpenWrt rootfs + BATS)
# Don't touch my dhcp
Нужно в первую очередь, чтоб использовать опцию `server`.
В случае если опция активна, podkop не трогает /etc/config/dhcp. И вам требуется самостоятельно указать следующие значения:
```
option noresolv '1'
option cachesize '0'
list server '127.0.0.42'
```
Без этого podkop работать не будет.
# Bad WAN
При использовании опции **Interface monitoring** необходимо рестартовать podkop, чтоб init.d подхватил это
```
service podkop restart
```
# Разработка
Есть два варианта:
- Просто поставить пакет на роутер или виртуалку и прям редактировать через SFTP (opkg install openssh-sftp-server)

View File

@@ -160,13 +160,13 @@ add_tunnel() {
;;
3)
opkg install opkg install openvpn-openssl luci-app-openvpn
opkg install openvpn-openssl luci-app-openvpn
printf "\e[1;32mUse these instructions to configure https://itdog.info/nastrojka-klienta-openvpn-na-openwrt/\e[0m\n"
break
;;
4)
opkg install opkg install openconnect luci-proto-openconnect
opkg install openconnect luci-proto-openconnect
printf "\e[1;32mUse these instructions to configure https://itdog.info/nastrojka-klienta-openconnect-na-openwrt/\e[0m\n"
break
;;
@@ -248,8 +248,8 @@ install_awg_packages() {
fi
fi
if opkg list-installed | grep -q luci-app-amneziawg; then
echo "luci-app-amneziawg already installed"
if opkg list-installed | grep -qE 'luci-app-amneziawg|luci-proto-amneziawg'; then
echo "luci-app-amneziawg or luci-proto-amneziawg already installed"
else
LUCI_APP_AMNEZIAWG_FILENAME="luci-app-amneziawg${PKGPOSTFIX}"
DOWNLOAD_URL="${BASE_URL}v${VERSION}/${LUCI_APP_AMNEZIAWG_FILENAME}"

View File

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

View File

@@ -62,6 +62,23 @@ function getNetworkInterfaces(o, section_id, excludeInterfaces = []) {
});
}
function getNetworkNetworks(o, section_id, excludeInterfaces = []) {
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);
});
}
function createConfigSection(section, map, network) {
const s = section;
@@ -82,6 +99,7 @@ function createConfigSection(section, map, network) {
o = s.taboption('basic', form.TextValue, 'proxy_string', _('Proxy Configuration URL'), _(''));
o.depends('proxy_config_type', 'url');
o.rows = 5;
o.rmempty = false;
o.ucisection = s.section;
o.sectionDescriptions = new Map();
o.placeholder = 'vless://uuid@server:port?type=tcp&security=tls#main\n// backup ss://method:pass@server:port\n// backup2 vless://uuid@server:port?type=grpc&security=reality#alt';
@@ -206,9 +224,9 @@ function createConfigSection(section, map, network) {
let params = new URLSearchParams(queryString.split('#')[0]);
let type = params.get('type');
const validTypes = ['tcp', 'udp', 'grpc', 'http'];
const validTypes = ['tcp', 'raw', 'udp', 'grpc', 'http'];
if (!type || !validTypes.includes(type)) {
return _('Invalid VLESS URL: type must be one of tcp, udp, grpc, http');
return _('Invalid VLESS URL: type must be one of tcp, raw, udp, grpc, http');
}
let security = params.get('security');
@@ -261,7 +279,7 @@ function createConfigSection(section, map, network) {
o.depends('mode', 'vpn');
o.ucisection = s.section;
o.load = function (section_id) {
return getNetworkInterfaces(this, section_id, ['br-lan', 'eth0', 'eth1', 'wan', 'phy0-ap0', 'phy1-ap0', 'pppoe-wan']).then(() => {
return getNetworkInterfaces(this, section_id, ['br-lan', 'eth0', 'eth1', 'wan', 'phy0-ap0', 'phy1-ap0', 'pppoe-wan', 'lan']).then(() => {
return this.super('load', section_id);
});
};
@@ -1026,9 +1044,9 @@ return view.extend({
return true;
}
const domainRegex = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$/;
const domainRegex = /^([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}(\/[^\s]*)?$/;
if (!domainRegex.test(value)) {
return _('Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com');
return _('Invalid DNS server format. Examples: 8.8.8.8 or dns.example.com or dns.example.com/nicedns for DoH');
}
return true;
@@ -1087,6 +1105,25 @@ return view.extend({
});
};
o = mainSection.taboption('additional', form.Flag, 'mon_restart_ifaces', _('Interface monitoring'), _('Interface monitoring for bad WAN'));
o.default = '0';
o.rmempty = false;
o.ucisection = 'main';
o = mainSection.taboption('additional', form.MultiValue, 'restart_ifaces', _('Interface for monitoring'), _('Select the WAN interfaces to be monitored'));
o.ucisection = 'main';
o.depends('mon_restart_ifaces', '1');
o.load = function (section_id) {
return getNetworkNetworks(this, section_id, ['lan', 'loopback']).then(() => {
return this.super('load', section_id);
});
};
o = mainSection.taboption('additional', form.Flag, 'dont_touch_dhcp', _('Dont touch my DHCP!'), _('Podkop will not change the DHCP config'));
o.default = '0';
o.rmempty = false;
o.ucisection = 'main';
// Extra IPs and exclusions (main section)
o = mainSection.taboption('basic', form.Flag, 'exclude_from_ip_enabled', _('IP for exclusion'), _('Specify local IP addresses that will never use the configured route'));
o.default = '0';

View File

@@ -88,8 +88,8 @@ msgstr "Введите имена доменов без протоколов (п
msgid "User Domains List"
msgstr "Список пользовательских доменов"
msgid "Enter domain names separated by comma, space or newline (example: sub.example.com, example.com or one domain per line)"
msgstr "Введите имена доменов через запятую, пробел или новую строку (пример: sub.example.com, example.com или один домен на строку)"
msgid "Enter domain names separated by comma, space or newline. You can add comments after //"
msgstr "Введите имена доменов, разделяя их запятой, пробелом или с новой строки. Вы можете добавлять комментарии после //"
msgid "Local Domain Lists"
msgstr "Локальные списки доменов"
@@ -556,6 +556,9 @@ msgstr "Путь должен содержать хотя бы одну дире
msgid "Invalid path format. Must be like /tmp/cache.db"
msgstr "Неверный формат пути. Пример: /tmp/cache.db"
msgid "Select the network interface from which the traffic will originate"
msgstr "Выберите сетевой интерфейс, с которого будет исходить трафик"
msgid "Copy to Clipboard"
msgstr "Копировать в буфер обмена"
@@ -812,4 +815,7 @@ msgid "available"
msgstr "доступен"
msgid "unavailable"
msgstr "недоступен"
msgstr "недоступен"
msgid "Apply for SS2022"
msgstr "Применить для SS2022"

View File

@@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=podkop
PKG_VERSION:=0.3.34
PKG_VERSION:=0.3.38
PKG_RELEASE:=1
PKG_MAINTAINER:=ITDog <podkop@itdog.info>
@@ -13,6 +13,7 @@ define Package/podkop
SECTION:=net
CATEGORY:=Network
DEPENDS:=+sing-box +curl +jq +kmod-nft-tproxy +coreutils-base64
CONFLICTS:=https-dns-proxy
TITLE:=Domain routing app
URL:=https://itdog.info
PKGARCH:=all

View File

@@ -36,4 +36,6 @@ config main 'main'
option dns_rewrite_ttl '60'
option cache_file '/tmp/cache.db'
list iface 'br-lan'
option mon_restart_ifaces '0'
#list restart_ifaces 'wan'
option ss_uot '0'

View File

@@ -6,38 +6,16 @@ USE_PROCD=1
script=$(readlink "$initscript")
NAME="$(basename ${script:-$initscript})"
config_load "$NAME"
resolv_conf="/etc/resolv.conf"
start_service() {
echo "Start podkop"
sing_box_version=$(sing-box version | head -n 1 | awk '{print $3}')
required_version="1.11.1"
resolv_conf="/etc/resolv.conf"
config_get mon_restart_ifaces "main" "mon_restart_ifaces"
config_get restart_ifaces "main" "restart_ifaces"
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 -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 ! 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
procd_open_instance
procd_set_param command /bin/sh -c "/usr/bin/podkop start"
procd_set_param command /usr/bin/podkop start
[ "$mon_restart_ifaces" = "1" ] && [ -n "$restart_ifaces" ] && procd_set_param netdev $restart_ifaces
procd_set_param stdout 1
procd_set_param stderr 1
procd_close_instance
@@ -47,17 +25,23 @@ stop_service() {
/usr/bin/podkop stop
}
restart_service() {
stop
start
}
reload_service() {
stop
start
/usr/bin/podkop reload > /dev/null 2>&1
}
service_triggers() {
echo "service_triggers start"
procd_add_config_trigger "config.change" "$NAME" "$initscript" reload 'on_config_change'
config_get mon_restart_ifaces "main" "mon_restart_ifaces"
config_get restart_ifaces "main" "restart_ifaces"
procd_open_trigger
procd_add_config_trigger "config.change" "$NAME" "$initscript" restart 'on_config_change'
if [ "$mon_restart_ifaces" = "1" ]; then
for iface in $restart_ifaces; do
procd_add_reload_interface_trigger $iface
done
fi
procd_close_trigger
}

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"
@@ -44,7 +45,7 @@ nolog() {
echo -e "${CYAN}[$timestamp]${RESET} ${GREEN}$message${RESET}"
}
start() {
start_main() {
log "Starting podkop"
# checking
@@ -60,16 +61,12 @@ start() {
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"
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
log "[critical] /etc/resolv.conf contains an external nameserver"
fi
migration
@@ -139,7 +136,12 @@ start() {
sing_box_config_check
/etc/init.d/sing-box start
/etc/init.d/sing-box enable
#/etc/init.d/sing-box enable
log "Nice"
}
start() {
start_main
config_get proxy_string "main" "proxy_string"
config_get interface "main" "interface"
@@ -153,13 +155,13 @@ start() {
fi
}
stop() {
stop_main() {
log "Stopping the podkop"
if [ -f /var/run/podkop_list_update.pid ]; then
pid=$(cat /var/run/podkop_list_update.pid)
if kill -0 "$pid"; then
kill "$pid"
kill "$pid" 2>/dev/null
log "Stopped list_update"
fi
rm -f /var/run/podkop_list_update.pid
@@ -167,11 +169,6 @@ stop() {
remove_cron_job
config_get_bool dont_touch_dhcp "main" "dont_touch_dhcp" "0"
if [ "$dont_touch_dhcp" -eq 0 ]; then
dnsmasq_restore
fi
rm -rf /tmp/podkop/*.lst
log "Flush nft"
@@ -191,8 +188,22 @@ stop() {
log "Stop sing-box"
/etc/init.d/sing-box stop
/etc/init.d/sing-box disable
#/etc/init.d/sing-box disable
}
stop() {
config_get_bool dont_touch_dhcp "main" "dont_touch_dhcp" "0"
if [ "$dont_touch_dhcp" -eq 0 ]; then
dnsmasq_restore
fi
stop_main
}
reload() {
log "Podkop reload"
stop_main
start_main
}
# Migrations and validation funcs
@@ -364,7 +375,8 @@ dnsmasq_add_resolver() {
uci -q delete dhcp.@dnsmasq[0].podkop_server
for server in $(uci get dhcp.@dnsmasq[0].server 2>/dev/null); do
if [[ "$server" == "127.0.0.42" ]]; then
log "Dnsmasq save config error: server=127.0.0.42"
log "Dnsmasq save config error: server=127.0.0.42 is already configured. Skip editing DHCP"
return
else
uci add_list dhcp.@dnsmasq[0].podkop_server="$server"
fi
@@ -595,10 +607,12 @@ sing_box_uci() {
log "Change sing-box UCI config"
fi
if grep -q '#\s*list ifaces' "$config"; then
sed -i '/ifaces/s/#//g' $config
log "Uncommented list ifaces"
fi
[ -f /etc/rc.d/S99sing-box ] && log "Disable sing-box" && /etc/init.d/sing-box disable
# if grep -q '#\s*list ifaces' "$config"; then
# sed -i '/ifaces/s/#//g' $config
# log "Uncommented list ifaces"
# fi
}
add_socks5_for_section() {
@@ -2159,9 +2173,8 @@ case "$1" in
stop)
stop
;;
restart)
stop
start
reload)
reload
;;
main)
main
@@ -2221,7 +2234,7 @@ case "$1" in
check_dns_available
;;
*)
echo "Usage: $0 {start|stop|restart|reload|enable|disable|main|list_update|check_proxy|check_nft|check_github|check_logs|check_sing_box_connections|check_sing_box_logs|check_fakeip|check_dnsmasq|show_config|show_version|show_sing_box_config|show_luci_version|show_sing_box_version|show_system_info|get_status|get_sing_box_status|check_dns_available}"
echo "Usage: $0 {start|stop|reload|enable|disable|main|list_update|check_proxy|check_nft|check_github|check_logs|check_sing_box_connections|check_sing_box_logs|check_fakeip|check_dnsmasq|show_config|show_version|show_sing_box_config|show_luci_version|show_sing_box_version|show_system_info|get_status|get_sing_box_status|check_dns_available}"
exit 1
;;
esac