Руководство будет включать:
Предисловие
Описание работы Cloak
Настройку сервера Cloak
Настройку клиента Cloak на OpenWRT
Настройку клиента 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 tunlocal 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