Настройка mTLS на cloudflare

Недавно я узнал о продукте cloudflare tunnel, который позволяет публиковать свои локальные сервисы в интернет даже находясь за NAT. И мне стало интересно как можно ещё прикрутить к этому mTLS, чтобы иметь гарантию что никто левый не постучит к моему сервису. А то даже находясь за cloudflare мы не можем иметь гарантию что к нам не придёт например zero-day червь пытающийся эксплуатировать какой нить log4j.

mTLS технология подерживается всеми современными браузерами, на всех платформах. Протестировано на: windows+edge, IOS+safari, chrome IOS не работает. Все что нужно это установить сертификат на конечное устройство.

Теория

Оказалось все просто: mTLS возможен на cloudflare только если включено "облачко", в этом режиме CF полностью занимается TLS-терминацией. Работает это как показано ниже на диаграмме:


Когда мы включаем mTLS в cloudflare dashboard, то к обычному TLS рукопожатию появляется 3 шаг: "Client certificate request". На 6 этапе cloudflare проверяет что запрос действительно валиден, и если все ок то помечает его для WAF. Но если сертификат даже не валидный, то решение о блокировки запроса все равно принимает WAF. Понять это можно по тому что если зайти на страницу не имея сертификата то мы увидим Access Blocked.

В классических mTLS обычно просто происходит разрыв коннекта сразу, но cloudflare всеравно дают запросу пройти и только лишь дают возможность настроить политику блокировки запросов непрошедших client certificate на уровне WAF. Именно на WAF и происходит решение принятии/блокировки запроса проходящего mTLS.

Практика

Для настройки mTLS нам нужно выполнить следующие шаги:
  1. Включить "облачко" на нашем поддомене
  2. Добавить hostname в список mTLS
  3. Добавить WAF-rule который запретит трафик
  4. Сгенерировать клиентские сертификаты и установить их

Включить "облачко" на нашем поддомене

Включить терминацию можно в настройках DNS на странице вашего домена. DNS -> records  

Добавить hostname в список mTLS

Заходим на панель настройки client certificates, вписываем наш домен, нажимаем "Save". 
Этим действием мы включаем "3 шаг", который мы обсуждали выше.

Добавить WAF-rule который запретит трафик

Заходим на страницу Security -> Security rules. Там нажимаем Create rule, custom rules.

Назвать можно как угодно, но самое важное это expression "When incoming requests match".
В виде expression получается вот так: (not cf.tls_client_auth.cert_verified and http.host eq "adminer99.mkhitaryan.dev"). Очень важно добавить http.host eq, иначе вы заставите весь трафик ходить к вашему домену по TLS, а не только поддомен который вы хотите закрыть.

Сгенерировать клиентские сертификаты и установить их

На этом этапе нам нужно client certificates, там "Create certificate". Тип RSA/ECC можно выставить любой.


Cloudflare отдаст сертификат public key и private key в формате pem. Для простоты их можно сконвертировать через openssl в p12, чтоб на любой платформе можно было сразу его установить.

Результат

При коннекте в браузере у вас должен открываться такой вот промпт выбора сертификата. Если нажать на него и тыкнуть "ОК" то у нас откроется наше приложение. 

Если отказать нажав на "Cancel" то видим 403 от WAF:


Комментарии

Популярные сообщения из этого блога

DOS атака при помощи Python

Как компилировать встроенные приложения gnome

TypeError: __init__() got an unexpected keyword argument 'decode'