#!/bin/bash # Цвета для вывода GRN='\033[1;32m' RED='\033[1;31m' YEL='\033[1;33m' NC='\033[0m' # No Color [[ $EUID -eq 0 ]] || { echo -e "${RED}❌ скрипту нужны root права ${NC}"; exit 1; } DOMAIN=$1 shift VLESS_URLS=("$@") if [ -z "$DOMAIN" ]; then echo -e "${RED}❌ Ошибка: домен не задан.${NC}" exit 1 fi if [ ${#VLESS_URLS[@]} -eq 0 ]; then echo -e "${RED}❌ Ошибка: конфиги vless не заданы. Укажите хотя бы одну vless:// ссылку.${NC}" exit 1 fi # Функция URL-декодинга urldecode() { printf '%b' "${1//%/\\x}" } COUNT=${#VLESS_URLS[@]} echo -e "${GRN}Обнаружено $COUNT vless ссылок для моста!${NC}" # Массивы для хранения параметров каждой ноды declare -a NODE_UUID NODE_ADDR NODE_PORT NODE_NAME NODE_TYPE NODE_SEC NODE_FP NODE_SNI NODE_PBK NODE_SID NODE_SPX NODE_MODE NODE_PATH NODE_EXTRA # Уникальные UUID для сервера-моста (RU) declare -a BRIDGE_UUID # Генерируем базовый UUID сервера для всех подключений (будет один клиент в конфиге сервера) SERVER_UUID=$(openssl rand -hex 16 | sed 's/\(........\)\(....\)\(....\)\(....\)\(............\)/\1-\2-\3-\4-\5/') # Разбиваем UUID на группы для удобной подмены 3-й группы (7 и 8 байты) g1="${SERVER_UUID:0:8}" g2="${SERVER_UUID:9:4}" g3="${SERVER_UUID:14:4}" g4="${SERVER_UUID:19:4}" g5="${SERVER_UUID:24:12}" for (( i=0; i/dev/null) if [ "$bbr" = "bbr" ]; then echo -e "${GRN}BBR уже запущен${NC}" else echo "net.core.default_qdisc=fq" > /etc/sysctl.d/999-autoXRAY.conf echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.d/999-autoXRAY.conf sysctl --system echo -e "${GRN}BBR активирован${NC}" fi cat < /etc/security/limits.d/99-autoXRAY.conf * soft nofile 1048576 * hard nofile 1048576 root soft nofile 1048576 root hard nofile 1048576 EOF ulimit -n 65535 echo -e "${GRN}Лимиты применены. Текущий ulimit -n: $(ulimit -n) ${NC}" # Блок CERTBOT - START # Определяем путь к конфигу nginx if [ -f /etc/nginx/sites-available/default ]; then CONFIG_PATH="/etc/nginx/sites-available/default" echo -e "${GRN}Обнаружена стандартная сборка nginx. ${NC}" elif [ -f /etc/nginx/conf.d/default.conf ]; then CONFIG_PATH="/etc/nginx/conf.d/default.conf" echo -e "${YEL}Обнаружена нестандартная сборка nginx. Предварительная настройка NGINX для CERTBOT ${NC}" mkdir -p /var/www/html # Записываем временный конфиг cat < "$CONFIG_PATH" server { listen 80 default_server; server_name _; location /.well-known/acme-challenge/ { root /var/www/html; allow all; } location / { return 301 https://\$host\$request_uri; } } EOF systemctl reload nginx else echo -e "${RED}Не найден ни один default конфиг nginx${NC}" exit 1 fi certbot certonly --webroot -w /var/www/html \ -d $DOMAIN \ -m mail@$DOMAIN \ --agree-tos --non-interactive \ --deploy-hook "systemctl reload nginx" RET=$? if [ $RET -eq 0 ]; then echo -e "\n${GRN}========================================" echo "✅ Команда certbot успешно выполнена" echo "✅ Сертификат https от letsencrypt ПОЛУЧЕН" echo "========================================" echo -e "${NC}" else echo -e "\n${RED}========================================" echo "❌ CERTBOT ЗАВЕРШИЛСЯ С ОШИБКОЙ" echo "❌ Сертификат https от letsencrypt НЕ ПОЛУЧЕН!" echo "❌ Смотрите выше логи процесса получения сертификата" echo "❌ Код возврата: $RET" echo "========================================" echo -e "${NC}" exit 1 fi # Блок CERTBOT - END path_subpage=$(openssl rand -base64 15 | tr -dc 'A-Za-z0-9' | head -c 20) # конфиг nginx cat < "$CONFIG_PATH" server { server_name $DOMAIN; listen unix:/dev/shm/nginx.sock ssl http2 proxy_protocol; set_real_ip_from unix:; real_ip_header proxy_protocol; root /var/www/$DOMAIN; index index.php index.html; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; ssl_session_tickets off; ssl_certificate "/etc/letsencrypt/live/$DOMAIN/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/$DOMAIN/privkey.pem"; location = /${path_subpage}.json { add_header profile-title "base64:YXV0b1hSQVk="; add_header routing "happ://routing/onadd/eyJOYW1lIjoiYXV0b1hSQVkiLCJHbG9iYWxQcm94eSI6InRydWUiLCJSb3V0ZU9yZGVyIjoiYmxvY2stcHJveHktZGlyZWN0IiwiUmVtb3RlRE5TVHlwZSI6IkRvSCIsIlJlbW90ZUROU0RvbWFpbiI6Imh0dHBzOi8vZG5zLmdvb2dsZS9kbnMtcXVlcnkiLCJSZW1vdGVETlNJUCI6IjguOC40LjQiLCJEb21lc3RpY0ROU1R5cGUiOiJEb0giLCJEb21lc3RpY0ROU0RvbWFpbiI6Imh0dHBzOi8vY2xvdWRmbGFyZS1kbnMuY29tL2Rucy1xdWVyeSIsIkRvbWVzdGljRE5TSVAiOiIxLjEuMS4xIiwiR2VvaXB1cmwiOiJodHRwczovL2dpdGh1Yi5jb20vTG95YWxzb2xkaWVyL3YycmF5LXJ1bGVzLWRhdC9yZWxlYXNlcy9sYXRlc3QvZG93bmxvYWQvZ2VvaXAuZGF0IiwiR2Vvc2l0ZXVybCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9Mb3lhbHNvbGRpZXIvdjJyYXktcnVsZXMtZGF0L3JlbGVhc2VzL2xhdGVzdC9kb3dubG9hZC9nZW9zaXRlLmRhdCIsIkxhc3RVcGRhdGVkIjoiMTc3NTIwNjEwOCIsIkRuc0hvc3RzIjp7fSwiRGlyZWN0U2l0ZXMiOlsiZ2Vvc2l0ZTpjYXRlZ29yeS1ydSIsImdlb3NpdGU6cHJpdmF0ZSJdLCJEaXJlY3RJcCI6WyJnZW9pcDpwcml2YXRlIl0sIlByb3h5U2l0ZXMiOltdLCJQcm94eUlwIjpbXSwiQmxvY2tTaXRlcyI6WyJnZW9zaXRlOmNhdGVnb3J5LWFkcyIsImdlb3NpdGU6d2luLXNweSJdLCJCbG9ja0lwIjpbXSwiRG9tYWluU3RyYXRlZ3kiOiJJUElmTm9uTWF0Y2giLCJGYWtlRE5TIjoiZmFsc2UiLCJVc2VDaHVua0ZpbGVzIjoiZmFsc2UifQ"; add_header routing-enable 0; } location ~ /\.ht { deny all; } } server { listen 80; server_name $DOMAIN; location /.well-known/acme-challenge/ { root /var/www/html; } location / { return 301 https://\$host\$request_uri; } } EOF systemctl restart nginx # Создание директории WEB_PATH="/var/www/$DOMAIN" mkdir -p "$WEB_PATH" # Генерируем сайт маскировку bash -c "$(curl -sL https://github.com/xVRVx/autoXRAY/raw/refs/heads/main/test/gen_page2.sh)" -- "$WEB_PATH" # Установка Xray bash -c "$(curl -sL https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install SCRIPT_DIR=/usr/local/etc/xray # Генерируем глобальные ключи для сервера-моста key_output=$(xray x25519) xray_privateKey_vrv=$(echo "$key_output" | awk -F': ' '/PrivateKey/ {print $2}') xray_publicKey_vrv=$(echo "$key_output" | awk -F': ' '/Password/ {print $2}') xray_shortIds_vrv=$(openssl rand -hex 8) path_xhttp=$(openssl rand -base64 15 | tr -dc 'a-z0-9' | head -c 6) socksUser=$(openssl rand -base64 16 | tr -dc 'A-Za-z0-9' | head -c 6) socksPasw=$(openssl rand -base64 32 | tr -dc 'A-Za-z0-9' | head -c 16) # ====СОЗДАНИЕ КОНФИГА СЕРВЕРА В ЦИКЛЕ ==== ROUTING_RULES="" OUTBOUNDS="" for (( i=0; i "$SCRIPT_DIR/config.json" { "log": { "dnsLog": false, "access": "/var/log/xray/access.log", "error": "/var/log/xray/error.log", "loglevel": "none" }, "burstObservatory": { "pingConfig": { "timeout": "3s", "interval": "40s", "sampling": 1, "destination": "https://www.gstatic.com/generate_204", "connectivity": "" }, "subjectSelector": [ "proxy" ] }, "dns": { "servers": [ "https+local://8.8.4.4/dns-query", "https+local://8.8.8.8/dns-query", "https+local://1.1.1.1/dns-query", "localhost" ], "queryStrategy": "UseIP" }, "inbounds": [ { "tag": "RUbrEUraw", "port": 443, "listen": "0.0.0.0", "protocol": "vless", "settings": { "clients": [ { "flow": "xtls-rprx-vision", "id": "$SERVER_UUID" } ], "decryption": "none", "fallbacks": [ { "dest": "3333", "xver": 2 } ] }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls", "quic" ] }, "streamSettings": { "network": "raw", "security": "reality", "sockopt": { "acceptProxyProtocol": false }, "realitySettings": { "show": false, "xver": 2, "target": "${TARGET_MTP}", "spiderX": "/", "shortIds": [ "$xray_shortIds_vrv" ], "privateKey": "$xray_privateKey_vrv", "serverNames": [ "$DOMAIN" ] } } }, { "tag": "RUbrEUxhttp", "port": 3333, "listen": "127.0.0.1", "protocol": "vless", "settings": { "clients": [ { "id": "$SERVER_UUID" } ], "decryption": "none" }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls", "quic" ] }, "streamSettings": { "network": "xhttp", "xhttpSettings": { "mode": "stream-one", "path": "/$path_xhttp", "acceptProxyProtocol": false }, "security": "none", "sockopt": { "acceptProxyProtocol": true } } }, { "tag": "RUsocks5", "port": 10443, "listen": "0.0.0.0", "protocol": "mixed", "settings": { "ip": "0.0.0.0", "udp": true, "auth": "password", "accounts": [ { "user": "$socksUser", "pass": "$socksPasw" } ] } } ], "outbounds": [ $OUTBOUNDS { "tag": "direct", "protocol": "freedom", "settings": { "domainStrategy": "ForceIPv4" } }, { "tag": "block", "protocol": "blackhole" } ], "routing": { "domainMatcher": "hybrid", "domainStrategy": "IPIfNonMatch", "balancers": [ { "tag": "Super_Balancer", "selector": [ "proxy" ], "strategy": { "type": "leastLoad", "settings": { "maxRTT": "1s", "expected": $COUNT, "baselines": [ "1s" ], "tolerance": 0.01 } }, "fallbackTag": "direct" } ], "rules": [ { "ip": [ "geoip:private" ], "outboundTag": "block" }, { "port": "25", "outboundTag": "block" }, { "protocol": [ "bittorrent" ], "outboundTag": "block" }, { "domain": [ "geosite:category-ads", "geosite:win-spy", "geosite:private" ], "outboundTag": "block" }, { "domain": [ "habr.com", "apkmirror.com", "ifconfig.me", "checkip.amazonaws.com", "pify.org", "geosite:category-ip-geo-detect" ], "balancerTag": "Super_Balancer" }, { "domain": [ "testipv6.net", "geosite:apple", "geosite:apple-pki", "geosite:yandex", "geosite:vk", "geosite:category-ru" ], "outboundTag": "direct" }, { "inboundTag": [ "RUsocks5" ], "balancerTag": "Super_Balancer" }, $ROUTING_RULES ] } } EOF # Создаем JSON конфигурацию клиента print_config() { local PROXY_OUTBOUND="$1" local REMARK="$2" cat << TPL { "log": { "loglevel": "warning" }, "dns": { "servers":[ "https://8.8.4.4/dns-query", "https://8.8.8.8/dns-query", "https://1.1.1.1/dns-query" ], "queryStrategy": "UseIPv4" }, "routing": { "domainMatcher": "hybrid", "domainStrategy": "IPIfNonMatch", "rules":[ { "domain":[ "geosite:category-ads", "geosite:win-spy" ], "outboundTag": "block" }, { "protocol":[ "bittorrent" ], "outboundTag": "direct" }, { "domain":[ "habr.com", "apkmirror.com" ], "outboundTag": "proxy" }, { "domain":[ "geosite:private", "ifconfig.me", "checkip.amazonaws.com", "pify.org", "geosite:category-ip-geo-detect", "geosite:apple", "geosite:apple-pki", "geosite:yandex", "geosite:vk", "geosite:category-ru" ], "outboundTag": "direct" }, { "ip":[ "geoip:private" ], "outboundTag": "direct" } ] }, "inbounds":[ { "tag": "socks-in", "protocol": "socks", "listen": "127.0.0.1", "port": 10808, "settings": { "udp": true }, "sniffing": { "enabled": true, "destOverride":[ "http", "tls", "quic" ] } }, { "tag": "socks-sb", "protocol": "socks", "listen": "127.0.0.1", "port": 2080, "settings": { "udp": true }, "sniffing": { "enabled": true, "destOverride":[ "http", "tls", "quic" ] } }, { "tag": "http-in", "protocol": "http", "listen": "127.0.0.1", "port": 10809, "sniffing": { "enabled": true, "destOverride":[ "http", "tls", "quic" ] } } ], "outbounds":[ $PROXY_OUTBOUND, { "tag": "direct", "protocol": "freedom" }, { "tag": "block", "protocol": "blackhole" } ], "remarks": "$REMARK" } TPL } CLIENT_CONFIGS="" declare -a CONFIGS_ARRAY ALL_LINKS_TEXT="" # Цикл генерации клиентов по каждой ссылке for (( i=0; iEU xhttp | $REMARK_BASE")" CLIENT_CONFIGS+="," CLIENT_CONFIGS+="$(print_config "$OUT_REALITY_VISION" "🇷🇺 RU>EU raw | $REMARK_BASE")" CLIENT_CONFIGS+="," CLIENT_CONFIGS+="$(print_config "$OUT_DIRECT_EU" "🇪🇺 EU dir | $REMARK_BASE")" if [ $i -lt $((COUNT-1)) ]; then CLIENT_CONFIGS+="," fi # --- Генерируем ссылки vless:// для HTML странички (с портом моста) --- link_xhttp="vless://${BRIDGE_UUID[$i]}@$DOMAIN:$SERVER_PORT?security=reality&type=xhttp&headerType=&path=%2F$path_xhttp&host=&mode=stream-one&extra=%7B%22xmux%22%3A%7B%22cMaxReuseTimes%22%3A%221000-3000%22%2C%22maxConcurrency%22%3A%223-5%22%2C%22maxConnections%22%3A0%2C%22hKeepAlivePeriod%22%3A0%2C%22hMaxRequestTimes%22%3A%22400-700%22%2C%22hMaxReusableSecs%22%3A%221200-1800%22%7D%2C%22headers%22%3A%7B%7D%2C%22noGRPCHeader%22%3Afalse%2C%22xPaddingBytes%22%3A%22400-800%22%2C%22scMaxEachPostBytes%22%3A1500000%2C%22scMinPostsIntervalMs%22%3A20%2C%22scStreamUpServerSecs%22%3A%2260-240%22%7D&sni=$DOMAIN&fp=$fpBro&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#RU%3EEU_xhttp_$REMARK_BASE" link_raw="vless://${BRIDGE_UUID[$i]}@$DOMAIN:$SERVER_PORT?security=reality&type=tcp&headerType=&path=&host=&flow=xtls-rprx-vision&sni=$DOMAIN&fp=$fpBro&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#RU%3EEU_raw_$REMARK_BASE" CONFIGS_ARRAY+=( "XHTTP (RU>EU $REMARK_BASE)|$link_xhttp" ) CONFIGS_ARRAY+=( "RAW VISION (RU>EU $REMARK_BASE)|$link_raw" ) CONFIGS_ARRAY+=( "Direct EU ($REMARK_BASE)|${VLESS_URLS[$i]}" ) done # Записываем массив в файл подписки echo "[$CLIENT_CONFIGS]" > "$WEB_PATH/$path_subpage.json" systemctl restart xray echo -e "Перезапуск XRAY" subPageLink="https://$DOMAIN/$path_subpage.json" configListLink="https://$DOMAIN/$path_subpage.html" if [ "$INSTALL_MTP" = true ]; then echo -e "\n\n${GRN}Устанавливаем MTProto FakeTLS ${NC}" source <(curl -sL https://github.com/xVRVx/autoXRAY/raw/refs/heads/main/test/telemt-test.sh) else echo -e "\n\n${YEL}Установка MTProto FakeTLS пропущена.${NC}" MTProto="" fi echo -e "\n\n${GRN}Создаем страницу подписки ${NC}" cat > "$WEB_PATH/$path_subpage.html" <<'EOF' autoXRAY bridge configs EOF cat >> "$WEB_PATH/$path_subpage.html" <📂 Ссылка на подписку (готовый конфиг клиента с роутингом)
Subscription

