Руководство будет включать:

  1. Предисловие

  2. Описание работы Cloak

  3. Настройку сервера Cloak

  4. Настройку клиента Cloak на OpenWRT

  5. Настройку клиента OpenVPN

1. Предисловие

В данной статье рассматривается способ установки и настройки прокси Cloak из репозитория автора проекта на Github. Уже несколько лет существует коробочное решение от Amnezia VPN c клиентами для Windows, Mac, Linux, Android и iOS (iOS поддерживает Cloak начиная с версии 3.08). Здесь мы рассмотрим установку чистого Cloak для существующего сервера OpenVPN (если такого сервера у вас нет, можно воспользоваться множеством решений в интернете, например этим) Способ описанный в статье является не самым лучшим и актуальным средством обхода блокировок, стоит обратить внимание на более свежие решения (Пользователь @MiraclePtr исчерпывающе описал существующие на данный момент способы).

Эта статья результат моего ознакомления с инструментом Cloak и рабочий гайд по настройке работы OpenVPN на OpenWRT через него.

2. Описание работы Cloak

Cloak — это подключаемый транспорт, который расширяет возможности традиционных прокси‑инструментов, таких как OpenVPN, для обхода сложной цензуры и дискриминации данных.

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

Cloak можно использовать в сочетании с любой прокси‑программой, которая туннелирует трафик через TCP или UDP, например Shadowsocks, OpenVPN и Tor. На одном хосте сервера может работать несколько прокси‑серверов, а сервер Cloak будет действовать как обратный прокси‑сервер, соединяя клиентов с желаемым прокси‑концом.

Cloak мультиплексирует трафик через несколько базовых TCP‑соединений, что уменьшает блокировку начала линии и устраняет накладные расходы на TCP‑квитирование. Это также делает структуру трафика более похожей на реальные веб‑сайты.

Cloak обеспечивает многопользовательскую поддержку, позволяя нескольким клиентам подключаться к прокси‑серверу через один и тот же порт (по умолчанию 443). Он также предоставляет функции управления трафиком, такие как кредит на использование и контроль пропускной способности. Это позволяет прокси‑серверу обслуживать нескольких пользователей, даже если базовое программное обе��печение прокси не было разработано для нескольких пользователей.

Cloak также поддерживает туннелирование через промежуточный сервер CDN, такой как Amazon Cloudfront.

Принцип работы Cloak заключается в том, что весь передаваемый через него трафик преобразуется в HTTPS‑трафик. Это была бы тривиальная задача, если бы Cloak просто туннелировал трафик через TCP‑порт 443 и добавлял заголовки TLS. Он способен обмануть простые классификаторы, подобные тому, который использует Wireshark, который ищет только фиксированные шаблоны байтов и магические числа; возможно, именно это и делают большинство коммерческих межсетевых экранов и интернет‑провайдеров в неавторитарных странах. Однако, поскольку известно, что для фильтрации используют сложные методы глубокой проверки пакетов в поисках «отпечатков пальцев» на протяжении всего сетевого сеанса, обойти эти меры — нетривиальная задача.

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

Для этого сервер Cloak сначала генерирует статическую пару ключей Диффи‑Хеллмана с эллиптической кривой и распространяет открытый ключ потенциальным клиентам. Когда пользователь Cloak хочет подключиться, клиент Cloak должен сгенерировать еще одну эфемерную пару ключей ECDH. Предварительно распределенный статический открытый ключ и частная часть эфемерного ключа используются для создания общего секрета, с помощью которого секретный идентификатор клиента (UID), а также некоторая различная информация (например, временная метка предотвращения ответа) симметрично шифруются. Открытая часть эфемерного ключа и зашифрованный UID вместе отправляются на сервер в первом пакете (TLS ClientHello).

После получения первого пакета сервер Cloak сначала выполняет простую проверку его формата. Затем он вычисляет общий секрет на основе частной части предварительно сгенерированного ключа и открытой части эфемерного ключа, сгенерированной клиентом. С помощью этого общего секрета расшифровывается UID. Затем UID запрашивается в базе данных, чтобы проверить, авторизован ли он. Таким образом, личность инициатора соединения установлена.

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

Теперь перейдём к настройке сервера.

3. Настройка сервера Cloak

Настройка сервера будет производится на примере Debian 11 (amd64)

Для начала нам нужно скачать исполняемый файл с сайта проекта на Github

wget https://github.com/cbeuw/Cloak/releases/download/v2.7.0/ck-server-linux-amd64-v2.7.0 -O ck-server

Делаем файл исполняемым:

chmod +x ck-server

Переносим файл в /usr/bin (требует прав root)

sudo mv ck-server /usr/bin/ck-server

Далее нам необходимо сгенерировать публичный и приватный ключи доступа Cloak

/usr/bin/ck-server -key

Получаем:

