Свой VPN на 3x-ui

Инструкция · XorekCloud · ноябрь 2026

Свой VPN на 3x-ui со своим доменом

От заказа сервера до подключения: VPS и домен в XorekCloud, 3x-ui с сертификатом Let's Encrypt, nginx-заглушка, бан сканеров и подключение с телефона.

на скриншотах: куда нажимать и в каком порядке Нажмите на скриншот, чтобы открыть его крупно

Что получится в итоге

  • VPS с панелью 3x-ui в любой локации и на любом тарифе. В примере — Финляндия.
  • Ваш домен (в примере — 213awsdasd.top) с настоящим сертификатом Let's Encrypt, который продлевается сам.
  • Подключение VLESS на порту 443. Всё, что не является вашим VPN-клиентом (браузер, сканер, «проверяльщик»), видит обычный сайт.
  • Панель и подписка спрятаны за nginx по секретным путям. Снаружи открыты только 22, 80, 443.
  • Подсети известных сканеров (ГРЧЦ, CyberOK «СКИПА», F6) забанены на входе. Список обновляется сам каждый день.
  • Сервер не ходит на российские сайты и IP. Так IP VPS не «светится» как выход VPN: по наблюдениям на ntc.party за это тоже банят.

В статье два варианта, выберите один:

Вариант А (основной) Вариант Б
Протокол VLESS + TCP + TLS + Vision VLESS + TCP + Reality + Vision
Сертификат для клиентов ваш сертификат Let's Encrypt (TLS делает Xray) ваш же сертификат, его отдаёт nginx через Reality («selfsteal»)
Кто отвечает «чужим» на 443 Xray → fallback → nginx (сайт) Reality → nginx (сайт)

Оба варианта используют один и тот же nginx и один и тот же сайт-заглушку. Разница только в одной вкладке настроек подключения.

Что понадобится

  • Аккаунт в личном кабинете XorekCloud (my.xorek.cloud) с деньгами на балансе.
  • Домен. Как его заказать — в шаге 2.
  • VPS в любом дата-центре и на любом тарифе: Германия, Нидерланды, Финляндия — инструкция везде одинаковая. Для VPN на несколько человек хватает 1 vCPU и 1–2 ГБ RAM. В примере взят тариф FI-E-2 (Финляндия, 1 vCPU, 2 ГБ RAM, 30 ГБ NVMe, канал 1 Гбит/с) за 459 ₽/мес.
  • SSH-клиент. В Windows 10/11 он встроен: откройте «Терминал» или PowerShell. В macOS и Linux — обычный «Терминал».
  • 40–60 минут вручную или 10 минут с автоустановкой.

Быстрая установка одной командой

Если не хочется настраивать всё руками, шаги 7–17 делает скрипт:

  1. Закажите сервер и домен (шаги 1–4).
  2. Пропишите A-запись домена на IP сервера (шаг 5). Можно поддомен, например vpn.ваш-домен.ru.
  3. Подключитесь к серверу по SSH (шаг 6) и выполните одну команду, подставив свой домен:
