Настройка VPN (vless ws tls)

Настройка VPN (vless ws tls)

Serv.Host

Перейдите в браузер и откройте сайт https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html. Скачайте программу PuTTY для вашей операционной системы.

После этого установите PuTTY на компьютер.

Во время установки нажимайте Next, затем Finish. При необходимости можно снять флажок View README file.


Шаг 1. Подготовка домена и серверов

На сайте регистратора доменов (например, beget.com) приобретите домен в зоне .ru (или любой другой).

Зарегистрируйтесь на Cloudflare, добавьте туда домен с помощью кнопки Add -> Connect domain.

Замените NS-записи у вашего регистратора на те, что предоставил Cloudflare. (Обновление NS-записей может занимать до 24 часов).


Теперь можно перейти к покупке VPS-серверов. Откройте сайт https://my.serv.host/, зарегистрируйтесь и приобретите два сервера: один в России, второй — в Германии.


Шаг 2. Первоначальная настройка сервера в России

Подключитесь к российскому серверу по SSH через PuTTY (используя IP-адрес, логин root и пароль из письма хостинга).

Выполните команды для обновления системы и установки необходимых пакетов:


apt update && apt full-upgrade -y && apt install sudo certbot curl python3-certbot-nginx nginx ufw -y
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Генерация секретного пути

Для WebSocket нужно сгенерировать случайную строку, которая будет использоваться в качестве пути (location). Выполните следующую команду:


openssl rand -hex 16

Запишите полученную строку (например, 4a2f8b9e1c3d5f7a0b2c4d6e8f0a1b2c). В дальнейших шагах она будет упоминаться как <сгенерированный_путь>.

Выпуск SSL-сертификата

В панели управления Cloudflare в разделе DNS -> Records создайте A-запись, например up.вашдомен, указывающую на IP-адрес вашего российского сервера.

Выпустите SSL-сертификат командой:


certbot --nginx -d up.вашдомен

(Замените на ваш домен)


Шаг 3. Настройка маскировочного сайта и веб-сервера Nginx (РФ)

Создайте директорию для сайта-заглушки:


mkdir /var/www/html/site
nano /var/www/html/site/index.html

Вставьте HTML-код для имитации сайта:


