Добавить autoXRAY-ip.sh
This commit is contained in:
+818
@@ -0,0 +1,818 @@
|
|||||||
|
#!/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; }
|
||||||
|
|
||||||
|
# --- Определяем SERVER_IP (аргумент или автоопределение) ---
|
||||||
|
SERVER_IP="${1:-$(hostname -I | awk '{print $1}')}"
|
||||||
|
|
||||||
|
if ! echo "$SERVER_IP" | grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}$'; then
|
||||||
|
echo -e "${RED}❌ Некорректный IP-адрес: $SERVER_IP${NC}"
|
||||||
|
echo -e "${YEL}Использование: $0 [IP-адрес]${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$SERVER_IP" == "127.0.0.1" || "$SERVER_IP" == "127."* ]]; then
|
||||||
|
echo -e "${RED}❌ Нельзя использовать loopback-адрес. Укажите внешний IP сервера.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
MASQUERADE_HOST="www.googletagmanager.com"
|
||||||
|
|
||||||
|
echo -e "${YEL}⚙️ IP-адрес: ${GRN}$SERVER_IP${YEL} | Маскировка: ${GRN}$MASQUERADE_HOST${NC}"
|
||||||
|
|
||||||
|
# --- Проверка ОС ---
|
||||||
|
OS_ID=$(grep '^ID=' /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"')
|
||||||
|
if [[ "$OS_ID" != "ubuntu" && "$OS_ID" != "debian" ]]; then
|
||||||
|
echo -e "${YEL}⚠️ Обнаружена ОС: $OS_ID. Скрипт тестировался на Ubuntu/Debian.${NC}"
|
||||||
|
read -p "Продолжить? (y/N): " choice
|
||||||
|
[[ "$choice" =~ ^[Yy]$ ]] || { echo -e "${RED}Прервано.${NC}"; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Проверка порта 443 ---
|
||||||
|
if ss -tnlp | grep -q ':443 '; then
|
||||||
|
echo -e "${YEL}⚠️ Порт 443 уже занят:${NC}"
|
||||||
|
ss -tnlp | grep ':443 '
|
||||||
|
read -p "Продолжить на ваш страх и риск? (y/N): " choice
|
||||||
|
[[ "$choice" =~ ^[Yy]$ ]] || { echo -e "${RED}Прервано.${NC}"; exit 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YEL}Обновление и установка необходимых пакетов...${NC}"
|
||||||
|
apt-get update && apt-get install curl jq dnsutils openssl nginx -y
|
||||||
|
systemctl enable --now nginx
|
||||||
|
|
||||||
|
# Включаем BBR
|
||||||
|
bbr=$(sysctl -a 2>/dev/null | grep net.ipv4.tcp_congestion_control)
|
||||||
|
if [ "$bbr" = "net.ipv4.tcp_congestion_control = 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 <<EOF > /etc/security/limits.d/99-autoXRAY.conf
|
||||||
|
* soft nofile 65535
|
||||||
|
* hard nofile 65535
|
||||||
|
root soft nofile 65535
|
||||||
|
root hard nofile 65535
|
||||||
|
EOF
|
||||||
|
ulimit -n 65535
|
||||||
|
echo -e "${GRN}Лимиты применены. Текущий ulimit -n: $(ulimit -n) ${NC}"
|
||||||
|
|
||||||
|
# Создание директории сайта
|
||||||
|
WEB_PATH="/var/www/$SERVER_IP"
|
||||||
|
mkdir -p "$WEB_PATH"
|
||||||
|
# Очищаем папку от старых конфигов и страниц
|
||||||
|
find "$WEB_PATH" -mindepth 1 -not -name '.gitkeep' -delete
|
||||||
|
echo -e "${GRN}✅ Папка $WEB_PATH очищена.${NC}"
|
||||||
|
|
||||||
|
# Генерируем сайт маскировку
|
||||||
|
bash -c "$(curl -L https://github.com/xVRVx/autoXRAY/raw/refs/heads/main/test/gen_page2.sh)" -- "$WEB_PATH"
|
||||||
|
|
||||||
|
# Установка Xray
|
||||||
|
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
|
||||||
|
|
||||||
|
# Конфиг nginx
|
||||||
|
|
||||||
|
path_xhttp=$(openssl rand -base64 15 | tr -dc 'a-z0-9' | head -c 6)
|
||||||
|
path_subpage=$(openssl rand -base64 15 | tr -dc 'A-Za-z0-9' | head -c 20)
|
||||||
|
configPageUser=$(cat /dev/urandom | tr -dc 'A-Za-z0-9' | head -c 12)
|
||||||
|
configPagePass=$(cat /dev/urandom | tr -dc 'A-Za-z0-9!@#$%^&*_-' | head -c 20)
|
||||||
|
configPort=$(shuf -i 10100-59999 -n 1)
|
||||||
|
|
||||||
|
# Определяем путь к конфигу 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.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}Не найден ни один default конфиг nginx${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /etc/nginx/conf.d
|
||||||
|
cat > /etc/nginx/conf.d/autoXRAY-security.conf <<'SECEOF'
|
||||||
|
limit_req_zone $binary_remote_addr zone=axray_proxy:10m rate=20r/m;
|
||||||
|
|
||||||
|
map $http_user_agent $axray_bad_bot {
|
||||||
|
default 0;
|
||||||
|
~*(masscan|zgrab|nmap|nikto|sqlmap|nuclei) 1;
|
||||||
|
}
|
||||||
|
SECEOF
|
||||||
|
|
||||||
|
echo "${configPageUser}:$(openssl passwd -apr1 "${configPagePass}")" > /etc/nginx/conf.d/autoXRAY-htpasswd
|
||||||
|
NGINX_USER=$(ps -eo user,comm | awk '$2=="nginx" && $1!="root" {print $1; exit}')
|
||||||
|
NGINX_USER=${NGINX_USER:-www-data}
|
||||||
|
chown root:"$NGINX_USER" /etc/nginx/conf.d/autoXRAY-htpasswd
|
||||||
|
chmod 640 /etc/nginx/conf.d/autoXRAY-htpasswd
|
||||||
|
|
||||||
|
# Генерируем самоподписанный SSL-сертификат для IP (7 дней)
|
||||||
|
openssl req -x509 -newkey rsa:2048 -nodes \
|
||||||
|
-keyout /etc/nginx/conf.d/autoXRAY-ip.key \
|
||||||
|
-out /etc/nginx/conf.d/autoXRAY-ip.crt \
|
||||||
|
-days 7 \
|
||||||
|
-subj "/CN=$SERVER_IP" \
|
||||||
|
-addext "subjectAltName=IP:$SERVER_IP" 2>/dev/null
|
||||||
|
chmod 600 /etc/nginx/conf.d/autoXRAY-ip.key
|
||||||
|
chmod 644 /etc/nginx/conf.d/autoXRAY-ip.crt
|
||||||
|
echo -e "${GRN}✅ Самоподписанный SSL-сертификат создан (действителен 7 дней).${NC}"
|
||||||
|
|
||||||
|
# Скрипт автоперевыпуска сертификата (запускается systemd-таймером каждые 6 дней)
|
||||||
|
cat > /usr/local/bin/autoXRAY-ip-renew.sh <<RENEWEOF
|
||||||
|
#!/bin/bash
|
||||||
|
SERVER_IP="$SERVER_IP"
|
||||||
|
openssl req -x509 -newkey rsa:2048 -nodes \\
|
||||||
|
-keyout /etc/nginx/conf.d/autoXRAY-ip.key \\
|
||||||
|
-out /etc/nginx/conf.d/autoXRAY-ip.crt \\
|
||||||
|
-days 7 \\
|
||||||
|
-subj "/CN=\$SERVER_IP" \\
|
||||||
|
-addext "subjectAltName=IP:\$SERVER_IP" 2>/dev/null
|
||||||
|
chmod 600 /etc/nginx/conf.d/autoXRAY-ip.key
|
||||||
|
chmod 644 /etc/nginx/conf.d/autoXRAY-ip.crt
|
||||||
|
nginx -t 2>/dev/null && systemctl reload nginx
|
||||||
|
RENEWEOF
|
||||||
|
chmod 755 /usr/local/bin/autoXRAY-ip-renew.sh
|
||||||
|
|
||||||
|
# systemd-сервис
|
||||||
|
cat > /etc/systemd/system/autoXRAY-ip-renew.service <<'SVCEOF'
|
||||||
|
[Unit]
|
||||||
|
Description=autoXRAY self-signed IP certificate renewal
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/bin/autoXRAY-ip-renew.sh
|
||||||
|
SVCEOF
|
||||||
|
|
||||||
|
# systemd-таймер: запускать каждые 6 дней (сертификат на 7 дней)
|
||||||
|
cat > /etc/systemd/system/autoXRAY-ip-renew.timer <<'TMREOF'
|
||||||
|
[Unit]
|
||||||
|
Description=autoXRAY self-signed IP certificate renewal timer
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-1/6
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
TMREOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now autoXRAY-ip-renew.timer
|
||||||
|
echo -e "${GRN}✅ Таймер автоперевыпуска сертификата включён (каждые 6 дней).${NC}"
|
||||||
|
|
||||||
|
bash -c "cat > $CONFIG_PATH" <<EOF
|
||||||
|
# Маскировочный сайт (порт 80)
|
||||||
|
server {
|
||||||
|
listen 80 default_server;
|
||||||
|
server_name _;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
root /var/www/$SERVER_IP;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
if (\$axray_bad_bot) {
|
||||||
|
return 444;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Страница конфигов на случайном порту (HTTPS + Basic Auth)
|
||||||
|
server {
|
||||||
|
listen $configPort ssl;
|
||||||
|
server_name _;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/conf.d/autoXRAY-ip.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/conf.d/autoXRAY-ip.key;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
ssl_session_cache shared:AXIP:2m;
|
||||||
|
ssl_session_timeout 1d;
|
||||||
|
|
||||||
|
root /var/www/$SERVER_IP;
|
||||||
|
|
||||||
|
if (\$axray_bad_bot) {
|
||||||
|
return 444;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /${path_subpage}.json {
|
||||||
|
add_header profile-title "base64:YXV0b1hSQVk=";
|
||||||
|
add_header routing "happ://routing/onadd/eyJOYW1lIjoiYXV0b1hSQVkiLCJHbG9iYWxQcm94eSI6InRydWUiLCJSb3V0ZU9yZGVyIjoiYmxvY2stcHJveHktZGlyZWN0IiwiUmVtb3RlRE5TVHlwZSI6IkRvSCIsIlJlbW90ZUROU0RvbWFpbiI6Imh0dHBzOi8vZG5zLmdvb2dsZS9kbnMtcXVlcnkiLCJSZW1vdGVETlNJUCI6IjguOC40LjQiLCJEb21lc3RpY0ROU1R5cGUiOiJEb0giLCJEb21lc3RpY0ROU0RvbWFpbiI6Imh0dHBzOi8vY2xvdWRmbGFyZS1kbnMuY29tL2Rucy1xdWVyeSIsIkRvbWVzdGljRE5TSVAiOiIxLjEuMS4xIiwiR2VvaXB1cmwiOiJodHRwczovL2dpdGh1Yi5jb20vTG95YWxzb2xkaWVyL3YycmF5LXJ1bGVzLWRhdC9yZWxlYXNlcy9sYXRlc3QvZG93bmxvYWQvZ2VvaXAuZGF0IiwiR2Vvc2l0ZXVybCI6Imh0dHBzOi8vZ2l0aHViLmNvbS9Mb3lhbHNvbGRpZXIvdjJyYXktcnVsZXMtZGF0L3JlbGVhc2VzL2xhdGVzdC9kb3dubG9hZC9nZW9zaXRlLmRhdCIsIkxhc3RVcGRhdGVkIjoiMTc3NTIwNjEwOCIsIkRuc0hvc3RzIjp7fSwiRGlyZWN0U2l0ZXMiOlsiZ2Vvc2l0ZTpjYXRlZ29yeS1ydSIsImdlb3NpdGU6cHJpdmF0ZSJdLCJEaXJlY3RJcCI6WyJnZW9pcDpwcml2YXRlIl0sIlByb3h5U2l0ZXMiOltdLCJQcm94eUlwIjpbXSwiQmxvY2tTaXRlcyI6WyJnZW9zaXRlOmNhdGVnb3J5LWFkcyIsImdlb3NpdGU6d2luLXNweSJdLCJCbG9ja0lwIjpbXSwiRG9tYWluU3RyYXRlZ3kiOiJJUElmTm9uTWF0Y2giLCJGYWtlRE5TIjoiZmFsc2UiLCJVc2VDaHVua0ZpbGVzIjoiZmFsc2UifQ";
|
||||||
|
add_header routing-enable 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /${path_subpage}.html {
|
||||||
|
auth_basic "autoXRAY";
|
||||||
|
auth_basic_user_file /etc/nginx/conf.d/autoXRAY-htpasswd;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if nginx -t 2>/dev/null; then
|
||||||
|
systemctl restart nginx
|
||||||
|
echo -e "${GRN}✅ Конфигурация nginx обновлена.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Ошибка в конфигурации nginx:${NC}"
|
||||||
|
nginx -t
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверяем, что nginx запустился и отвечает
|
||||||
|
sleep 1
|
||||||
|
NGINX_HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "http://$SERVER_IP/" 2>/dev/null || echo "000")
|
||||||
|
if [[ "$NGINX_HTTP_CODE" == "200" ]]; then
|
||||||
|
echo -e "${GRN}✅ Nginx отвечает корректно (HTTP $NGINX_HTTP_CODE).${NC}"
|
||||||
|
elif [[ "$NGINX_HTTP_CODE" == "000" ]]; then
|
||||||
|
echo -e "${YEL}⚠️ Nginx не ответил на HTTP-запрос (возможно, порт 80 закрыт фаерволом).${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Nginx вернул HTTP $NGINX_HTTP_CODE. Диагностика:${NC}"
|
||||||
|
nginx -t
|
||||||
|
echo -e "${RED}--- Последние ошибки nginx: ---${NC}"
|
||||||
|
journalctl -u nginx --no-pager -n 20
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR=/usr/local/etc/xray
|
||||||
|
|
||||||
|
# Генерируем переменные
|
||||||
|
xray_uuid_vrv=$(xray uuid)
|
||||||
|
|
||||||
|
key_output=$(xray x25519)
|
||||||
|
xray_privateKey_vrv=$(echo "$key_output" | awk '/[Pp]rivate/ {print $NF}')
|
||||||
|
xray_publicKey_vrv=$(echo "$key_output" | awk '/[Pp]ublic/ {print $NF}')
|
||||||
|
|
||||||
|
xray_shortIds_vrv=$(openssl rand -hex 8)
|
||||||
|
xray_shortIds_vrv2=$(openssl rand -hex 4)
|
||||||
|
xray_shortIds_vrv3=$(openssl rand -hex 6)
|
||||||
|
|
||||||
|
xray_fp="chrome"
|
||||||
|
xray_spiderX="/$(openssl rand -base64 9 | tr -dc 'a-z' | 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)
|
||||||
|
|
||||||
|
# Установка WARP-cli
|
||||||
|
# Посмотреть порт(2408): grep -r "Endpoint" /etc/wireguard/
|
||||||
|
if ss -tuln | grep -q ":40000 "; then
|
||||||
|
echo -e "${GRN}WARP-cli (Socks5 на порту 40000) уже работает. Пропускаем.${NC}"
|
||||||
|
else
|
||||||
|
echo -e "${GRN}Установка WARP-cli (автоматически)...${NC}"
|
||||||
|
echo -e "1\n1\n40000" | bash <(curl -fsSL https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh) w
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Экспортируем переменные для envsubst
|
||||||
|
export xray_uuid_vrv xray_privateKey_vrv xray_publicKey_vrv xray_shortIds_vrv xray_shortIds_vrv2 xray_shortIds_vrv3 xray_fp xray_spiderX SERVER_IP MASQUERADE_HOST path_subpage path_xhttp WEB_PATH socksUser socksPasw
|
||||||
|
|
||||||
|
# Создаем JSON конфигурацию сервера
|
||||||
|
# Reality target — внешний хост (www.googletagmanager.com:443), xver=0 (без proxy protocol к внешнему серверу)
|
||||||
|
# Fallback на порт 3333 (XHTTP) — для VLESS-соединений без flow xtls-rprx-vision
|
||||||
|
cat << 'EOF' | envsubst > "$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": "vsRAWrtyVISION",
|
||||||
|
"port": 443,
|
||||||
|
"listen": "0.0.0.0",
|
||||||
|
"protocol": "vless",
|
||||||
|
"settings": {
|
||||||
|
"clients": [
|
||||||
|
{
|
||||||
|
"flow": "xtls-rprx-vision",
|
||||||
|
"id": "${xray_uuid_vrv}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decryption": "none",
|
||||||
|
"fallbacks": [
|
||||||
|
{
|
||||||
|
"dest": "3333",
|
||||||
|
"xver": 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sniffing": {
|
||||||
|
"enabled": true,
|
||||||
|
"destOverride": [
|
||||||
|
"http",
|
||||||
|
"tls",
|
||||||
|
"quic"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"streamSettings": {
|
||||||
|
"network": "raw",
|
||||||
|
"security": "reality",
|
||||||
|
"sockopt": {
|
||||||
|
"tcpFastOpen": true,
|
||||||
|
"tcpNoDelay": true
|
||||||
|
},
|
||||||
|
"realitySettings": {
|
||||||
|
"show": false,
|
||||||
|
"xver": 0,
|
||||||
|
"target": "${MASQUERADE_HOST}:443",
|
||||||
|
"spiderX": "${xray_spiderX}",
|
||||||
|
"shortIds": [
|
||||||
|
"${xray_shortIds_vrv}",
|
||||||
|
"${xray_shortIds_vrv2}",
|
||||||
|
"${xray_shortIds_vrv3}"
|
||||||
|
],
|
||||||
|
"privateKey": "${xray_privateKey_vrv}",
|
||||||
|
"serverNames": [
|
||||||
|
"${MASQUERADE_HOST}",
|
||||||
|
"tagmanager.google.com",
|
||||||
|
"googletagmanager.com"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": "stream-one",
|
||||||
|
"path": "/${path_xhttp}"
|
||||||
|
},
|
||||||
|
"security": "none",
|
||||||
|
"sockopt": {
|
||||||
|
"acceptProxyProtocol": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"port": "25",
|
||||||
|
"outboundTag": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"protocol": [
|
||||||
|
"bittorrent"
|
||||||
|
],
|
||||||
|
"outboundTag": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": [
|
||||||
|
"geosite:category-ads",
|
||||||
|
"geosite:win-spy",
|
||||||
|
"geosite:private"
|
||||||
|
],
|
||||||
|
"outboundTag": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"outboundTag": "warp",
|
||||||
|
"domain": ["ifconfig.me","checkip.amazonaws.com","pify.org","2ip.io","habr.com","geosite:category-ip-geo-detect","geosite:google-gemini","geosite:canva","geosite:openai","geosite:whatsapp","geosite:category-ru"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"domainStrategy": "IPIfNonMatch"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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": {
|
||||||
|
"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: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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Config 1: VLESS RAW REALITY VISION
|
||||||
|
OUT_REALITY_VISION='{
|
||||||
|
"mux": { "concurrency": -1, "enabled": false },
|
||||||
|
"tag": "proxy",
|
||||||
|
"protocol": "vless",
|
||||||
|
"settings": {
|
||||||
|
"vnext": [{
|
||||||
|
"address": "${SERVER_IP}",
|
||||||
|
"port": 443,
|
||||||
|
"users": [{ "id": "${xray_uuid_vrv}", "flow": "xtls-rprx-vision", "encryption": "none" }]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"streamSettings": {
|
||||||
|
"network": "raw",
|
||||||
|
"security": "reality",
|
||||||
|
"realitySettings": {
|
||||||
|
"show": false, "fingerprint": "${xray_fp}", "serverName": "${MASQUERADE_HOST}",
|
||||||
|
"password": "${xray_publicKey_vrv}", "shortId": "${xray_shortIds_vrv}", "spiderX": "${xray_spiderX}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
|
||||||
|
# --- Config 2: VLESS XHTTP REALITY EXTRA
|
||||||
|
OUT_REALITY_XHTTP='{
|
||||||
|
"mux": { "concurrency": -1, "enabled": false },
|
||||||
|
"tag": "proxy",
|
||||||
|
"protocol": "vless",
|
||||||
|
"settings": {
|
||||||
|
"vnext": [{
|
||||||
|
"address": "${SERVER_IP}",
|
||||||
|
"port": 443,
|
||||||
|
"users": [{ "id": "${xray_uuid_vrv}", "encryption": "none" }]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"streamSettings": {
|
||||||
|
"network": "xhttp",
|
||||||
|
"security": "reality",
|
||||||
|
"xhttpSettings": {
|
||||||
|
"mode": "stream-one",
|
||||||
|
"path": "/${path_xhttp}",
|
||||||
|
"extra": {
|
||||||
|
"noGRPCHeader": true,
|
||||||
|
"scMaxEachPostBytes": 1500000,
|
||||||
|
"scMinPostsIntervalMs": 20,
|
||||||
|
"scStreamUpServerSecs": "60-240",
|
||||||
|
"xPaddingBytes": "100-1500",
|
||||||
|
"xmux": {
|
||||||
|
"cMaxReuseTimes": "1000-3000",
|
||||||
|
"hKeepAlivePeriod": 300,
|
||||||
|
"hMaxRequestTimes": "400-700",
|
||||||
|
"hMaxReusableSecs": "1200-1800",
|
||||||
|
"maxConcurrency": "3-5",
|
||||||
|
"maxConnections": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"realitySettings": {
|
||||||
|
"show": false, "fingerprint": "${xray_fp}", "serverName": "${MASQUERADE_HOST}",
|
||||||
|
"password": "${xray_publicKey_vrv}", "shortId": "${xray_shortIds_vrv}", "spiderX": "${xray_spiderX}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
|
||||||
|
(
|
||||||
|
echo "["
|
||||||
|
print_config "$OUT_REALITY_XHTTP" "🌐 VLESS XHTTP REALITY EXTRA"
|
||||||
|
echo ","
|
||||||
|
print_config "$OUT_REALITY_VISION" "🌐 VLESS RAW REALITY VISION"
|
||||||
|
echo "]"
|
||||||
|
) | envsubst > "$WEB_PATH/$path_subpage.json"
|
||||||
|
|
||||||
|
systemctl restart xray
|
||||||
|
echo -e "Перезапуск XRAY"
|
||||||
|
|
||||||
|
# Формирование ссылок
|
||||||
|
subPageLink="https://$SERVER_IP:$configPort/$path_subpage.json"
|
||||||
|
|
||||||
|
linkRTY1="vless://${xray_uuid_vrv}@${SERVER_IP}:443?security=reality&type=tcp&headerType=&path=&host=&flow=xtls-rprx-vision&sni=${MASQUERADE_HOST}&fp=${xray_fp}&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#vlessRAWrealityVISION-autoXRAY-ip"
|
||||||
|
|
||||||
|
linkRTY2="vless://${xray_uuid_vrv}@${SERVER_IP}:443?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%3A300%2C%22hMaxRequestTimes%22%3A%22400-700%22%2C%22hMaxReusableSecs%22%3A%221200-1800%22%7D%2C%22headers%22%3A%7B%7D%2C%22noGRPCHeader%22%3Atrue%2C%22xPaddingBytes%22%3A%22100-1500%22%2C%22scMaxEachPostBytes%22%3A1500000%2C%22scMinPostsIntervalMs%22%3A20%2C%22scStreamUpServerSecs%22%3A%2260-240%22%7D&sni=${MASQUERADE_HOST}&fp=${xray_fp}&pbk=${xray_publicKey_vrv}&sid=${xray_shortIds_vrv}&spx=%2F#vlessXHTTPrealityEXTRA-autoXRAY-ip"
|
||||||
|
|
||||||
|
configListLink="https://$SERVER_IP:$configPort/$path_subpage.html"
|
||||||
|
|
||||||
|
CONFIGS_ARRAY=(
|
||||||
|
"VLESS XHTTP REALITY EXTRA|$linkRTY2"
|
||||||
|
"VLESS RAW REALITY VISION|$linkRTY1"
|
||||||
|
)
|
||||||
|
|
||||||
|
# --- ЗАПИСЬ HTML-СТРАНИЦЫ (HEAD + СТАТИЧЕСКИЙ JS/CSS) ---
|
||||||
|
cat > "$WEB_PATH/$path_subpage.html" <<'HTMLEOF'
|
||||||
|
<!DOCTYPE html><html lang="ru"><head>
|
||||||
|
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><meta name="robots" content="noindex,nofollow">
|
||||||
|
<title>autoXRAY</title>
|
||||||
|
<link rel="icon" type="image/svg+xml" href='data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDBCRkZGIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTIxIDJsLTIgMm0tNy42MSA3LjYxYTUuNSA1LjUgMCAxIDEtNy43NzggNy43NzggNS41IDUuNSAwIDAgMSA3Ljc3Ny03Ljc3N3ptMCAwTDE1LjUgNy41bTAgMGwzIDNMMjIgN2wtMy0zbS0zLjUgMy41TDE5IDQiLz48L3N2Zz4='>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>
|
||||||
|
<style>
|
||||||
|
:root{--bg:#0d0d0f;--sf:#18181b;--bd:#27272a;--tx:#f4f4f5;--mt:#71717a;--gn:#4ade80;--ac:#6366f1}
|
||||||
|
*{box-sizing:border-box;margin:0;padding:0}
|
||||||
|
body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:var(--bg);color:var(--tx);min-height:100vh;padding:24px 16px}
|
||||||
|
.w{max-width:680px;margin:0 auto}
|
||||||
|
header{text-align:center;padding:40px 0 36px}
|
||||||
|
header h1{font-size:22px;font-weight:700;letter-spacing:-.5px;background:linear-gradient(135deg,#c7d2fe,#a5b4fc);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
|
||||||
|
header p{color:var(--mt);font-size:13px;margin-top:6px}
|
||||||
|
@keyframes fi{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
|
||||||
|
.card{background:var(--sf);border:1px solid var(--bd);border-radius:16px;padding:20px;margin-bottom:12px;transition:border-color .2s,box-shadow .2s;animation:fi .4s ease calc(var(--di,0)*.1s) both}
|
||||||
|
.card:hover{border-color:#3f3f46;box-shadow:0 0 0 1px #3f3f4640}
|
||||||
|
.card.open{border-color:#4f4f7a;box-shadow:0 0 0 1px rgba(99,102,241,.2)}
|
||||||
|
.ct{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
|
||||||
|
.badge{font-size:10.5px;font-weight:600;padding:4px 11px;border-radius:20px;letter-spacing:.4px;text-transform:uppercase}
|
||||||
|
.card[data-i="1"] .badge{background:rgba(99,102,241,.1);color:#a5b4fc;border:1px solid rgba(99,102,241,.2)}
|
||||||
|
.card[data-i="2"] .badge{background:rgba(20,184,166,.1);color:#5eead4;border:1px solid rgba(20,184,166,.2)}
|
||||||
|
.bts{display:flex;gap:7px}
|
||||||
|
.ib{width:34px;height:34px;border-radius:9px;border:1px solid var(--bd);background:transparent;color:var(--mt);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .15s;flex-shrink:0}
|
||||||
|
.ib:hover{background:#27272a;color:var(--tx);border-color:#3f3f46}
|
||||||
|
.ib.ok{background:rgba(74,222,128,.08);color:var(--gn);border-color:rgba(74,222,128,.25)}
|
||||||
|
.ib svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||||
|
.cfg{font-family:ui-monospace,'SF Mono','Fira Code',monospace;font-size:11.5px;color:#a1a1aa;background:rgba(0,0,0,.35);border:1px solid var(--bd);border-radius:10px;padding:12px 14px;word-break:break-all;line-height:1.7;filter:blur(4px);user-select:none;transition:filter .3s;pointer-events:none}
|
||||||
|
.cfg.show{filter:none;user-select:text;pointer-events:auto}
|
||||||
|
.modal{display:none;position:fixed;inset:0;background:rgba(0,0,0,.72);z-index:99;justify-content:center;align-items:center;backdrop-filter:blur(8px)}
|
||||||
|
.modal.on{display:flex}
|
||||||
|
.mbox{background:var(--sf);border:1px solid var(--bd);border-radius:18px;padding:28px 24px;text-align:center;display:flex;flex-direction:column;align-items:center}
|
||||||
|
.qtitle{color:var(--mt);font-size:11px;font-weight:600;letter-spacing:.5px;text-transform:uppercase;margin-bottom:14px}
|
||||||
|
#qrc{background:#fff;padding:12px;border-radius:10px;margin-bottom:16px;display:inline-block}
|
||||||
|
.mc{background:#ef4444;color:#fff;border:none;padding:8px 26px;border-radius:9px;cursor:pointer;font-weight:600;font-size:13px;transition:opacity .15s}
|
||||||
|
.mc:hover{opacity:.85}
|
||||||
|
footer{text-align:center;padding:40px 0 20px;color:var(--mt);font-size:12px}
|
||||||
|
footer a{color:var(--ac);text-decoration:none}
|
||||||
|
@media(max-width:480px){.card{padding:16px}.cfg{font-size:11px}.badge{font-size:10px}.ib{width:40px;height:40px}}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
var EO='<svg viewBox="0 0 24 24"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>';
|
||||||
|
var EX='<svg viewBox="0 0 24 24"><path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24"/><line x1="1" y1="1" x2="23" y2="23"/></svg>';
|
||||||
|
var CK='<svg viewBox="0 0 24 24" stroke-width="2.5"><polyline points="20 6 9 17 4 12"/></svg>';
|
||||||
|
function toggleVis(id,b){var e=document.getElementById(id),on=e.classList.toggle('show');b.classList.toggle('ok',on);b.innerHTML=on?EX:EO;b.title=on?'Скрыть':'Показать';var c=b.closest('.card');if(c)c.classList.toggle('open',on);}
|
||||||
|
function doCopy(id,b){var e=document.getElementById(id),t=e.dataset.v||e.innerText;navigator.clipboard.writeText(t).then(function(){var o=b.innerHTML;b.innerHTML=CK;b.classList.add('ok');setTimeout(function(){b.innerHTML=o;b.classList.remove('ok');},1500);});}
|
||||||
|
function doQR(id,title){var e=document.getElementById(id),t=e.dataset.v||e.innerText;document.getElementById('qrc').innerHTML='';document.getElementById('qtitle').innerText=title||'';new QRCode(document.getElementById('qrc'),{text:t,width:240,height:240,colorDark:'#000',colorLight:'#fff',correctLevel:QRCode.CorrectLevel.L});document.getElementById('modal').classList.add('on');}
|
||||||
|
function closeModal(){document.getElementById('modal').classList.remove('on');}
|
||||||
|
window.onclick=function(e){if(e.target.id==='modal')closeModal();};
|
||||||
|
document.addEventListener('keydown',function(e){if(e.key==='Escape')closeModal();});
|
||||||
|
</script></head><body>
|
||||||
|
<div class="w">
|
||||||
|
<header><h1>autoXRAY</h1><p>Конфигурации прокси-клиента</p></header>
|
||||||
|
HTMLEOF
|
||||||
|
|
||||||
|
# --- ДИНАМИЧЕСКИЕ КАРТОЧКИ КОНФИГОВ ---
|
||||||
|
idx=1
|
||||||
|
for item in "${CONFIGS_ARRAY[@]}"; do
|
||||||
|
title="${item%%|*}"
|
||||||
|
link="${item#*|}"
|
||||||
|
cat >> "$WEB_PATH/$path_subpage.html" <<CARDEOF
|
||||||
|
<div class="card" data-i="${idx}" style="--di:${idx}">
|
||||||
|
<div class="ct">
|
||||||
|
<span class="badge">$title</span>
|
||||||
|
<div class="bts">
|
||||||
|
<button class="ib" title="Показать" onclick="toggleVis('c${idx}',this)"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
|
||||||
|
<button class="ib" title="Копировать" onclick="doCopy('c${idx}',this)"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></button>
|
||||||
|
<button class="ib" title="QR-код" onclick="doQR('c${idx}','$title')"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><path d="M14 14h3v3m3-3v3m0 3h-6m3 0v-3"/></svg></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="cfg" id="c${idx}" data-v="$link">$link</div>
|
||||||
|
</div>
|
||||||
|
CARDEOF
|
||||||
|
((idx++))
|
||||||
|
done
|
||||||
|
|
||||||
|
# --- ПОДВАЛ И МОДАЛКА ---
|
||||||
|
cat >> "$WEB_PATH/$path_subpage.html" <<'HTMLEOF'
|
||||||
|
<footer><a href="https://gitea.creative-tg1.ru/CREATIVE_tg1/autoXRAY">gitea.creative-tg1.ru/CREATIVE_tg1/autoXRAY</a></footer>
|
||||||
|
</div>
|
||||||
|
<div id="modal" class="modal"><div class="mbox"><p id="qtitle" class="qtitle"></p><div id="qrc"></div><button class="mc" onclick="closeModal()">Закрыть</button></div></div>
|
||||||
|
</body></html>
|
||||||
|
HTMLEOF
|
||||||
|
|
||||||
|
# --- ФИНАЛЬНАЯ ПРОВЕРКА ---
|
||||||
|
echo -e "\n${YEL}=== Финальная проверка статусов ===${NC}"
|
||||||
|
|
||||||
|
# Проверка WARP-cli (Socks5 порт 40000)
|
||||||
|
if ss -nlt | grep -q ":40000\b"; then
|
||||||
|
echo -e "WARP-cli: ${GRN}LISTENING${NC}"
|
||||||
|
else
|
||||||
|
echo -e "WARP-cli: ${RED}NOT LISTENING${NC}"
|
||||||
|
echo "Возникла ошибка! Возможные пути решения проблемы смотрите здесь:"
|
||||||
|
echo "https://github.com/xVRVx/autoXRAY/blob/main/test/warp-readme.md"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка Nginx
|
||||||
|
if systemctl is-active --quiet nginx; then
|
||||||
|
echo -e "Nginx: ${GRN}RUNNING${NC}"
|
||||||
|
else
|
||||||
|
echo -e "Nginx: ${RED}STOPPED/ERROR${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка XRAY
|
||||||
|
if systemctl is-active --quiet xray; then
|
||||||
|
echo -e "XRAY: ${GRN}RUNNING${NC}"
|
||||||
|
else
|
||||||
|
echo -e "XRAY: ${RED}STOPPED/ERROR${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "
|
||||||
|
${YEL}Ссылка на сохраненные конфиги ${NC}
|
||||||
|
${GRN}$configListLink ${NC}
|
||||||
|
|
||||||
|
${YEL}Страница конфигов — Basic Auth:${NC}
|
||||||
|
Логин: ${GRN}$configPageUser${NC}
|
||||||
|
Пароль: ${GRN}$configPagePass${NC}
|
||||||
|
|
||||||
|
${YEL}⚠️ Браузер покажет предупреждение о самоподписанном сертификате — это нормально (сертификат для IP).${NC}
|
||||||
|
${YEL} Нажмите «Дополнительно» → «Всё равно перейти». Сертификат действителен 7 дней.${NC}
|
||||||
|
"
|
||||||
Reference in New Issue
Block a user