bash
bash <(curl -Ls https://nastoika.net/3xui.sh) -d vpn.example.com

Через 5–10 минут скрипт выдаст адрес панели, логин и пароль, ссылку подписки и QR-код для телефона. Всё это он сохранит в /root/3xui-info.txt.

Автоустановка: вывод скрипта на новом сервере

Скрипт делает всё то же, что описано ниже: - обновляет систему, ставит 3x-ui официальным установщиком; - выпускает сертификат Let's Encrypt на домен и настраивает автопродление; - поднимает nginx с сайтом-заглушкой (случайный из нескольких вариантов, чтобы серверы не были одинаковыми); - прячет панель и подписку на 127.0.0.1 за nginx по случайным секретным путям; - создаёт подключение VLESS + TLS + Vision на 443 с uTLS firefox и первого клиента; - оставляет открытыми только SSH, 80 и 443, банит подсети сканеров РКН, запрещает серверу ходить в РФ; - в конце сам проверяет: сайт открывается, подписка отдаёт ссылку, тестовое подключение через VPN работает.

Ключ Что делает
-d домен домен, который уже указывает на сервер (без него скрипт спросит)
--reality VLESS + Reality selfsteal вместо TLS (вариант Б)
--client имя имя первого клиента, по умолчанию user1
--no-rkn не банить подсети сканеров РКН
--no-ru-block разрешить серверу ходить на российские сайты
--no-upgrade не обновлять систему

Шаг 1Вход в личный кабинет

Откройте https://my.xorek.cloud/ и войдите со своими логином и паролем.

Вход в личный кабинет
Главная страница кабинета

Шаг 2Заказ домена

Если домен уже есть, переходите к шагу 3. В примере используется уже купленный 213awsdasd.top.

  1. Откройте Товары/Услуги → Домены. Там видны ваши домены. Нажмите Регистрация.

    Список доменов
  2. Откроется прайс зон. Смотрите не только на цену регистрации, но и на цену продления: например, .top стоит 600 ₽ в первый год и 2 500 ₽ за продление.

    Цены на домены
  3. Введите имя без зоны и нажмите Проверить. Выбирайте нейтральное имя, без слов vpn, proxy и подобных (myvpn-example на скриншоте — только для примера).

    Проверка имени
  4. Нажмите ⊕ у нужной зоны, затем Зарегистрировать.

    Выбор зоны
  5. На странице «Настройка доменов»:

    • Период: 1 год.
    • Владелец: профиль с вашими данными. Если профиля нет, создайте его кнопкой «Редактировать».
    • Автопродление: по желанию.
    Настройка заказа домена
  6. В блоке Серверы имён (NS) оставьте включённым «Серверы имён провайдера». Тогда DNS-записи можно будет править прямо в кабинете (шаг 5).

    Серверы имён
  7. Нажмите Оплатить. Домен появится в разделе «Домены» со статусом «Активен».

Шаг 3Заказ сервера

  1. Товары/Услуги → Виртуальные серверы.

    Меню «Виртуальные серверы»
  2. Нажмите Заказать.

    Список серверов
  3. Откроется список тарифов. Нажмите Дата-центр.

    Список тарифов
  4. Отметьте страну, где нужен сервер, и нажмите Выбрать. Подходит любая локация, дальше всё делается одинаково. На скриншоте выбрана Финляндия.

    Фильтр по дата-центру
  5. У любого подходящего тарифа нажмите Заказать. Для VPN на несколько человек хватает 1 vCPU и 1–2 ГБ RAM, больше нужно, только если пользователей десятки.

    Тариф FI-E-2
  6. Выберите Операционную систему: Ubuntu 24.04 (стрелка у Ubuntu) и Период оплаты.

    Выбор ОС
  7. Внизу формы поставьте галочку «Я прочитал и согласен с условиями предоставления услуг». При желании выключите Автопродление. Нажмите Оплатить.

    Условия и оплата
  8. Выберите способ оплаты, например Лицевой счёт, и снова нажмите Оплатить.

    Способ оплаты
    Заказ оплачен
  9. Сервер появится в списке со статусом «Обрабатывается (открытие)». Через 1–2 минуты он станет «Активен».

    Сервер создаётся
    Сервер готов

Шаг 4Данные для входа на сервер

Отметьте сервер галочкой. На панели инструментов нажмите стрелку > справа, затем Инструкция.

Кнопка «Инструкция»

В инструкции указаны IP-адрес, пользователь root и пароль. Сохраните их.

Инструкция с данными сервера

Шаг 5A-запись домена: домен → IP сервера

  1. Товары/Услуги → Домены. Отметьте домен и нажмите DNS.

    Выбор домена
  2. Откроется DNS-зона. Нам нужна запись типа A с именем @ (сам домен без поддомена).

    DNS-зона домена
  3. Отметьте запись @ и нажмите Изменить. Если записи @ нет, нажмите Добавить и выберите тип A, имя @.

    Выбор записи
  4. В поле Значение впишите IP сервера из шага 4, TTL поставьте «15 минут», нажмите Ok.

    Редактирование A-записи
    Запись @ указывает на IP сервера

Проверьте, что домен уже смотрит на новый IP. В Windows:

bash
nslookup 213awsdasd.top 1.1.1.1

В ответе должен быть IP сервера. В нашем случае запись обновилась примерно за минуту, но иногда это занимает до нескольких часов. Не переходите к шагу 8, пока домен не указывает на сервер, иначе сертификат не выпустится.

Шаг 6Подключение к серверу по SSH

Откройте терминал (в Windows — «Терминал» или PowerShell) и выполните:

bash
ssh root@152.234.237.183
  • При первом подключении на вопрос Are you sure you want to continue connecting ответьте yes.
  • Затем вставьте пароль из инструкции (правой кнопкой мыши или Ctrl+Shift+V) и нажмите Enter. Символы пароля на экране не отображаются — это нормально.
Вход по SSH

Шаг 7Обновление системы

bash
apt update && apt upgrade -y
apt update

Если в конце видно Pending kernel upgrade, перезагрузите сервер и через минуту подключитесь снова (шаг 6):

bash
reboot
Обновление завершено

Шаг 8Установка 3x-ui и сертификата на домен

Запустите официальный установщик:

bash
bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)
Начало установки