Your PUBLIC key is:                      dnc7/Tbif51pXZ6EcWwc2367rHAbzVOzlzJ4qyS1uC4=
Your PRIVATE key is (keep it secret):    ULn0VAREq6zgk3kVOUYTbauwhKOGK48nRDibL5wLans=

Сохраняем эти данные, они понадобятся чуть позже.

Далее нам необходимо сгенерировать UID Пользователя и Администратора

/usr/bin/ck-server -uid
/usr/bin/ck-server -uid

На выходе получаем два UID: Пользователя и Администратора

Your UID is: w2S8IMf/T4/TAC7MJZQlWw== #Пользователь USER_UID1
Your UID is: 9bNJTRNEaN3iwljIAT2U+Q== #Администратор ADMIN_UID

Сохраняем эти данные.

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

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

sudo cat /etc/openvpn/server.conf

в примере это OpenVPN UDP и порт 51000.

Далее подготавливаем конфигурацию сервера /etc/cloak/ckserver.json

Создадим папку и файл следующего содержания

sudo mkdir /etc/cloak
sudo nano /etc/cloak/ckserver.json

/etc/cloak/ckserver.json:

{
  "ProxyBook": {
    "openvpn": [
      "udp",
      "127.0.0.1:51000"
    ]
  },
  "BindAddr": [
    ":443",
    ":80"
  ],
  "BypassUID": [
    "w2S8IMf/T4/TAC7MJZQlWw=="
  ],
  "RedirAddr": "dzen.ru",
  "PrivateKey": "ULn0VAREq6zgk3kVOUYTbauwhKOGK48nRDibL5wLans=",
  "AdminUID": "9bNJTRNEaN3iwljIAT2U+Q==",
  "DatabasePath": "userinfo.db"
}

Сюда вводим ваши полученные ранее значения.

В примере это:

"ProxyBook": "openvpn" - вводим "udp" и порт 51000

В "PrivateKey" ULn0VAREq6zgk3kVOUYTbauwhKOGK48nRDibL5wLans=

В "AdminUID" 9bNJTRNEaN3iwljIAT2U+Q==

В "BypassUID" w2S8IMf/T4/TAC7MJZQlWw== (при наличии нескольких пользователей каждый UID вводится в кавычках на отдельной строке, через запятую как в примере)

Сохраняем изменения.

Далее создаём службу systemd для автозапуска:

sudo nano /etc/systemd/system/cloak-server.service

/etc/systemd/system/cloak-server.service:

[Unit]
Description=cloak-server
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
#Service variables
Environment=CONFIG="/etc/cloak/ckserver.json"
ExecStart=/usr/bin/ck-server -c "$CONFIG"
Restart=always
[Install]
WantedBy=multi-user.target

Сохраняем изменения.

Перезагружаем список служб, активируем автозапуск и запускаем службу:

sudo systemctl daemon-reload
sudo systemctl enable cloak-server.service
sudo systemctl start cloak-server.service

Так же необходимо будет убедится что у вас открыты порты 80 и 443, в настройках UFW или вашего внешнего файрволла.

Так же необходимо внести изменения в конфигурацию вашего сервера OpenVPN

Убедитесь что в конфигурации /etc/openvpn/server.conf присутствуют следующие строки:

# So that OpenVPN is listening to ck-server
local 127.0.0.1
dev tun

local 127.0.0.1 означает что OpenVPN сервер теперь будет слушать только на локальном интерфейсе и все клиенты должны будут подключаться через Cloak.

dev tap не поддерживается Cloak.

Cloak поддерживает TCP (стабильно) и UDP (в статусе экспериментальной поддержки).

Перезагружаем сервер OpenVPN:

sudo /etc/init.d/openvpn restart

Переходим к настройке клиента.

4.Настройка клиента Cloak на OpenWRT

Рекомендуется роутер минимум с 128 МБ RAM и памятью более 16 Мб.

На примере OpenWRT 22.03.5

Необходимо скачать с Github файл клиента для архитектуры вашего роутера.

Определяем архитектуру:

cat /sys/devices/system/cpu/modalias | grep -r -E -o ".{0,4}type.{0,6}"

На выходе получаем ответ похожего вида (В моём случае TP-Link Archer C6U):

cpu:type:mips:

Далее ищем пакет для архитектуры MIPS - Release v2.7.0 · cbeuw/Cloak (github.com).

Так как в репозитории Github есть версии для Mips и mipsle рекомендую сверится с OpenWRT Table of Hardware Wiki для вашего устройства.

Для TP-Link Archer C6U - архитектура mipsle (он же mipsel)

Скачиваем по ссылке на роутер при помощи wget:

cd /tmp
wget https://github.com/cbeuw/Cloak/releases/download/v2.7.0/ck-client-linux-mipsle_softfloat-v2.7.0 -O ck-client

