Merge pull request #1 from denpiligrim/dp-fix

Stable release v1.0
This commit is contained in:
DenPiligrim
2025-12-25 22:49:27 +03:00
committed by GitHub
19 changed files with 2228 additions and 156 deletions
+127 -22
View File
@@ -1,63 +1,168 @@
[English](https://github.com/denpiligrim/3dp-manager/blob/main/README_EN.md)
[English](/README_EN.md) | [中文](/README_CN.md) | [فارسی](/README_IR.md) | [Türkmençe](/README_TK.md)
<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-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
> [!WARNING]
> **Это бета-версия!**
>
> Программа находится в активной разработке. Возможны баги, нестабильность и изменения API.
> Используйте с осторожностью.
Утилита для автогенерации инбаундов к панели [3x-ui](https://github.com/MHSanaei/3x-ui), формирования единой подписки и настройки перенаправления трафика с промежуточного сервера на основной.
3DP-MANAGER — утилита, которая позволяет регулярно генерировать входящие подключения для панели 3X-UI на основе списка разрешённых доменов (whitelist). Белый список общий, но вы также можете добавить свой собственный список, назвав его `my_whitelist.txt` и поместив его в папку `/opt/3dp-manager/app` на вашем сервере.
Обсуждения доступны в Телеграм канале: [@denpiligrim_web](https://t.me/denpiligrim_web/719)
**Поддержать проект**
- Реквизиты / донаты:
- Карта МИР: `2204320436318077`
- Карта MasterCard: `5395452209474530`
- ЮМоney: `4100116897060652`
- PayPal: `vasiljevdenisx@gmail.com`
- USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
- USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
- Bitcoin: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
- TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
- Bybit ID: `165292278`
## Описание
Главная цель утилиты — сделать так, чтобы ваш трафик не выглядел одинаковым. Бот генерирует по заданному интервалу 10 подключений с разными параметрами:
- протоколы: `vless`, `vmess`, `shadowsocks`, `trojan`;
- порты: `443`, `8443` (фиксированные) и случайные из диапазона `10000-60000`;
- транспорт: `tcp`, `websocket`, `grpc`, `xhttp`;
- SNI берутся из белого списка доменов (whitelist); можно использовать свой список.
Все подключения объединяются в одну подписку со статичным URL. Бот работает с панелью `3x-ui` и не вмешивается в её работу напрямую, используя открытое API панели.
Вторичная цель — стабильность подключения: клиент получает 10 вариантов поключений и может выбрать любое из них.
Дополнительно: бот можно использовать в каскадной схеме. Сервис перенаправления автоматически настроит переадресацию подписки и трафика к основному серверу.
Рекомендации:
- Используйте HTTPS для подписки (домен + SSL сертификат).
- Интервал генерации задавайте ≥ 10 минут; для стабильности рекомендуется — раз в сутки (1440 минут).
- В клиенте установите автообновление чаще (например, каждый час), чтобы была синхронизация с сервером.
## Возможности
- Генерация 10 разнообразных подключений
- Формирование единой подписки со статичным URL
- Поддержка кастомного `whitelist` доменов
- Автоматическая настройка перенаправления трафика (опционально)
## Требования
- Ubuntu 20.04 (и выше)
- Панель `3x-ui`
- Домен + SSL сертификат (опционально)
---
## Установка
Установите проект на сервер командой:
### Установка
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
### Обновление
<small>Краткое описание: запускает скрипт установки и разворачивает контейнеры и сервисы.</small>
## Обновление
Обновление до последней версии:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
### Удаление
<small>Краткое описание: подтягивает последние изменения и перезапускает контейнеры.</small>
## Удаление
Полное удаление сервиса:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>Краткое описание: удаляет контейнеры и файлы конфигурации, возвращая систему к состоянию до установки.</small>
---
Сервис подписок и перенаправления входящего трафика работает совместно с **3DP-MANAGER** и позволяет перенаправлять весь входящий трафик с промежуточного сервера на основной сервер. Перенаправляются те же порты: `443`, `8443` и диапазон `10000-60000`. Сервис также создаёт ссылку на подписку, автоматически заменяя IP-адрес или домен в конфигурациях. Перенаправления настраиваются добавлением правил iptables в конфигурационный файл ufw, что обеспечивает стабильную работу в сочетании с файрволом. Рекомендуется устанавливать сервис на чистый сервер без ранее настроенных правил.
## Установка сервиса перенаправления (forwarding)
Сервис перенаправления позволяет проксировать входящие порты с промежуточного сервера на основной.
### Установка перенаправления
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
### Удаление перенаправления
<small>Краткое описание: добавляет правила перенаправления и создает сервис для обновления подписки.</small>
## Удаление перенаправления
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>Краткое описание: удаляет правила и отключает сервис перенаправления.</small>
---
### Показать URL подписки
## Показать URL подписки
Команда для вывода текущего URL подписки из среды контейнера:
```bash
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
---
<small>Краткое описание: выводит статичный URL подписки, который можно использовать в клиентах. Работает как на основном, так и на промежуточном сервере.</small>
## Сбор доменов из мульти-подписок
Утилита извлекает домены из подписок и формирует `whitelist` для генератора.
### Утилита для сбора доменов из мульти-подписок
Позволяет собирать домены из подписок с несколькими конфигурациями. В интернете встречается много подобных списков конфигураций, использующих белый SNI. Инструмент позволяет извлечь домены и подготовить готовый список для дальнейшего использования в генераторе входящих подключений.
Вставьте ссылку на подписку в скрипт и запустите команду в окружении `Node.js`.
```bash
node get_domains.js
```
### Использовать свой белый список
Файл должен иметь структуру аналогичную `whitelist.txt`. Переименуйте имя файла на `my_whitelist.txt`. Загрузите файл в папку `/opt/3dp-manager/app` на сервере и выполните команду:
<small>Краткое описание: добавьте ссылку на мульти-подписку в скрипт и запустите команду — на выходе получите список доменов. Неободим `Node.js` для работы скрипта.</small>
## Использование собственного белого списка
1. Подготовьте файл в формате `whitelist.txt`.
2. Переименуйте на `my_whitelist.txt` и скопируйте в папку `/opt/3dp-manager/app`.
```bash
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>
---
## Замечания и текущие ограничения
- Общий список доменов работает не у всех провайдеров, поэтому рекомендуется составить и использовать свой whitelist.
---
## Внести вклад
Буду рад любому вкладу в разработку проекта! Простой процесс для контрибьюторов:
1. Форкните репозиторий на GitHub.
2. Создайте ветку с осмысленным именем, например `feature/add-README` или `fix/whitelist-load`.
3. Внесите изменения и добавьте короткое описание в коммите.
4. Запустите локально базовые проверки (если есть).
5. Отправьте ветку в ваш форк и создайте Pull Request в основной репозиторий.
<small>Советы: описывайте изменения в PR, указывайте цель и тестовые шаги. Если изменения большие — разделяйте на маленькие коммиты.</small>
---
## Обсуждение
- Телеграм: [@denpiligrim_web](https://t.me/denpiligrim_web)
- Раздел Issues в данном репозитории
+167
View File
@@ -0,0 +1,167 @@
[Русский](/README.md) | [English](/README_EN.md) | [فارسی](/README_IR.md) | [Türkmençe](/README_TK.md)
<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-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
这是一个用于为 `3x-ui` 面板自动生成入站连接、生成统一订阅并将流量从中继服务器转发到主服务器的实用工具。
**支持项目**
- 捐助/支付信息:
- MIR 卡: `2204320436318077`
- MasterCard: `5395452209474530`
- PayPal: `vasiljevdenisx@gmail.com`
- USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
- USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
- 比特币: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
- TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
- Bybit ID: `165292278`
## 描述
该工具的主要目标是使您的流量看起来不那么统一。机器人会在设定间隔生成 10 个具有不同参数的连接:
- 协议:`vless``vmess``shadowsocks``trojan`
- 端口:`443``8443`(固定)以及 `10000-60000` 范围内的随机端口
- 传输:`tcp``websocket``grpc``xhttp`
- SNI 从域名白名单(`whitelist`)中获取;也可以使用自定义列表
所有连接会合并为具有静态 URL 的单一订阅。该机器人通过 `3x-ui` 面板的公共 API 工作,不会直接修改面板内部。
次要目标是提高连接稳定性:客户端会收到 10 个可选连接,用户可以选择任意一个。
此外,机器人可用于级联部署。转发服务会自动配置将订阅和流量重定向到主服务器。
建议:
- 订阅请使用 HTTPS(域名 + SSL 证书)。
- 生成间隔设置为 ≥ 10 分钟;为稳定性建议每天一次(1440 分钟)。
- 在客户端设置更频繁的自动更新(例如每小时),以便与服务器同步。
## 功能
- 生成 10 个多样化连接
- 形成具有静态 URL 的统一订阅
- 支持自定义 `whitelist` 域名
- 可选的自动流量转发配置
## 要求
- Ubuntu 20.04 或更高
- `3x-ui` 面板
- 域名 + SSL 证书(可选)
---
## 安装
在服务器上运行以下命令安装项目:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>简要说明:运行安装脚本并部署容器和服务。</small>
## 更新
更新到最新版本:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>简要说明:拉取最新更改并重启容器。</small>
## 删除
彻底删除服务:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>简要说明:删除容器和配置文件,恢复到安装前状态。</small>
---
## 安装转发服务(forwarding
转发服务允许将中继服务器的入站端口代理到主服务器。
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
<small>简要说明:添加转发规则并创建用于更新订阅的服务。</small>
## 删除转发
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>简要说明:删除规则并禁用转发服务。</small>
---
## 显示订阅 URL
在容器环境中打印当前订阅 URL 的命令:
```bash
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
<small>简要说明:打印可在客户端使用的静态订阅 URL,适用于主服务器和中继服务器。</small>
## 从多订阅收集域名
该工具可从订阅中提取域名并为生成器构建 `whitelist`
```bash
node get_domains.js
```
<small>简要说明:在脚本中添加多订阅链接并运行命令 — 输出为域名列表。运行脚本需要 `Node.js`。</small>
## 使用自定义白名单
1. 准备一个与 `whitelist.txt` 相同格式的文件。
2. 将其重命名为 `my_whitelist.txt` 并复制到 `/opt/3dp-manager/app`
```bash
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
<small>简要说明:将您的域名文件添加到应用容器中。</small>
---
## 注意与当前限制
- 共享的域名列表可能并非对所有提供商都有效;建议准备并使用自定义 `whitelist`
---
## 贡献
欢迎贡献!简单的贡献流程:
1. 在 GitHub 上 fork 仓库。
2. 创建有意义的分支名,例如 `feature/add-README``fix/whitelist-load`
3. 提交更改并添加简短的提交信息。
4. 在本地运行检查(如有)。
5. 推送分支到您的 fork 并创建 Pull Request。
<small>建议:在 PR 中说明更改和测试步骤;较大更改请拆成小提交。</small>
---
## 讨论
- Telegram: [@denpiligrim_web](https://t.me/denpiligrim_web)
- Issues
+127 -22
View File
@@ -1,62 +1,167 @@
[Русский](https://github.com/denpiligrim/3dp-manager/blob/main/README.md)
[Русский](/README.md) | [中文](/README_CN.md) | [فارسی](/README_IR.md) | [Türkmençe](/README_TK.md)
<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-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
> [!WARNING]
> **This is a beta version!**
>
> The program is currently under active development. Bugs, instability, and API changes are possible.
> Use with caution.
A utility for auto-generating inbound connections for the [3x-ui](https://github.com/MHSanaei/3x-ui) panel, creating a single subscription URL, and configuring traffic forwarding from an intermediate server to the main server.
3DP-MANAGER is a utility that allows you to regularly generate inbound connections for the 3X-UI panel based on a whitelist of domains. The whitelist is shared, but you can also add your own list by naming it `my_whitelist.txt` and adding it to the `/opt/3dp-manager/app` folder on your server.
Discussions are available on the Telegram channel: [@denpiligrim_web](https://t.me/denpiligrim_web/719)
**Support the project**
- Donation / payment details:
- MIR card: `2204320436318077`
- MasterCard: `5395452209474530`
- PayPal: `vasiljevdenisx@gmail.com`
- USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
- USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
- Bitcoin: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
- TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
- Bybit ID: `165292278`
## Description
The main goal of the utility is to make your traffic appear non-uniform. The bot generates 10 connection entries at a configured interval with varying parameters:
- Protocols: `vless`, `vmess`, `shadowsocks`, `trojan`;
- Ports: `443`, `8443` (fixed) and random ports from the range `10000-60000`;
- Transport: `tcp`, `websocket`, `grpc`, `xhttp`;
- SNI values are taken from a whitelist of domains (`whitelist`); you can use your own list.
All generated connections are combined into a single subscription with a static URL. The bot works with the `3x-ui` panel using its public API and does not directly modify the panel internals.
The secondary goal is connection stability: the client receives 10 alternate connection options and can choose any of them.
Additionally, the bot can be used in a cascading setup. The forwarding service will automatically configure the subscription and traffic redirection to the main server.
Recommendations:
- Use HTTPS for the subscription (domain + SSL certificate).
- Set the generation interval to ≥ 10 minutes; for stability, once per day (1440 minutes) is recommended.
- Configure the client to check for updates more frequently (for example, hourly) to stay synchronized with the server.
## Features
- Generates 10 diverse connection entries
- Creates a single subscription with a static URL
- Supports custom `whitelist` domains
- Optional automatic configuration of traffic forwarding
## Requirements
- Ubuntu 20.04 or newer
- `3x-ui` panel
- Domain + SSL certificate (optional)
---
## Installation
Install the project on your server with:
### Install
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
### Update
<small>Short description: runs the installer script and deploys containers and services.</small>
## Update
Update to the latest version:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
### Delete
<small>Short description: pulls the latest changes and restarts containers.</small>
## Removal
Remove the service completely:
```bash
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>
---
The subscription and inbound redirection service works in conjunction with **3DP-MANAGER** and allows you to redirect all inbound traffic from the intermediate server to the main server. The same ports are redirected, namely `443`, `8443`, and the range `10000-60000`. The service also creates a link to the subscription, automatically replacing the IP address or domain in the configurations. Redirects are configured by adding iptables rules to the ufw configuration file, which ensures stable operation in conjunction with the firewall. It is recommended to install the service on a clean server without any previously installed rules.
### Install forwarding
## Install forwarding service
The forwarding service allows proxying incoming ports from the intermediate server to the main server.
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
### Delete forwarding
<small>Short description: adds forwarding rules and creates a service to update the subscription.</small>
## Remove forwarding
```bash
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>
---
### Show sub URL
## Show subscription URL
Command to print the current subscription URL from the container environment:
```bash
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>
## Collect domains from multi-subscriptions
The utility extracts domains from subscriptions and builds a `whitelist` for the generator.
### Utility for collecting domains from multi-subscriptions
Allows you to collect domains from subscriptions with multiple configurations. There are many similar configuration lists circulating on the internet that use white SNI. The tool allows you to extract domains and prepare a ready-made list for further use in the inbound generator.
Insert a subscription link into the script and run the command in the `Node.js` environment.
```bash
node get_domains.js
```
### Use your whitelist
The file should have a structure similar to `whitelist.txt`. Rename the file to `my_whitelist.txt`. Upload the file to the `/opt/3dp-manager/app` folder on the server and run the command:
<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>
## Use your own whitelist
1. Prepare a file in the format of `whitelist.txt`.
2. Rename it to `my_whitelist.txt` and copy it into `/opt/3dp-manager/app`.
```bash
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>
---
## Notes and current limitations
- The shared domain list may not work with all providers; it is recommended to prepare and use your own `whitelist`.
---
## Contributing
Contributions are welcome! Simple contributor workflow:
1. Fork the repository on GitHub.
2. Create a branch with a meaningful name, e.g. `feature/add-README` or `fix/whitelist-load`.
3. Make changes and add a short commit message.
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>
---
## Discussion
- Telegram: [@denpiligrim_web](https://t.me/denpiligrim_web)
- Issues
+167
View File
@@ -0,0 +1,167 @@
[Русский](/README.md) | [English](/README_EN.md) | [中文](/README_CN.md) | [Türkmençe](/README_TK.md)
<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-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
ابزاری برای تولید خودکار اتصال‌های inbound برای پنل `3x-ui`، ساخت یک اشتراک یکپارچه و هدایت ترافیک از سرور واسط به سرور اصلی.
**حمایت از پروژه**
- اطلاعات پرداخت/اهدا:
- کارت MIR: `2204320436318077`
- کارت MasterCard: `5395452209474530`
- PayPal: `vasiljevdenisx@gmail.com`
- USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
- USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
- بیت‌کوین: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
- TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
- Bybit ID: `165292278`
## توضیحات
هدف اصلی این ابزار این است که ترافیک شما یکسان به نظر نرسد. ربات در فواصل زمانی مشخص 10 اتصال با پارامترهای مختلف تولید می‌کند:
- پروتکل‌ها: `vless`, `vmess`, `shadowsocks`, `trojan`
- پورت‌ها: `443`, `8443` (ثابت) و پورت‌های تصادفی در بازه `10000-60000`
- لایه انتقال: `tcp`, `websocket`, `grpc`, `xhttp`
- SNI از لیست سفید دامنه‌ها گرفته می‌شود (`whitelist`); می‌توانید از لیست خود استفاده کنید.
تمام اتصالات در یک اشتراک با URL ثابت تجمیع می‌شوند. ربات با پنل `3x-ui` از طریق API باز کار می‌کند و به‌طور مستقیم در عملکرد داخلی پنل دخالت نمی‌کند.
هدف ثانویه افزایش پایداری اتصال است: مشتری 10 گزینه اتصال دریافت می‌کند و می‌تواند هر کدام را انتخاب کند.
علاوه بر این، ربات می‌تواند در طرح‌های آبشاری استفاده شود. سرویس فورواردینگ به‌طور خودکار بازنشانی اشتراک و ترافیک به سرور اصلی را تنظیم می‌کند.
توصیه‌ها:
- برای اشتراک از HTTPS استفاده کنید (دامنه + گواهی SSL).
- فاصله تولید را ≥ 10 دقیقه در نظر بگیرید؛ برای پایداری توصیه می‌شود یک‌بار در روز (1440 دقیقه) تنظیم شود.
- در کلاینت به‌روزرسانی خودکار را بیشتر تنظیم کنید (مثلاً هر ساعت) تا همگام‌سازی با سرور انجام شود.
## قابلیت‌ها
- تولید 10 اتصال متنوع
- تشکیل یک اشتراک یکپارچه با URL ثابت
- پشتیبانی از دامنه‌های `whitelist` سفارشی
- پیکربندی خودکار فورواردینگ ترافیک (اختیاری)
## نیازمندی‌ها
- Ubuntu 20.04 یا بالاتر
- پنل `3x-ui`
- دامنه + گواهی SSL (اختیاری)
---
## نصب
برای نصب پروژه در سرور، دستور زیر را اجرا کنید:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)
```
<small>توضیح کوتاه: اسکریپت نصب را اجرا کرده و کانتینرها و سرویس‌ها را راه‌اندازی می‌کند.</small>
## به‌روزرسانی
برای به‌روزرسانی به آخرین نسخه:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/update.sh)
```
<small>توضیح کوتاه: تغییرات جدید را می‌کشد و کانتینرها را ری‌استارت می‌کند.</small>
## حذف
برای حذف کامل سرویس:
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/delete.sh)
```
<small>توضیح کوتاه: کانتینرها و فایل‌های پیکربندی را حذف می‌کند و سیستم را به وضعیت پیش از نصب برمی‌گرداند.</small>
---
## نصب سرویس فورواردینگ (forwarding)
سرویس فورواردینگ امکان پراکسی کردن پورت‌های ورودی از سرور واسط به سرور اصلی را فراهم می‌کند.
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
<small>توضیح کوتاه: قوانین فورواردینگ را اضافه کرده و سرویسی برای به‌روزرسانی اشتراک ایجاد می‌کند.</small>
## حذف فورواردینگ
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
<small>توضیح کوتاه: قوانین را حذف کرده و سرویس فورواردینگ را غیرفعال می‌کند.</small>
---
## نمایش URL اشتراک
دستور برای نمایش URL اشتراک فعلی در محیط کانتینر:
```bash
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
<small>توضیح کوتاه: URL ثابت اشتراک را نمایش می‌دهد که می‌توان در کلاینت‌ها استفاده کرد. هم در سرور اصلی و هم در سرور واسط کار می‌کند.</small>
## جمع‌آوری دامنه‌ها از چندین اشتراک
ابزار دامنه‌ها را از اشتراک‌های دارای چندین پیکربندی استخراج کرده و `whitelist` تولید می‌کند.
```bash
node get_domains.js
```
<small>توضیح کوتاه: لینک چندین اشتراک را در اسکریپت قرار داده و فرمان را اجرا کنید — خروجی فهرست دامنه‌ها خواهد بود. نیازمند `Node.js` است.</small>
## استفاده از whitelist شخصی
1. فایلی با ساختار مشابه `whitelist.txt` آماده کنید.
2. آن را به `my_whitelist.txt` تغییر نام دهید و در پوشه `/opt/3dp-manager/app` کپی کنید.
```bash
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
<small>توضیح کوتاه: فایل دامنه شما را به کانتینر برنامه اضافه می‌کند.</small>
---
## نکات و محدودیت‌های فعلی
- لیست عمومی دامنه‌ها برای همه ارائه‌دهندگان کار نمی‌کند؛ پیشنهاد می‌شود `whitelist` خود را تهیه و استفاده کنید.
---
## مشارکت
از هرگونه مشارکت در توسعه پروژه خوشحال می‌شوم! روند ساده برای مشارکت‌کنندگان:
1. مخزن را در GitHub fork کنید.
2. شاخه‌ای با نام معنادار ایجاد کنید مانند `feature/add-README` یا `fix/whitelist-load`.
3. تغییرات را اعمال کرده و یک پیام کوتاه در کامیت اضافه کنید.
4. در صورت وجود، بررسی‌های محلی را اجرا کنید.
5. شاخه را به fork خود پوش کرده و Pull Request ایجاد کنید.
<small>نکات: تغییرات را در PR شرح دهید و مراحل تست را بنویسید. در صورت تغییرات بزرگ، آنها را به کامیت‌های کوچک تقسیم کنید.</small>
---
## بحث
- تلگرام: [@denpiligrim_web](https://t.me/denpiligrim_web)
- Issues
+155
View File
@@ -0,0 +1,155 @@
[Русский](/README.md) | [English](/README_EN.md) | [中文](/README_CN.md) | [فارسی](/README_IR.md)
<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-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
Bu gural `3x-ui` paneli üçin awtomatiki ýagdaýda inbound baglanyşlaryny döredýär, birleşdirilen abunany (subscription) döretmäge we aragatnaşyk serwerinden esasy servere trafigiň ugradylyşyny sazlamaga kömek edýär.
**Taslamany goldaň**
- Töleg / goşant maglumatlary:
- MIR kart: `2204320436318077`
- MasterCard: `5395452209474530`
- PayPal: `vasiljevdenisx@gmail.com`
- USDT | ETH (ERC20 | BEP20): `0x6fe140040f6Cdc1E1Ff2136cd1d60C0165809463`
- USDT | TRX (TRC20): `TEWxXmJxvkAmhshp7E61XJGHB3VyM9hNAb`
- Bitcoin: `bc1qctntwncsv2yn02x2vgnkrqm00c4h04c0afkgpl`
- TON: `UQCZ3MiwyYHXftPItMMzJRYRiKHugr16jFMq2nfOQOOoemLy`
- Bybit ID: `165292278`
## Düşündiriş
Esasy maksady trafigiňizi birmeňzeş bolmaz ýaly etmekdir. Bot bellenen aralykda dürli parametrler bilen 10 sany baglanyşygy döredýär:
- Protokollar: `vless`, `vmess`, `shadowsocks`, `trojan`;
- Portlar: `443`, `8443` (hemişelik) we `10000-60000` aralygyndan tötänleýin portlar;
- Transport: `tcp`, `websocket`, `grpc`, `xhttp`;
- SNI `whitelist` domen sanawyndan alynýar; öz sanawyňyzy hem ulanyp bilersiňiz.
Ähli döredilen baglanyşyklary biri-birine birleşdirip, statik URL bilen bir abuna döredilýär. Bot `3x-ui` paneliniň açyk API-sini ulanýar we paneliň içki konfigurasiýasyna gönüden-göni aralaşmaýar.
Ikinji maksady baglanyşygyň durnuklylygyny ýokarlandyrmakdyr: müşderi 10 dürli baglanyşyk opsiýasyny alýar we islese haýsyny islese saýlap bilýär.
Göçürme (forwarding) hyzmaty bilen birleşdirilende, bot abonnament we trafik diňe esasy servere ugradylyşyny awtomatiki sazlar.
Maslahatchylyklar:
- Abuna üçin HTTPS ulanyň (domain + SSL şahadatnamasy).
- Dörediş aralygyny ≥ 10 minut goýuň; durnuklylyk üçin her gün bir gezek (1440 minut) maslahat berilýär.
- Müşderide awtomatiki täzelenmäni ýygylaşdyryň (meselem, her sagat) — serwera sazlaşyklylyk üçin.
## Imkançylyklar
- 10 dürli baglanyşygy öndürýär
- Statik URL bilen bir abuna döredýär
- Öz `whitelist` domenleriňizi goldaýar
- Trafigiň awtomatik forwarding sazlamalary (islege bagly)
## Talaplar
- Ubuntu 20.04 ýa-da täze
- `3x-ui` paneli
- Domain + SSL şahadatnamasy (islege bagly)
---
## Gurnama
Taslamany serwera gurnamak üçin şu komandany ýerine ýetiriň:
```bash
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>
## Täzelik
Soňky wersiýa çenli täzeläň:
```bash
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>
## Pozmak
Hyzmaty doly pozmak üçin:
```bash
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>
---
## Forwarding hyzmatyny gurnamak
Forwarding hyzmaty aragatnaşyk serwerinden esasy servere gelýän portlary proxy arkaly geçirýär.
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_install.sh)
```
## Forwarding-i pozmak
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/forwarding_delete.sh)
```
---
## Abuna URL-ni görkezmek
Konteýner gurşawynda häzirki abuna URL-ni görkezýän komanda:
```bash
cd /opt/3dp-manager && docker compose exec node env | grep SUB_URL | cut -d'=' -f2
```
## Multi-abunalardan domenleri toplamak
Gural birden köp konfigurasiýa içeren abunalardan domenleri çykaryp `whitelist` düzýär.
```bash
node get_domains.js
```
## Öz `whitelist`-iňizi ulanmak
1. `whitelist.txt` bilen meňzeş struktura eýe faýl taýýarlaň.
2. Ony `my_whitelist.txt` diýip atlandyryp `/opt/3dp-manager/app` içine göçüriň.
```bash
cd /opt/3dp-manager && docker cp ./app/my_whitelist.txt node:/app/my_whitelist.txt
```
---
## Bellikler we çäklendirmeler
- Umumy domen sanawy ähli üpjün edijilerde işlemeýär; öz `whitelist`-iňizi düzmegiňizi maslahat berýäris.
---
## Goşanty
Proýekte goşant bermäge hoş geldiňiz! Goşant prosesi ýönekeý:
1. GitHub-da repo-ny fork ediň.
2. Meni manly at bilen şahamça (branch) dörediň, meselem `feature/add-README` ýa-da `fix/whitelist-load`.
3. Üýtgeşmeleri giriziň we gysga commit ýazmagy unutmaň.
4. Lokal barlaglary işlediň (bardy bolsa).
5. Şahamçany fork-a iteriň we Pull Request dörediň.
---
## Çeperdeşlik
- Telegram: [@denpiligrim_web](https://t.me/denpiligrim_web)
- Issues
+1
View File
@@ -2,6 +2,7 @@ SUB_TOKEN=$SUB_TOKEN
UI_URL=$UI_URL
UI_LOGIN=$UI_LOGIN
UI_PASSWORD=$UI_PASSWORD
COUNTRY_FLAG=$COUNTRY_FLAG
NGINX_PORT=$NGINX_PORT
UI_HOST=$UI_HOST
UI_PROTO=$UI_PROTO
File diff suppressed because it is too large Load Diff
+7 -5
View File
@@ -1,3 +1,5 @@
const flag = process.env.COUNTRY_FLAG ?? '%F0%9F%92%AF';
export function buildInboundLink(inbound, domain, idOrPass) {
let link = "";
@@ -48,7 +50,7 @@ function buildVlessLink(inbound, domain, uuid) {
params.set("fp", r.settings.fingerprint || "random");
params.set("sni", r.serverNames?.[0] || "");
params.set("sid", r.shortIds?.[0] || "");
params.set("spx", '%2F');
params.set("spx", '/');
// TCP Reality flow
if (network === "tcp") {
@@ -88,7 +90,7 @@ function buildVlessLink(inbound, domain, uuid) {
return (
`vless://${uuid}@${domain}:${inbound.port}` +
`?${params.toString()}` +
`#${encodeURIComponent(inbound.remark)}`
`#${flag}%20${encodeURIComponent(inbound.remark)}`
);
}
@@ -105,7 +107,7 @@ function buildVmessLink(inbound, domain, uuid) {
net: stream.network || "tcp",
path: "/",
port: inbound.port,
ps: inbound.remark,
ps: decodeURIComponent(flag) + ' ' + inbound.remark,
scy: "",
sni: "",
tls: stream.security || "none",
@@ -134,7 +136,7 @@ function buildSsLink(inbound, domain) {
.from(userInfo, "utf8")
.toString("base64");
return `ss://${base64}@${domain}:${inbound.port}?type=tcp#${inbound.remark}`;
return `ss://${base64}@${domain}:${inbound.port}?type=tcp#${flag}%20${inbound.remark}`;
}
function buildTrojanLink(inbound, domain, password) {
@@ -155,6 +157,6 @@ function buildTrojanLink(inbound, domain, password) {
`&sni=${sni}` +
`&sid=${sid}` +
`&spx=${spx}` +
`#${inbound.remark}-${password}`
`#${flag}%20${inbound.remark}`
);
}
-2
View File
@@ -1,5 +1,3 @@
import crypto from "crypto";
export function buildVlessWs({ port, uuid, domain }) {
return {
enable: true,
+2 -1
View File
@@ -14,7 +14,8 @@ export function buildVmessTcp({ port, uuid }) {
totalGB: 0,
expiryTime: 0,
tgId: "",
subId: "",
subId: "0",
alterId: "0",
reset: 0
}],
}),
+1
View File
@@ -9,6 +9,7 @@ services:
nginx:
image: nginx:alpine
restart: unless-stopped
depends_on: [node]
ports:
- "80:80"
+36 -8
View File
@@ -13,6 +13,7 @@ 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 api = axios.create({ baseURL: UI_URL, timeout: 15000, withCredentials: true });
@@ -25,7 +26,7 @@ api.interceptors.request.use(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 });
@@ -124,6 +125,26 @@ async function getInbounds() {
} 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 { }
}
@@ -131,14 +152,14 @@ async function deleteInbound(id) {
async function addInbound(config) {
try {
const res = await api.post("/panel/api/inbounds/add", config);
return res.data?.id || null;
return res.data?.obj?.id || null;
} catch (e) {
console.error("Add inbound failed:", e.message);
return null;
}
}
// Основная ротация inbound'ов
// Main rotation of inbound entries
async function rotate() {
await login();
@@ -147,8 +168,7 @@ async function rotate() {
const usedPorts = new Set();
const subs = [];
const existing = await getInbounds();
for (const i of existing) await deleteInbound(i.id);
await deleteInbounds();
const builders = [
async (d) => buildVlessRealityTcp({ port: await isPortFree(8443) ? 8443 : await getFreePort(usedPorts), uuid: await uuid(), domain: d, keys: await generateRealityKeys() }),
@@ -163,23 +183,31 @@ async function rotate() {
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);
usedPorts.add(inbound.port);
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);
await addInbound(inbound);
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();
let interval = parseInt(process.env.ROTATE_INTERVAL) || 30;
+2
View File
@@ -7,6 +7,8 @@ http {
location = /bus/$SUB_TOKEN {
alias /subscriptions/list.txt;
default_type text/plain;
add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
add_header Access-Control-Allow-Origin *;
}
location / {
+13 -7
View File
@@ -9,7 +9,6 @@ trap 'echo -e "\033[1;31m[ERROR]\033[0m Ошибка в строке $LINENO"; e
#################################
# HELPERS
#################################
log() { echo -e "\033[1;32m[INFO]\033[0m $1"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
@@ -18,10 +17,21 @@ need_root() {
[[ $EUID -eq 0 ]] || die "Запускать только от root"
}
read -r -p "Вы уверены, что хотите удалить? (y/N): " answer
case "$answer" in
y|Y)
echo "Начинаю удаление..."
;;
*)
echo "Удаление отменено"
exit 1
;;
esac
#################################
# START
#################################
need_root
PROJECT_DIR="/opt/3dp-manager"
@@ -38,7 +48,6 @@ cd "$PROJECT_DIR"
#################################
# DOCKER COMPOSE DOWN
#################################
if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
if [[ -f docker-compose.yml ]]; then
log "Останавливаем контейнеры 3dp-manager"
@@ -51,9 +60,8 @@ else
fi
#################################
# CLEAN IMAGES (ТОЛЬКО НАШИ)
# CLEAN IMAGES
#################################
log "Удаляем образы 3dp-manager (если есть)"
docker images --format '{{.Repository}} {{.ID}}' \
@@ -64,12 +72,10 @@ docker images --format '{{.Repository}} {{.ID}}' \
#################################
# REMOVE DIRECTORY
#################################
log "Удаляем $PROJECT_DIR"
rm -rf "$PROJECT_DIR"
#################################
# DONE
#################################
log "✔ 3dp-manager полностью удалён"
+20 -9
View File
@@ -14,6 +14,18 @@ warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
[[ $EUID -eq 0 ]] || { echo "Запускать нужно от root"; exit 1; }
read -r -p "Вы уверены, что хотите удалить? (y/N): " answer
case "$answer" in
y|Y)
echo "Начинаю удаление..."
;;
*)
echo "Удаление отменено"
exit 1
;;
esac
#################################
# PATHS
#################################
@@ -42,14 +54,11 @@ rm -rf "$BASE_DIR"
#################################
# UFW NAT CLEAN
#################################
echo "--- 1. Удаление оптимизаций ядра ---"
echo "--- Удаление перенаправления ---"
rm -f /etc/sysctl.d/99-relay-optimization.conf
# Применяем стандартные настройки (отключаем BBR и forward, если они не были включены до этого)
sysctl net.ipv4.ip_forward=0
sysctl net.core.default_qdisc=pfifo_fast
sysctl net.ipv4.tcp_congestion_control=cubic
echo "--- 2. Восстановление правил UFW из бэкапа ---"
echo "--- Восстановление правил UFW из бэкапа ---"
if [ -f /etc/ufw/before.rules.bak ]; then
mv /etc/ufw/before.rules.bak /etc/ufw/before.rules
echo "Файл before.rules восстановлен из бэкапа."
@@ -57,17 +66,19 @@ else
echo "ВНИМАНИЕ: Бэкап before.rules.bak не найден. Правила NAT придется удалять вручную."
fi
echo "--- 3. Удаление разрешающих правил портов ---"
echo "--- Удаление разрешающих правил портов ---"
ufw delete allow 443/tcp
ufw delete allow 443/udp
ufw delete allow 8443/tcp
ufw delete allow 8443/udp
ufw delete allow "$NGINX_PORT"/tcp
ufw delete allow 10000:60000/tcp
ufw delete allow 10000:60000/udp
echo "--- 4. Возврат политики FORWARD по умолчанию (DROP) ---"
echo "--- Возврат политики FORWARD по умолчанию (DROP) ---"
sed -i 's/DEFAULT_FORWARD_POLICY="ACCEPT"/DEFAULT_FORWARD_POLICY="DROP"/' /etc/default/ufw
echo "--- 5. Перезапуск фаервола ---"
echo "--- Перезапуск фаервола ---"
ufw reload
#################################
@@ -77,4 +88,4 @@ ufw reload
echo "Docker контейнеры удалены"
echo "UFW NAT очищен"
echo "ip_forward отключён"
log "Откат завершён. Для применения изменений перезагрузите систему!"
log "Откат завершён. Для окончательного применения изменений перезагрузите систему!"
+23 -31
View File
@@ -15,7 +15,9 @@ die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
[[ $EUID -eq 0 ]] || die "Запускать нужно от root"
# --- ASCII-баннер ---
#################################
# ASCII-баннер
#################################
echo "==================================================="
echo " ____ ____ _ ___ _ "
echo " / __ \___ ____ / __ \(_) (_)___ ______(_)___ ___ "
@@ -27,7 +29,6 @@ echo ""
echo " 3DP-MANAGER SUBSCRIPTION FORWARDER "
echo "==================================================="
echo ""
# --------------------
#################################
# INPUT
@@ -51,22 +52,16 @@ SUB_PATH="/$(echo "$ORIGIN_SUB_URL" | cut -d/ -f4-)"
#################################
# Определяем ORIGIN_IP
#################################
if [[ "$ORIGIN_HOST" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
# Это уже IP-адрес
ORIGIN_IP="$ORIGIN_HOST"
log "Используем прямой IP из URL: $ORIGIN_IP"
else
# Это домен — разрешаем в IP
log "Разрешаем домен $ORIGIN_HOST в IP..."
# Пробуем getent ahosts (IPv4 приоритет)
ORIGIN_IP=$(getent ahosts "$ORIGIN_HOST" | awk '/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {print $1; exit}')
# Если не вышло — fallback на hosts
[[ -z "$ORIGIN_IP" ]] && ORIGIN_IP=$(getent hosts "$ORIGIN_HOST" | awk '{print $1; exit}')
# Последний шанс — dig (если установлен)
if [[ -z "$ORIGIN_IP" ]] && command -v dig >/dev/null; then
ORIGIN_IP=$(dig +short "$ORIGIN_HOST" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n1)
fi
@@ -76,7 +71,6 @@ else
log "Домен $ORIGIN_HOST разрешён в IP: $ORIGIN_IP"
fi
# Финальная проверка
[[ -n "$ORIGIN_IP" && -n "$ORIGIN_PORT" && -n "$SUB_PATH" ]] || die "Ошибка парсинга URL подписки"
#################################
@@ -117,7 +111,12 @@ cd "$BASE_DIR"
#################################
REPO="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
NGINX_PORT=$ORIGIN_PORT
SUB_URL="$ORIGIN_PROTO://$LOCAL_HOST:$NGINX_PORT$SUB_PATH"
if [[ "$USE_HTTPS" == "true" ]]; then
NGINX_PROTO="https"
else
NGINX_PROTO="http"
fi
SUB_URL="$NGINX_PROTO://$LOCAL_HOST:$NGINX_PORT$SUB_PATH"
#################################
# ENV
@@ -194,7 +193,6 @@ EOF
#################################
# NGINX & DOCKER COMPOSE
#################################
if $USE_HTTPS; then
cat > nginx.conf <<EOF
events {}
@@ -213,6 +211,9 @@ http {
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
add_header Access-Control-Allow-Origin *;
}
}
}
@@ -229,6 +230,7 @@ services:
nginx:
image: nginx:alpine
restart: unless-stopped
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
@@ -253,6 +255,9 @@ http {
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
add_header Access-Control-Allow-Origin *;
}
}
}
@@ -269,6 +274,7 @@ services:
nginx:
image: nginx:alpine
restart: unless-stopped
container_name: nginx
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
@@ -293,12 +299,10 @@ else
systemctl restart docker
fi
# Проверка docker compose v2
if docker compose version >/dev/null 2>&1; then
log "docker compose v2 доступен"
else
log "Устанавливаем docker-compose-v2"
# решаем конфликт с docker-compose-plugin
apt install -y --allow-downgrades --allow-remove-essential --allow-change-held-packages \
docker-compose-v2 || warn "docker-compose-v2 не установлен, возможно уже есть плагин"
fi
@@ -313,27 +317,20 @@ docker compose up -d --build
#################################
LOCAL_IP=$(hostname -I | awk '{print $1}')
# Проверка и установка UFW, если не установлен
if ! command -v ufw >/dev/null 2>&1; then
echo "UFW не установлен. Устанавливаю..."
apt update -qq && apt install -y ufw
fi
# Проверка статуса UFW (независимо от локали, на английском)
if LC_ALL=C ufw status 2>/dev/null | grep -q "Status: active"; then
echo "UFW уже активен."
else
echo "ВНИМАНИЕ: UFW выключен или не настроен. Включаю..."
# Разрешаем SSH (или другой порт, если используете не 22)
# OpenSSH — стандартный профиль, обычно порт 22
ufw allow OpenSSH >/dev/null 2>&1 || true
# Если SSH на другом порту, добавьте: ufw allow 2222/tcp
# Включаем UFW без подтверждения
ufw --force enable >/dev/null 2>&1
# Проверяем, успешно ли включён
if LC_ALL=C ufw status 2>/dev/null | grep -q "Status: active"; then
echo "UFW успешно включён."
else
@@ -342,7 +339,7 @@ else
fi
fi
echo "--- 1. Оптимизация сетевого стека ядра ---"
echo "--- Оптимизация сетевого стека ядра ---"
cat <<EOF > /etc/sysctl.d/99-relay-optimization.conf
net.ipv4.ip_forward = 1
net.core.default_qdisc = fq
@@ -361,10 +358,9 @@ net.ipv4.tcp_tw_reuse=1
EOF
sysctl --system
echo "--- 2. Настройка правил перенаправления (before.rules) ---"
echo "--- Настройка правил перенаправления (before.rules) ---"
cp /etc/ufw/before.rules /etc/ufw/before.rules.bak
# Создаем временный файл с вашими правилами
cat <<EOF > /tmp/ufw_nat_rules
*nat
:PREROUTING ACCEPT [0:0]
@@ -400,28 +396,24 @@ COMMIT
EOF
# Удаляем старые блоки *nat и *mangle из оригинала, если они там были (от прошлых запусков)
# И создаем чистую копию без них
sed -i '/\*nat/,/COMMIT/d' /etc/ufw/before.rules
sed -i '/\*mangle/,/COMMIT/d' /etc/ufw/before.rules
# Склеиваем: Сначала NAT/Mangle, потом остаток оригинального before.rules
cat /tmp/ufw_nat_rules /etc/ufw/before.rules > /etc/ufw/before.rules.new
mv /etc/ufw/before.rules.new /etc/ufw/before.rules
echo "--- 3. Открытие портов в самом фаерволе ---"
# Разрешаем входящий трафик на эти порты
echo "--- Открытие портов в самом фаерволе ---"
ufw allow 443/tcp
ufw allow 443/udp
ufw allow 8443/tcp
ufw allow 8443/udp
ufw allow "$NGINX_PORT"/tcp
ufw allow 10000:60000/tcp
ufw allow 10000:60000/udp
# Разрешаем FORWARD (пересылку)
# Это критически важный шаг для корректной работы DNAT в UFW
sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
echo "--- 4. Перезапуск ---"
echo "--- Перезапуск ---"
ufw reload
echo "Готово! Система оптимизирована, порты открыты, трафик перенаправлен."
+1 -1
View File
@@ -48,7 +48,7 @@ async function processSubscription() {
const result = Array.from(domains).sort(); // Сортируем для удобства
if (result.length > 0) {
fs.writeFileSync('domains.txt', result.join('\n'), 'utf8');
fs.writeFileSync('my_whitelist.txt', result.join('\n'), 'utf8');
console.log(`Успешно! Сохранено уникальных доменов: ${result.length}`);
} else {
console.log('Валидные домены не найдены.');
+71 -38
View File
@@ -2,14 +2,13 @@
set -euo pipefail
#################################
# TRAP ДЛЯ ОТЛАДКИ
# DEBUG TRAP
#################################
trap 'echo -e "\033[1;31m[ERROR]\033[0m Ошибка в строке $LINENO"; exit 1' ERR
#################################
# ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
# HELPER FUNCTIONS
#################################
log() { echo -e "\033[1;32m[INFO]\033[0m $1"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
@@ -22,12 +21,13 @@ validate_url() {
}
#################################
# ПРОВЕРКИ
# CHECKS
#################################
need_root
# --- ASCII-баннер ---
#################################
# ASCII-баннер
#################################
echo "==================================================="
echo " ____ ____ _ ___ _ "
echo " / __ \___ ____ / __ \(_) (_)___ ______(_)___ ___ "
@@ -39,22 +39,39 @@ echo ""
echo " 3DP-MANAGER FOR 3X-UI "
echo "==================================================="
echo ""
# --------------------
#################################
# ВВОД ДАННЫХ
# INPUT / USER DATA
#################################
# Function to get panel URL from 3x-ui
get_xui_url() {
local output=$(x-ui settings 2>/dev/null)
read -rp "URL панели 3x-ui (с портом и путем): " UI_URL
UI_URL="${UI_URL%/}"
validate_url "$UI_URL" || die "Некорректный URL 3x-ui"
echo "$output" | sed 's/\x1b\[[0-9;]*m//g' | grep "Access URL:" | grep -oE 'https?://[^[:space:]]+' | head -n1
}
echo "Определяем URL панели 3x-ui..."
UI_URL=$(get_xui_url)
if [[ -z "$UI_URL" ]]; then
echo "Не удалось автоматически получить URL"
read -rp "Введите URL панели 3x-ui вручную: " UI_URL
fi
UI_URL=$(echo "$UI_URL" | sed -E 's/[[:space:]]*$//; s|/*$||')
echo "URL панели 3x-ui: $UI_URL"
# Validate URL correctness
validate_url "$UI_URL" || die "Некорректный URL панели 3x-ui: $UI_URL"
read -rp "Логин 3x-ui: " UI_LOGIN
read -rsp "Пароль 3x-ui: " UI_PASSWORD
echo
[[ -z "$UI_LOGIN" || -z "$UI_PASSWORD" ]] && die "Логин/пароль обязательны"
# Проверка логина
# Check login
LOGIN_RESPONSE=$(curl -s -X POST "$UI_URL/login" -H "Content-Type: application/json" -d "{\"username\":\"$UI_LOGIN\",\"password\":\"$UI_PASSWORD\"}")
# Проверка успешного логина по ключевому полю "success" или наличию куки
@@ -65,9 +82,9 @@ fi
echo "✔ Успешный логин в 3x-ui"
# Разбор UI_URL
UI_HOST=$(echo "$UI_URL" | awk -F[/:] '{print $4}') # домен или IP
UI_PROTO=$(echo "$UI_URL" | awk -F: '{print $1}') # http или https
# Parse UI_URL
UI_HOST=$(echo "$UI_URL" | awk -F[/:] '{print $4}') # domain or IP
UI_PROTO=$(echo "$UI_URL" | awk -F: '{print $1}') # http or https
if [[ "$UI_PROTO" == "https" ]]; then
log "HTTPS панель обнаружена, проверяем SSL сертификаты"
@@ -90,11 +107,11 @@ if [[ "$UI_PROTO" == "https" ]]; then
fi
# Ввод интервала ротации
# Input rotation interval
read -rp "Интервал генерации инбаундов в минутах (от 10, по умолчанию 30): " ROTATE_INTERVAL
ROTATE_INTERVAL="${ROTATE_INTERVAL:-30}" # по умолчанию 30
# Проверка, что это число и ≥10
# Check that it's a number and ≥10
if ! [[ "$ROTATE_INTERVAL" =~ ^[0-9]+$ ]] || [ "$ROTATE_INTERVAL" -lt 10 ]; then
echo "Неверное значение. Используется значение по умолчанию 30 минут."
ROTATE_INTERVAL=30
@@ -109,25 +126,42 @@ mkdir -p "$PROJECT_DIR"
cd "$PROJECT_DIR"
#################################
# Белый лист
# Get country flag
#################################
REPO_BASE="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
COUNTRY_FLAG=""
# Get countryCode
IP_JSON=$(curl -s --fail http://ip-api.com/json/ || true)
[ -z "$IP_JSON" ] && exit 0
COUNTRY_CODE=$(echo "$IP_JSON" | jq -r '.countryCode // empty' 2>/dev/null)
[ -z "$COUNTRY_CODE" ] && exit 0
# Flags JSON URL
FLAGS_JSON_URL="$REPO_BASE/app/assets/flags.json"
FLAGS_JSON=$(curl -s "$FLAGS_JSON_URL" || true)
[ -z "$FLAGS_JSON" ] && exit 0
# Ищем emoji
COUNTRY_FLAG=$(echo "$FLAGS_JSON" | jq -r --arg code "$COUNTRY_CODE" '.[] | select(.code == $code) | .emoji // empty' 2>/dev/null | head -n1)
#################################
# Whitelist
#################################
curl -fsSL "$REPO_BASE/whitelist.txt" -o whitelist.txt
log "whitelist.txt скопирован"
#################################
# ГЕНЕРАЦИЯ ТОКЕНА
# TOKEN GENERATION
#################################
SUB_TOKEN="$(openssl rand -hex 24)"
log "Сгенерирован токен подписки"
#################################
# DOCKER
#################################
log "Проверка Docker"
if command -v docker >/dev/null 2>&1; then
@@ -140,7 +174,7 @@ else
systemctl restart docker
fi
# Проверка docker compose v2
# Check docker compose v2
if docker compose version >/dev/null 2>&1; then
log "docker compose v2 доступен"
else
@@ -151,15 +185,14 @@ else
fi
#################################
# СТРУКТУРА
# STRUCTURE
#################################
mkdir -p app app/builders subscriptions
# Генерация случайного свободного порта для подписки/Nginx
# Generate a random free port for subscription/Nginx
get_random_port() {
while :; do
PORT=$((RANDOM % 50000 + 10000)) # диапазон 10000-60000
PORT=$((RANDOM % 50000 + 10000)) # range 10000-60000
if ! ss -ltn | awk '{print $4}' | grep -q ":$PORT\$"; then
echo "$PORT"
return
@@ -168,18 +201,18 @@ get_random_port() {
}
NGINX_PORT=$(get_random_port)
# Генерация URL подписки
# Generate subscription URL
SUB_URL="$UI_PROTO://$UI_HOST:$NGINX_PORT/bus/$SUB_TOKEN"
#################################
# ENV
#################################
cat > .env <<EOF
SUB_TOKEN=$SUB_TOKEN
UI_URL=$UI_URL
UI_LOGIN=$UI_LOGIN
UI_PASSWORD=$UI_PASSWORD
COUNTRY_FLAG=$COUNTRY_FLAG
NGINX_PORT=$NGINX_PORT
UI_HOST=$UI_HOST
UI_PROTO=$UI_PROTO
@@ -190,19 +223,16 @@ EOF
#################################
# Dockerfile
#################################
curl -fsSL "$REPO_BASE/app/Dockerfile" -o app/Dockerfile
#################################
# package.json
#################################
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/builders/buildVlessRealityTcp.js" -o app/builders/buildVlessRealityTcp.js
curl -fsSL "$REPO_BASE/app/builders/buildVlessRealityXhttp.js" -o app/builders/buildVlessRealityXhttp.js
@@ -216,8 +246,7 @@ curl -fsSL "$REPO_BASE/app/builders/buildInboundLink.js" -o app/builders/buildIn
#################################
# NGINX & DOCKER COMPOSE
#################################
# Генерация nginx.conf
# Generate nginx.conf
if [[ "$UI_PROTO" == "https" ]]; then
cat > docker-compose.yml <<EOF
services:
@@ -232,6 +261,7 @@ services:
nginx:
image: nginx:alpine
restart: unless-stopped
depends_on: [node]
ports:
- "$NGINX_PORT:$NGINX_PORT"
@@ -256,6 +286,8 @@ http {
location = /bus/$SUB_TOKEN {
alias /subscriptions/list.txt;
default_type text/plain;
add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
add_header Access-Control-Allow-Origin *;
}
location / {
@@ -278,6 +310,7 @@ services:
nginx:
image: nginx:alpine
restart: unless-stopped
depends_on: [node]
ports:
- "$NGINX_PORT:$NGINX_PORT"
@@ -297,6 +330,8 @@ http {
location = /bus/$SUB_TOKEN {
alias /subscriptions/list.txt;
default_type text/plain;
add_header Subscription-Userinfo "upload=0; download=0; total=109951162777600; expire=0" always;
add_header Access-Control-Allow-Origin *;
}
location / {
@@ -308,9 +343,8 @@ EOF
fi
#################################
# ЗАПУСК
# RUN
#################################
log "Сборка контейнеров"
docker compose build
@@ -321,9 +355,8 @@ docker compose ps | grep node >/dev/null || die "Backend не запущен"
docker compose ps | grep nginx >/dev/null || die "Nginx не запущен"
#################################
# РЕЗУЛЬТАТ
# RESULT
#################################
log "✔ Установка завершена"
echo
echo "URL подписки:"
+1 -10
View File
@@ -9,7 +9,6 @@ trap 'echo -e "\033[1;31m[ERROR]\033[0m Ошибка в строке $LINENO"; e
#################################
# HELPERS
#################################
log() { echo -e "\033[1;32m[INFO]\033[0m $1"; }
warn() { echo -e "\033[1;33m[WARN]\033[0m $1"; }
die() { echo -e "\033[1;31m[ERROR]\033[0m $1"; exit 1; }
@@ -21,14 +20,12 @@ need_root() {
#################################
# CONFIG
#################################
PROJECT_DIR="/opt/3dp-manager"
REPO_RAW="https://raw.githubusercontent.com/denpiligrim/3dp-manager/main"
#################################
# START
#################################
need_root
log "Обновление 3dp-manager"
@@ -40,14 +37,12 @@ cd "$PROJECT_DIR"
#################################
# CHECK DOCKER
#################################
command -v docker >/dev/null 2>&1 || die "Docker не установлен"
docker compose version >/dev/null 2>&1 || die "docker compose v2 недоступен"
#################################
# DOWNLOAD FILES
#################################
log "Загружаем обновлённые файлы из репозитория"
mkdir -p app
@@ -70,21 +65,18 @@ log "Файлы обновлены"
#################################
# REBUILD BACKEND
#################################
log "Пересобираем backend"
docker compose build node
#################################
# RESTART CONTAINERS
#################################
log "Перезапускаем контейнеры"
docker compose up -d
#################################
# HEALTH CHECK
#################################
sleep 2
docker compose ps | grep node >/dev/null || die "Backend не запущен"
@@ -93,5 +85,4 @@ docker compose ps | grep nginx >/dev/null || die "Nginx не запущен"
#################################
# DONE
#################################
log "3dp-manager успешно обновлён ✅"
log "3dp-manager успешно обновлён ✅"