234 lines
6.1 KiB
Bash
234 lines
6.1 KiB
Bash
#!/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"
|