136 lines
6.7 KiB
Bash
Executable File
136 lines
6.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# transparent-proxy.sh — Настройка прозрачного прокси для подсети TV через tproxy
|
||
# Запускать от root: sudo bash transparent-proxy.sh
|
||
set -euo pipefail
|
||
|
||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
|
||
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
|
||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||
error() { echo -e "${RED}[ERR]${NC} $*"; exit 1; }
|
||
|
||
[[ $EUID -ne 0 ]] && error "Запускай от root (sudo bash transparent-proxy.sh)"
|
||
|
||
### ── Параметры ────────────────────────────────────────────────────────────
|
||
PARAMS_FILE="/etc/xray/params.env"
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
||
if [[ -f "$PARAMS_FILE" ]]; then
|
||
source "$PARAMS_FILE"
|
||
elif [[ -f "$SCRIPT_DIR/params.env" ]]; then
|
||
source "$SCRIPT_DIR/params.env"
|
||
else
|
||
error "Файл параметров не найден: $PARAMS_FILE"
|
||
fi
|
||
|
||
: "${TV_SUBNET:?Укажи TV_SUBNET в params.env (например: 192.168.3.0/24)}"
|
||
: "${VLESS_SERVER_IP:?Укажи VLESS_SERVER_IP в params.env}"
|
||
|
||
TPROXY_PORT=12345
|
||
TPROXY_MARK=1
|
||
|
||
info "TV подсеть: $TV_SUBNET"
|
||
info "Tproxy порт: $TPROXY_PORT"
|
||
info "VLESS сервер: $VLESS_SERVER_IP"
|
||
|
||
### ── Модули ядра ──────────────────────────────────────────────────────────
|
||
info "Загружаю модули ядра..."
|
||
modprobe xt_TPROXY 2>/dev/null || warn "xt_TPROXY не загружен (возможно уже встроен)"
|
||
modprobe xt_mark 2>/dev/null || true
|
||
modprobe xt_socket 2>/dev/null || true
|
||
|
||
### ── Сброс старых правил ──────────────────────────────────────────────────
|
||
info "Сбрасываю старые правила TV_TPROXY..."
|
||
iptables -t mangle -D PREROUTING -j TV_TPROXY 2>/dev/null || true
|
||
iptables -t mangle -F TV_TPROXY 2>/dev/null || true
|
||
iptables -t mangle -X TV_TPROXY 2>/dev/null || true
|
||
|
||
ip rule del fwmark "$TPROXY_MARK" table 100 2>/dev/null || true
|
||
ip route del local default dev lo table 100 2>/dev/null || true
|
||
|
||
### ── IP rule + route для tproxy ──────────────────────────────────────────
|
||
info "Настраиваю ip rule и ip route..."
|
||
ip rule add fwmark "$TPROXY_MARK" table 100
|
||
ip route add local default dev lo table 100
|
||
|
||
### ── iptables mangle — цепочка TV_TPROXY ─────────────────────────────────
|
||
info "Создаю iptables цепочку TV_TPROXY..."
|
||
iptables -t mangle -N TV_TPROXY
|
||
|
||
# Не трогаем трафик до самого сервера Xray (чтоб не зациклилось)
|
||
iptables -t mangle -A TV_TPROXY -d "$VLESS_SERVER_IP/32" -j RETURN
|
||
|
||
# Не трогаем локальные/private диапазоны
|
||
for NET in 0.0.0.0/8 127.0.0.0/8 169.254.0.0/16 192.168.0.0/16 \
|
||
172.16.0.0/12 10.0.0.0/8 224.0.0.0/4 240.0.0.0/4; do
|
||
iptables -t mangle -A TV_TPROXY -d "$NET" -j RETURN
|
||
done
|
||
|
||
# TCP трафик TV подсети → tproxy на порт 12345
|
||
iptables -t mangle -A TV_TPROXY \
|
||
-s "$TV_SUBNET" -p tcp \
|
||
-j TPROXY --tproxy-mark "$TPROXY_MARK" --on-port "$TPROXY_PORT"
|
||
|
||
# UDP трафик TV подсети → tproxy на порт 12345
|
||
iptables -t mangle -A TV_TPROXY \
|
||
-s "$TV_SUBNET" -p udp \
|
||
-j TPROXY --tproxy-mark "$TPROXY_MARK" --on-port "$TPROXY_PORT"
|
||
|
||
# Применяем цепочку к PREROUTING
|
||
iptables -t mangle -A PREROUTING -j TV_TPROXY
|
||
|
||
### ── DNS через прокси (перенаправление UDP 53 из TV подсети) ──────────────
|
||
info "Настраиваю перехват DNS для TV подсети..."
|
||
# Перехватываем DNS запросы из TV подсети и редиректим на локальный DNS (через прокси)
|
||
iptables -t nat -D PREROUTING -s "$TV_SUBNET" -p udp --dport 53 \
|
||
-j REDIRECT --to-ports 53 2>/dev/null || true
|
||
iptables -t nat -A PREROUTING -s "$TV_SUBNET" -p udp --dport 53 \
|
||
-j DNAT --to-destination 1.1.1.1
|
||
|
||
# Xray обработает DNS через VLESS outbound (доменные запросы уйдут через тоннель)
|
||
|
||
### ── Сохранение правил через iptables-persistent ─────────────────────────
|
||
info "Сохраняю iptables правила..."
|
||
if command -v netfilter-persistent &>/dev/null; then
|
||
netfilter-persistent save
|
||
else
|
||
iptables-save > /etc/iptables/rules.v4
|
||
fi
|
||
|
||
### ── Скрипт восстановления правил при перезагрузке ──────────────────────
|
||
info "Создаю /etc/network/if-up.d/tproxy-routes для восстановления ip rule/route..."
|
||
cat > /etc/network/if-up.d/tproxy-routes <<SCRIPT
|
||
#!/bin/sh
|
||
ip rule add fwmark ${TPROXY_MARK} table 100 2>/dev/null || true
|
||
ip route add local default dev lo table 100 2>/dev/null || true
|
||
SCRIPT
|
||
chmod +x /etc/network/if-up.d/tproxy-routes
|
||
|
||
# Также через systemd (более надёжно на Ubuntu)
|
||
cat > /etc/systemd/system/tproxy-routes.service <<UNIT
|
||
[Unit]
|
||
Description=Restore tproxy ip rules and routes
|
||
After=network.target
|
||
|
||
[Service]
|
||
Type=oneshot
|
||
ExecStart=/sbin/ip rule add fwmark ${TPROXY_MARK} table 100
|
||
ExecStart=/sbin/ip route add local default dev lo table 100
|
||
RemainAfterExit=yes
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
UNIT
|
||
systemctl daemon-reload
|
||
systemctl enable tproxy-routes
|
||
|
||
### ── Итог ─────────────────────────────────────────────────────────────────
|
||
echo ""
|
||
info "══════════════════════════════════════════════════════"
|
||
info " Прозрачный прокси настроен!"
|
||
info " Весь TCP/UDP трафик из $TV_SUBNET"
|
||
info " направляется через Xray tproxy (порт $TPROXY_PORT)"
|
||
info ""
|
||
info " Следующий шаг: подключи телевизор к SSID с шлюзом"
|
||
info " $(hostname -I | awk '{print $1}') и проверь: bash check.sh"
|
||
info "══════════════════════════════════════════════════════"
|