diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e602ad9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,11 @@ +# Внести вклад + +Буду рад любому вкладу в разработку проекта! Простой процесс для контрибьюторов: + +1. Форкните репозиторий на GitHub. +2. Создайте ветку с осмысленным именем, например `feature/add-README` или `fix/whitelist-load`. +3. Внесите изменения и добавьте короткое описание в коммите. +4. Запустите локально базовые проверки (если есть). +5. Отправьте ветку в ваш форк и создайте Pull Request в основной репозиторий. + +Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты. \ No newline at end of file diff --git a/README.md b/README.md index c40ac99..b1f97c7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

3dp-manager preview

-![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) ``` -Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы. +Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы. + +Если панель 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) ``` -Краткое описание: подтягивает последние изменения и перезапускает контейнеры. +Краткое описание: подтягивает последние изменения и перезапускает контейнеры. ## Удаление @@ -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) ``` -Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки. +Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки. --- ## Установка сервиса перенаправления (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) ``` -Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки. +Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки. ## Удаление перенаправления @@ -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) ``` -Краткое описание: удаляет правила и отключает сервис перенаправления. +Краткое описание: удаляет правила и отключает сервис перенаправления. --- @@ -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 ``` -Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на основном, так и на промежуточном сервере. +Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на основном, так и на промежуточном сервере. ## Сбор доменов из мульти-подписок @@ -133,7 +142,7 @@ cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' - node get_domains.js ``` -Краткое описание: добавьте ссылку на мульти-подписку в скрипт и запустите команду — на выходе получите список доменов. Необходим `Node.js` для работы скрипта. +Краткое описание: добавьте ссылку на мульти-подписку в скрипт и запустите команду — на выходе получите список доменов. Необходим `Node.js` для работы скрипта. ## Использование собственного белого списка @@ -144,7 +153,19 @@ node get_domains.js cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt ``` -Краткое описание: добавляет ваш файл доменов в контейнер приложения. Чтобы сразу же сгенерировать инбаунды с новым списком, выполните `docker exec -it node sh` и затем `node index.js`. +Краткое описание: добавляет ваш файл доменов в контейнер приложения. Чтобы сразу же сгенерировать инбаунды с новым списком, выполните `docker exec -it node sh` и затем `node rotate.js`. + +## Ручной запуск генерации + +Чтобы создать новые инбаунды, выполните команды поочередно: + +```bash +cd /opt/3dp-manager +docker exec -it node sh +node rotate.js +``` + +Краткое описание: выполняет немедленную генерацию инбаундов, не влияя на заданный интервал ротации. --- @@ -164,7 +185,7 @@ cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.t 4. Запустите локально базовые проверки (если есть). 5. Отправьте ветку в ваш форк и создайте Pull Request в основной репозиторий. -Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты. +Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты. --- diff --git a/README_CN.md b/README_CN.md index dbd90c4..ffbeb83 100644 --- a/README_CN.md +++ b/README_CN.md @@ -2,7 +2,7 @@

3dp-manager preview

