Какие части HTTP-запроса (хедеры, тело) шифруются в HTTPS
Что проверяют
Понимаете ли вы, что HTTPS это обычный HTTP внутри TLS-туннеля, и где в Go-сервисе этот туннель на самом деле заканчивается. Уточнение почти всегда такое: а между балансировщиком и вашим сервисом трафик тоже зашифрован?
Как отвечать
Сначала граница. Внутри TLS идёт всё HTTP-сообщение: метод, путь, query-строка, все заголовки, включая Host, Cookie и Authorization, и тело. Снаружи видно:
- IP и порты обеих сторон;
- имя хоста: в DNS-запросе и в поле SNI сообщения
ClientHello. На сервере оно доступно какr.TLS.ServerName, а спрятать его от сети может только ECH; - объёмы и тайминги пакетов.
Теперь про Go. http.ListenAndServeTLS или http.Server с заполненным TLSConfig поднимают TLS прямо в процессе. crypto/tls сам договаривается о TLS 1.3, если клиент его умеет, а нижнюю границу задают через MinVersion: tls.VersionTLS12. Пришёл ли запрос по TLS, видно по r.TLS != nil.
Чаще TLS терминируется раньше: на Nginx, Ingress или облачном балансировщике. Тогда до сервиса доходит обычный HTTP, заголовки читает любой, кто видит внутреннюю сеть, а исходную схему приходится брать из X-Forwarded-Proto. Если сети не доверяют, между балансировщиком и сервисом включают mTLS, часто через service mesh.
И последнее: после расшифровки URL оказывается в логах. Middleware, которое пишет r.URL.String(), сохранит токен из query в открытом виде, поэтому секреты передают в заголовке, а в логах маскируют.
Где спотыкаются
Утверждают, что URL не шифруется. Путь и параметры зашифрованы, наружу уходит только имя хоста.
Не думают о терминации: говорят «у нас HTTPS», хотя внутри кластера сервисы общаются открытым HTTP.
Ставят в клиенте InsecureSkipVerify: true «на время» и забывают в проде. Шифрование при этом есть, а защиты от подмены сервера нет.