Виртуальные путешествия с XRay (vless)

Виртуальные путешествия с XRay (vless)

У меня тут состоялся небольшой спор с ChatGPT. Да, я знаю, по сути это спор меня с собой, но поделюсь.
Концептуальная идея всех этих VPN и проблема, как быть наиболее незамеченным, в том, что непонятно, как лучше — смешаться с толпой или притвориться кустом.

Большинство настроек XRay — это коробочные решения с закосом под Google, но в современных российских (и не только) реалиях притворяться вражеским сайтом может стать себе дороже. Проблема в том, что сам факт того, что SNI указывает на google.com, но IP-адрес не принадлежит Google, теоретически можно отследить. Это называется SNI–IP mismatch.

Поэтому бесконечное количество «сайтов» на мусорных и часто уже зашкваренных IP попадает под блокировку довольно быстро.

Что бы я делал в такой ситуации. Во-первых, я бы покупал свой собственный домен, но не в ru-зоне, поскольку сайты в ней попадают под закон о приземлении. При покупке доплатил бы за скрытие информации о владельце.

Во-вторых, я бы брал VDS там, где предоставляют более-менее облачные услуги, но не в популярном месте. Поясню: реселлеров в интернете много, они есть на poiskvps и т.д., но обычно это перепродажа каких-нибудь OVH. Обычно это дешевые VPS под VPN, что не так уж и плохо, но с уже заблокированными IP-адресами, потому что эти адреса ранее уже кому-то давали. Тут уже лотерея.

По возможности стоит искать тех, кто может продать всё выше перечисленное за крипту. Но это для продвинутых. Даже если вы сможете первые два пункта как-то зарешать — честь вам и хвала.

А теперь к делу.
Ранее я писал, как спрятать VPN за Cloudflare. Но это не помогло, потому что добрались и до половины интернета. Этому тоже есть альтернативы, но о них я только намекну в конце статьи.

Итак, нам нужна VPS, домен yapidor.example.com и docker.


  1. Создаём рабочие директории:
mkdir -p /root/certbot_etc /root/certbot_www
  1. Проверяем, есть ли уже сертификат:
ls /root/certbot_etc/live/yapidor.example.com/fullchain.pem

Если файла нет — идём дальше.

  1. Получаем сертификат через standalone (nginx в этот момент не должен быть запущен):
docker run --rm --name certbot \
  -v /root/certbot_etc:/etc/letsencrypt \
  -v /root/certbot_www:/var/www/certbot \
  -p 80:80 -p 443:443 \
  certbot/certbot certonly \
  --standalone \
  --agree-tos --no-eff-email \
  --email email@google.com \
  -d yapidor.example.com
  1. Кладём заглушку для сайта. Сделайте какой-то простенький landing page с нейросетью, чтобы это выглядело как какой-то сайт в интернете:
cp files/index.html /root/index.html
chmod 644 /root/index.html

Добавляем конфиг nginx, чтобы было примерно так. Тоже прям /root кидаем. Обрати внимание на /75zfvok754jbi132asn5. По этому пути в будущем у нас будет админка 3x-ui:

# HTTP - redirect + ACME
server {
  listen 80;
  listen [::]:80;
  server_name yapidor.example.com;

  location /.well-known/acme-challenge/ {
    root /var/www/certbot;
    allow all;
  }

  location / {
    return 301 https://$host$request_uri;
  }
}

