Секреты, TLS и идея mTLS

О лекции

Секрет не кладут в git и не запекают в слой образа. TLS на краю шифрует канал до балансировщика. mTLS — обе стороны показывают сертификат, а не «просто HTTPS снаружи».

Наблюдаемость и секреты observability собеседование

Секрет — то, чем можно действовать от чужого имени: пароль БД, ключ подписи JWT, API-токен, приватный ключ. Утечка — инцидент: отозвать, заменить, проверить доступ.

«Пересоберём образ» само по себе ничего не отзывает. Ключ уже могли вытянуть из registry или из истории git.

Где не хранить

  • Репозиторий, тикет, лог CI, ENV в Dockerfile, слой образа.
  • В проде — Secret Kubernetes или Vault. Короткий срок жизни. Свой пароль не на весь namespace.
  • Ротация: какое-то время работают новый и старый ключ. Потом старый выключают.

Пример. Ключ в Dockerfile через ENV. Образ в private registry. Кажется безопасно. docker history и pull на ноду всё равно отдают байты.

# плохо: ключ в слое
# RUN echo "$JWT_PRIVATE_PEM" > /app/key.pem
#
# лучше: K8s Secret → volume, байты не в registry
apiVersion: v1
kind: Pod
spec:
  containers:
    - name: api
      image: registry.example/api@sha256:abc123
      volumeMounts:
        - name: jwt
          mountPath: /var/run/secrets/jwt
          readOnly: true
  volumes:
    - name: jwt
      secret:
        secretName: jwt-signing-key

Секрет не копируют в образ. Под монтирует его в рантайме.

Ротация

Сертификаты истекают. Чаще прод ломает календарь, а не «хакеры». Автовыпуск важнее ручного копипаста с ноутбука.

Ключ подписи JWT не меняют в одну секунду. Иначе все сессии умрут. Держат окно двух ключей: новый уже принимают, старый ещё принимают. Потом старый отзывают.

Пример. Выпустили ключ B, ключ A ещё валиден сутки. Клиенты постепенно получают токены на B. Через сутки A выключают. Резкого «всех разлогинило» нет.

TLS и mTLS

Обычный TLS: клиент проверяет сертификат сервера. Сервер клиента по сертификату может не знать. Дальше часто пароль или JWT.

Terminate на балансировщике: браузер шифрует до края. Внутри кластера трафик часто открытый. Это нормально только если вы так решили, а не «так вышло».

mTLS — взаимный TLS. Обе стороны показывают сертификат. Сервис верит идентичности соседа, а не «пришёл с внутреннего IP, значит свой».

Пример. Сервис orders вызывает billing. При mTLS orders предъявляет свой сертификат, billing — свой. Каждый проверяет другого. Как двое показывают паспорт, а не только охрана на входе.

Типичная ошибка

Запечь секрет в образ и считать, что private registry спасает. Сменить ключ JWT мгновенно без окна двух ключей. Назвать terminate TLS на балансировщике «у нас mTLS», хотя внутри кластера трафик открыт и поды сертификат не показывают.

На собеседовании

Секрет не в git и не в слое образа. Ротация с окном двух ключей. mTLS — обе стороны показывают сертификат. HTTPS снаружи на LB — это ещё не mTLS.