-![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) ``` -简要说明:运行安装脚本并部署容器和服务。 +简要说明:运行安装脚本并部署容器和服务。 ## 更新 @@ -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) ``` -简要说明:拉取最新更改并重启容器。 +简要说明:拉取最新更改并重启容器。 ## 删除 @@ -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) ``` -简要说明:删除容器和配置文件,恢复到安装前状态。 +简要说明:删除容器和配置文件,恢复到安装前状态。 --- @@ -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) ``` -简要说明:添加转发规则并创建用于更新订阅的服务。 +简要说明:添加转发规则并创建用于更新订阅的服务。 ## 删除转发 @@ -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) ``` -简要说明:删除规则并禁用转发服务。 +简要说明:删除规则并禁用转发服务。 --- @@ -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 ``` -简要说明:打印可在客户端使用的静态订阅 URL,适用于主服务器和中继服务器。 +简要说明:打印可在客户端使用的静态订阅 URL,适用于主服务器和中继服务器。 ## 从多订阅收集域名 @@ -126,7 +126,7 @@ cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' - node get_domains.js ``` -简要说明:在脚本中添加多订阅链接并运行命令 — 输出为域名列表。运行脚本需要 `Node.js`。 +简要说明:在脚本中添加多订阅链接并运行命令 — 输出为域名列表。运行脚本需要 `Node.js`。 ## 使用自定义白名单 @@ -137,7 +137,7 @@ node get_domains.js cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt ``` -简要说明:将您的域名文件添加到应用容器中。 +简要说明:将您的域名文件添加到应用容器中。 --- @@ -157,7 +157,7 @@ cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.t 4. 在本地运行检查(如有)。 5. 推送分支到您的 fork 并创建 Pull Request。 -建议:在 PR 中说明更改和测试步骤;较大更改请拆成小提交。 +建议:在 PR 中说明更改和测试步骤;较大更改请拆成小提交。 --- diff --git a/README_EN.md b/README_EN.md index d6de078..6f86786 100644 --- a/README_EN.md +++ b/README_EN.md @@ -2,7 +2,7 @@

3dp-manager preview

-![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) ``` -Short description: runs the installer script and deploys containers and services. +Short description: runs the installer script and deploys containers and services. ## Update @@ -74,7 +74,7 @@ Update to the latest version: bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh) ``` -Short description: pulls the latest changes and restarts containers. +Short description: pulls the latest changes and restarts containers. ## Removal @@ -84,7 +84,7 @@ Remove the service completely: bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh) ``` -Short description: removes containers and configuration files, restoring the system to the pre-install state. +Short description: removes containers and configuration files, restoring the system to the pre-install state. --- @@ -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) ``` -Short description: adds forwarding rules and creates a service to update the subscription. +Short description: adds forwarding rules and creates a service to update the subscription. ## 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) ``` -Short description: removes rules and disables the forwarding service. +Short description: removes rules and disables the forwarding service. --- @@ -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 ``` -Short description: prints the static subscription URL that can be used in clients. Works on both main and intermediate servers. +Short description: prints the static subscription URL that can be used in clients. Works on both main and intermediate servers. ## 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 ``` -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. +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. ## 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 ``` -Short description: adds your domain file into the application container. +Short description: adds your domain file into the application container. --- @@ -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. -Tips: describe changes and testing steps in the PR. For large changes, split into smaller commits. +Tips: describe changes and testing steps in the PR. For large changes, split into smaller commits. --- diff --git a/README_IR.md b/README_IR.md index e573987..fa84383 100644 --- a/README_IR.md +++ b/README_IR.md @@ -2,7 +2,7 @@

3dp-manager preview