📱 Приложение HAPP (Windows/Android/iOS/MAC/Linux)

Маршрутизацию нужно выключить, она тут встроенная. По умолчанию она выключена - включается, если вы пользовались сторонними сервисами.

➡️ Конфиги ($COUNT VPS x 3 протокола)

EOF # Вывод строк конфигов idx=1 for item in "${CONFIGS_ARRAY[@]}"; do title="${item%%|*}" link="${item#*|}" if [ -z "$ALL_LINKS_TEXT" ]; then ALL_LINKS_TEXT="$link"; else ALL_LINKS_TEXT="$ALL_LINKS_TEXT
$link"; fi cat >> "$WEB_PATH/$path_subpage.html" <
$title
$link
EOF ((idx++)) done SOCKS5_url_tg="tg://socks?server=$DOMAIN&port=10443&user=${socksUser}&pass=${socksPasw}" SOCKS5_url="${socksUser}:${socksPasw}@$DOMAIN:10443" # Добавляем socks5 блок cat >> "$WEB_PATH/$path_subpage.html" <
socks5 WARNING
${SOCKS5_url}
EOF # Добавляем MTProxy блок только если он установлен if [ "$INSTALL_MTP" = true ]; then cat >> "$WEB_PATH/$path_subpage.html" <
MTProtoFakeTLS (TG)
${MTProto}
✈️ Add to TG EOF fi # Дописываем конец страницы cat >> "$WEB_PATH/$path_subpage.html" <💠 Все конфиги вместе
$ALL_LINKS_TEXT
EOF # --- ФИНАЛЬНАЯ ПРОВЕРКА --- echo -e "\n${YEL}=== Финальная проверка статусов ===${NC}" if [ "$INSTALL_MTP" = true ]; then if systemctl is-active --quiet telemt; then echo -e "Telemt: ${GRN}RUNNING${NC}"; else echo -e "Telemt: ${RED}STOPPED/ERROR${NC}"; fi fi if systemctl is-active --quiet nginx; then echo -e "Nginx: ${GRN}RUNNING${NC}"; else echo -e "Nginx: ${RED}STOPPED/ERROR${NC}"; fi if systemctl is-active --quiet xray; then echo -e "XRAY: ${GRN}RUNNING${NC}"; else echo -e "XRAY: ${RED}STOPPED/ERROR${NC}"; fi echo -e "\n" if [ "$INSTALL_MTP" = true ]; then echo -e "${YEL}MTProto FakeTLS для ТГ${NC}\n$MTProto\n" fi echo -e " ${YEL}✅ Сгенерировано мостов: ${GRN}$COUNT${NC} ${YEL}Ваша json страничка подписки ${NC} ${GRN}$subPageLink${NC} ${YEL}Ссылка на сохраненные конфиги (Web UI) ${NC} ${GRN}$configListLink ${NC} Скопируйте подписку в специализированное приложение: - iOS: Happ или v2RayTun или v2rayN - Android: Happ или v2RayTun или v2rayNG - Windows: конфиги Happ или winLoadXRAY или v2rayN для vless v2RayTun или Throne Открыт локальный socks5 на порту 10443. Внутри клиента: socks5 на 10808, 2080 и http на 10809. ${GRN}Поддержать автора: https://github.com/xVRVx/autoXRAY ${NC} "