Следующим шагом в обеспечении защиты своих self-hosted сервисов после настройки reverse tunnel на основе wireguard является настройка двустороннего SSL шифрования (mTLS). Этот механизм безопасность расширяет традиционный TLS, добавляя в него этап удостоверения сертификатов и от сервера, и от клиента. Это позволит закрыть доступ к вашим сервисам любым клиентам, не обладающим вашим сертификатом.

Конфигурация

В первую очередь необходимо сгенерировать самоподписанный сертификат.

Генерация сертификата и указание его в Caddy

Проще всего будет сгенерировать самоподписанный сертификат при помощи утилиты mkcert:

mkcert -install # генерация сертификата и установка в систему
mkcert -CAROOT # эта команда укажет место, где лежит сертификат

В Caddy можно настроить mtls как глобально на весь инстанс, так и локально под каждый домен. В бОльшинстве случаев предпочтительнее воспользоваться вторым вариантом:

# где угодно в конфигурации Caddy объявляем сниппет с любым
# удобным вам именем
(mutual_tls) {
        tls {
                protocols tls1.3
                client_auth {
                        mode require_and_verify
                        trusted_ca_cert_file rootCA.pem
                }
        }
}

Указанный выше rootCA.pem должен лежать в той же дирректории, что и Caddyfile. В противном случае в сниппет необходимо вставить полный фиксированный путь до сертификата (например /home/user/.local/share/mkcert/rootCA.pem).

Далее мы можем использовать этот сниппет для любого домена в конфигурации:

subdomain.example.org {
	import mutual_tls
	reverse_proxy 10.1.1.69:6969
}

Проверка и генерация клиентского сертификата

После обновления конфига Caddy можно заметить, что веб-страницы сервисов больше не открываются в браузере, ссылаясь на ошибку сертификатов. Проверить работоспособность всего сетапа с использованием сгенерированных сертификатов можно при помощи curl:

curl -k https://subdomain.example.org --cert rootCA.pem --key rootCA-key.pem

Если описанный выше запрос возвращает HTML страницы, значит все настроено правильно.

Для того, чтобы получить доступ к закрытому за mTLS ресурсу, необходимо сгенерировать клиентский сертификат и установить его на клиенте:

# сертификат может указывать как на фиксированные домены, так и на wildcard домен
mkcert -key-file rootCA-key.pem -cert-file rootCA.pem example.org *.example.org
 
# создаем p12 пакет полученных из команды выше сертификата и ключа
# для облегченного импорта на клиенте
openssl pkcs12 -export -out client_cert.p12 -inkey subdomain.example.org-client-key.pem -in subdomain.example.org-client.pem -name "My Client CA"

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

Полученный из последней команды файл client_cert.p12 уже можно переносить на любые необходимые вам клиенты и устанавливать, используя указанный вами при создании пакета пароль.

Установка пакета сертификата

Android

На любом устройстве под управлением Android для установки сертификата достаточно открыть его при помощи утилиты Certificate installer (т.е. найти в файловой системе устройства, нажать на файл, чтобы открыть, и среди вариантов выбрать Certificate installer). Далее при попытке зайти на закрытый за mTLS ресурс система будет спрашивать, какой из установленных клиентских сертификатов использовать (если такой сертификат в системе только один, то в списке будет только один пункт).

Windows, Linux

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

  • Chrome и chromium-based браузеры — Настройки Приватность и безопасность Безопасность Управление сертификатами Ваши сертификаты Импортировать клиентский сертификат. Указываете на пакет сертификата в файловой системе, даете использованный вами при создании пакета пароль и подтверждаете импорт
  • Firefox и firefox-based браузеры — Настройки Приватность и безопасность блок Безопасность Показать сертификаты Ваши сертификаты Импорт. Указываете на пакет сертификата в файловой системе, даете использованный вами при создании пакета пароль и подтверждаете импорт

В обоих случаях после установки сертификата при попытке зайти на закрытый за mTLS ресурс браузер спросит у вас, какой сертификат использовать. В обоих вариантах браузеров можно выбрать постоянное использование нужного вам сертификата на этом ресурсе.

Также этот сертификат можно установить в системные, но этот вариант я рассматривать не буду.