-![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) ``` -توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویس‌ها را راه‌اندازی می‌کند. +توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویس‌ها را راه‌اندازی می‌کند. ## به‌روزرسانی @@ -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) ``` -توضیح کوتاه: تغییرات جدید را می‌کشد و کانتینرها را ری‌استارت می‌کند. +توضیح کوتاه: تغییرات جدید را می‌کشد و کانتینرها را ری‌استارت می‌کند. ## حذف @@ -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) ``` -توضیح کوتاه: کانتینرها و فایل‌های پیکربندی را حذف می‌کند و سیستم را به وضعیت پیش از نصب برمی‌گرداند. +توضیح کوتاه: کانتینرها و فایل‌های پیکربندی را حذف می‌کند و سیستم را به وضعیت پیش از نصب برمی‌گرداند. --- @@ -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) ``` -توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای به‌روزرسانی اشتراک ایجاد می‌کند. +توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای به‌روزرسانی اشتراک ایجاد می‌کند. ## حذف فورواردینگ @@ -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) ``` -توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال می‌کند. +توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال می‌کند. --- @@ -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 ``` -توضیح کوتاه: URL ثابت اشتراک را نمایش می‌دهد که می‌توان در کلاینت‌ها استفاده کرد. هم در سرور اصلی و هم در سرور واسط کار می‌کند. +توضیح کوتاه: URL ثابت اشتراک را نمایش می‌دهد که می‌توان در کلاینت‌ها استفاده کرد. هم در سرور اصلی و هم در سرور واسط کار می‌کند. ## جمع‌آوری دامنه‌ها از چندین اشتراک @@ -126,7 +126,7 @@ cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' - node get_domains.js ``` -توضیح کوتاه: لینک چندین اشتراک را در اسکریپت قرار داده و فرمان را اجرا کنید — خروجی فهرست دامنه‌ها خواهد بود. نیازمند `Node.js` است. +توضیح کوتاه: لینک چندین اشتراک را در اسکریپت قرار داده و فرمان را اجرا کنید — خروجی فهرست دامنه‌ها خواهد بود. نیازمند `Node.js` است. ## استفاده از whitelist شخصی @@ -137,7 +137,7 @@ node get_domains.js cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt ``` -توضیح کوتاه: فایل دامنه شما را به کانتینر برنامه اضافه می‌کند. +توضیح کوتاه: فایل دامنه شما را به کانتینر برنامه اضافه می‌کند. --- @@ -157,7 +157,7 @@ cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.t 4. در صورت وجود، بررسی‌های محلی را اجرا کنید. 5. شاخه را به fork خود پوش کرده و Pull Request ایجاد کنید. -نکات: تغییرات را در PR شرح دهید و مراحل تست را بنویسید. در صورت تغییرات بزرگ، آنها را به کامیت‌های کوچک تقسیم کنید. +نکات: تغییرات را در PR شرح دهید و مراحل تست را بنویسید. در صورت تغییرات بزرگ، آنها را به کامیت‌های کوچک تقسیم کنید. --- diff --git a/README_TK.md b/README_TK.md index 18545bc..70cf6d8 100644 --- a/README_TK.md +++ b/README_TK.md @@ -2,7 +2,7 @@

3dp-manager preview

-![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) ``` -Gysgaça: gurnama skripti işledilýär we konteýnerler we hyzmatlar döredilýär. +Gysgaça: gurnama skripti işledilýär we konteýnerler we hyzmatlar döredilýär. ## 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) ``` -Gysgaça: iň soňky üýtgeşmeleri çekýär we konteýnerleri gaýtadan işledýär. +Gysgaça: iň soňky üýtgeşmeleri çekýär we konteýnerleri gaýtadan işledýär. ## Pozmak @@ -84,7 +84,7 @@ Hyzmaty doly pozmak üçin: bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh) ``` -Gysgaça: konteýnerleri we konfigurasiýa faýllaryny pozup, systemany gurnamadan öňki ýagdaýyna getirer. +Gysgaça: konteýnerleri we konfigurasiýa faýllaryny pozup, systemany gurnamadan öňki ýagdaýyna getirer. --- diff --git a/app/Dockerfile b/app/Dockerfile index 4a63d4e..d50bd86 100644 --- a/app/Dockerfile +++ b/app/Dockerfile @@ -6,6 +6,7 @@ COPY package.json ./ RUN npm install --production COPY index.js . +COPY rotate.js . COPY builders ./builders CMD ["node", "index.js"] \ No newline at end of file diff --git a/app/index.js b/app/index.js index 0ef17cc..510e2ed 100644 --- a/app/index.js +++ b/app/index.js @@ -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 { diff --git a/app/rotate.js b/app/rotate.js new file mode 100644 index 0000000..7f583de --- /dev/null +++ b/app/rotate.js @@ -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(); \ No newline at end of file diff --git a/install.sh b/install.sh index c5733aa..21b4c24 100644 --- a/install.sh +++ b/install.sh @@ -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 diff --git a/update.sh b/update.sh index 3b4eda0..6c7c399 100644 --- a/update.sh +++ b/update.sh @@ -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 #################################