5 Commits

Author SHA1 Message Date
DenPiligrim 0c16656c4f Merge pull request #5 from denpiligrim/dp-fix
v1.0.2
2026-01-05 14:29:03 +03:00
Den Piligrim 45f67d3848 add: self-signed cert, docker, cmd rotate 2026-01-05 14:27:03 +03:00
Den Piligrim b77e5560c8 fix url 2026-01-03 22:09:46 +03:00
Den Piligrim c48e3df360 fix var 2026-01-03 22:04:50 +03:00
Den Piligrim 17f7baaf61 fix: docker panel, selfsigned cert 2026-01-03 16:05:00 +03:00
11 changed files with 332 additions and 63 deletions
+11
View File
@@ -0,0 +1,11 @@
# Внести вклад
Буду рад любому вкладу в разработку проекта! Простой процесс для контрибьюторов:
1. Форкните репозиторий на GitHub.
2. Создайте ветку с осмысленным именем, например `feature/add-README` или `fix/whitelist-load`.
3. Внесите изменения и добавьте короткое описание в коммите.
4. Запустите локально базовые проверки (если есть).
5. Отправьте ветку в ваш форк и создайте Pull Request в основной репозиторий.
<sup>Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты.</sup>
+32 -11
View File
@@ -2,7 +2,7 @@
<p><img src="https://denpiligrim.ru/storage/images/3dp-manager.png" alt="3dp-manager preview"></p>
![Version](https://img.shields.io/badge/version-1.0.1-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
![Version](https://img.shields.io/badge/version-1.0.2-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
@@ -61,6 +61,9 @@
## Установка
> [!WARNING]
> Утилита работает на основном сервере
У вас должны быть установлены пакеты на сервере `curl`, `jq` командой: `apt install curl jq` и панель управления `3x-ui`, которую можно установить командой: `bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)`
Установите проект на сервер командой:
@@ -68,7 +71,13 @@
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы.</small>
<sup>Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы.</sup>
Если панель 3x-ui находится в Docker контейнере, установите командой:
```bash
REMOTE_PANEL=true bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
## Обновление
@@ -78,7 +87,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>Краткое описание: подтягивает последние изменения и перезапускает контейнеры.</small>
<sup>Краткое описание: подтягивает последние изменения и перезапускает контейнеры.</sup>
## Удаление
@@ -88,14 +97,14 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки.</small>
<sup>Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки.</sup>
---
## Установка сервиса перенаправления (forwarding)
> [!WARNING]
> Сервис перенаправления работает на промежуточном сервере.
> Сервис перенаправления работает на промежуточном сервере
Сервис перенаправления позволяет проксировать входящие порты с промежуточного сервера на основной.
@@ -103,7 +112,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
<small>Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки.</small>
<sup>Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки.</sup>
## Удаление перенаправления
@@ -111,7 +120,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>Краткое описание: удаляет правила и отключает сервис перенаправления.</small>
<sup>Краткое описание: удаляет правила и отключает сервис перенаправления.</sup>
---
@@ -123,7 +132,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
<small>Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на основном, так и на промежуточном сервере.</small>
<sup>Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на основном, так и на промежуточном сервере.</sup>
## Сбор доменов из мульти-подписок
@@ -133,7 +142,7 @@ cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -
node get_domains.js
```
<small>Краткое описание: добавьте ссылку на мульти-подписку в скрипт и запустите команду — на выходе получите список доменов. Необходим `Node.js` для работы скрипта.</small>
<sup>Краткое описание: добавьте ссылку на мульти-подписку в скрипт и запустите команду — на выходе получите список доменов. Необходим `Node.js` для работы скрипта.</sup>
## Использование собственного белого списка
@@ -144,7 +153,19 @@ node get_domains.js
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
<small>Краткое описание: добавляет ваш файл доменов в контейнер приложения. Чтобы сразу же сгенерировать инбаунды с новым списком, выполните `docker exec -it node sh` и затем `node index.js`.</small>
<sup>Краткое описание: добавляет ваш файл доменов в контейнер приложения. Чтобы сразу же сгенерировать инбаунды с новым списком, выполните `docker exec -it node sh` и затем `node rotate.js`.</sup>
## Ручной запуск генерации
Чтобы создать новые инбаунды, выполните команды поочередно:
```bash
cd /opt/3dp-manager
docker exec -it node sh
node rotate.js
```
<sup>Краткое описание: выполняет немедленную генерацию инбаундов, не влияя на заданный интервал ротации.</sup>
---
@@ -164,7 +185,7 @@ cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.t
4. Запустите локально базовые проверки (если есть).
5. Отправьте ветку в ваш форк и создайте Pull Request в основной репозиторий.
<small>Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты.</small>
<sup>Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты.</sup>
---
+10 -10
View File
@@ -2,7 +2,7 @@
<p><img src="https://denpiligrim.ru/storage/images/3dp-manager.png" alt="3dp-manager preview"></p>
![Version](https://img.shields.io/badge/version-1.0.1.1-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
![Version](https://img.shields.io/badge/version-1.0.2.1-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
@@ -64,7 +64,7 @@
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>简要说明:运行安装脚本并部署容器和服务。</small>
<sup>简要说明:运行安装脚本并部署容器和服务。</sup>
## 更新
@@ -74,7 +74,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>简要说明:拉取最新更改并重启容器。</small>
<sup>简要说明:拉取最新更改并重启容器。</sup>
## 删除
@@ -84,7 +84,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>简要说明:删除容器和配置文件,恢复到安装前状态。</small>
<sup>简要说明:删除容器和配置文件,恢复到安装前状态。</sup>
---
@@ -96,7 +96,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
<small>简要说明:添加转发规则并创建用于更新订阅的服务。</small>
<sup>简要说明:添加转发规则并创建用于更新订阅的服务。</sup>
## 删除转发
@@ -104,7 +104,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>简要说明:删除规则并禁用转发服务。</small>
<sup>简要说明:删除规则并禁用转发服务。</sup>
---
@@ -116,7 +116,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
<small>简要说明:打印可在客户端使用的静态订阅 URL,适用于主服务器和中继服务器。</small>
<sup>简要说明:打印可在客户端使用的静态订阅 URL,适用于主服务器和中继服务器。</sup>
## 从多订阅收集域名
@@ -126,7 +126,7 @@ cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -
node get_domains.js
```
<small>简要说明:在脚本中添加多订阅链接并运行命令 — 输出为域名列表。运行脚本需要 `Node.js`。</small>
<sup>简要说明:在脚本中添加多订阅链接并运行命令 — 输出为域名列表。运行脚本需要 `Node.js`。</sup>
## 使用自定义白名单
@@ -137,7 +137,7 @@ node get_domains.js
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
<small>简要说明:将您的域名文件添加到应用容器中。</small>
<sup>简要说明:将您的域名文件添加到应用容器中。</sup>
---
@@ -157,7 +157,7 @@ cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.t
4. 在本地运行检查(如有)。
5. 推送分支到您的 fork 并创建 Pull Request。
<small>建议:在 PR 中说明更改和测试步骤;较大更改请拆成小提交。</small>
<sup>建议:在 PR 中说明更改和测试步骤;较大更改请拆成小提交。</sup>
---
+10 -10
View File
@@ -2,7 +2,7 @@
<p><img src="https://denpiligrim.ru/storage/images/3dp-manager.png" alt="3dp-manager preview"></p>
![Version](https://img.shields.io/badge/version-1.0.1-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
![Version](https://img.shields.io/badge/version-1.0.2-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
@@ -64,7 +64,7 @@ Install the project on your server with:
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>Short description: runs the installer script and deploys containers and services.</small>
<sup>Short description: runs the installer script and deploys containers and services.</sup>
## Update
@@ -74,7 +74,7 @@ Update to the latest version:
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>Short description: pulls the latest changes and restarts containers.</small>
<sup>Short description: pulls the latest changes and restarts containers.</sup>
## Removal
@@ -84,7 +84,7 @@ Remove the service completely:
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>Short description: removes containers and configuration files, restoring the system to the pre-install state.</small>
<sup>Short description: removes containers and configuration files, restoring the system to the pre-install state.</sup>
---
@@ -96,7 +96,7 @@ The forwarding service allows proxying incoming ports from the intermediate serv
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
<small>Short description: adds forwarding rules and creates a service to update the subscription.</small>
<sup>Short description: adds forwarding rules and creates a service to update the subscription.</sup>
## Remove forwarding
@@ -104,7 +104,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>Short description: removes rules and disables the forwarding service.</small>
<sup>Short description: removes rules and disables the forwarding service.</sup>
---
@@ -116,7 +116,7 @@ Command to print the current subscription URL from the container environment:
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
<small>Short description: prints the static subscription URL that can be used in clients. Works on both main and intermediate servers.</small>
<sup>Short description: prints the static subscription URL that can be used in clients. Works on both main and intermediate servers.</sup>
## Collect domains from multi-subscriptions
@@ -126,7 +126,7 @@ The utility extracts domains from subscriptions and builds a `whitelist` for the
node get_domains.js
```
<small>Short description: add a multi-subscription link to the script and run the command — the output will be a list of domains. `Node.js` is required to run the script.</small>
<sup>Short description: add a multi-subscription link to the script and run the command — the output will be a list of domains. `Node.js` is required to run the script.</sup>
## Use your own whitelist
@@ -137,7 +137,7 @@ node get_domains.js
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
<small>Short description: adds your domain file into the application container.</small>
<sup>Short description: adds your domain file into the application container.</sup>
---
@@ -157,7 +157,7 @@ Contributions are welcome! Simple contributor workflow:
4. Run local checks if available.
5. Push the branch to your fork and create a Pull Request to the main repository.
<small>Tips: describe changes and testing steps in the PR. For large changes, split into smaller commits.</small>
<sup>Tips: describe changes and testing steps in the PR. For large changes, split into smaller commits.</sup>
---
+10 -10
View File
@@ -2,7 +2,7 @@
<p><img src="https://denpiligrim.ru/storage/images/3dp-manager.png" alt="3dp-manager preview"></p>
![Version](https://img.shields.io/badge/version-1.0.1-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
![Version](https://img.shields.io/badge/version-1.0.2-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
@@ -64,7 +64,7 @@
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویس‌ها را راه‌اندازی می‌کند.</small>
<sup>توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویس‌ها را راه‌اندازی می‌کند.</sup>
## به‌روزرسانی
@@ -74,7 +74,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>توضیح کوتاه: تغییرات جدید را می‌کشد و کانتینرها را ری‌استارت می‌کند.</small>
<sup>توضیح کوتاه: تغییرات جدید را می‌کشد و کانتینرها را ری‌استارت می‌کند.</sup>
## حذف
@@ -84,7 +84,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>توضیح کوتاه: کانتینرها و فایل‌های پیکربندی را حذف می‌کند و سیستم را به وضعیت پیش از نصب برمی‌گرداند.</small>
<sup>توضیح کوتاه: کانتینرها و فایل‌های پیکربندی را حذف می‌کند و سیستم را به وضعیت پیش از نصب برمی‌گرداند.</sup>
---
@@ -96,7 +96,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
<small>توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای به‌روزرسانی اشتراک ایجاد می‌کند.</small>
<sup>توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای به‌روزرسانی اشتراک ایجاد می‌کند.</sup>
## حذف فورواردینگ
@@ -104,7 +104,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال می‌کند.</small>
<sup>توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال می‌کند.</sup>
---
@@ -116,7 +116,7 @@ bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
<small>توضیح کوتاه: URL ثابت اشتراک را نمایش می‌دهد که می‌توان در کلاینت‌ها استفاده کرد. هم در سرور اصلی و هم در سرور واسط کار می‌کند.</small>
<sup>توضیح کوتاه: URL ثابت اشتراک را نمایش می‌دهد که می‌توان در کلاینت‌ها استفاده کرد. هم در سرور اصلی و هم در سرور واسط کار می‌کند.</sup>
## جمع‌آوری دامنه‌ها از چندین اشتراک
@@ -126,7 +126,7 @@ cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -
node get_domains.js
```
<small>توضیح کوتاه: لینک چندین اشتراک را در اسکریپت قرار داده و فرمان را اجرا کنید — خروجی فهرست دامنه‌ها خواهد بود. نیازمند `Node.js` است.</small>
<sup>توضیح کوتاه: لینک چندین اشتراک را در اسکریپت قرار داده و فرمان را اجرا کنید — خروجی فهرست دامنه‌ها خواهد بود. نیازمند `Node.js` است.</sup>
## استفاده از whitelist شخصی
@@ -137,7 +137,7 @@ node get_domains.js
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
<small>توضیح کوتاه: فایل دامنه شما را به کانتینر برنامه اضافه می‌کند.</small>
<sup>توضیح کوتاه: فایل دامنه شما را به کانتینر برنامه اضافه می‌کند.</sup>
---
@@ -157,7 +157,7 @@ cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.t
4. در صورت وجود، بررسی‌های محلی را اجرا کنید.
5. شاخه را به fork خود پوش کرده و Pull Request ایجاد کنید.
<small>نکات: تغییرات را در PR شرح دهید و مراحل تست را بنویسید. در صورت تغییرات بزرگ، آنها را به کامیت‌های کوچک تقسیم کنید.</small>
<sup>نکات: تغییرات را در PR شرح دهید و مراحل تست را بنویسید. در صورت تغییرات بزرگ، آنها را به کامیت‌های کوچک تقسیم کنید.</sup>
---
+4 -4
View File
@@ -2,7 +2,7 @@
<p><img src="https://denpiligrim.ru/storage/images/3dp-manager.png" alt="3dp-manager preview"></p>
![Version](https://img.shields.io/badge/version-1.0.1-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
![Version](https://img.shields.io/badge/version-1.0.2-blue.svg) [![License](https://img.shields.io/badge/license-GPL%20V3-blue.svg?longCache=true)](https://www.gnu.org/licenses/gpl-3.0) [![Telegram](https://img.shields.io/badge/Telegram-26A5E4?style=flat&logo=telegram&logoColor=white)](https://t.me/denpiligrim_web) [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCOv2tFFYDY4mXOM60PVz8zw)](https://www.youtube.com/@denpiligrim)
# 3DP-MANAGER
@@ -64,7 +64,7 @@ Taslamany serwera gurnamak üçin şu komandany ýerine ýetiriň:
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>Gysgaça: gurnama skripti işledilýär we konteýnerler we hyzmatlar döredilýär.</small>
<sup>Gysgaça: gurnama skripti işledilýär we konteýnerler we hyzmatlar döredilýär.</sup>
## Täzelik
@@ -74,7 +74,7 @@ Soňky wersiýa çenli täzeläň:
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>Gysgaça: iň soňky üýtgeşmeleri çekýär we konteýnerleri gaýtadan işledýär.</small>
<sup>Gysgaça: iň soňky üýtgeşmeleri çekýär we konteýnerleri gaýtadan işledýär.</sup>
## Pozmak
@@ -84,7 +84,7 @@ Hyzmaty doly pozmak üçin:
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>Gysgaça: konteýnerleri we konfigurasiýa faýllaryny pozup, systemany gurnamadan öňki ýagdaýyna getirer.</small>
<sup>Gysgaça: konteýnerleri we konfigurasiýa faýllaryny pozup, systemany gurnamadan öňki ýagdaýyna getirer.</sup>
---
+1
View File
@@ -6,6 +6,7 @@ COPY package.json ./
RUN npm install --production
COPY index.js .
COPY rotate.js .
COPY builders ./builders
CMD ["node", "index.js"]
+11 -8
View File
@@ -1,5 +1,5 @@
import axios from "axios";
import cron from "node-cron";
import https from "https";
import fs from "fs";
import net from "net";
import { buildVlessRealityTcp } from "./builders/buildVlessRealityTcp.js";
@@ -16,7 +16,10 @@ const SUB_FILE = "/subscriptions/list.txt";
const LAST_INBOUNDS = '/subscriptions/latestInbounds.json';
const cookieJar = {};
const api = axios.create({ baseURL: UI_URL, timeout: 15000, withCredentials: true });
const agent = new https.Agent({
rejectUnauthorized: false
});
const api = axios.create({ baseURL: UI_URL, timeout: 15000, withCredentials: true, httpsAgent: agent });
api.interceptors.request.use(config => {
if (cookieJar.value) config.headers['Cookie'] = cookieJar.value;
@@ -121,12 +124,12 @@ async function login() {
} catch (e) { console.error("Login failed:", e.message); throw e; }
}
async function getInbounds() {
try {
const res = await api.get("/panel/api/inbounds/list");
return res.status === 200 ? res.data.obj || [] : [];
} catch (e) { console.error("Get inbounds failed:", e.message); return []; }
}
// async function getInbounds() {
// try {
// const res = await api.get("/panel/api/inbounds/list");
// return res.status === 200 ? res.data.obj || [] : [];
// } catch (e) { console.error("Get inbounds failed:", e.message); return []; }
// }
async function deleteInbounds() {
try {
+216
View File
@@ -0,0 +1,216 @@
import axios from "axios";
import https from "https";
import fs from "fs";
import net from "net";
import { buildVlessRealityTcp } from "./builders/buildVlessRealityTcp.js";
import { buildVlessRealityXhttp } from "./builders/buildVlessRealityXhttp.js";
import { buildTrojanRealityTcp } from "./builders/buildTrojanRealityTcp.js";
import { buildShadowsocksTcp } from "./builders/buildShadowsocksTcp.js";
import { buildVmessTcp } from "./builders/buildVmessTcp.js";
import { buildVlessRealityGrpc } from "./builders/buildVlessRealityGrpc.js";
import { buildVlessWs } from "./builders/buildVlessWs.js";
import { buildInboundLink } from "./builders/buildInboundLink.js";
const { UI_URL, UI_LOGIN, UI_PASSWORD, UI_HOST } = process.env;
const SUB_FILE = "/subscriptions/list.txt";
const LAST_INBOUNDS = '/subscriptions/latestInbounds.json';
const cookieJar = {};
const agent = new https.Agent({
rejectUnauthorized: false
});
const api = axios.create({ baseURL: UI_URL, timeout: 15000, withCredentials: true, httpsAgent: agent });
api.interceptors.request.use(config => {
if (cookieJar.value) config.headers['Cookie'] = cookieJar.value;
return config;
});
const WHITELIST_FILE = "/app/whitelist.txt";
const WHITELIST_REPO_URL = "https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/whitelist.txt";
// Helper functions
async function updateWhitelist() {
try {
const res = await axios.get(WHITELIST_REPO_URL, { timeout: 10000 });
fs.writeFileSync(WHITELIST_FILE, res.data, "utf8");
console.log("✔ whitelist.txt обновлен из репозитория");
} catch (err) {
console.warn("⚠ Не удалось обновить whitelist.txt, будет использоваться локальный файл:", err.message);
}
}
function loadWhitelist() {
let fileToUse = WHITELIST_FILE;
if (fs.existsSync("/app/my_whitelist.txt")) {
console.log('Найден кастомный whitelist: /app/my_whitelist.txt. Используется он.');
fileToUse = "/app/my_whitelist.txt";
} else {
console.log(`Кастомный whitelist не найден. Используется дефолтный: ${WHITELIST_FILE}`);
if (!fs.existsSync(WHITELIST_FILE)) {
throw new Error("Дефолтный whitelist.txt не найден");
}
}
return fs.readFileSync(fileToUse, "utf8")
.split("\n")
.map(v => v.trim())
.filter(Boolean);
}
function pickDomain(list) {
return list[Math.floor(Math.random() * list.length)];
}
async function isPortFree(port) {
return new Promise(resolve => {
const s = net.createServer()
.once("error", () => resolve(false))
.once("listening", () => {
s.close();
resolve(true);
})
.listen(port, "0.0.0.0");
});
}
async function getFreePort(used) {
while (true) {
const p = Math.floor(Math.random() * (60000 - 10000)) + 10000;
if (used.has(p)) continue;
if (await isPortFree(p)) {
used.add(p);
return p;
}
}
}
async function generateRealityKeys() {
try {
const res = await api.get("/panel/api/server/getNewX25519Cert");
if (res.data?.success && res.data?.obj) {
return {
privateKey: res.data.obj.privateKey,
publicKey: res.data.obj.publicKey
};
}
throw new Error("Invalid key response");
} catch (e) {
console.error("Failed to get Reality keys:", e.message);
throw e;
}
}
async function uuid() {
try {
const res = await api.get("/panel/api/server/getNewUUID");
if (res.data?.success && res.data?.obj?.uuid) {
return res.data.obj.uuid;
}
throw new Error("Invalid UUID response");
} catch (e) {
console.error("Failed to get UUID:", e.message);
throw e;
}
}
// API 3x-ui
async function login() {
try {
const res = await api.post("/login", { username: UI_LOGIN, password: UI_PASSWORD });
if (res.headers['set-cookie']) cookieJar.value = res.headers['set-cookie'].join('; ');
console.log("Login success");
} catch (e) { console.error("Login failed:", e.message); throw e; }
}
// async function getInbounds() {
// try {
// const res = await api.get("/panel/api/inbounds/list");
// return res.status === 200 ? res.data.obj || [] : [];
// } catch (e) { console.error("Get inbounds failed:", e.message); return []; }
// }
async function deleteInbounds() {
try {
const data = fs.readFileSync(LAST_INBOUNDS, 'utf-8');
const oldIds = JSON.parse(data);
if (Array.isArray(oldIds) && oldIds.length > 0) {
console.log(`Удаляем старые инбаунды: ${oldIds.length} шт.`);
for (const id of oldIds) {
try {
await deleteInbound(id);
} catch (err) {
console.error(`Ошибка при удалении инбаунда ${id}:`, err.message);
}
}
}
} catch (error) {
console.log("Старых ID не найдено, пропускаем удаление.");
}
}
async function deleteInbound(id) {
try { await api.post(`/panel/api/inbounds/del/${id}`); } catch { }
}
async function addInbound(config) {
try {
const res = await api.post("/panel/api/inbounds/add", config);
return res.data?.obj?.id || null;
} catch (e) {
console.error("Add inbound failed:", e.message);
return null;
}
}
// Main rotation of inbound entries
async function rotate() {
await login();
await updateWhitelist();
const whitelist = loadWhitelist();
const usedPorts = new Set();
const subs = [];
await deleteInbounds();
const builders = [
async (d) => buildVlessRealityTcp({ port: await isPortFree(8443) ? 8443 : await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
async (d) => buildVlessRealityXhttp({ port: await isPortFree(443) ? 443 : await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
async (d) => buildVlessRealityGrpc({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
async (d) => buildVlessWs({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d }),
async (d) => buildVlessRealityTcp({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
async (d) => buildVlessRealityTcp({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
async (d) => buildVlessRealityTcp({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
async (d) => buildVmessTcp({ port: await getFreePort(usedPorts), uuid: await uuid() }),
async (d) => buildShadowsocksTcp({ port: await getFreePort(usedPorts), uuid: await uuid() }),
async (d) => buildTrojanRealityTcp({ port: await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
];
const inboundIds = [];
for (const b of builders) {
const domain = pickDomain(whitelist);
const inbound = await b(domain);
const idOrPass = inbound.settings ? JSON.parse(inbound.settings).clients?.[0]?.id || JSON.parse(inbound.settings).clients?.[0]?.password : "";
// Build the link depending on the protocol
const link = buildInboundLink(inbound, UI_HOST, idOrPass);
if (link) subs.push(link);
const id = await addInbound(inbound);
inboundIds.push(id);
}
if (inboundIds.length > 0) {
fs.writeFileSync(LAST_INBOUNDS, JSON.stringify(inboundIds, null, 2));
console.log(`Новые ID (${inboundIds.length} шт.) сохранены в ${LAST_INBOUNDS}`);
}
fs.writeFileSync(SUB_FILE, subs.join("\n") + "\n", "utf8");
console.log("✔ 10 inbound created, подписка обновлена");
}
// Initial run
rotate();
+22 -10
View File
@@ -31,14 +31,17 @@ if [[ "$ID" != "ubuntu" && "$ID" != "debian" ]]; then
die "Этот скрипт поддерживает только Ubuntu или Debian: $ID"
fi
if ! x-ui status >/dev/null 2>&1; then
echo "❌ Панель 3x-ui не найдена или не работает."
echo " Чтобы установить, выполните:"
echo "bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)"
exit 1
fi
REMOTE_PANEL=${REMOTE_PANEL:-false}
echo "✔ Панель 3x-ui найдена и работает"
if [[ "$REMOTE_PANEL" != "true" ]]; then
if ! x-ui status >/dev/null 2>&1; then
echo "❌ Панель 3x-ui не найдена или не работает."
echo " Чтобы установить, выполните:"
echo " bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)"
exit 1
fi
echo "✔ Панель 3x-ui найдена и работает"
fi
#################################
# ASCII-баннер
@@ -60,6 +63,11 @@ echo ""
#################################
# Function to get panel URL from 3x-ui
get_xui_url() {
if [[ "$REMOTE_PANEL" == "true" ]]; then
echo ""
return
fi
local output=$(x-ui settings 2>/dev/null || true)
echo "$output" | sed 's/\x1b\[[0-9;]*m//g' | grep "Access URL:" | grep -oE 'https?://[^[:space:]]+' | head -n1 || true
@@ -83,6 +91,9 @@ echo "URL панели 3x-ui: $UI_URL"
read -rp "Логин 3x-ui: " UI_LOGIN
read -rsp "Пароль 3x-ui: " UI_PASSWORD
echo
UI_LOGIN=$(echo "$UI_LOGIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
UI_PASSWORD=$(echo "$UI_PASSWORD" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
[[ -z "$UI_LOGIN" || -z "$UI_PASSWORD" ]] && die "Логин/пароль обязательны"
# Check login
@@ -92,7 +103,7 @@ if ! command -v curl >/dev/null 2>&1; then
exit 1
fi
LOGIN_RESPONSE=$(curl -s -X POST "$UI_URL/login" -H "Content-Type: application/json" -d "{\"username\":\"$UI_LOGIN\",\"password\":\"$UI_PASSWORD\"}" || true)
LOGIN_RESPONSE=$(curl -s -k --connect-timeout 10 -X POST "$UI_URL/login" -H "Content-Type: application/json" -d "{\"username\":\"$UI_LOGIN\",\"password\":\"$UI_PASSWORD\"}" || true)
if ! echo "$LOGIN_RESPONSE" | grep -q '"success":true'; then
echo "Не удалось залогиниться в 3x-ui. Проверьте URL, логин и пароль."
@@ -117,8 +128,8 @@ if [[ "$UI_PROTO" == "https" ]]; then
log "Найдены сертификаты Let's Encrypt для $UI_HOST"
else
log "⚠ Сертификаты Let's Encrypt для $UI_HOST не найдены"
read -rp "Введите полный путь к SSL сертификату (fullchain.pem): " CERT_PATH
read -rp "Введите полный путь к SSL ключу (privkey.pem): " KEY_PATH
read -rp "Введите полный путь к сертификату (публичный ключ): " CERT_PATH
read -rp "Введите полный путь к ключу (приватный ключ): " KEY_PATH
[[ -f "$CERT_PATH" ]] || die "Файл сертификата не найден: $CERT_PATH"
[[ -f "$KEY_PATH" ]] || die "Файл ключа не найден: $KEY_PATH"
@@ -274,6 +285,7 @@ curl -fsSL "$REPO_BASE/app/package.json" -o app/package.json
# JS Files
#################################
curl -fsSL "$REPO_BASE/app/index.js" -o app/index.js
curl -fsSL "$REPO_BASE/app/rotate.js" -o app/rotate.js
curl -fsSL "$REPO_BASE/app/builders/buildVlessRealityTcp.js" -o app/builders/buildVlessRealityTcp.js
curl -fsSL "$REPO_BASE/app/builders/buildVlessRealityXhttp.js" -o app/builders/buildVlessRealityXhttp.js
curl -fsSL "$REPO_BASE/app/builders/buildTrojanRealityTcp.js" -o app/builders/buildTrojanRealityTcp.js
+5
View File
@@ -80,6 +80,11 @@ docker compose build node
log "Перезапускаем контейнеры"
docker compose up -d
if [ -f "app/my_whitelist.txt" ]; then
log "✔ Копируем my_whitelist.txt в контейнер..."
docker cp app/my_whitelist.txt node:/app/my_whitelist.txt
fi
#################################
# HEALTH CHECK
#################################