Установщик задаст вопросы. Отвечайте так:

Вопрос установщика Что ответить
Choose [1]: (база данных) 1 (SQLite)
Would you like to customize the Panel Port settings? [y/N] y
Please set up the panel port: любой свободный порт от 1024 до 65535, кроме 80, 443 и 2096. В примере 47821
Choose an option (default 2 for IP): 1 — Let's Encrypt for Domain
Please enter your domain name: 213awsdasd.top
Please choose which port to use (default is 80): 80 или просто Enter
Would you like to modify --reloadcmd for ACME? (y/n) n
Would you like to set this certificate for the panel? (y/n) y
Выбор способа выпуска SSL
Выпуск сертификата Let's Encrypt

В выводе может появиться строка Failed to restart x-ui.service: Unit x-ui.service not found. При первой установке это нормально: служба создаётся чуть позже тем же скриптом.

Сертификат установлен в панель

В конце установщик выведет логин, пароль, порт, WebBasePath (секретный путь) и Access URL. Обязательно сохраните их. Позже их можно посмотреть командой x-ui settings или в файле /etc/x-ui/install-result.env.

Данные для входа в панель

Заодно установщик ставит fail2ban и включает автозапуск панели.

Установка завершена

Где лежит сертификат: /root/cert/213awsdasd.top/fullchain.pem и /root/cert/213awsdasd.top/privkey.pem.

Шаг 9Первый вход в панель

Откройте Access URL из вывода установщика, вида https://213awsdasd.top:47821/<секретный-путь>/. Замок в адресной строке означает, что сертификат на домен работает. Войдите с логином и паролем из шага 8.

Страница входа 3x-ui
Дашборд 3x-ui

Шаг 10nginx и сайт-заглушка

Зачем это нужно:

  • Любой, кто зайдёт на https://213awsdasd.top/ без VPN-ключа (браузер, сканер РКН/ТСПУ), увидит обычный сайт, а не обрыв соединения или ошибку.
  • Через этот же nginx откроем панель и подписку по секретным путям на порту 443. Отдельные порты панели и подписки закроем.
  • nginx на порту 80 будет обслуживать продление сертификата.

10.1. Установка и папки

bash
apt install -y nginx
mkdir -p /var/www/213awsdasd.top /var/www/acme

10.2. Сайт-заглушка

Положите в /var/www/213awsdasd.top/ любой простой статический сайт: лендинг, блог, визитку. Главное, чтобы он выглядел как живой сайт. Простейший вариант — одна страница:

bash
nano /var/www/213awsdasd.top/index.html

(В примере это маленькая страница «фотоблога». Подойдёт любой HTML-шаблон.)

10.3. Конфиг nginx

bash
nano /etc/nginx/sites-available/213awsdasd.top

Вставьте конфиг ниже, заменив: - 213awsdasd.top на ваш домен; - /ПУТЬ_ПАНЕЛИ/ на ваш WebBasePath (из шага 8), например /Xk3pQ9vT2mLr8sYd/; - /ПУТЬ_ПОДПИСКИ/ на путь подписки: Настройки панели → Подписка → URI-путь; - 47821 на ваш порт панели.

nginx
map $http_upgrade $connection_upgrade { default upgrade; '' close; }

# Порт 80: только проверка Let's Encrypt и редирект на https
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    location /.well-known/acme-challenge/ { root /var/www/acme; }
    location / { return 301 https://213awsdasd.top$request_uri; }
}