<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <title>Beszel - Sign In</title>
    <script src="https://unpkg.com/lucide@latest"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
            -webkit-tap-highlight-color: transparent;
        }
        body {
            background-color: #0b0c0e;
            color: #ffffff;
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        .login-container {
            width: 100%;
            max-width: 380px;
            text-align: center;
        }
        h1 {
            font-size: 2rem;
            margin-bottom: 8px;
            font-weight: 700;
        }
        .subtitle {
            color: #71717a;
            margin-bottom: 24px;
            font-size: 0.9rem;
        }
        .input-group {
            position: relative;
            margin-bottom: 16px;
        }
        .input-icon {
            position: absolute;
            left: 12px;
            top: 50%;
            transform: translateY(-50%);
            color: #71717a;
            width: 18px;
            height: 18px;
        }
        input {
            width: 100%;
            padding: 12px 12px 12px 40px;
            background: #111214;
            border: 1px solid #27272a;
            border-radius: 8px;
            color: white;
            outline: none;
            font-size: 16px;
            transition: border-color 0.2s;
        }
        input:focus {
            border-color: #52525b;
        }
        .btn-signin {
            width: 100%;
            padding: 12px;
            background-color: #ffffff;
            color: #000000;
            border: none;
            border-radius: 8px;
            font-weight: 600;
            cursor: pointer;
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 8px;
            font-size: 0.95rem;
            transition: background 0.2s;
        }
        .btn-signin:hover { background-color: #e4e4e7; }
        .btn-signin:active { transform: scale(0.98); }
        .divider {
            margin: 24px 0;
            display: flex;
            align-items: center;
            color: #71717a;
            font-size: 0.75rem;
            font-weight: 500;
        }
        .divider::before, .divider::after {
            content: "";
            flex: 1;
            height: 1px;
            background: #27272a;
        }
        .divider span { padding: 0 10px; }
        .btn-github {
            width: 100%;
            padding: 12px;
            background: #111214;
            border: 1px solid #27272a;
            color: white;
            border-radius: 8px;
            cursor: pointer;
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 8px;
            font-size: 0.95rem;
            transition: background 0.2s;
        }
        .btn-github:hover { background: #18181b; }
        .forgot-wrapper {
            margin-top: 24px;
        }
        .forgot-password {
            color: #a1a1aa;
            text-decoration: none;
            font-size: 0.85rem;
            padding: 8px;
            border-bottom: 1px solid transparent;
            transition: all 0.3s ease;
        }
        .forgot-password:hover { 
            color: #ffffff;
            border-bottom: 1px solid #ffffff;
        }
        #error-msg {
            color: #f87171;
            font-size: 0.85rem;
            margin-bottom: 15px;
            display: none;
            background: rgba(248, 113, 113, 0.1);
            padding: 8px;
            border-radius: 6px;
        }
    </style>
</head>
<body>
    <div class="login-container">
        <h1>Beszel</h1>
        <p class="subtitle">Please sign in to your account</p>
        <div id="error-msg"></div>
        <form id="loginForm">
            <div class="input-group">
                <i data-lucide="mail" class="input-icon"></i>
                <input type="text" id="email" placeholder="name@example.com" required>
            </div>
            <div class="input-group">
                <i data-lucide="lock" class="input-icon"></i>
                <input type="password" id="password" placeholder="password" required>
            </div>
            <button type="submit" class="btn-signin">
                <i data-lucide="arrow-right" style="width: 16px;"></i> Sign in
            </button>
        </form>
        <div class="divider">
            <span>OR CONTINUE WITH</span>
        </div>
        <button class="btn-github" onclick="alert('GitHub login is not available.')">
            <i data-lucide="github" style="width: 16px;"></i> GitHub
        </button>
        <div class="forgot-wrapper">
            <a href="#" class="forgot-password" onclick="alert('Redirecting to recovery...')">Forgot password?</a>
        </div>
    </div>
    <script>
        lucide.createIcons();
        document.getElementById('loginForm').addEventListener('submit', function(e) {
            e.preventDefault(); 
            const emailInput = document.getElementById('email').value;
            const errorMsg = document.getElementById('error-msg');
            const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            if (!emailPattern.test(emailInput)) {
                errorMsg.textContent = "Please enter a valid email address.";
                errorMsg.style.display = 'block';
            } else {
                errorMsg.textContent = "Invalid email or password.";
                errorMsg.style.display = 'block';
            }
            document.getElementById('password').value = '';
        });
    </script>
</body>
</html>

Сохраните файл (Ctrl + X, затем Y, затем Enter).

Удалите стандартный конфиг Nginx и создайте новый:


rm /etc/nginx/sites-enabled/default
nano /etc/nginx/sites-available/sni.conf

Вставьте конфигурацию, заменив up.вашдомен на ваш домен, а /путь — на косую черту со сгенерированной строкой (например, /4a2f8b9e1c3d5f7a0b2c4d6e8f0a1b2c):


server {
  listen 80;
  server_name up.вашдомен;

  if ($host = up.вашдомен) {
    return 301 https://$host$request_uri;
  }

  return 404;
}

server {
  listen 443 ssl http2;
  server_name up.вашдомен;

  ssl_certificate /etc/letsencrypt/live/up.вашдомен/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/up.вашдомен/privkey.pem;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;

  ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
  ssl_session_cache shared:SSL:1m;
  ssl_session_timeout 1d;
  ssl_session_tickets off;

  root /var/www/html/site;
  index index.html;

  location ^~ /<сгенерированный путь> {
        proxy_pass http://127.0.0.1:8080;
        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_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 86400s;
        proxy_send_timeout 86400s;
        proxy_buffering off;
  }

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

Сохраните изменения. Включите конфигурацию и перезапустите Nginx:


ln -s /etc/nginx/sites-available/sni.conf /etc/nginx/sites-enabled/
systemctl restart nginx

Шаг 4. Установка Marzban на сервере в России

Установите Docker:


sudo curl -fsSL https://get.docker.com | sh

Установите панель Marzban:


sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban-scripts/raw/master/marzban.sh)" @ install

Обновите ядро Xray:


marzban core-update

Поставьте самую новую версию потом повторите ещё раз. С первого раза может установиться не сразу.


Создайте администратора панели:


marzban cli admin create --sudo

Введите имя пользователя и дважды укажите пароль (так и должно быть что пароля не видно).

Откройте на локальном компьютере командную строку (команда cmd через Win + R) и введите следующую для доступа к панели управления:


ssh -L 8000:localhost:8000 root@<IP_вашего_российского_сервера>


Откройте браузер и перейдите в панель по адресу:

http://127.0.0.1:8000/dashboard


Шаг 5. Настройка конфига на RU vps сервере

В панели Marzban перейдите в Settings (значок шестерёнки в левом меню). В поле редактирования конфигурации Xray найдите блок входящих соединений (inbounds).

Найдите и замените блок Shadowsocks TCP на этот:


{
  "tag": "VLESS WS NOTLS",
  "listen": "127.0.0.1",
  "port": 8080,
  "protocol": "vless",
  "settings": {
    "clients": [],
    "decryption": "none"
  },
  "streamSettings": {
    "network": "ws",
    "wsSettings": {
      "path": "/<сгенерированный_путь>"
    },
    "security": "none"
  },
  "sniffing": {
    "enabled": true,
    "destOverride": [
      "http",
      "tls",
      "quic"
    ]
  }
}

Убедитесь, что заменили <сгенерированный_путь> на свой путь.

Нажмите Save для применения настроек.


Шаг 6. Настройка зарубежного сервера (Германия)

Подключитесь ко второму серверу (Германия) по SSH и выполните команды:


apt update && apt full-upgrade -y && apt install sudo ufw -y
ufw allow 22/tcp
ufw allow from <IP_российского_сервера> to any port 1080
ufw enable

Установите Docker и Marzban:


sudo curl -fsSL https://get.docker.com | sh
sudo bash -c "$(curl -sL https://github.com/Gozargah/Marzban-scripts/raw/master/marzban.sh)" @ install

Обновите ядро командой

marzban core-update 

И создайте пользователя командой

marzban cli admin create --sudo

На локальном компьютере откройте еще одно окно командной строки (cmd) и пробросьте порт для второй панели на порт 8001:


ssh -L 8001:localhost:8000 root@<IP_немецкого_сервера>

Откройте в браузере адрес http://127.0.0.1:8001/dashboard, авторизуйтесь под созданными для немецкого сервера данными.

Во второй панели необходимо создать ключ для VPN, а затем вставить его в приложение v2rayTUN.

Укажите любое название и скопируйте ключ.

После этого нажмите на кнопку из скриншота и просмотрите параметры подключения.

Из конфига вам потребуются:

  • IP-адрес (Германия)
  • Порт (должен быть 1080)
  • Пароль

Шаг 7. Настройка моста через сервер в России

Вернитесь в первую панель (российский сервер, http://127.0.0.1:8000/dashboard).

Перейдите в настройки (Settings).

  1. Найдите блок "outbounds" и добавьте туда эти строки для Shadowsocks перед уже существующими блоками:
"outbounds": [
  {
    "tag": "shadowsocks",
    "protocol": "shadowsocks",
    "settings": {
      "servers": [
        {
          "address": "IP_немецкого_сервера",
          "port": 1080,
          "password": "пароль",
          "method": "chacha20-ietf-poly1305",
          "level": 0
        }
      ]
    }
  },
  {
    "protocol": "freedom",
    "tag": "DIRECT"
  },
  {
    "protocol": "blackhole",
    "tag": "BLOCK"
  }
]

Замените в полях address на ip сервера Германии и пароль на пароль из конфига.


Найдите блок "routing" -> "rules". Вставьте следующие строки:

"routing": {
  "rules": [
    {
      "ip": [
        "geoip:private"
      ],
      "outboundTag": "BLOCK",
      "type": "field"
    },
    {
      "domain": [
        "geosite:youtube"
      ],
      "outboundTag": "DIRECT"
    },
    {
      "inboundTag": [
        "VLESS WS NOTLS"
      ],
      "outboundTag": "shadowsocks"
    }
  ]
}

(Правило для YouTube чтобы был без рекламы (если гео базы на ру сервере правильные))

Нажмите Save для применения конфигурации.


Шаг 8. Настройка хостов.

Перейдите на ру сервере в раздел настройки хоста.

Нажмите на кнопку со скриншота.

Вводите данные в поля ниже

Шаг 9. Создание пользователя и подключение

  1. На российском сервере в панели (http://127.0.0.1:8000/dashboard) создайте пользователя.
  2. Задайте имя пользователя.
  3. В списке протоколов отметьте только VLESS WS NOTLS.
  4. Поле Flow оставьте пустым.
  5. Нажмите кнопку создания и скопируйте сгенерированный ключ.

Импортируйте ссылку в клиентское приложение (например, v2rayTUN, v2rayN, Nekobox или Shadowrocket) для подключения к VPN.


Report Page