Вопрос про шифрование в каскадных VPN

Добрый день!

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

Вопрос, это как-то преодолимо на практике? Не очень хочется показывать трафик хосту в РФ.
Или оно не особенно нужно, по крайней мере для веб https трафика?

Вопрос скорее всего базовый, но что-то мне не удалось нагуглить простое объяснение, если есть ссылки, буду очень благодарен.

К̶о̶г̶д̶а̶ ̶у̶ ̶В̶а̶с̶ ̶Р̶Ф̶ ̶V̶P̶S̶ ̶п̶о̶д̶к̶л̶ю̶ч̶а̶е̶т̶с̶я̶ ̶к̶ ̶н̶е̶Р̶Ф̶ ̶т̶а̶м̶ ̶е̶с̶т̶ь̶ ̶R̶e̶a̶l̶i̶t̶y̶/̶T̶L̶S̶?̶ ̶Р̶Ф̶ ̶с̶е̶р̶в̶е̶р̶ ̶д̶о̶л̶ж̶е̶н̶ ̶н̶о̶в̶о̶е̶ ̶с̶о̶е̶д̶и̶н̶е̶н̶и̶е̶ ̶у̶с̶т̶а̶н̶а̶в̶л̶и̶в̶а̶т̶ь̶ ̶с̶ ̶ш̶и̶ф̶р̶о̶в̶а̶н̶и̶е̶м̶,̶ ̶е̶с̶л̶и̶ ̶и̶д̶ё̶т̶ ̶п̶о̶д̶к̶л̶ю̶ч̶е̶н̶и̶е̶ ̶ч̶е̶р̶е̶з̶ ̶к̶о̶н̶ф̶и̶г̶.̶

̶и̶л̶и̶ ̶я̶ ̶В̶а̶ш̶е̶г̶о̶ ̶в̶о̶п̶р̶о̶с̶а̶ ̶н̶е̶ ̶п̶о̶й̶м̶у̶ ̶п̶о̶л̶н̶о̶с̶т̶ь̶ю̶?̶

Я понял суть вопроса. Обойти это можно вложенным шифрованием, клиент сам оборачивает трафик в туннель до второго сервера, потом в туннель до первого. Первый видит только зашифрованный пакет, не содержимое. По сути это то, как работает Tor. На практике реализуется как WireGuard-over-WireGuard: сначала поднимаешь интерфейс до зарубежного сервера, потом поверх него до РФ.

Если трафик HTTPS, то оператор первого VPS в любом случае видит только домены (SNI) и IP, но не содержимое.

Пока ничего вообще нет, потому что я продумываю, что и как я буду делать. Пока у меня концептуальный вопрос.

Если я буду делать на Xray, то да, VPS в РФ будет соединяться со вторым VPS по VLESS+Reality. Я пока не решил, какой именно протокол буду использовать, но обфускацию планирую.

Я не до конца понимаю, как работает Xray. Допустим, у меня он используется на обеих VPS. Когда я туннелирую трафик от клиента до РФ, а потом вне РФ, он будет расшифровываться посередине, чтобы xray на VPS в РФ мог решить, куда его направить?

Я ещё встретил тут на NTC вариант sing-box+NaiveProxy, рассматриваю такую комбинацию тоже.

Простите, если вопросы не в ту степь, скажите, если что, пжл

Да, именно так. Xray на РФ VPS терминирует туннель, видит destination, принимает роутить трафик или нет, потом либо отпускает напрямую (РФ трафик), либо заворачивает в новый туннель до зарубежного VPS. В точке принятия решения трафик расшифрован.

HTTPS трафик end-to-end зашифрован TLS, РФ VPS видит только IP/домен назначения, но не содержимое. Поэтому смысла лично я особого не вижу. Сообщение сверху обновил как это в теории можно реализовать

Я могу ошибаться, но для Вас это сути не меняет, первый сервер терминирует соединение, принимает решение роутить траффик или нет, трафик в этот момент доступен. REALITY/TLS терминируется на РФ VPS в любом случае, иначе он не поймёт даже какой это inbound. Протокол не имеет значения.