# Сайт-заглушка + панель и подписка по секретным путям
#  8001/8002 — сюда Xray отдаёт «чужой» трафик (вариант А, TLS уже снят Xray)
#  8443      — сюда смотрит Reality (вариант Б, здесь TLS с сертификатом домена)
server {
    listen 127.0.0.1:8001 proxy_protocol;
    listen 127.0.0.1:8002 http2 proxy_protocol;
    listen 127.0.0.1:8443 ssl http2 proxy_protocol;
    server_name 213awsdasd.top;

    ssl_certificate     /root/cert/213awsdasd.top/fullchain.pem;
    ssl_certificate_key /root/cert/213awsdasd.top/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    set_real_ip_from 127.0.0.1;
    real_ip_header proxy_protocol;
    server_tokens off;
    absolute_redirect off;

    root /var/www/213awsdasd.top;
    index index.html;

    # Панель 3x-ui
    location /ПУТЬ_ПАНЕЛИ/ {
        proxy_pass https://127.0.0.1:47821;
        proxy_ssl_verify off;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    # Подписка 3x-ui
    location /ПУТЬ_ПОДПИСКИ/ {
        proxy_pass https://127.0.0.1:2096;
        proxy_ssl_verify off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }

    location / { try_files $uri $uri/ =404; }
}

Включите сайт и проверьте конфиг:

bash
rm -f /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/213awsdasd.top /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
nginx запущен

Наружу nginx слушает только порт 80. Остальные его порты висят на 127.0.0.1: их видит только Xray на этом же сервере.

Шаг 11Подключение VLESS + TLS + Vision (вариант А)

  1. В меню слева откройте Входящие и нажмите Создать подключение.

    Меню «Входящие»
    Список подключений и кнопка «Создать подключение»
  2. Вкладка Основное:

    Поле Значение
    Примечание любое, например VLESS-TLS-Vision
    Протокол vless
    Адрес пусто
    Стратегия адреса для ссылок Пользовательская
    Пользовательский адрес для ссылок 213awsdasd.top: в ссылках клиентов будет домен, а не IP
    Отключить поток XTLS выключено
    Порт 443
    Вкладка «Основное»
  3. Вкладка Протокол: «Расшифрование» и «Шифрование» оставьте none. Fallback'и настроим после вкладки «Безопасность»: они становятся доступны только после выбора TLS.

    Вкладка «Протокол»
  4. Вкладка Поток: транспорт RAW (это обычный TCP). Остальное не трогайте.

    Вкладка «Поток»
  5. Вкладка Безопасность → TLS:

    Поле Значение
    SNI 213awsdasd.top
    Мин/Макс версия 1.2 / 1.3
    uTLS firefox
    ALPN h2, http/1.1
    TLS: SNI и uTLS

    Ниже, в блоке SSL-сертификат, выберите «Путь к сертификату» и нажмите «Установить сертификат панели». Поля заполнятся путями /root/cert/213awsdasd.top/fullchain.pem и .../privkey.pem.

    TLS: сертификат

    Блок ECH оставьте пустым.

    Низ вкладки «Безопасность»
  6. Вернитесь на вкладку Протокол. В блоке Fallback'и дважды нажмите «Добавить фолбэк» и заполните:

    SNI ALPN Path Dest xver
    1 — — — 127.0.0.1:8001 1
    2 — h2 — 127.0.0.1:8002 1

    Так всё, что пришло на 443 и не является вашим VLESS-клиентом, уходит в nginx: браузеры с HTTP/2 — на 8002, остальные — на 8001. xver 1 передаёт nginx настоящий IP посетителя (PROXY protocol).

    Fallback на nginx
  7. Нажмите Создать.

    Подключение создано

Шаг 12Клиент (пользователь VPN)

В 3x-ui v3 клиенты вынесены на отдельную страницу и привязываются к одному или нескольким подключениям.

  1. Откройте Клиенты → Добавить клиентов.

    Страница «Клиенты»
  2. Вкладка Основное:

    • Email: любое имя клиента, например my-phone.
    • По желанию задайте лимиты: трафика в ГБ, IP, HWID, срок действия.
    Клиент: основное

    Ниже, в поле Привязанные входящие, выберите созданное подключение.

    Привязка к подключению
  3. Вкладка Учетные данные → Flow: xtls-rprx-vision. UUID и остальное сгенерируются сами.

    Flow xtls-rprx-vision
  4. Нажмите Создать.

    Клиент создан
  5. Иконка QR в строке клиента покажет:

    • Информация о подписке: QR и ссылку на подписку. Удобно, если подключений несколько, клиенты сами её обновляют.

      QR подписки
    • Блок Vless TCP TLS: QR и ссылку vless:// на конкретное подключение. Иконка копирования рядом с названием.

      QR ссылки vless

Ссылка выглядит так (UUID заменён):

текст
vless://<UUID>@213awsdasd.top:443?alpn=h2%2Chttp%2F1.1&encryption=none&flow=xtls-rprx-vision&fp=firefox&security=tls&sni=213awsdasd.top&type=tcp#VLESS-TLS-Vision-my-phone

Шаг 13Прячем панель и подписку за nginx

  1. Настройки панели → Панель → IP-адрес для управления панелью: 127.0.0.1 → Сохранить.

    Панель слушает только localhost
  2. Настройки панели → Подписка:

    • Прослушивание IP: 127.0.0.1.
    • URI обратного прокси: https://213awsdasd.top/ПУТЬ_ПОДПИСКИ/. Тогда в QR и ссылках подписки будет адрес на порту 443.

    Нажмите Сохранить → Перезапустить панель.

    Подписка за nginx

Теперь: - панель: https://213awsdasd.top/ПУТЬ_ПАНЕЛИ/; - подписка: https://213awsdasd.top/ПУТЬ_ПОДПИСКИ/<subId>; - порты 47821 и 2096 снаружи не отвечают.

Где лежат пути к сертификату панели: Настройки панели → Панель → вкладка «Сертификаты».

Сертификат панели

Шаг 14Продление сертификата через nginx

Установщик выпустил сертификат в режиме standalone: acme.sh сам занимал порт 80. Теперь порт 80 занят nginx, поэтому переводим продление на webroot и задаём команду, которая после продления перезагружает nginx и Xray:

bash
~/.acme.sh/acme.sh --issue -d 213awsdasd.top -w /var/www/acme --server letsencrypt --force
~/.acme.sh/acme.sh --install-cert -d 213awsdasd.top --ecc \
  --key-file /root/cert/213awsdasd.top/privkey.pem \
  --fullchain-file /root/cert/213awsdasd.top/fullchain.pem \
  --reloadcmd 'systemctl reload nginx; systemctl restart x-ui'
Перевыпуск через webroot

Сертификат живёт 90 дней. acme.sh продлевает его сам: проверка идёт по cron 4 раза в сутки, ближайшее продление видно в строке Next renewal time. Посмотреть список сертификатов можно командой ~/.acme.sh/acme.sh --list.

Шаг 15Фаервол: открыты только 22, 80, 443

bash
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
ufw status verbose

На вопрос Proceed with operation (y|n)? ответьте y. Правило для 22 (SSH) добавляется до включения, иначе вы потеряете доступ к серверу.

ufw: открыты 22, 80, 443
  • 443: VPN и сайт.
  • 80: продление сертификата и редирект на https.
  • 22: SSH.

Порт панели и порт подписки не открываем: они доступны только через nginx.

Шаг 16Бан подсетей сканеров РКН

Что это даёт и чего не даёт. На ntc.party собрали адреса, с которых сканируют серверы: ФГУП ГРЧЦ (AS61280), CyberOK «СКИПА», F6. Бан этих подсетей — гигиена: сканер не увидит, что у вас открыто. Но это не броня. Волны блокировок 04.08 и 21.09.2026 били целыми пачками IP популярных хостеров, и бан сканеров от такого не спасает.

Какие списки используем:

Источник Что внутри Обновление
shadow-netlab/traffic-guard-lists только antiscanner (ГРЧЦ) периодически
tread-lightly/CyberOK_Skipa_ips сканер CyberOK «СКИПА» периодически
RIPEstat, AS61280 актуальные префиксы ГРЧЦ, включая IPv6 при каждом запуске
вручную 85.142.100.0/24 (СКИПА, из abuse policy самого CyberOK), F6: 46.161.48.0/22, 95.215.0.0/24, 45.91.64.0/24 —

16.1. ipset и скрипт обновления

bash
apt install -y ipset
nano /usr/local/sbin/rkn-blocklist-update.sh
bash
#!/usr/bin/env bash
# Обновляет ipset-наборы rkn4/rkn6 подсетями сканеров РКН/ГРЧЦ/CyberOK/F6.
set -euo pipefail
URLS=(
  https://raw.githubusercontent.com/shadow-netlab/traffic-guard-lists/refs/heads/main/public/antiscanner.list
  https://raw.githubusercontent.com/tread-lightly/CyberOK_Skipa_ips/refs/heads/main/lists/skipa_cidr.txt
)
ASNS="61280"                                    # ФГУП ГРЧЦ: свежие анонсы из RIPEstat
EXTRA="85.142.100.0/24 46.161.48.0/22 95.215.0.0/24 45.91.64.0/24"   # CyberOK СКИПА, F6
ALLOW=/etc/rkn-allow.txt                        # свои адреса, которые банить нельзя

T=$(mktemp -d); trap 'rm -rf "$T"' EXIT
for u in "${URLS[@]}"; do
  curl -fsSL --retry 3 --max-time 60 "$u" >> "$T/raw" || echo "WARN: не скачался $u" >&2
  echo >> "$T/raw"
done
for a in $ASNS; do
  curl -fsSL --max-time 60 "https://stat.ripe.net/data/announced-prefixes/data.json?resource=AS$a" \
    | grep -oE '"prefix": ?"[^"]+"' | cut -d'"' -f4 >> "$T/raw" || echo "WARN: RIPEstat AS$a" >&2
done
echo "$EXTRA" | tr ' ' '\n' >> "$T/raw"

sed -e 's/#.*//' -e 's/[[:space:]]//g' "$T/raw" | grep -E '^[0-9a-fA-F:.]+(/[0-9]{1,3})?$' | sort -u > "$T/all" || true
N=$(wc -l < "$T/all")
[ "$N" -ge 50 ] || { echo "Подозрительно мало записей ($N), оставляю старые наборы" >&2; exit 1; }

{
  echo "create rkn4_tmp hash:net family inet hashsize 4096 maxelem 131072"
  echo "create rkn6_tmp hash:net family inet6 hashsize 1024 maxelem 32768"
  awk '!/:/{print "add rkn4_tmp "$0} /:/{print "add rkn6_tmp "$0}' "$T/all"
  if [ -s "$ALLOW" ]; then sed -e 's/#.*//' "$ALLOW" | awk 'NF && $1 !~ /:/ {print "add rkn4_tmp "$1" nomatch"}'; fi
} > "$T/restore"

ipset list -n rkn4 >/dev/null 2>&1 || ipset create rkn4 hash:net family inet hashsize 4096 maxelem 131072
ipset list -n rkn6 >/dev/null 2>&1 || ipset create rkn6 hash:net family inet6 hashsize 1024 maxelem 32768
ipset destroy rkn4_tmp 2>/dev/null || true; ipset destroy rkn6_tmp 2>/dev/null || true
ipset restore -exist < "$T/restore"
ipset swap rkn4_tmp rkn4 && ipset swap rkn6_tmp rkn6
ipset destroy rkn4_tmp && ipset destroy rkn6_tmp
{ ipset save rkn4; ipset save rkn6; } > /etc/ipset-rkn.conf.new && mv /etc/ipset-rkn.conf.new /etc/ipset-rkn.conf
echo "OK: $N подсетей (IPv4: $(ipset list rkn4 | grep -c '^[0-9]'), IPv6: $(ipset list rkn6 | grep -c '^[0-9a-f]*:'))"
bash
chmod +x /usr/local/sbin/rkn-blocklist-update.sh
touch /etc/rkn-allow.txt
/usr/local/sbin/rkn-blocklist-update.sh

Проверьте, что свой IP не попал в список: ipset test rkn4 ВАШ_IP.

Первое обновление списков

16.2. Автозапуск и ежедневное обновление

/etc/systemd/system/rkn-ipset-restore.service поднимает наборы до ufw. Если набора нет, ufw не стартует, и сервер останется без фаервола.

systemd
[Unit]
Description=Restore RKN ipsets before ufw
DefaultDependencies=no
After=local-fs.target
Before=ufw.service network-pre.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c '[ -s /etc/ipset-rkn.conf ] && ipset restore -exist -f /etc/ipset-rkn.conf; ipset list -n rkn4 >/dev/null 2>&1 || ipset create rkn4 hash:net family inet hashsize 4096 maxelem 131072; ipset list -n rkn6 >/dev/null 2>&1 || ipset create rkn6 hash:net family inet6 hashsize 1024 maxelem 32768'

[Install]
WantedBy=ufw.service

/etc/systemd/system/rkn-blocklist-update.service:

systemd
[Unit]
Description=Update RKN scanners ipset blocklists
Wants=network-online.target
After=network-online.target rkn-ipset-restore.service

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/rkn-blocklist-update.sh

/etc/systemd/system/rkn-blocklist-update.timer:

systemd
[Unit]
Description=Daily RKN blocklist update

[Timer]
OnCalendar=*-*-* 05:00:00
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target

16.3. Правило в ufw

Откройте /etc/ufw/before.rules и сразу после строки

текст
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

добавьте:

текст
# RKN/gov blocklist (только новые входящие)
-A ufw-before-input -m set --match-set rkn4 src -m limit --limit 10/min -j LOG --log-prefix "RKN-DROP: "
-A ufw-before-input -m set --match-set rkn4 src -j DROP

В /etc/ufw/before6.rules то же самое после строки с ufw6-before-input ... RELATED,ESTABLISHED, только цепочка ufw6-before-input и набор rkn6.

Включите всё:

bash
systemctl daemon-reload
systemctl enable rkn-ipset-restore.service
systemctl enable --now rkn-blocklist-update.timer
ufw reload
iptables -L ufw-before-input -n -v | grep rkn
systemctl list-timers rkn-blocklist-update.timer
Правила и таймер включены

Проверено: после reboot наборы восстанавливаются, ufw поднимается, правила на месте.

Через неделю посмотрите, срабатывает ли бан: journalctl -k | grep RKN-DROP и счётчики в iptables -L ufw-before-input -n -v.

Шаг 17Сервер не ходит в РФ

На ntc.party в ноябре 2026 описали баны IP, через которые VPS ходил на российские сайты. Входящих подключений из РФ на эти IP при этом не было. XTLS в эталонной конфигурации тоже советует запрещать трафик «обратно» в страну цензора. Поэтому запрещаем серверу ходить на российские IP и домены.

  1. Маршрутизация → Базовые соединения:

    • Заблокированные IP-адреса: Private IPs (уже стоит) + Russia;
    • Заблокированные домены: Russia + .ru.

    Нажмите Сохранить.

    Блокировка РФ

    На вкладке «Маршрутизация» это превратится в правила geoip_RU.dat:ru и geosite_RU.dat:ru-available-only-inside + *.ru → blocked.

    Правила маршрутизации
  2. Конфигурации Xray → Основные настройки → Настройка маршрутизации доменов: IPIfNonMatch → Сохранить. Без этого правила по IP (geoip:ru) не срабатывают, когда клиент передаёт домен: vk.com не в зоне .ru, но его IP российские.

    Стратегия маршрутизации доменов
  3. Входящие → карандаш у подключения → вкладка Сниффинг: Включить, протоколы HTTP, TLS, QUIC, Только маршрутизация — включено. Так доменные правила сработают, даже если клиент передаёт IP вместо домена, например в режиме TUN.

    Сниффинг

Проверка через туннель на тестовом сервере: ifconfig.me и github.com открываются, ya.ru, gosuslugi.ru и vk.com блокируются.

Шаг 18Проверка

  1. Откройте https://213awsdasd.top/ в обычном браузере без VPN. Должен открыться сайт-заглушка.

    Сайт-заглушка
  2. Откройте https://213awsdasd.top/случайный-путь. Должна прийти обычная страница 404 от nginx.

  3. Порт 47821 снаружи открываться не должен.
  4. Подключитесь клиентом (шаг 19) и откройте https://ifconfig.me (через VPN). Должен показаться IP сервера. В панели на странице «Входящие» пойдёт трафик.

    Трафик в панели

На тестовом сервере через VPN-туннель 50 МБ скачались примерно за 0,7 секунды (около 500 Мбит/с, замер с самого сервера).

Шаг 19Приложения для подключения

Платформа Приложения
Windows v2rayN, Happ, Hiddify, v2RayTun
macOS Happ, v2RayTun, Hiddify, FoXray
Android v2rayNG, Happ, v2RayTun, Hiddify
iOS / iPadOS Happ, v2RayTun, Streisand, FoXray, V2Box, Shadowrocket (платный)
Linux Hiddify, Happ, NekoRay

Как добавить подключение (во всех приложениях похоже): - QR-код: «+» → «Сканировать QR» → наведите камеру на QR из шага 12. - Ссылка: скопируйте vless://… или ссылку подписки → «+» → «Импорт из буфера обмена». - Подписка: «+» → «Добавить подписку» → вставьте https://213awsdasd.top/ПУТЬ_ПОДПИСКИ/<subId>. Приложение будет само подтягивать изменения.

Обязательно включите в приложении раздельную маршрутизацию «Россия напрямую». Сервер российские адреса блокирует (шаг 17), так что без неё ру-сайты через VPN не откроются.

Если в российском App Store нужного приложения нет, обычно его скачивают с Apple ID другого региона.

Вариант Б. VLESS + Reality «selfsteal»

Чем отличается. В варианте А TLS-сессию с клиентом устанавливает сам Xray своим сертификатом. В Reality сервер «одалживает» TLS-рукопожатие у сайта-цели. Здесь цель — наш собственный nginx на 127.0.0.1:8443 с сертификатом нашего домена (отсюда «selfsteal»). Посторонний, включая сканер, видит настоящий сертификат 213awsdasd.top и сайт-заглушку. Клиент с правильным ключом получает VPN.

Что нужно. Тот же nginx из шага 10: в конфиге уже есть listen 127.0.0.1:8443 ssl http2 proxy_protocol. Тот же сертификат, тот же клиент.

Что говорит практика (ntc.party, осень 2026). - Большинство банов IP, которые там разбирали, пришлось на Reality, замаскированный под чужие популярные сайты: Google, Apple, Yandex. Selfsteal со своим доменом заметно безопаснее, но самым надёжным там называют вариант А (TLS со своим доменом). - При selfsteal соседи по хостингу могут начать использовать ваш сервер как цель своего Reality. Советуют закрыть входящий 443 из подсети своего хостера: ufw insert 1 deny proto tcp from <подсеть хостера>/22 to any port 443. Делайте это осторожно: если в той же подсети ваш мониторинг или другие серверы, они тоже отрежутся. - Официальная документация 3x-ui советует брать в Reality сайт, который вам не принадлежит. Selfsteal — практика сообщества, учтите это.

  1. Входящие → Создать подключение. Вкладки «Основное», «Протокол» и «Поток» заполните как в шаге 11, только без fallback'ов: в Reality они не нужны.
  2. Вкладка Безопасность → Reality:

    Поле Значение
    Xver 1: nginx ждёт PROXY protocol
    uTLS firefox
    Цель 127.0.0.1:8443
    SNI 213awsdasd.top
    Short IDs, SpiderX сгенерированы автоматически, не трогайте
    Reality: цель и SNI

    Ключи (публичный и приватный) тоже сгенерированы сами. Кнопка «Получить новый сертификат» создаёт новую пару.

    Reality: ключи
  3. Нажмите Создать.

    Reality-подключение создано
  4. Клиенты → карандаш у клиента → в Привязанные входящие добавьте Reality-подключение → Сохранить. Flow у клиента остаётся xtls-rprx-vision.

    Привязка клиента к Reality
  5. QR и ссылку берите так же, как в шаге 12, блок Vless TCP REALITY.

    QR Reality
    Reality работает

Ссылка Reality содержит security=reality, sni=213awsdasd.top, fp=firefox, pbk=<публичный ключ>, sid=<short id>.

Полезные команды

Меню x-ui
Команда Зачем
x-ui меню управления
x-ui settings показать порт, путь и логин панели
x-ui status / x-ui restart статус / перезапуск
x-ui log логи
x-ui update обновить 3x-ui
меню x-ui → 7 сбросить логин и пароль
меню x-ui → 8 сменить секретный путь панели (не забудьте поправить location в nginx)
меню x-ui → 20 управление SSL-сертификатами
меню x-ui → 24 SSH-туннель к панели
меню x-ui → 26 включить BBR
~/.acme.sh/acme.sh --list список сертификатов и даты продления
nginx -t && systemctl reload nginx проверить и применить конфиг nginx

Частые проблемы

Симптом Причина и решение
Сертификат не выпускается Домен ещё не указывает на сервер (проверьте nslookup). Закрыт порт 80. Включено «оранжевое облако» Cloudflare. Неверная AAAA-запись
Браузер ругается на сертификат панели На вопрос про SSL нажали Enter и получили сертификат на IP. Решение: x-ui → 20 → выпустить для домена и поставить на панель
Пропал доступ к панели после шага 13 Панель слушает 127.0.0.1, а nginx-путь или fallback настроены неверно. Откройте туннель ssh -L 47821:127.0.0.1:47821 root@IP и зайдите на https://127.0.0.1:47821/ПУТЬ_ПАНЕЛИ/ (предупреждение о сертификате ожидаемо). Исправьте настройки
На https://домен/ пустой ответ или обрыв Нет fallback'ов (вариант А) или неверная цель или xver (вариант Б). Проверьте nginx -t и что nginx слушает 8001, 8002, 8443: ss -tlnp \| grep nginx
Клиент «подключён», но трафика нет Flow клиента не xtls-rprx-vision. Не совпадают SNI или fp. Включено подключение не того варианта. Попробуйте другой uTLS (firefox → edge/safari)
port 443 already used by inbound На 443 уже есть подключение, даже выключенное. Смените ему порт или удалите
Сертификат не продлился Закрыт порт 80 или nginx не отдаёт /.well-known/acme-challenge/. Проверьте: ~/.acme.sh/acme.sh --renew -d 213awsdasd.top --force
Через VPN не открываются российские сайты Так задумано (шаг 17). Включите в клиенте «Россия напрямую»
После перезагрузки ufw не поднялся Не создались ipset-наборы. Проверьте systemctl status rkn-ipset-restore и что он включён (systemctl enable rkn-ipset-restore)
VPN «резко перестал работать», а сайт-заглушка снаружи открывается Сначала проверьте, не режет ли клиента ваш же фаервол: journalctl -k -g RKN-DROP --since "-1h". Если там адреса вашего провайдера — уберите из шага 16 широкие списки или впишите адрес в /etc/rkn-allow.txt и запустите /usr/local/sbin/rkn-blocklist-update.sh. Если дропов нет, проверьте IP с российских узлов на check-host.net

Источники