---
title: 'Плащ-невидимка: обфусцируем VPN'
url: 'https://ky0uraku.xyz/blog/20220723-cloak-vpn-obfuscation'
markdown: 'https://ky0uraku.xyz/blog/20220723-cloak-vpn-obfuscation.md'
date: '2022-07-23'
description: 'Стремительное пике происходящих пятый месяц событий, если честно, полностью отбивает желание писать на игровые или любые другие темы развлекательного характера. Выходит натужно и через силу, поэтому я в очередной раз решил воспользоваться золотым правилом графомана "можешь не писать - не пиши". Хо…'
taxonomy:
  tag:
    - tech
    - privacy
  category:
    - articles
---

# Плащ-невидимка: обфусцируем VPN

  [Тексты](https://ky0uraku.xyz/blog) / 23 июля 2022   [tech](https://ky0uraku.xyz/blog/tag:tech) [privacy](https://ky0uraku.xyz/blog/tag:privacy)  

Стремительное пике происходящих пятый месяц событий, если честно, полностью отбивает желание писать на игровые или любые другие темы развлекательного характера. Выходит натужно и через силу, поэтому я в очередной раз решил воспользоваться золотым правилом графомана "можешь не писать - не пиши".

[![](https://ky0uraku.xyz/blog/20220723-cloak-vpn-obfuscation/10-1k.webp)](https://ky0uraku.xyz/blog/20220723-cloak-vpn-obfuscation/10.webp)

Хорошая новость в том, что у меня накопилось некоторое количество материалов для перевода, плюс к тому - судорожные телодвижения наших законодателей, бьющихся в агонии, продуцируют всё более драконовские манускрипты, которые скоро запретят, кажется, вообще весь интернет.

### Ну или как минимум - любые VPN-туннели, кроме одобренных дуболомами

Поскольку с точки зрения безопасности, анонимности и приватности любой посторонний VPN-сервис, будь то платный или бесплатный - это чёрный ящик, общественный консенсус криптоанархистов давно сложился в том виде, что VPN нужно организовывать до собственного, самостоятельно настроенного и нигде не засвеченного сервера. Пока этот вариант работает - но по большому счёту, ничто не мешает дуболомам в какой-то прекрасный момент перестать банить по IP-адресам - и начать банить по фингерпринтам протоколов, запрещая целые виды VPNов.

### Что с этим можно поделать? Сегодняшнее стоп-слово - обфускация!

Обфускацию, слегка упрощая и переводя на церковнославянский, можно назвать маскировкой. В данном случае - маскировкой самого факта использования VPN. Благодаря повсеместному (спасибо, [Let`s Encrypt](https://letsencrypt.org/)!) распространению HTTPS, шифрованный трафик в интернете сам по себе аномалией и объектом пристального внимания быть перестал. Да, пока что (до внедрения [ECH](https://datatracker.ietf.org/doc/draft-ietf-tls-esni/)) в процессе HTTPS-хэндшейка товарищ майор всё ещё может видеть, к какому доменному имени происходит подключение - и как-то эту информацию использовать, но в нашем случае этот момент учтён, и более того - поставлен на службу.

### Существует много разных способов обфускации трафика, но пока рассмотрим только один - Cloak

С точки зрения внешнего наблюдателя, передача данных с помощью Cloak не отличается от захода на обычный сайт. Внутри же может быть что угодно, как VPN-туннель, так и потоковое видео, торренты или нечто иное - главное, чтобы на обоих концах был установлен обфускатор с подходящими параметрами.

[![](https://ky0uraku.xyz/blog/20220723-cloak-vpn-obfuscation/11-1k.webp)](https://ky0uraku.xyz/blog/20220723-cloak-vpn-obfuscation/11.webp)

На более низком уровне, у нас происходит классическая организация безопасного канала через небезопасную среду передачи. Для этого на сервере генерируется пара эллиптических DH-ключей. Кроме того, у каждого клиента существует уникальный идентификатор (UID), отправляемый им в зашифрованном публичным ключом сервера виде при подключении - он играет роль Pre-shared Secret (PSK).

Защита от "дуболома посередине" реализуется следующими способами:

- Используются стандартные для HTTP(S) порты - 80 и 443
- TLS-хэндшейк выглядит совсем как "настоящий"
- В случае, если подключается не прошедший аутентификацию клиент, Cloak отдаёт настоящую HTTP-страницу как обычный веб-сервер

Говоря иначе - мы имеем нечто, выглядящее для тащмайора как утка, двигающееся как утка, и даже если это нечто потыкать палочкой - крякающее совсем как утка. А унутре у неё заяц, или яйцо, или игла - что пожелаете. А раз это нечто не отличить от вполне легитимной утки - то и блокировать это нечто незачем.

### Перейдём к практической части

Для организации обфусцированного VPN-туннеля нам понадобится следующее:

- VPS с белым IP-адресом и незанятыми 80 и 443 портами
- Установленный на нашу виртуалку VPN-сервер (я приведу пример для OpenVPN)
- Установленный на VPS и на локальную машину Cloak

NB! Я предполагаю, что в этот момент на VPS уже корректно настроен OpenVPN-сервер на UDP-порту 1984. Проделать это можно, воспользовавшись одним из гайдов в интернете - например, [вот этим](https://blog.securityevaluators.com/hardening-openvpn-in-2020-1672c3c4135a).

Cloak написан на Go, поэтому для начала нам нужно добавить в систему соответствующий компилятор: <https://go.dev/doc/install>. Затем клонируем репозиторий и собираем бинарники (также их можно скачать непосредственно [с Гитхаба](https://github.com/cbeuw/Cloak/releases)):

```
git clone https://github.com/cbeuw/Cloak
cd Cloak
go get ./...
make
```

После данных манипуляций мы получаем два исполняемых файла в каталоге build - `ck-server` и `ck-client`. Первый после заполнения конфига нужно будет запустить рядом с VPN-сервером, второй - на клиенте. Последовательность действий следующая:

1. Генерируем ключи шифрования с помощью команды `ck-server -key`, запоминаем их на будущее.
2. Генерируем UID клиента (можно нескольких) с помощью команды `ck-server -uid`, тоже запоминаем.
3. Берём из подкаталога example\_config рыбу серверного конфига, копируем, например, в `/etc/cloak` и вносим в этот файл изменения, приводя его примерно к следующему виду: ```
    {{
      "ProxyBook": {
        "openvpn": [
          "udp",
          "127.0.0.1:1984"
        ]
      },
      "BindAddr": [
        ":443",
        ":80"
      ],
      "BypassUID": [
        "MY5RmiOSRKRC1ajegifHSQ==" # Сюда копируем UID клиентов из шага 2
      ],
      "RedirAddr": "webbtelescope.org", # Выбираем один или несколько безобидных доменов, которые будут фигурировать в TLS-хэндшейке
      "PrivateKey": "IOAa0Rs9erpILNgPNhff/BQtkOB+Q6E4+b8QuXfH/Wo=", # Сюда копируем приватный ключ сервера из шага 1
      "AdminUID": "",
      "DatabasePath": "/tmp/userinfo.db"
    }
    ```
4. Вносим изменения в конфиг OpenVPN-сервера, оставляя его слушать только локально, а также добавляя отправку клиентам маршрута до Cloak-сервера (это внешний адрес нашей VPS): ```
    local 127.0.0.1
    push "redirect-gateway def1"
    push "route 1.2.3.4 255.255.255.255 net_gateway"
    ```
5. В конфиге OpenVPN-клиента меняем адрес сервера на локальный: ```
    remote 127.0.0.1 1984 udp4
    ```
6. Запускаем OpenVPN-сервер и Cloak-сервер (`ck-server -c <путь к файлу с конфигом>`)
7. Заполняем конфиг для Cloak-клиента: ```
    {
      "Transport": "direct",
      "ProxyMethod": "openvpn",
      "EncryptionMethod": "aes-gcm",
      "UID": "MY5RmiOSRKRC1ajegifHSQ==", # UID из шага 2
      "PublicKey": "Q7ccuTK+Nz/+Dkzu9AfBB/AwRd1gJh9ph0EWzcXeKCw=", # Публичный ключ сервера из шага 1
      "ServerName": "webbtelescope.org", # Список доменов должен быть идентичен на сервере и клиентах
      "NumConn": 4,
      "BrowserSig": "chrome",
      "StreamTimeout": 300
    }
    ```
8. Запускаем Cloak-клиент (`ck-client -u -c <путь к файлу с конфигом>`) и OpenVPN-клиент. Всё!

Можно попробовать подключиться по HTTP или HTTPS к внешнему адресу нашей VPS - при выключенном Cloak-клиенте в браузере произойдёт редирект на один из указанных в конфиге доменов.

Таким образом, у нас не торчит наружу порт VPN-сервера, а коннекты неотличимы от обычного веб-сёрфинга. Дуболомы в очередной раз посрамлены мощью математики.

---

## Navigation

- Parent: [Последние тексты](https://ky0uraku.xyz/blog.md)
- Previous: [Казахстан: первые впечатления](https://ky0uraku.xyz/blog/20230226-qasaqstan-1.md)
- Next: [Ravenous Devils: абсолютное кулинарное безумие](https://ky0uraku.xyz/blog/20220517-ravenous-devils-omnomnom.md)
