add mtp
This commit is contained in:
parent
d3a12fc48a
commit
cc84ee874e
@ -21,17 +21,16 @@ sudo bash nginx.sh # Nginx + правила UFW
|
||||
sudo bash certbot.sh # Certbot для SSL-сертификатов
|
||||
```
|
||||
|
||||
### 2. VPN-сервер
|
||||
### 2. Сервисы
|
||||
|
||||
Два варианта — выбирай нужный:
|
||||
|
||||
| | `vless.sh` | `vless_ip.sh` |
|
||||
|---|---|---|
|
||||
| Подключение | По домену | По IP-адресу |
|
||||
| Транспорт | WebSocket | TCP |
|
||||
| Шифрование | TLS (Let's Encrypt) | Reality (XTLS) |
|
||||
| Nginx | Нужен (проксирует WS) | Не нужен |
|
||||
| Маскировка | Обычный HTTPS-сайт | TLS-хендшейк с реальным сайтом |
|
||||
| | `vless.sh` | `vless_ip.sh` | `mtp.sh` |
|
||||
|---|---|---|---|
|
||||
| Назначение | VLESS VPN | VLESS VPN | MTProto Proxy (Telegram) |
|
||||
| Подключение | По домену | По IP-адресу | По домену |
|
||||
| Транспорт | WebSocket | TCP | TCP (fake-TLS) |
|
||||
| Шифрование | TLS (Let's Encrypt) | Reality (XTLS) | Fake-TLS |
|
||||
| Nginx | Нужен (проксирует WS) | Не нужен | Stream SNI routing |
|
||||
| Маскировка | Обычный HTTPS-сайт | TLS-хендшейк с реальным сайтом | TLS-хендшейк с заданным доменом |
|
||||
|
||||
## Скрипты
|
||||
|
||||
@ -134,9 +133,60 @@ sudo bash vless_ip.sh
|
||||
|
||||
---
|
||||
|
||||
### `mtp.sh` — MTProto Proxy для Telegram (по домену)
|
||||
|
||||
Поднимает официальный MTProto Proxy (TelegramMessenger/MTProxy) с fake-TLS и nginx stream SNI routing. Все сервисы (VLESS, MTProxy, сайты) работают на одном порту 443.
|
||||
|
||||
**Переменные `.env`:**
|
||||
|
||||
```env
|
||||
MTP_DOMAIN=mtp.example.com
|
||||
MTP_PORT=10002
|
||||
```
|
||||
|
||||
**Что делает:**
|
||||
|
||||
1. Собирает MTProxy из исходников (C, GitHub)
|
||||
2. Генерирует секрет, скачивает конфиг от Telegram
|
||||
3. Создаёт systemd-сервис `mtproxy`
|
||||
4. Устанавливает `libnginx-mod-stream`
|
||||
5. Добавляет stream-блок в nginx для SNI-роутинга на порту 443
|
||||
6. Патчит существующие HTTPS-сайты: `listen 443` -> `listen 8443`
|
||||
7. Выводит ссылку для клиента и данные для MTProxy Admin Bot
|
||||
|
||||
**Архитектура (после установки):**
|
||||
|
||||
```
|
||||
:443 (nginx stream, ssl_preread)
|
||||
|
|
||||
+-- SNI = mtp.example.com --> :10002 (MTProxy, fake-TLS)
|
||||
+-- SNI = * (default) --> :8443 (nginx http, TLS termination)
|
||||
|
|
||||
+-- WS /path --> :10001 (Xray VLESS)
|
||||
+-- / --> /var/www (static)
|
||||
```
|
||||
|
||||
**Ссылка для клиента:**
|
||||
|
||||
```
|
||||
tg://proxy?server=MTP_DOMAIN&port=443&secret=ee<SECRET><DOMAIN_HEX>
|
||||
```
|
||||
|
||||
**Для MTProxy Admin Bot:** `MTP_DOMAIN:443`
|
||||
|
||||
**Запуск:**
|
||||
|
||||
```bash
|
||||
sudo bash mtp.sh
|
||||
```
|
||||
|
||||
> **Важно:** `mtp.sh` перестраивает nginx — все HTTPS-сайты переезжают на внутренний порт 8443, а порт 443 занимает stream-модуль для SNI-маршрутизации. Если `vless.sh` запускается после `mtp.sh`, он автоматически использует 8443.
|
||||
|
||||
---
|
||||
|
||||
## Файл `.env`
|
||||
|
||||
Создай `initializator/.env` перед запуском VPN-скриптов:
|
||||
Создай `initializator/.env` перед запуском скриптов:
|
||||
|
||||
```env
|
||||
# Для vless.sh (доменный вариант)
|
||||
@ -146,51 +196,66 @@ PORT=10001
|
||||
|
||||
# Для vless_ip.sh (IP вариант)
|
||||
SERVER_IP=45.146.202.107
|
||||
|
||||
# Для mtp.sh (MTProto Proxy)
|
||||
MTP_DOMAIN=mtp.example.com
|
||||
MTP_PORT=10002
|
||||
```
|
||||
|
||||
## Управление сервисом
|
||||
## Управление сервисами
|
||||
|
||||
```bash
|
||||
# Статус
|
||||
systemctl status xray-vless # доменный
|
||||
systemctl status xray-vless-ip # IP
|
||||
systemctl status xray-vless # VLESS (домен)
|
||||
systemctl status xray-vless-ip # VLESS (IP)
|
||||
systemctl status mtproxy # MTProto Proxy
|
||||
|
||||
# Перезапуск
|
||||
systemctl restart xray-vless
|
||||
systemctl restart xray-vless-ip
|
||||
systemctl restart mtproxy
|
||||
|
||||
# Логи
|
||||
journalctl -u xray-vless -f
|
||||
journalctl -u xray-vless-ip -f
|
||||
journalctl -u mtproxy -f
|
||||
```
|
||||
|
||||
## Структура файлов на сервере
|
||||
|
||||
```
|
||||
~/services/
|
||||
├── vless/ # доменный вариант
|
||||
│ ├── xray # бинарник Xray-core
|
||||
│ ├── config.json # конфиг сервера
|
||||
│ └── connection.txt # строка подключения
|
||||
└── vless_ip/ # IP вариант
|
||||
├── xray
|
||||
├── config.json
|
||||
└── connection.txt
|
||||
├── vless/ # VLESS по домену
|
||||
│ ├── xray
|
||||
│ ├── config.json
|
||||
│ └── connection.txt
|
||||
├── vless_ip/ # VLESS по IP
|
||||
│ ├── xray
|
||||
│ ├── config.json
|
||||
│ └── connection.txt
|
||||
└── mtp/ # MTProto Proxy
|
||||
├── mtproto-proxy # бинарник (собран из C)
|
||||
├── proxy-secret # секрет от Telegram
|
||||
├── proxy-multi.conf # конфиг от Telegram (обновляется при старте)
|
||||
├── secret.txt # клиентский секрет
|
||||
└── connection.txt # ссылки для подключения
|
||||
|
||||
/etc/systemd/system/
|
||||
├── xray-vless.service
|
||||
└── xray-vless-ip.service
|
||||
├── xray-vless-ip.service
|
||||
└── mtproxy.service
|
||||
|
||||
/etc/nginx/sites-available/
|
||||
└── vless-$DOMAIN # только для доменного варианта
|
||||
/etc/nginx/
|
||||
├── nginx.conf # содержит stream {} блок (после mtp.sh)
|
||||
└── sites-available/
|
||||
└── vless-$DOMAIN # listen 8443 (после mtp.sh)
|
||||
```
|
||||
|
||||
## Клиенты
|
||||
|
||||
Строку подключения можно импортировать в:
|
||||
**VLESS** (v2rayNG, Nekoray, Streisand, V2Box и др.):
|
||||
- Импорт по ссылке `vless://...`
|
||||
|
||||
- **Android:** v2rayNG, NekoBox
|
||||
- **iOS:** Streisand, V2Box
|
||||
- **Windows:** Nekoray, v2rayN
|
||||
- **macOS:** V2RayXS, Nekoray
|
||||
- **Linux:** Nekoray
|
||||
**MTProto Proxy** (встроен в Telegram):
|
||||
- Импорт по ссылке `tg://proxy?...` или `https://t.me/proxy?...`
|
||||
- Настройки -> Данные и хранилище -> Прокси -> Добавить прокси
|
||||
|
||||
233
initializator/mtp.sh
Normal file
233
initializator/mtp.sh
Normal file
@ -0,0 +1,233 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
source "$(dirname "$0")/utils.sh"
|
||||
|
||||
require_root
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
ENV_FILE="$SCRIPT_DIR/.env"
|
||||
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
echo "ERROR: .env file not found at $ENV_FILE"
|
||||
echo "Create $ENV_FILE with:"
|
||||
echo " MTP_DOMAIN=mtp.example.com"
|
||||
echo " MTP_PORT=10002"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
source "$ENV_FILE"
|
||||
|
||||
: "${MTP_DOMAIN:?MTP_DOMAIN is not set in .env}"
|
||||
: "${MTP_PORT:?MTP_PORT is not set in .env}"
|
||||
|
||||
MTP_STATS_PORT="${MTP_STATS_PORT:-8888}"
|
||||
INTERNAL_HTTPS_PORT=8443
|
||||
|
||||
REAL_USER="${SUDO_USER:-$(whoami)}"
|
||||
REAL_HOME=$(eval echo "~$REAL_USER")
|
||||
MTP_DIR="$REAL_HOME/services/mtp"
|
||||
SERVICE_NAME="mtproxy"
|
||||
|
||||
echo "=== MTProto Proxy Installation ==="
|
||||
echo " MTP Domain: $MTP_DOMAIN"
|
||||
echo " MTP Port: $MTP_PORT (internal)"
|
||||
echo " Stats Port: $MTP_STATS_PORT"
|
||||
echo " Directory: $MTP_DIR"
|
||||
echo ""
|
||||
|
||||
# --- 1. Build MTProxy from source ---
|
||||
|
||||
mkdir -p "$MTP_DIR"
|
||||
|
||||
if [ -x "$MTP_DIR/mtproto-proxy" ]; then
|
||||
echo "[1] MTProxy already installed"
|
||||
else
|
||||
echo "[1] Building MTProxy from source..."
|
||||
|
||||
for pkg in git curl build-essential libssl-dev zlib1g-dev xxd; do
|
||||
if ! dpkg -l "$pkg" >/dev/null 2>&1; then
|
||||
NEED_INSTALL="${NEED_INSTALL:-} $pkg"
|
||||
fi
|
||||
done
|
||||
if [ -n "${NEED_INSTALL:-}" ]; then
|
||||
echo " Installing build dependencies:$NEED_INSTALL"
|
||||
apt-get update -y -qq
|
||||
apt-get install -y -qq $NEED_INSTALL
|
||||
fi
|
||||
|
||||
BUILD_DIR=$(mktemp -d)
|
||||
git clone --depth 1 https://github.com/TelegramMessenger/MTProxy.git "$BUILD_DIR"
|
||||
|
||||
echo " Compiling (this may take a minute)..."
|
||||
make -C "$BUILD_DIR" -j"$(nproc)" > /dev/null 2>&1 || {
|
||||
echo "ERROR: Build failed. Full output:"
|
||||
make -C "$BUILD_DIR" -j"$(nproc)"
|
||||
exit 1
|
||||
}
|
||||
|
||||
cp "$BUILD_DIR/objs/bin/mtproto-proxy" "$MTP_DIR/"
|
||||
chmod +x "$MTP_DIR/mtproto-proxy"
|
||||
rm -rf "$BUILD_DIR"
|
||||
|
||||
echo " Build successful"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# --- 2. Generate secrets & download configs ---
|
||||
|
||||
echo "[2] Generating configuration..."
|
||||
|
||||
curl -sf https://core.telegram.org/getProxySecret -o "$MTP_DIR/proxy-secret" || {
|
||||
echo "ERROR: Failed to download proxy-secret from core.telegram.org"
|
||||
exit 1
|
||||
}
|
||||
echo " Downloaded proxy-secret"
|
||||
|
||||
curl -sf https://core.telegram.org/getProxyConfig -o "$MTP_DIR/proxy-multi.conf" || {
|
||||
echo "ERROR: Failed to download proxy-multi.conf from core.telegram.org"
|
||||
exit 1
|
||||
}
|
||||
echo " Downloaded proxy-multi.conf"
|
||||
|
||||
if [ -f "$MTP_DIR/secret.txt" ]; then
|
||||
SECRET=$(cat "$MTP_DIR/secret.txt")
|
||||
echo " Using existing secret: $SECRET"
|
||||
else
|
||||
if ! command -v xxd >/dev/null 2>&1; then
|
||||
apt-get install -y -qq xxd
|
||||
fi
|
||||
SECRET=$(head -c 16 /dev/urandom | xxd -ps)
|
||||
echo "$SECRET" > "$MTP_DIR/secret.txt"
|
||||
echo " Generated secret: $SECRET"
|
||||
fi
|
||||
|
||||
DOMAIN_HEX=$(echo -n "$MTP_DOMAIN" | xxd -ps | tr -d '\n')
|
||||
CLIENT_SECRET="ee${SECRET}${DOMAIN_HEX}"
|
||||
|
||||
echo " Client secret (fake-TLS): $CLIENT_SECRET"
|
||||
echo ""
|
||||
|
||||
# --- 3. Systemd service ---
|
||||
|
||||
echo "[3] Creating systemd service..."
|
||||
|
||||
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
|
||||
[Unit]
|
||||
Description=MTProto Proxy
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/usr/bin/curl -sf -o ${MTP_DIR}/proxy-multi.conf https://core.telegram.org/getProxyConfig
|
||||
ExecStart=${MTP_DIR}/mtproto-proxy -u nobody -p ${MTP_STATS_PORT} -H ${MTP_PORT} -S ${SECRET} -D ${MTP_DOMAIN} --aes-pwd ${MTP_DIR}/proxy-secret ${MTP_DIR}/proxy-multi.conf -M 1
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
LimitNOFILE=65535
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable "$SERVICE_NAME" --quiet
|
||||
systemctl restart "$SERVICE_NAME"
|
||||
|
||||
sleep 2
|
||||
if systemctl is-active --quiet "$SERVICE_NAME"; then
|
||||
echo " Service $SERVICE_NAME started"
|
||||
else
|
||||
echo "ERROR: Service $SERVICE_NAME failed to start"
|
||||
journalctl -u "$SERVICE_NAME" --no-pager -n 15
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# --- 4. Nginx stream SNI routing ---
|
||||
|
||||
echo "[4] Setting up nginx stream SNI routing..."
|
||||
|
||||
if ! dpkg -l libnginx-mod-stream 2>/dev/null | grep -q '^ii'; then
|
||||
echo " Installing libnginx-mod-stream..."
|
||||
apt-get install -y -qq libnginx-mod-stream
|
||||
fi
|
||||
|
||||
# Patch all existing HTTPS sites: listen 443 ssl -> listen 8443 ssl
|
||||
for conf in /etc/nginx/sites-available/*; do
|
||||
[ -f "$conf" ] || continue
|
||||
if grep -q 'listen 443 ssl' "$conf" 2>/dev/null; then
|
||||
sed -i "s/listen 443 ssl/listen ${INTERNAL_HTTPS_PORT} ssl/" "$conf"
|
||||
echo " Patched $(basename "$conf"): 443 -> $INTERNAL_HTTPS_PORT"
|
||||
fi
|
||||
done
|
||||
|
||||
if grep -q 'stream {' /etc/nginx/nginx.conf 2>/dev/null; then
|
||||
echo " Stream block already exists in nginx.conf"
|
||||
else
|
||||
cat >> /etc/nginx/nginx.conf <<STREAM
|
||||
|
||||
stream {
|
||||
map \$ssl_preread_server_name \$backend {
|
||||
${MTP_DOMAIN} mtp_backend;
|
||||
default web_backend;
|
||||
}
|
||||
|
||||
upstream mtp_backend {
|
||||
server 127.0.0.1:${MTP_PORT};
|
||||
}
|
||||
|
||||
upstream web_backend {
|
||||
server 127.0.0.1:${INTERNAL_HTTPS_PORT};
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
ssl_preread on;
|
||||
proxy_pass \$backend;
|
||||
}
|
||||
}
|
||||
STREAM
|
||||
echo " Added stream block to nginx.conf"
|
||||
fi
|
||||
|
||||
nginx -t || { echo "ERROR: nginx config test failed"; exit 1; }
|
||||
systemctl reload nginx
|
||||
echo " Nginx configured and reloaded"
|
||||
echo ""
|
||||
|
||||
# --- 5. Firewall ---
|
||||
|
||||
if command -v ufw >/dev/null 2>&1; then
|
||||
ufw allow 443/tcp comment 'HTTPS + MTProxy' >/dev/null 2>&1 || true
|
||||
echo "[5] UFW: port 443 allowed"
|
||||
else
|
||||
echo "[5] UFW not installed, skipping firewall rule"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# --- 6. Fix ownership & output ---
|
||||
|
||||
chown -R "$REAL_USER:$REAL_USER" "$MTP_DIR"
|
||||
|
||||
MTP_LINK="tg://proxy?server=${MTP_DOMAIN}&port=443&secret=${CLIENT_SECRET}"
|
||||
HTTPS_LINK="https://t.me/proxy?server=${MTP_DOMAIN}&port=443&secret=${CLIENT_SECRET}"
|
||||
|
||||
cat > "$MTP_DIR/connection.txt" <<INFO
|
||||
MTProxy Admin Bot: ${MTP_DOMAIN}:443
|
||||
Secret: ${SECRET}
|
||||
Client secret (fake-TLS): ${CLIENT_SECRET}
|
||||
|
||||
tg:// link: ${MTP_LINK}
|
||||
https: link: ${HTTPS_LINK}
|
||||
INFO
|
||||
chown "$REAL_USER:$REAL_USER" "$MTP_DIR/connection.txt"
|
||||
|
||||
echo "=== MTPROTO PROXY READY ==="
|
||||
echo ""
|
||||
echo " For MTProxy Admin Bot: ${MTP_DOMAIN}:443"
|
||||
echo ""
|
||||
echo " tg:// ${MTP_LINK}"
|
||||
echo " https: ${HTTPS_LINK}"
|
||||
echo ""
|
||||
echo "Saved to: $MTP_DIR/connection.txt"
|
||||
@ -23,6 +23,13 @@ source "$ENV_FILE"
|
||||
: "${VLESS_WS_PATH:?VLESS_WS_PATH is not set in .env}"
|
||||
: "${PORT:?PORT is not set in .env}"
|
||||
|
||||
# If nginx stream SNI routing is active, HTTPS listens on internal port
|
||||
if grep -q 'stream {' /etc/nginx/nginx.conf 2>/dev/null; then
|
||||
HTTPS_LISTEN_PORT=8443
|
||||
else
|
||||
HTTPS_LISTEN_PORT=443
|
||||
fi
|
||||
|
||||
REAL_USER="${SUDO_USER:-$(whoami)}"
|
||||
REAL_HOME=$(eval echo "~$REAL_USER")
|
||||
VLESS_DIR="$REAL_HOME/services/vless"
|
||||
@ -234,7 +241,7 @@ server {
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen ${HTTPS_LISTEN_PORT} ssl;
|
||||
http2 on;
|
||||
server_name ${DOMAIN};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user