#!/bin/bash DOMAIN=$1 if [ -z "$DOMAIN" ]; then echo "❌ Ошибка: домен не задан." exit 1 fi echo "Обновление и установка необходимых пакетов..." apt update && apt install -y jq dnsutils LOCAL_IP=$(hostname -I | awk '{print $1}') DNS_IP=$(dig +short "$DOMAIN" | grep '^[0-9]') if [ "$LOCAL_IP" != "$DNS_IP" ]; then echo "❌ Внимание: IP-адрес ($LOCAL_IP) не совпадает с A-записью $DOMAIN ($DNS_IP)." echo "Правильно укажите одну A-запись для вашего домена в ДНС - $LOCAL_IP" read -p "Продолжить на ваш страх и риск? (y/N): " choice if [[ ! "$choice" =~ ^[Yy]$ ]]; then echo "Выполнение скрипта прервано." exit 1 fi echo "Продолжение выполнения скрипта..." fi apt install nginx -y systemctl enable --now nginx # Блок CERTBOT - START apt install certbot -y 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\033[1;32m========================================" echo "✅ Команда certbot успешно выполнена" echo "✅ Сертификат https от letsencrypt ПОЛУЧЕН" echo "========================================" echo -e "\033[0m" else echo -e "\n\033[1;31m========================================" echo "❌ CERTBOT ЗАВЕРШИЛСЯ С ОШИБКОЙ" echo "❌ Сертификат https от letsencrypt НЕ ПОЛУЧЕН!" echo "❌ Код возврата: $RET" echo "========================================" echo -e "\033[0m" exit 1 fi # Блок CERTBOT - END CONFIG_PATH="/etc/nginx/sites-available/default" echo "✅ Записываем конфигурацию в $CONFIG_PATH для домена $DOMAIN" bash -c "cat > $CONFIG_PATH" < "$SCRIPT_DIR/config.json" { "log": { "dnsLog": false, "access": "/var/log/xray/access.log", "error": "/var/log/xray/error.log", "loglevel": "none" }, "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": "UseIPv4" }, "inbounds": [ { "tag": "vsRAWrtyXTLS", "port": 443, "listen": "0.0.0.0", "protocol": "vless", "settings": { "clients": [ { "flow": "xtls-rprx-vision", "id": "${xray_uuid_vrv}" } ], "decryption": "none", "fallbacks": [ { "path": "/${path_xhttp}44", "dest": "4444", "xver": 2 }, { "dest": "3333", "xver": 2 } ] }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls", "quic" ] }, "streamSettings": { "network": "raw", "security": "reality", "realitySettings": { "show": false, "xver": 2, "target": "/dev/shm/nginx.sock", "spiderX": "/", "shortIds": [ "${xray_shortIds_vrv}" ], "privateKey": "${xray_privateKey_vrv}", "serverNames": [ "$DOMAIN" ], "limitFallbackUpload": { "afterBytes": 0, "bytesPerSec": 65536, "burstBytesPerSec": 0 }, "limitFallbackDownload": { "afterBytes": 5242880, "bytesPerSec": 262144, "burstBytesPerSec": 2097152 } } } }, { "tag": "vsXHTTPrty", "port": 3333, "listen": "127.0.0.1", "protocol": "vless", "settings": { "clients": [ { "id": "${xray_uuid_vrv}" } ], "decryption": "none" }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls", "quic" ] }, "streamSettings": { "network": "xhttp", "xhttpSettings": { "mode": "auto", "path": "/${path_xhttp}" }, "security": "none", "sockopt": { "acceptProxyProtocol": true } } }, { "tag": "vsRAWrty", "port": 4444, "listen": "127.0.0.1", "protocol": "vless", "settings": { "clients": [ { "id": "${xray_uuid_vrv}" } ], "decryption": "none" }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls", "quic" ] }, "streamSettings": { "network": "raw", "rawSettings": { "acceptProxyProtocol": true, "header": { "type": "http", "request": { "path": [ "/${path_xhttp}44" ] } } }, "security": "none" } }, { "tag": "ShadowSocks2022", "port": 8443, "listen": "0.0.0.0", "protocol": "shadowsocks", "settings": { "method": "2022-blake3-chacha20-poly1305", "password": "${xray_sspasw_vrv}", "network": "tcp,udp" }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls", "quic" ] } }, { "tag": "socks5", "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": [ { "tag": "direct", "protocol": "freedom", "settings": { "domainStrategy": "ForceIPv4" } }, { "tag": "block", "protocol": "blackhole" }, { "tag": "warp", "protocol": "socks", "settings": { "servers": [ { "address": "127.0.0.1", "port": 40000 } ] } } ], "routing": { "rules": [ { "ip": [ "geoip:private" ], "outboundTag": "block" }, { "protocol": [ "bittorrent" ], "outboundTag": "block" }, { "domain": [ "geosite:category-ads", "geosite:win-spy", "geosite:private" ], "outboundTag": "block" }, { "outboundTag": "direct", "domain": ["geosite:google-gemini","geosite:category-ru"] } ], "domainStrategy": "IPIfNonMatch" } } EOF # Создаем JSON конфигурацию клиента #!/bin/bash # 1. Функция-шаблон (содержит повторяющуюся часть: Log, DNS, Routing, Inbounds) 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": { "domainStrategy": "IPIfNonMatch", "rules": [ { "domain": [ "geosite:category-ads", "geosite:win-spy" ], "outboundTag": "block" }, { "protocol": [ "bittorrent" ], "outboundTag": "direct" }, { "domain": [ "geosite:private", "geosite:apple", "geosite:apple-pki", "geosite:huawei", "geosite:xiaomi", "geosite:category-android-app-download", "geosite:f-droid", "geosite:yandex", "geosite:vk", "geosite:microsoft", "geosite:win-update", "geosite:win-extra", "geosite:google-play", "geosite:steam", "geosite:category-ru" ], "outboundTag": "direct" }, { "ip": [ "geoip:private" ], "outboundTag": "direct" }, { "ip": [ "geoip:!ru" ], "outboundTag": "proxy" }, { "domain": [ "geosite:discord", "geosite:youtube", "geosite:tiktok", "geosite:signal" ], "outboundTag": "proxy" } ] }, "inbounds": [ { "tag": "socks-in", "protocol": "socks", "listen": "127.0.0.1", "port": 10808, "settings": { "udp": true } }, { "tag": "socks-sb", "protocol": "socks", "listen": "127.0.0.1", "port": 2080, "settings": { "udp": true } }, { "tag": "http-in", "protocol": "http", "listen": "127.0.0.1", "port": 10809 } ], "outbounds": [ $PROXY_OUTBOUND, { "tag": "direct", "protocol": "freedom" }, { "tag": "block", "protocol": "blackhole" } ], "remarks": "$REMARK" } TPL } # 2. Определяем уникальные настройки (Outbounds) # --- Config 1: VLESS Reality + Vision --- OUT_REALITY_VISION='{ "mux": { "concurrency": -1, "enabled": false }, "tag": "proxy", "protocol": "vless", "settings": { "vnext": [{ "address": "$DOMAIN", "port": 443, "users": [{ "id": "${xray_uuid_vrv}", "flow": "xtls-rprx-vision", "encryption": "none" }] }] }, "streamSettings": { "network": "raw", "security": "reality", "realitySettings": { "show": false, "fingerprint": "chrome", "serverName": "$DOMAIN", "password": "${xray_publicKey_vrv}", "shortId": "${xray_shortIds_vrv}", "spiderX": "/" } } }' # --- Config 2: VLESS Reality + XHTTP (с Extra настройками) --- OUT_REALITY_XHTTP='{ "mux": { "concurrency": -1, "enabled": false }, "tag": "proxy", "protocol": "vless", "settings": { "vnext": [{ "address": "$DOMAIN", "port": 443, "users": [{ "id": "${xray_uuid_vrv}", "encryption": "none" }] }] }, "streamSettings": { "network": "xhttp", "security": "reality", "xhttpSettings": { "mode": "auto", "path": "/${path_xhttp}", "extra": { "noGRPCHeader": false, "scMaxEachPostBytes": 1500000, "scMinPostsIntervalMs": 20, "scStreamUpServerSecs": "60-240", "xPaddingBytes": "400-800", "xmux": { "cMaxReuseTimes": "1000-3000", "hKeepAlivePeriod": 0, "hMaxRequestTimes": "400-700", "hMaxReusableSecs": "1200-1800", "maxConcurrency": "3-5", "maxConnections": 0 } } }, "realitySettings": { "show": false, "fingerprint": "chrome", "serverName": "$DOMAIN", "password": "${xray_publicKey_vrv}", "shortId": "${xray_shortIds_vrv}", "spiderX": "/" } } }' # --- Config 3: VLESS Reality usual MUX--- OUT_REALITY_usual='{ "mux": { "concurrency": 8, "enabled": true, "xudpConcurrency": 16, "xudpProxyUDP443": "reject" }, "tag": "proxy", "protocol": "vless", "settings": { "vnext": [{ "address": "$DOMAIN", "port": 443, "users": [{ "id": "${xray_uuid_vrv}", "flow": "", "encryption": "none" }] }] }, "streamSettings": { "network": "raw", "security": "reality", "realitySettings": { "show": false, "fingerprint": "chrome", "serverName": "$DOMAIN", "password": "${xray_publicKey_vrv}", "shortId": "${xray_shortIds_vrv}", "spiderX": "/" }, "rawSettings": { "header": { "request": { "path": [ "/${path_xhttp}44" ] }, "type": "http" } } } }' # --- Config 4: Shadowsocks 2022 (Port 8443, Chacha20) --- OUT_SS='{ "mux": { "concurrency": -1, "enabled": false }, "tag": "proxy", "protocol": "shadowsocks", "settings": { "servers": [{ "port": 8443, "method": "2022-blake3-chacha20-poly1305", "address": "$DOMAIN", "password": "${xray_sspasw_vrv}" }] } }' # 3. Сборка JSON массива и сохранение в файл ( echo "[" print_config "$OUT_REALITY_VISION" "🇪🇺 vlessRAWrealityXTLS" echo "," print_config "$OUT_REALITY_XHTTP" "🇪🇺 vlessXHTTPrealityEXTRA" echo "," print_config "$OUT_REALITY_usual" "🇪🇺 vlessRAWrealityMUX" echo "," print_config "$OUT_SS" "🇪🇺 ShadowS2022blake3" echo "]" ) | envsubst > "$WEB_PATH/$path_subpage.json" # Перезапуск Xray echo "Перезапуск Xray..." systemctl restart xray echo -e "Готово!\n" # Формирование ссылок subPageLink="https://$DOMAIN/$path_subpage.json" # Формирование ссылок link1="vless://${xray_uuid_vrv}@$DOMAIN:443?security=reality&type=tcp&headerType=&path=&host=&flow=xtls-rprx-vision&sni=$DOMAIN&fp=chrome&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#vlessRAWrealityXTLS-autoXRAY" link2="vless://${xray_uuid_vrv}@$DOMAIN:443?security=reality&type=xhttp&headerType=&path=%2F$path_xhttp&host=&mode=auto&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=chrome&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#vlessXHTTPrealityEXTRA-autoXRAY" link3="vless://${xray_uuid_vrv}@$DOMAIN:443?security=reality&type=tcp&headerType=http&path=%2F${path_xhttp}44&host=&flow=&sni=$DOMAIN&fp=chrome&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#vlessRAWrealityNOmux-autoXRAY" ENCODED_STRING=$(echo -n "2022-blake3-chacha20-poly1305:${xray_sspasw_vrv}" | base64 -w 0) linkSS="ss://$ENCODED_STRING@${DOMAIN}:8443#Shadowsocks2022-autoXRAY" configListLink="https://$DOMAIN/$path_subpage.html" CONFIGS_ARRAY=( "VLESS RAW Reality XTLS|$link1" "VLESS XHTTP Reality (для моста)|$link2" "VLESS RAW Reality NoMux|$link3" "Shadowsocks 2022|$linkSS" ) ALL_LINKS_TEXT="" # --- ЗАПИСЬ HEAD (СТАТИКА, МИНИФИЦИРОВАННЫЕ СТИЛИ И JS) --- cat > "$WEB_PATH/$path_subpage.html" <<'EOF' autoXRAY configs EOF # --- ЗАПИСЬ BODY (ДИНАМИЧЕСКИЕ ДАННЫЕ) --- cat >> "$WEB_PATH/$path_subpage.html" <📂 Ссылка на подписку (готовый конфиг клиента с роутингом)
Subscription

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

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

➡️ Конфиги

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, All links и подвал cat >> "$WEB_PATH/$path_subpage.html" <
Socks5 (TG)
server=$DOMAIN port=10443 user=${socksUser} pass=${socksPasw}
✈️ Add to TG

💠 Все конфиги вместе

$ALL_LINKS_TEXT
https://github.com/xVRVx/autoXRAY
EOF echo -e " Ваш конфиг vless RAW reality XTLS: $link1 Ваш конфиг vless XHTTP reality EXTRA: $link2 Ваш конфиг vless RAW reality noMUX: $link3 Ваш конфиг Shadowsocks 2022-blake3-chacha20-poly1305: $linkSS Ваша страничка подписки: \033[32m$subPageLink\033[0m Ссылка на сохраненные конфиги: \033[32m$configListLink\033[0m Скопируйте подписку в специализированное приложение: - iOS: Happ или v2RayTun или v2rayN - Android: Happ или v2RayTun или v2rayNG - Windows: конфиги Happ или winLoadXRAY или v2rayN для vless v2RayTun или Throne Открыт локальный socks5 на порту 10808, 2080 и http на 10809. Поддержать автора: https://github.com/xVRVx/autoXRAY "