mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-08 12:36:50 +03:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fae43d0471 | ||
|
|
9d6dc45fdb | ||
|
|
9aa5a2d242 | ||
|
|
63dc86fca4 | ||
|
|
4d9cedaf4c | ||
|
|
14e7cbae01 | ||
|
|
c9f610bb1e | ||
|
|
19671c7f67 | ||
|
|
6d1e4091e5 | ||
|
|
96d661c49f | ||
|
|
da8dd06b34 | ||
|
|
2c1bcffb6d |
160
README.md
160
README.md
@@ -11,68 +11,22 @@
|
|||||||
- Если у вас не что-то не работает, то следуюет сходить в телеграм чат, прочитать закрепы и выполнить что там написано..
|
- Если у вас не что-то не работает, то следуюет сходить в телеграм чат, прочитать закрепы и выполнить что там написано..
|
||||||
- Если у вас установлен Getdomains, его следует удалить.
|
- Если у вас установлен Getdomains, его следует удалить.
|
||||||
|
|
||||||
# Удаление GetDomains скриптом
|
# Документация
|
||||||
```
|
https://podkop.net/
|
||||||
sh <(wget -O - https://raw.githubusercontent.com/itdoginfo/domain-routing-openwrt/refs/heads/master/getdomains-uninstall.sh)
|
|
||||||
```
|
|
||||||
|
|
||||||
Оставляет туннели, зоны, forwarding. А также stubby и dnscrypt. Они не помешают. Конфиг sing-box будет перезаписан в podkop.
|
|
||||||
|
|
||||||
# Установка Podkop
|
# Установка Podkop
|
||||||
Пакет работает на всех архитектурах.
|
Полная информация в [документации](https://podkop.net/docs/install/)
|
||||||
Тестировался на **ванильной** OpenWrt 23.05 и OpenWrt 24.10.
|
|
||||||
На FriendlyWrt 23.05 присуствуют зависимости от iptables, которые ломают tproxy. Если у вас появляется warning про это в логах, следуйте инструкции по приведённой там ссылке.
|
|
||||||
|
|
||||||
Поддержки APK на данный момент нет. APK будет сделан после того как разгребу основное.
|
Вкратце, достаточно одного скрипта:
|
||||||
|
|
||||||
## Автоматическая
|
|
||||||
```
|
```
|
||||||
sh <(wget -O - https://raw.githubusercontent.com/itdoginfo/podkop/refs/heads/main/install.sh)
|
sh <(wget -O - https://raw.githubusercontent.com/itdoginfo/podkop/refs/heads/main/install.sh)
|
||||||
```
|
```
|
||||||
|
|
||||||
Скрипт также предложит выбрать, какой туннель будет использоваться. Для выбранного туннеля будут установлены нужные пакеты, а для Wireguard и AmneziaWG также будет предложена автоматическая настройка - прямо в консоли скрипт запросит данные конфига. Для AmneziaWG можно также выбрать вариант с использованием конфига обычного Wireguard и автоматической обфускацией до AmneziaWG.
|
## Обновление
|
||||||
|
|
||||||
Для AmneziaWG скрипт проверяет наличие пакетов под вашу платформу в [стороннем репозитории](https://github.com/Slava-Shchipunov/awg-openwrt/releases), так как в официальном репозитории OpenWRT они отсутствуют, и автоматически их устанавливает.
|
|
||||||
|
|
||||||
## Вручную
|
|
||||||
Сделать `opkg update`, чтоб установились зависимости.
|
|
||||||
Скачать пакеты `podkop_*.ipk` и `luci-app-podkop_*.ipk` из релиза. `opkg install` сначала первый, потом второй.
|
|
||||||
|
|
||||||
# Обновление
|
|
||||||
Та же самая команда, что для установки. Но с флагом **upgrade** сразу передёт к обновлению.
|
|
||||||
```
|
```
|
||||||
sh <(wget -qO- https://raw.githubusercontent.com/itdoginfo/podkop/refs/heads/main/install.sh) --upgrade
|
sh <(wget -qO- https://raw.githubusercontent.com/itdoginfo/podkop/refs/heads/main/install.sh) --upgrade
|
||||||
```
|
```
|
||||||
|
|
||||||
# Удаление
|
|
||||||
```
|
|
||||||
opkg remove luci-i18n-podkop-ru luci-app-podkop podkop
|
|
||||||
```
|
|
||||||
|
|
||||||
# Использование
|
|
||||||
Конфиг: /etc/config/podkop
|
|
||||||
|
|
||||||
Luci: Services/podkop
|
|
||||||
|
|
||||||
## Режимы
|
|
||||||
|
|
||||||
### Proxy
|
|
||||||
Для VLESS и Shadowsocks. Другие протоколы тоже будут, кидайте в чат примеры строк без чувствительных данных.
|
|
||||||
|
|
||||||
В этом режиме просто копируйте строку в **Proxy String** и из неё автоматически настроится sing-box.
|
|
||||||
|
|
||||||
### VPN
|
|
||||||
Здесь у вас должен быть уже настроен WG/OpenVPN/OpenConnect etc, зона Zone и Forwarding не обязательны.
|
|
||||||
|
|
||||||
Просто выбрать интерфейс из списка.
|
|
||||||
|
|
||||||
## Настройка доменов и подсетей
|
|
||||||
**Community Lists** - Включить списки комьюнити
|
|
||||||
|
|
||||||
**Custom domains enable** - Добавить свои домены
|
|
||||||
|
|
||||||
**Custom subnets enable** - Добавить подсети или IP-адреса. Для подсетей задать маску.
|
|
||||||
|
|
||||||
# ToDo
|
# ToDo
|
||||||
Этот раздел не означает задачи, которые нужно брать и делать. Это общий список хотелок. Если вы хотите помочь, пожалуйста, спросите сначала в телеграмме.
|
Этот раздел не означает задачи, которые нужно брать и делать. Это общий список хотелок. Если вы хотите помочь, пожалуйста, спросите сначала в телеграмме.
|
||||||
|
|
||||||
@@ -83,109 +37,5 @@ Luci: Services/podkop
|
|||||||
- [ ] IPv6. Только после наполнения Wiki
|
- [ ] IPv6. Только после наполнения Wiki
|
||||||
|
|
||||||
Рефактор
|
Рефактор
|
||||||
- [ ] Handle для sing-box
|
|
||||||
- [ ] Handle для dnsmasq
|
|
||||||
- [ ] Unit тесты (BATS)
|
- [ ] Unit тесты (BATS)
|
||||||
- [ ] Интеграционые тесты бекенда (OpenWrt rootfs + 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 работать не будет.
|
|
||||||
|
|
||||||
Если нужно до определённых доменов ходить через определённый DNS-сервер, то конфиг выглядит так
|
|
||||||
```
|
|
||||||
option noresolv '1'
|
|
||||||
option cachesize '0'
|
|
||||||
list server '/itdog.info/1.1.1.1'
|
|
||||||
list server '127.0.0.42'
|
|
||||||
```
|
|
||||||
|
|
||||||
В этом случае домен и все субдомены ресурса itdog.info будут резолвится через DNS-сервер 1.1.1.1
|
|
||||||
|
|
||||||
# Bad WAN
|
|
||||||
При использовании опции **Interface monitoring** необходимо рестартовать podkop, чтоб init.d подхватил это
|
|
||||||
```
|
|
||||||
service podkop restart
|
|
||||||
```
|
|
||||||
|
|
||||||
# Разработка
|
|
||||||
Есть два варианта:
|
|
||||||
- Просто поставить пакет на роутер или виртуалку и прям редактировать через SFTP (opkg install openssh-sftp-server)
|
|
||||||
- SDK, чтоб собирать пакеты
|
|
||||||
|
|
||||||
Для сборки пакетов нужен SDK, один из вариантов скачать прям файл и разархивировать
|
|
||||||
https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/
|
|
||||||
Нужен файл с SDK в имени
|
|
||||||
|
|
||||||
```
|
|
||||||
wget https://downloads.openwrt.org/releases/23.05.5/targets/x86/64/openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
|
||||||
tar xf openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz
|
|
||||||
mv openwrt-sdk-23.05.5-x86-64_gcc-12.3.0_musl.Linux-x86_64 SDK
|
|
||||||
```
|
|
||||||
Последнее для удобства.
|
|
||||||
|
|
||||||
Создаём директорию для пакета
|
|
||||||
```
|
|
||||||
mkdir package/utilites
|
|
||||||
```
|
|
||||||
|
|
||||||
Симлинк из репозитория
|
|
||||||
```
|
|
||||||
ln -s ~/podkop/podkop package/utilites/podkop
|
|
||||||
ln -s ~/podkop/luci-app-podkop package/luci-app-podkop
|
|
||||||
```
|
|
||||||
|
|
||||||
В первый раз для сборки luci-app необходимо обновить пакеты
|
|
||||||
```
|
|
||||||
./scripts/feeds update -a
|
|
||||||
```
|
|
||||||
|
|
||||||
Для make можно добавить флаг -j N, где N - количество ядер для сборки. Первый раз пройдёт быстрее.
|
|
||||||
|
|
||||||
При первом make выводится менюшка, можно просто save, exit и всё. Первый раз долго грузит зависимости.
|
|
||||||
|
|
||||||
Сборка пакета. Сами пакеты собираются быстро.
|
|
||||||
```
|
|
||||||
make package/podkop/{clean,compile} V=s
|
|
||||||
```
|
|
||||||
|
|
||||||
Также для luci
|
|
||||||
```
|
|
||||||
make package/luci-app-podkop/{clean,compile} V=s
|
|
||||||
```
|
|
||||||
|
|
||||||
.ipk лежат в `bin/packages/x86_64/base/`
|
|
||||||
|
|
||||||
## Примеры строк
|
|
||||||
https://github.com/itdoginfo/podkop/blob/main/String-example.md
|
|
||||||
|
|
||||||
## Ошибки
|
|
||||||
```
|
|
||||||
Makefile:17: /SDK/feeds/luci/luci.mk: No such file or directory
|
|
||||||
make[2]: *** No rule to make target '/SDK/feeds/luci/luci.mk'. Stop.
|
|
||||||
time: package/luci/luci-app-podkop/clean#0.00#0.00#0.00
|
|
||||||
ERROR: package/luci/luci-app-podkop failed to build.
|
|
||||||
make[1]: *** [package/Makefile:129: package/luci/luci-app-podkop/clean] Error 1
|
|
||||||
make[1]: Leaving directory '/SDK'
|
|
||||||
make: *** [/SDK/include/toplevel.mk:226: package/luci-app-podkop/clean] Error 2
|
|
||||||
```
|
|
||||||
|
|
||||||
Не загружены пакеты для luci
|
|
||||||
|
|
||||||
## make зависимости
|
|
||||||
https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem
|
|
||||||
|
|
||||||
Ubuntu
|
|
||||||
```
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install build-essential clang flex bison g++ gawk \
|
|
||||||
gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev \
|
|
||||||
python3-distutils rsync unzip zlib1g-dev file wget
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ check_system() {
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if opkg list-installed | grep -qE "iptables|kmod-iptab"; then
|
if opkg list-installed | grep -q "iptables-mod-extra"; then
|
||||||
printf "\033[31;1mFound incompatible iptables packages. If you're using FriendlyWrt: https://t.me/itdogchat/44512/181082\033[0m\n"
|
printf "\033[31;1mFound incompatible iptables packages. If you're using FriendlyWrt: https://t.me/itdogchat/44512/181082\033[0m\n"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-podkop
|
PKG_NAME:=luci-app-podkop
|
||||||
PKG_VERSION:=0.3.43
|
PKG_VERSION:=0.3.46
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI podkop app
|
LUCI_TITLE:=LuCI podkop app
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ function createConfigSection(section, map, network) {
|
|||||||
o = s.taboption('basic', form.ListValue, 'mode', _('Connection Type'), _('Select between VPN and Proxy connection methods for traffic routing'));
|
o = s.taboption('basic', form.ListValue, 'mode', _('Connection Type'), _('Select between VPN and Proxy connection methods for traffic routing'));
|
||||||
o.value('proxy', ('Proxy'));
|
o.value('proxy', ('Proxy'));
|
||||||
o.value('vpn', ('VPN'));
|
o.value('vpn', ('VPN'));
|
||||||
|
o.value('block', ('Block'));
|
||||||
o.ucisection = s.section;
|
o.ucisection = s.section;
|
||||||
|
|
||||||
o = s.taboption('basic', form.ListValue, 'proxy_config_type', _('Configuration Type'), _('Select how to configure the proxy'));
|
o = s.taboption('basic', form.ListValue, 'proxy_config_type', _('Configuration Type'), _('Select how to configure the proxy'));
|
||||||
@@ -638,7 +639,7 @@ const showConfigModal = async (command, title) => {
|
|||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||||
|
|
||||||
const response = await fetch('https://fakeip.tech-domain.club/check', { signal: controller.signal });
|
const response = await fetch('https://fakeip.podkop.fyi/check', { signal: controller.signal });
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
@@ -646,15 +647,15 @@ const showConfigModal = async (command, title) => {
|
|||||||
if (data.fakeip === true) {
|
if (data.fakeip === true) {
|
||||||
formattedOutput += '\n✅ ' + _('FakeIP is working in browser!') + '\n';
|
formattedOutput += '\n✅ ' + _('FakeIP is working in browser!') + '\n';
|
||||||
} else {
|
} else {
|
||||||
formattedOutput += '❌ ' + _('FakeIP is not working in browser') + '\n';
|
formattedOutput += '\n❌ ' + _('FakeIP is not working in browser') + '\n';
|
||||||
formattedOutput += _('Check DNS server on current device (PC, phone)') + '\n';
|
formattedOutput += _('Check DNS server on current device (PC, phone)') + '\n';
|
||||||
formattedOutput += _('Its must be router!') + '\n';
|
formattedOutput += _('Its must be router!') + '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bypass check
|
// Bypass check
|
||||||
const bypassResponse = await fetch('https://fakeip.tech-domain.club/check', { signal: controller.signal });
|
const bypassResponse = await fetch('https://fakeip.podkop.fyi/check', { signal: controller.signal });
|
||||||
const bypassData = await bypassResponse.json();
|
const bypassData = await bypassResponse.json();
|
||||||
const bypassResponse2 = await fetch('https://ip.tech-domain.club/check', { signal: controller.signal });
|
const bypassResponse2 = await fetch('https://ip.podkop.fyi/check', { signal: controller.signal });
|
||||||
const bypassData2 = await bypassResponse2.json();
|
const bypassData2 = await bypassResponse2.json();
|
||||||
|
|
||||||
formattedOutput += '━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
|
formattedOutput += '━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
|
||||||
@@ -734,7 +735,7 @@ const createStatusPanel = (title, status, buttons, extraData = {}) => {
|
|||||||
title === 'Sing-box Status' ?
|
title === 'Sing-box Status' ?
|
||||||
(status.running && !status.enabled ? '✔ running' : '✘ ' + status.status) :
|
(status.running && !status.enabled ? '✔ running' : '✘ ' + status.status) :
|
||||||
title === 'Podkop Status' ?
|
title === 'Podkop Status' ?
|
||||||
(status.enabled ? '✔ enabled' : '✘ disabled') :
|
(status.enabled ? '✔ Autostart enabled' : '✘ Autostart disabled') :
|
||||||
(status.running ? '✔' : '✘') + ' ' + status.status
|
(status.running ? '✔' : '✘') + ' ' + status.status
|
||||||
])
|
])
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
@@ -754,14 +755,20 @@ const createStatusPanel = (title, status, buttons, extraData = {}) => {
|
|||||||
action: 'restart',
|
action: 'restart',
|
||||||
reload: true
|
reload: true
|
||||||
}),
|
}),
|
||||||
|
ButtonFactory.createActionButton({
|
||||||
|
label: 'Stop Podkop',
|
||||||
|
type: 'apply',
|
||||||
|
action: 'stop',
|
||||||
|
reload: true
|
||||||
|
}),
|
||||||
ButtonFactory.createInitActionButton({
|
ButtonFactory.createInitActionButton({
|
||||||
label: status.enabled ? 'Disable Podkop' : 'Enable Podkop',
|
label: status.enabled ? 'Disable Autostart' : 'Enable Autostart',
|
||||||
type: status.enabled ? 'remove' : 'apply',
|
type: status.enabled ? 'remove' : 'apply',
|
||||||
action: status.enabled ? 'disable' : 'enable',
|
action: status.enabled ? 'disable' : 'enable',
|
||||||
reload: true
|
reload: true
|
||||||
}),
|
}),
|
||||||
ButtonFactory.createModalButton({
|
ButtonFactory.createModalButton({
|
||||||
label: _('Global check'),
|
label: E('strong', _('Global check')),
|
||||||
command: 'global_check',
|
command: 'global_check',
|
||||||
title: _('Click here for all the info')
|
title: _('Click here for all the info')
|
||||||
}),
|
}),
|
||||||
@@ -1140,7 +1147,7 @@ return view.extend({
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
o = mainSection.taboption('additional', form.Value, 'dns_rewrite_ttl', _('DNS Rewrite TTL'), _('Time in seconds for DNS record caching (default: 600)'));
|
o = mainSection.taboption('additional', form.Value, 'dns_rewrite_ttl', _('DNS Rewrite TTL'), _('Time in seconds for DNS record caching (default: 60)'));
|
||||||
o.default = '60';
|
o.default = '60';
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.ucisection = 'main';
|
o.ucisection = 'main';
|
||||||
@@ -1212,6 +1219,11 @@ return view.extend({
|
|||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.ucisection = 'main';
|
o.ucisection = 'main';
|
||||||
|
|
||||||
|
o = mainSection.taboption('additional', form.Flag, 'detour', _('Proxy download of lists'), _('Downloading all lists via main Proxy/VPN'));
|
||||||
|
o.default = '0';
|
||||||
|
o.rmempty = false;
|
||||||
|
o.ucisection = 'main';
|
||||||
|
|
||||||
// Extra IPs and exclusions (main section)
|
// 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 = 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';
|
o.default = '0';
|
||||||
@@ -1302,7 +1314,7 @@ return view.extend({
|
|||||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch('https://fakeip.tech-domain.club/check', { signal: controller.signal });
|
const response = await fetch('https://fakeip.podkop.fyi/check', { signal: controller.signal });
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
@@ -1341,7 +1353,7 @@ return view.extend({
|
|||||||
return resolve(createStatus('not_working', 'DNS not configured', 'ERROR'));
|
return resolve(createStatus('not_working', 'DNS not configured', 'ERROR'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await safeExec('nslookup', ['-timeout=2', 'fakeip.tech-domain.club', '127.0.0.42']);
|
const result = await safeExec('nslookup', ['-timeout=2', 'fakeip.podkop.fyi', '127.0.0.42']);
|
||||||
|
|
||||||
if (result.stdout && result.stdout.includes('198.18')) {
|
if (result.stdout && result.stdout.includes('198.18')) {
|
||||||
return resolve(createStatus('working', 'working on router', 'SUCCESS'));
|
return resolve(createStatus('working', 'working on router', 'SUCCESS'));
|
||||||
@@ -1390,7 +1402,7 @@ return view.extend({
|
|||||||
const controller1 = new AbortController();
|
const controller1 = new AbortController();
|
||||||
const timeoutId1 = setTimeout(() => controller1.abort(), 10000);
|
const timeoutId1 = setTimeout(() => controller1.abort(), 10000);
|
||||||
|
|
||||||
const response1 = await fetch('https://fakeip.tech-domain.club/check', { signal: controller1.signal });
|
const response1 = await fetch('https://fakeip.podkop.fyi/check', { signal: controller1.signal });
|
||||||
const data1 = await response1.json();
|
const data1 = await response1.json();
|
||||||
clearTimeout(timeoutId1);
|
clearTimeout(timeoutId1);
|
||||||
|
|
||||||
@@ -1405,7 +1417,7 @@ return view.extend({
|
|||||||
const controller2 = new AbortController();
|
const controller2 = new AbortController();
|
||||||
const timeoutId2 = setTimeout(() => controller2.abort(), 10000);
|
const timeoutId2 = setTimeout(() => controller2.abort(), 10000);
|
||||||
|
|
||||||
const response2 = await fetch('https://ip.tech-domain.club/check', { signal: controller2.signal });
|
const response2 = await fetch('https://ip.podkop.fyi/check', { signal: controller2.signal });
|
||||||
const data2 = await response2.json();
|
const data2 = await response2.json();
|
||||||
clearTimeout(timeoutId2);
|
clearTimeout(timeoutId2);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=podkop
|
PKG_NAME:=podkop
|
||||||
PKG_VERSION:=0.3.43
|
PKG_VERSION:=0.3.46
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_MAINTAINER:=ITDog <podkop@itdog.info>
|
PKG_MAINTAINER:=ITDog <podkop@itdog.info>
|
||||||
@@ -15,7 +15,7 @@ define Package/podkop
|
|||||||
DEPENDS:=+sing-box +curl +jq +kmod-nft-tproxy +coreutils-base64
|
DEPENDS:=+sing-box +curl +jq +kmod-nft-tproxy +coreutils-base64
|
||||||
CONFLICTS:=https-dns-proxy
|
CONFLICTS:=https-dns-proxy
|
||||||
TITLE:=Domain routing app
|
TITLE:=Domain routing app
|
||||||
URL:=https://itdog.info
|
URL:=https://podkop.net
|
||||||
PKGARCH:=all
|
PKGARCH:=all
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|||||||
@@ -38,4 +38,5 @@ config main 'main'
|
|||||||
list iface 'br-lan'
|
list iface 'br-lan'
|
||||||
option mon_restart_ifaces '0'
|
option mon_restart_ifaces '0'
|
||||||
#list restart_ifaces 'wan'
|
#list restart_ifaces 'wan'
|
||||||
option ss_uot '0'
|
option ss_uot '0'
|
||||||
|
option detour '0'
|
||||||
@@ -20,7 +20,7 @@ SING_BOX_CONFIG="/etc/sing-box/config.json"
|
|||||||
FAKEIP="198.18.0.0/15"
|
FAKEIP="198.18.0.0/15"
|
||||||
VALID_SERVICES="russia_inside russia_outside ukraine_inside geoblock block porn news anime youtube discord meta twitter hdrezka tiktok telegram cloudflare"
|
VALID_SERVICES="russia_inside russia_outside ukraine_inside geoblock block porn news anime youtube discord meta twitter hdrezka tiktok telegram cloudflare"
|
||||||
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.140.15.15 208.67.220.220 208.67.222.222 77.88.8.1 77.88.8.8"
|
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.140.15.15 208.67.220.220 208.67.222.222 77.88.8.1 77.88.8.8"
|
||||||
TEST_DOMAIN="fakeip.tech-domain.club"
|
TEST_DOMAIN="fakeip.podkop.fyi"
|
||||||
INTERFACES_LIST=""
|
INTERFACES_LIST=""
|
||||||
SRC_INTERFACE=""
|
SRC_INTERFACE=""
|
||||||
RESOLV_CONF="/etc/resolv.conf"
|
RESOLV_CONF="/etc/resolv.conf"
|
||||||
@@ -29,11 +29,7 @@ CLOUDFLARE_OCTETS="103.21 103.22 103.31 104.16 104.17 104.18 104.19 104.20 104.2
|
|||||||
log() {
|
log() {
|
||||||
local message="$1"
|
local message="$1"
|
||||||
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
|
||||||
local CYAN="\033[0;36m"
|
|
||||||
local GREEN="\033[0;32m"
|
|
||||||
local RESET="\033[0m"
|
|
||||||
|
|
||||||
echo -e "${CYAN}[$timestamp]${RESET} ${GREEN}$message${RESET}"
|
|
||||||
logger -t "podkop" "$timestamp $message"
|
logger -t "podkop" "$timestamp $message"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +67,10 @@ start_main() {
|
|||||||
|
|
||||||
config_foreach process_validate_service
|
config_foreach process_validate_service
|
||||||
|
|
||||||
sleep 3
|
# Sync time for DoH/DoT
|
||||||
|
/usr/sbin/ntpd -q -p 194.190.168.1 -p 216.239.35.0 -p 216.239.35.4 -p 162.159.200.1 -p 162.159.200.123
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
mkdir -p /tmp/podkop
|
mkdir -p /tmp/podkop
|
||||||
|
|
||||||
@@ -132,6 +131,12 @@ start_main() {
|
|||||||
sing_box_quic_reject
|
sing_box_quic_reject
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
config_get_bool detour "main" "detour" "0"
|
||||||
|
if [ "$detour" -eq 1 ]; then
|
||||||
|
log "Detour mixed enable"
|
||||||
|
detour_mixed
|
||||||
|
fi
|
||||||
|
|
||||||
sing_box_config_check
|
sing_box_config_check
|
||||||
/etc/init.d/sing-box start
|
/etc/init.d/sing-box start
|
||||||
#/etc/init.d/sing-box enable
|
#/etc/init.d/sing-box enable
|
||||||
@@ -204,6 +209,12 @@ reload() {
|
|||||||
start_main
|
start_main
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restart() {
|
||||||
|
log "Podkop restart"
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
}
|
||||||
|
|
||||||
# Migrations and validation funcs
|
# Migrations and validation funcs
|
||||||
migration() {
|
migration() {
|
||||||
# list migrate
|
# list migrate
|
||||||
@@ -564,10 +575,19 @@ list_update() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
for i in $(seq 1 60); do
|
for i in $(seq 1 60); do
|
||||||
if curl -s -m 3 https://github.com >/dev/null; then
|
config_get_bool detour "main" "detour" "0"
|
||||||
log "GitHub is available"
|
if [ "$detour" -eq 1 ]; then
|
||||||
break
|
if http_proxy="http://127.0.0.1:4534" https_proxy="http://127.0.0.1:4534" curl -s -m 3 https://github.com >/dev/null; then
|
||||||
|
log "GitHub is available"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if curl -s -m 3 https://github.com >/dev/null; then
|
||||||
|
log "GitHub is available"
|
||||||
|
break
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "GitHub is unavailable [$i/60]"
|
log "GitHub is unavailable [$i/60]"
|
||||||
sleep 3
|
sleep 3
|
||||||
done
|
done
|
||||||
@@ -776,7 +796,7 @@ sing_box_create_bypass_ruleset() {
|
|||||||
"rules": [
|
"rules": [
|
||||||
{
|
{
|
||||||
"domain_suffix": [
|
"domain_suffix": [
|
||||||
"ip.tech-domain.club"
|
"ip.podkop.fyi"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -922,6 +942,9 @@ sing_box_outdound() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
"block")
|
||||||
|
log "Block mode"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
log "Requires *vpn* or *proxy* value"
|
log "Requires *vpn* or *proxy* value"
|
||||||
return
|
return
|
||||||
@@ -1012,7 +1035,7 @@ sing_box_config_outbound_json() {
|
|||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
log "Outbound config updated successfully"
|
log "Outbound config updated successfully"
|
||||||
else
|
else
|
||||||
log "Error: Invalid JSON config generated"
|
log "Error: Outbound invalid JSON config generated"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -1073,9 +1096,9 @@ sing_box_config_shadowsocks() {
|
|||||||
)' $SING_BOX_CONFIG >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json $SING_BOX_CONFIG
|
)' $SING_BOX_CONFIG >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json $SING_BOX_CONFIG
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
log "Config updated successfully"
|
log "Config Shadowsocks updated successfully"
|
||||||
else
|
else
|
||||||
log "Error: Invalid JSON config generated"
|
log "Error: Shadowsocks invalid JSON config generated"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -1200,9 +1223,9 @@ sing_box_config_vless() {
|
|||||||
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
log "Config created successfully"
|
log "Config VLESS created successfully"
|
||||||
else
|
else
|
||||||
log "Error: Invalid JSON config generated"
|
log "Error: VLESS invalid JSON config generated"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -1356,6 +1379,7 @@ sing_box_ruleset_remote() {
|
|||||||
local tag=$1
|
local tag=$1
|
||||||
local type=$2
|
local type=$2
|
||||||
local update_interval=$3
|
local update_interval=$3
|
||||||
|
local detour=$4
|
||||||
|
|
||||||
url="$SRS_MAIN_URL/$tag.srs"
|
url="$SRS_MAIN_URL/$tag.srs"
|
||||||
|
|
||||||
@@ -1371,15 +1395,19 @@ sing_box_ruleset_remote() {
|
|||||||
--arg type "$type" \
|
--arg type "$type" \
|
||||||
--arg url "$url" \
|
--arg url "$url" \
|
||||||
--arg update_interval "$update_interval" \
|
--arg update_interval "$update_interval" \
|
||||||
|
--arg detour "$detour" \
|
||||||
'
|
'
|
||||||
.route.rule_set += [
|
.route.rule_set += [
|
||||||
{
|
(
|
||||||
"tag": $tag,
|
{
|
||||||
"type": $type,
|
"tag": $tag,
|
||||||
"format": "binary",
|
"type": $type,
|
||||||
"url": $url,
|
"format": "binary",
|
||||||
"update_interval": $update_interval
|
"url": $url,
|
||||||
}
|
"update_interval": $update_interval
|
||||||
|
} +
|
||||||
|
(if $detour == "1" then {"download_detour": "main"} else {} end)
|
||||||
|
)
|
||||||
]' "$SING_BOX_CONFIG" > /tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
]' "$SING_BOX_CONFIG" > /tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
||||||
|
|
||||||
log "Added new ruleset with tag $tag"
|
log "Added new ruleset with tag $tag"
|
||||||
@@ -1414,7 +1442,13 @@ list_subnets_download() {
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
local filename=$(basename "$URL")
|
local filename=$(basename "$URL")
|
||||||
wget -O "/tmp/podkop/$filename" "$URL"
|
|
||||||
|
config_get_bool detour "main" "detour" "0"
|
||||||
|
if [ "$detour" -eq 1 ]; then
|
||||||
|
http_proxy="http://127.0.0.1:4534" https_proxy="http://127.0.0.1:4534" wget -O "/tmp/podkop/$filename" "$URL"
|
||||||
|
else
|
||||||
|
wget -O "/tmp/podkop/$filename" "$URL"
|
||||||
|
fi
|
||||||
|
|
||||||
while IFS= read -r subnet; do
|
while IFS= read -r subnet; do
|
||||||
if [ "$service" = "discord" ]; then
|
if [ "$service" = "discord" ]; then
|
||||||
@@ -1430,27 +1464,54 @@ sing_box_rules() {
|
|||||||
local rule_set="$1"
|
local rule_set="$1"
|
||||||
local outbound="$2"
|
local outbound="$2"
|
||||||
|
|
||||||
# Check if there is an outbound rule for "tproxy-in"
|
config_get mode "$section" "mode"
|
||||||
local rule_exists=$(jq -r '.route.rules[] | select(.outbound == "'"$outbound"'" and .inbound == ["tproxy-in"])' "$SING_BOX_CONFIG")
|
|
||||||
|
|
||||||
if [[ -n "$rule_exists" ]]; then
|
if [[ "$mode" == "block" ]]; then
|
||||||
# If a rule for tproxy-in exists, add a new rule_set to the existing rule
|
# Action reject
|
||||||
jq \
|
# Check if there is an rule with reject"
|
||||||
--arg rule_set "$rule_set" \
|
local rule_exists=$(jq -r '.route.rules[] | select(.inbound == ["tproxy-in"] and .action == "reject")' "$SING_BOX_CONFIG")
|
||||||
--arg outbound "$outbound" \
|
|
||||||
'(.route.rules[] | select(.outbound == $outbound and .inbound == ["tproxy-in"]) .rule_set) += [$rule_set]' \
|
if [[ -n "$rule_exists" ]]; then
|
||||||
"$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
# If a rule for rejectexists, add a new rule_set to the existing rule
|
||||||
|
jq \
|
||||||
|
--arg rule_set "$rule_set" \
|
||||||
|
'(.route.rules[] | select(.inbound == ["tproxy-in"] and .action == "reject") .rule_set) += [$rule_set]' \
|
||||||
|
"$SING_BOX_CONFIG" > /tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
||||||
|
else
|
||||||
|
# If there is no rule for reject, create a new one with rule_set
|
||||||
|
jq \
|
||||||
|
--arg rule_set "$rule_set" \
|
||||||
|
'.route.rules += [{
|
||||||
|
"inbound": ["tproxy-in"],
|
||||||
|
"rule_set": [$rule_set],
|
||||||
|
"action": "reject"
|
||||||
|
}]' "$SING_BOX_CONFIG" > /tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
||||||
|
fi
|
||||||
|
return
|
||||||
else
|
else
|
||||||
# If there is no rule for tproxy-in, create a new one with rule_set
|
# Action route
|
||||||
jq \
|
# Check if there is an outbound rule for "tproxy-in"
|
||||||
--arg rule_set "$rule_set" \
|
local rule_exists=$(jq -r '.route.rules[] | select(.outbound == "'"$outbound"'" and .inbound == ["tproxy-in"])' "$SING_BOX_CONFIG")
|
||||||
--arg outbound "$outbound" \
|
|
||||||
'.route.rules += [{
|
if [[ -n "$rule_exists" ]]; then
|
||||||
"inbound": ["tproxy-in"],
|
# If a rule for tproxy-in exists, add a new rule_set to the existing rule
|
||||||
"rule_set": [$rule_set],
|
jq \
|
||||||
"outbound": $outbound,
|
--arg rule_set "$rule_set" \
|
||||||
"action": "route"
|
--arg outbound "$outbound" \
|
||||||
}]' "$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
'(.route.rules[] | select(.outbound == $outbound and .inbound == ["tproxy-in"]) .rule_set) += [$rule_set]' \
|
||||||
|
"$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
||||||
|
else
|
||||||
|
# If there is no rule for tproxy-in, create a new one with rule_set
|
||||||
|
jq \
|
||||||
|
--arg rule_set "$rule_set" \
|
||||||
|
--arg outbound "$outbound" \
|
||||||
|
'.route.rules += [{
|
||||||
|
"inbound": ["tproxy-in"],
|
||||||
|
"rule_set": [$rule_set],
|
||||||
|
"outbound": $outbound,
|
||||||
|
"action": "route"
|
||||||
|
}]' "$SING_BOX_CONFIG" >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json "$SING_BOX_CONFIG"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1476,8 +1537,9 @@ sing_box_quic_reject() {
|
|||||||
process_remote_ruleset_srs() {
|
process_remote_ruleset_srs() {
|
||||||
config_get_bool domain_list_enabled "$section" "domain_list_enabled" "0"
|
config_get_bool domain_list_enabled "$section" "domain_list_enabled" "0"
|
||||||
if [ "$domain_list_enabled" -eq 1 ]; then
|
if [ "$domain_list_enabled" -eq 1 ]; then
|
||||||
|
config_get_bool detour "main" "detour" "0"
|
||||||
log "Adding a srs list for $section"
|
log "Adding a srs list for $section"
|
||||||
config_list_foreach "$section" domain_list "sing_box_ruleset_remote" "remote" "1d"
|
config_list_foreach "$section" domain_list "sing_box_ruleset_remote" "remote" "1d" "$detour"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1544,7 +1606,12 @@ list_custom_url_domains_create() {
|
|||||||
local URL="$1"
|
local URL="$1"
|
||||||
local filename=$(basename "$URL")
|
local filename=$(basename "$URL")
|
||||||
|
|
||||||
wget -q -O "/tmp/podkop/${filename}" "$URL"
|
config_get_bool detour "main" "detour" "0"
|
||||||
|
if [ "$detour" -eq 1 ]; then
|
||||||
|
http_proxy="http://127.0.0.1:4534" https_proxy="http://127.0.0.1:4534" wget -O "/tmp/podkop/${filename}" "$URL"
|
||||||
|
else
|
||||||
|
wget -O "/tmp/podkop/${filename}" "$URL"
|
||||||
|
fi
|
||||||
|
|
||||||
while IFS= read -r domain; do
|
while IFS= read -r domain; do
|
||||||
log "From downloaded file: $domain"
|
log "From downloaded file: $domain"
|
||||||
@@ -1584,7 +1651,12 @@ list_custom_url_subnets_create() {
|
|||||||
local URL="$1"
|
local URL="$1"
|
||||||
local filename=$(basename "$URL")
|
local filename=$(basename "$URL")
|
||||||
|
|
||||||
wget -q -O "/tmp/podkop/${filename}" "$URL"
|
config_get_bool detour "main" "detour" "0"
|
||||||
|
if [ "$detour" -eq 1 ]; then
|
||||||
|
http_proxy="http://127.0.0.1:4534" https_proxy="http://127.0.0.1:4534" wget -O "/tmp/podkop/${filename}" "$URL"
|
||||||
|
else
|
||||||
|
wget -O "/tmp/podkop/${filename}" "$URL"
|
||||||
|
fi
|
||||||
|
|
||||||
while IFS= read -r subnet; do
|
while IFS= read -r subnet; do
|
||||||
log "From local file: $subnet"
|
log "From local file: $subnet"
|
||||||
@@ -1643,6 +1715,31 @@ sing_box_rules_source_ip_cidr() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
detour_mixed() {
|
||||||
|
local section="main"
|
||||||
|
local port="4534"
|
||||||
|
local tag="detour"
|
||||||
|
|
||||||
|
log "Adding detour Socks5 for $section on port $port"
|
||||||
|
|
||||||
|
jq \
|
||||||
|
--arg tag "$tag" \
|
||||||
|
--arg port "$port" \
|
||||||
|
--arg section "$section" \
|
||||||
|
'.inbounds += [{
|
||||||
|
"tag": $tag,
|
||||||
|
"type": "mixed",
|
||||||
|
"listen": "127.0.0.1",
|
||||||
|
"listen_port": ($port|tonumber),
|
||||||
|
"set_system_proxy": false
|
||||||
|
}] |
|
||||||
|
.route.rules += [{
|
||||||
|
"inbound": [$tag],
|
||||||
|
"outbound": $section,
|
||||||
|
"action": "route"
|
||||||
|
}]' $SING_BOX_CONFIG >/tmp/sing-box-config-tmp.json && mv /tmp/sing-box-config-tmp.json $SING_BOX_CONFIG
|
||||||
|
}
|
||||||
|
|
||||||
## nftables
|
## nftables
|
||||||
list_all_traffic_from_ip() {
|
list_all_traffic_from_ip() {
|
||||||
local ip="$1"
|
local ip="$1"
|
||||||
@@ -1777,7 +1874,14 @@ check_github() {
|
|||||||
for url in "$DOMAINS_RU_INSIDE" "$DOMAINS_RU_OUTSIDE" "$DOMAINS_UA" "$DOMAINS_YOUTUBE" \
|
for url in "$DOMAINS_RU_INSIDE" "$DOMAINS_RU_OUTSIDE" "$DOMAINS_UA" "$DOMAINS_YOUTUBE" \
|
||||||
"$SUBNETS_TWITTER" "$SUBNETS_META" "$SUBNETS_DISCORD"; do
|
"$SUBNETS_TWITTER" "$SUBNETS_META" "$SUBNETS_DISCORD"; do
|
||||||
local list_name=$(basename "$url")
|
local list_name=$(basename "$url")
|
||||||
wget -q -O /dev/null "$url"
|
|
||||||
|
config_get_bool detour "main" "detour" "0"
|
||||||
|
if [ "$detour" -eq 1 ]; then
|
||||||
|
http_proxy="http://127.0.0.1:4534" https_proxy="http://127.0.0.1:4534" wget -q -O /dev/null "$url"
|
||||||
|
else
|
||||||
|
wget -q -O /dev/null "$url"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
nolog "- $list_name: available"
|
nolog "- $list_name: available"
|
||||||
else
|
else
|
||||||
@@ -2310,6 +2414,9 @@ case "$1" in
|
|||||||
reload)
|
reload)
|
||||||
reload
|
reload
|
||||||
;;
|
;;
|
||||||
|
restart)
|
||||||
|
restart
|
||||||
|
;;
|
||||||
main)
|
main)
|
||||||
main
|
main
|
||||||
;;
|
;;
|
||||||
@@ -2371,7 +2478,7 @@ case "$1" in
|
|||||||
global_check
|
global_check
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
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|global_check}"
|
echo "Usage: $0 {start|stop|reload|restart|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|global_check}"
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
Reference in New Issue
Block a user