Вы всегда можете использовать один сервер как “прокладку” для подключения ко второму вне зависимости от используемого протокола. Первый сервер просто будет пересылать пакеты на второй. При этом, если это будут пакеты ВПН трафика, то они, естественно, будет зашифрованы. А их содержимое недоступно даже тому, кто получит доступ к первому серверу. Другими словами, ваш первый сервер - это такой же промежуточный узел для трафика, как и маршрутизаторы вашего провайдера и все остальные узлы сети, через которые он идет. Для этого надо на первом сервере задать правила файрвола. Вот пример для nftables, для протокола Wireguard (udp, port 51820).
#!/usr/sbin/nft -f

flush ruleset

table ip nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
iif ens3 udp dport 51820 dnat to 2.2.2.2
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oif ens3 snat to 1.1.1.1
}
}
Где 2.2.2.2 - адрес второго сервера, 1.1.1.1 - адрес первого сервера, ens3 - название основного сетевого интерфейса (посмотреть можно по команде: ip a). Порт (51820) и протокол (udp) можно поменять на свои.
Это нужно вставить в файл /etc/nftables.conf. Перезагрузить nftables: systemctl restart nftables.service. Если nftables еще не запущены, то запустить и добавить в загрузку: systemctl enbale --now nftables.service.

Сделать сплит на клиенте (РФ сайты уже блокируют РФ хостинги). На РФ сервере настроить forwarding.

Да, спасибо! Со всем согласен.

После ночи раздумий пришёл примерно к тому же. Спасибо!

Спасибо за детальный ответ,! Я так понимаю, это как раз то, что предлагает @Xunlei ?

Да. Только он предлагает использовать firewall-cmd (обертку для iptables/nftables). А я написал уже готовые правила для nftables. В целом, думаю, разницы нет. Но лучше убедитесь в том, что вы понимаете, что вы делаете, перед тем как использовать. Например, если у вас на сервере уже что-то настроено, то мои правила надо добавить в /etc/nftables.conf, а не перезаписать то, что там уже есть. Попросите ГПТ объяснить, как это работает. Думаю, быстро разберетесь.

Как уже сказали если не хочется чтоб расшифровывалось на ru vps (даже если после расшифровки один фиг останется зашифрованный https), то можно сделать вложенный тунель на клиенте.

В clash это делается через

в xray-core не пробовал, но кажется Transport (uTLS, REALITY) | Project X (поле dialerProxy).

Есть минус, что клиент знает настройки подключения ко всем серверам – кто-то из пользователей может вытянуть ключи и настроить по другому (прямое подключение к зарубежному VPS или использовать российский как exit node). Если это как риск не рассматривается, то как минимум в Clash удобно – пользователь сам может выбирать любую комбинацию ru vps + зарубежный exit node (можно так же дать возможность прямого подключения). Когда добавляется новый сервер, то на уже существующих ничего не нужно менять.

пример
proxies:
  - name: "hetzner 1"
    type: vless
    # к этому прокси подключаемся через прокси выбранный в группе со следующим именем
    dialer-proxy: "Совершать промежуточный прыжок?"
    # ...

  - name: "hetzner 2"
    type: vless
    dialer-proxy: "Совершать промежуточный прыжок?"
    # ...
    
  - name: "mow 1"
    type: vless
    # ...

  - name: "mow 2"
    type: vless
    # ...

  - name: "mow 3"
    type: vless
    # ...

  - name: "нет"
    hidden: true
    type: direct
  
proxy-groups:
  - name: "Совершать промежуточный прыжок?"
    type: select
    proxies:
      - "нет"
      - "автовыбор прыжка"
      - "mow 1"
      - "mow 2"
      - "mow 3"

  - name: "автовыбор прыжка"
    hidden: true
    type: load-balance 
    strategy: round-robin
    proxies:
      - "mow 1"
      - "mow 2"
      - "mow 3"
    url: 'https://www.gstatic.com/generate_204'
    expected-status: 204
    interval: 300
    timeout: 1000
    disable-udp: false

  - name: "PROXY"
    type: select
    proxies:
      - "автовыбор"
      - "hetzner 1"
      - "hetzner 2"
    url: 'https://www.gstatic.com/generate_204'
    expected-status: 204
    interval: 0
    disable-udp: false

  - name: "автовыбор"
    hidden: true
    type: load-balance
    strategy: consistent-hashing
    proxies:
      - "hetzner 1"
      - "hetzner 2"
    url: 'https://www.gstatic.com/generate_204'
    expected-status: 204
    interval: 300
    timeout: 1000
    lazy: true
    disable-udp: false

Здорово, спасибо! С клиентами по идее не проблема, у меня их совсем мало.