# HTTPS
server {
  listen  0.0.0.0:444;
  listen  0.0.0.0:443 ssl so_keepalive=on;
  http2 on;


  server_name yapidor.example.com;

  ssl_certificate /etc/letsencrypt/live/{{ server_domain }}/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/{{ server_domain }}/privkey.pem;

    location /75zfvok754jbi132asn5 {
        proxy_pass http://3x-ui:2053;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 52w;
    }

    location /grpc/Tun {
        if ($content_type !~ "application/grpc") {
            return 404;
        }
        grpc_set_header X-Real-IP $remote_addr;
        client_max_body_size 0;
        client_body_buffer_size 512k;
        client_body_timeout 1w;
        grpc_read_timeout 1w;
        grpc_send_timeout 1w;
        grpc_pass grpc://3x-ui:8888;
    }

    location /websocket {
        if ($http_upgrade != "websocket") {
                return 404;
        }
        proxy_pass http://3x-ui:8889;
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 52w;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}
  1. То же самое для docker-compose.yaml:
version: "3"
services:
  3x-ui:
    image: ghcr.io/mhsanaei/3x-ui:latest
    container_name: 3x-ui
    hostname: 3x-ui
    ports:
      - "2053:2053"
    volumes:
      - $PWD/db/:/etc/x-ui/
      - ./certbot_etc:/root/cert/
    environment:
      XRAY_VMESS_AEAD_FORCED: "false"
    tty: true
    restart: unless-stopped
    networks:
      - my-network

  nginx:
    image: nginx:alpine
    container_name: nginx
    hostname: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - ./certbot_etc:/etc/letsencrypt
      - ./certbot_www:/var/www/certbot
      - ./index.html:/var/www/html/index.html
    restart: unless-stopped
    networks:
      - my-network

networks:
  my-network:
    driver: bridge
  1. Если конфиги поменялись, перегружаем nginx:
cd /root
docker compose down
docker compose up -d
  1. Добавляем крон на продление сертификата:
crontab -e

И туда:

0 0 * * 0 docker run --rm --name certbot -v /root/certbot_etc:/etc/letsencrypt -v /root/certbot_www:/var/www/certbot certbot/certbot renew --webroot --webroot-path /var/www/certbot
5 0 * * 0 docker exec nginx nginx -s reload

По идее все готово. Осталось настроить сам XRay.

Сначала твоя панель станет доступна по адресу VPS на порту 2053. Заходим в нее:
http://yapidor.example.com:2053

Логин и пароль - admin:admin. Сразу же залетаем в Panel Settings в раздел Authentication и там меняем логин и пароль на что-то посложнее:

В первой вкладке General в том же Panel Settings находим URI Path и меняем его на тот location, что мы ранее указали в nginx - /75zfvok754jbi132asn5

Всё, панель теперь доступна будет через nginx и станет частью нашего сайта. После этого очень советую закрыть фаерволлом вообще все кроме 80, 443 и 22 портов. То есть 2053 должен не быть доступным наружу.

Далее проходим в нашу админку через сайт: https://yapidor.example.com/75zfvok754jbi132asn5 и там заходим с нашими новыми логином и паролем.

Заходим в Inbounds и создаем подключение с Websocket. Нажимаем кнопку "Add Inbound" и примерно такое делаем:

Добавляем клиента, копируем себе его ID:

Дальше устанавливаем себе nekoray из Play Market. И настраиваем подключение.
Тут ключевой момент в том, что просто отсканировать QR из панели не получится, потому что панель у нас не стоит на входе. Мы хостим сайт через nginx и через него же создаем коннект с VPN. Или можно отсканировать, но придется кое-что поменять. Но я сейчас просто напишу, что именно надо вбить в Nekoray:
1. Сервер: yapidor.example.com
2. Удаленный порт: 443
3. Логин пользователя: ID, который мы получили при добавлении клиента
4. Сеть: ws
5. Хост WebSocket: yapidor.example.com
6. Путь к WebSocket: /websocket
7. Шифрование транспортного уровня: tls
8. uTLS fingerprint: chrome

Сохраняем, выбираем профиль, который создали, нажимаем самолетик, все должно работать.

Для провайдера это выглядит как обычный https трафик на сайт в интернете. Попадете ли вы под DPI? Да, такое возможно, потому что DPI не палит вашу работу с удаленным сайтом, а анализирует поведение. Но вероятность не так высока, если вы используете это только для себя и точечно.

Под точечным я имею в виду, что ваш клиент настроен на работу так, чтобы через VPN ходить только на заблокированные сайты. На сайты в РФ вам необходимо ходить через вашего провайдера, тогда это будет наиболее эффективно и проживет дольше (если не всегда).

Кроме того, сам Nekoray позволяет добавлять в VPN именно приложения, то есть используйте для VPN например только приложение Instagram, но не все остальные.


P.S. Я не пробовал, но вероятно это тоже могло бы сработать. Есть такая штука - pangolin. Это аналог тоннелей для Zero Trust от Cloudflare. Только self-hosted и open source. Вы можете попробовать провернуть схему как с тоннелями, о которой я писал раньше. Покупаете VPS в РФ, на ней ставите Pangolin, к нему подключаете VPS из Европы и далее все по той же схеме.

Но я не уверен, что это будет работать стабильно, поскольку внутри таких решений используется Wireguard, хоть и немного кастомный. Трафик между VPS все равно будет попадать под DPI. Но попробовать можно, почему бы и нет. Pangolin вполне в силах решить вопрос с получением серта.


P.P.S. Возможно стоит под ваш фейковый домен купить вполне себе официальный сертификат не от LetsEncrypt, а какой-нибудь Comodo на годик. Это со стороны тоже будет смотреться чуть лучше при открытии сайта. Но не факт, что и это поможет.