В моём случае подошла версия mipsle-softfloat, если на более позднем этапе установки выдаст ошибку "line 1: syntax error: unexpected "(" , то сверьтесь ещё раз с OpenWRT wiki и попробуйте версию mipsle.

Разрешаем запуск исполняемого файла:

chmod +x /tmp/ck-client

Проверяем работу программы:

./ck-client --help

Если выдаёт справку по командам то движемся дальше, если выдаёт ошибку "line 1: syntax error: unexpected "(" то возвращаемся к началу п.4.

Далее перенесём файл ck-client в /usr/bin (ПЗУ) (Файл займет около 9Мб)

mv /tmp/ck-client /usr/bin/ck-client

Далее подготавливаем конфигурацию клиента.

Создадим папку конфигурации

mkdir /etc/config/cloak

И сам файл

/etc/config/cloak/ckclient.json:

{
"Transport": "direct",
"ProxyMethod": "openvpn",
"EncryptionMethod": "aes-gcm",
"UID": "w2S8IMf/T4/TAC7MJZQlWw==",
"PublicKey": "dnc7/Tbif51pXZ6EcWwc2367rHAbzVOzlzJ4qyS1uC4=",
"ServerName": "dl.google.com",
"NumConn": 4,
"BrowserSig": "chrome",
"StreamTimeout": 300
}

в примере:

"UID" из "BypassUID" сервера - w2S8IMf/T4/TAC7MJZQlWw==

"PublicKey" - dnc7/Tbif51pXZ6EcWwc2367rHAbzVOzlzJ4qyS1uC4=

Сохраняем.

Далее создаём службу автозапуска Cloak:

/etc/init.d/cloak:

#!/bin/sh /etc/rc.common
USE_PROCD=1
#starts after network starts
START=89 #Number in rc.d queue, before S90OpenVPN
#stops before networking stops
STOP=90
PROG=/usr/bin/ck-client
#Enter your OpenVPN Server IP or Hostname
HOST="0.0.0.0"
#The default Port
PORT="1984"
CONFIG="/etc/config/cloak/ckclient.json"
start_service() {
procd_open_instance
procd_set_param user root
#For OpenVPN UDP
procd_set_param command "$PROG" -s "$HOST" -l "$PORT" -u -c "$CONFIG"
#For OpenVPN TCP (Uncomment and comment OpenVPN UDP)
#procd_set_param command "$PROG" -s "$HOST" -l "$PORT" -c "$CONFIG"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
procd_close_instance
echo "Cloak is working!"
}
stop_service() {
service_stop $PROG
echo "Cloak has stopped!"
}
reload_service() {
stop
sleep 5s
echo "Cloak restarted!"
start
}

Вносим в HOST IP адрес вашего OpenVPN сервера.

PORT меняем по желанию, по умолчанию 1984 (это локальный порт роутера 127.0.0.1 к которому будет подключаться клиент OpenVPN).

В зависимости от настроек вашего сервера рас/закомментируем строки OpenVPN UDP и TCP.

Делаем файл исполняемым:

chmod +x /etc/init.d/cloak

Делаем автозапуск:

ln -s /etc/init.d/cloak /etc/rc.d/S89Cloak

Запускаем:

/etc/init.d/cloak start

Далее переходим к настройке клиента OpenVPN.

5. Настройка клиента OpenVPN

Вносим изменения в конфигурацию клиента OpenVPN, на примере LuCI.

Переходим в раздел VPN - OpenVPN:

Редактируем текущую конфигурацию:

Заменяем в строке remote адрес вашего OpenVPN сервера и порт на 127.0.0.1 1984 или иной порт, если вы изменили 1984 на своё значение.

Сохраняем изменения.

Далее переходим в раздел Сеть - Маршрутизация:

И добавляем новый маршрут через шлюз по умолчанию до своего VPN сервера.

В Target вводим IP адрес вашего VPN сервера (/32 подсеть из одного IP адреса).

В gateway ваш шлюз по умолчанию (можно посмотреть в настройках подключения к интернету).

Ваш Interface выбираете из выпадающего списка.

От @palkinev89 :

Если ваш OpenVPN сервер посылает маршруты клиентам, например через

push «route <server_host_ip> 255.255.255.255 net_gateway»

То вносить маршрут вручную необязательно

Сохраняем маршрут.

Далее возвращаемся в VPN - OpenVPN.

И перезагружаем подключение к серверу OpenVPN:

После чего проверяем работу OpenVPN.

Для Cloak существуют клиенты для Windows, Mac, Linux и Android. К сожалению настроить OpenVPN через Cloak на iOS на данный момент невозможно, но ShadowRocket поддерживает Shadowsocks over Cloak.

UPD. Важные замечания от пользователя @navion:

  • Для SELinux надо пометить файл, иначе он будет гасить сервис:

    chcon -t bin_t /usr/bin/ck-server

  • Во время отладки настроек сервера стоит использовать команду для мониторинга:

    journalctl -u cloak-server.service -f