> Как обезопасить взаимодействие микросервисов при использовании REST или gRPC (Go)

Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы

Компании: Black Wall Group (BWG)

Стек: Go

> Пример ответа

Короткий ответ

Безопасность взаимодействия микросервисов строится на нескольких уровнях: транспортное шифрование (mTLS), аутентификация (JWT, OAuth2, service-to-service), авторизация (RBAC/ABAC), валидация входных данных, rate limiting, таймауты и ретраи с backoff. Для gRPC дополнительно используется interceptor для аутентификации и метаданных. В Go это реализуется через стандартные библиотеки (crypto/tls, net/http) и фреймворки (grpc-go, go-micro). Ключевой принцип - zero trust: каждый запрос проверяется независимо, даже внутри доверенной сети.

Подробное объяснение

Безопасность взаимодействия микросервисов - это не одна мера, а совокупность практик, закрывающих разные векторы атак.

Транспортный уровень. Внутри кластера трафик между сервисами должен быть зашифрован. mTLS (mutual TLS) - стандарт для service mesh (Istio, Linkerd) или ручной настройки. Каждый сервис имеет сертификат, и обе стороны проверяют друг друга. Это защищает от man-in-the-middle и спуфинга.

Аутентификация. Для service-to-service используется два подхода:

  • JWT с коротким сроком жизни (например, 5 минут), подписанный общим секретом или через OIDC.
  • OAuth2 client credentials flow - сервис получает токен от identity provider. В Go часто используют github.com/golang-jwt/jwt для проверки подписи.

Авторизация. После аутентификации нужно проверить права. Для микросервисов удобно передавать claims в JWT (роли, scope). На стороне получателя - middleware, который проверяет наличие нужного scope. В gRPC это делается через interceptor.

Валидация входных данных. Каждый сервис должен валидировать все входящие запросы, даже если они приходят от доверенного внутреннего сервиса. Используйте go-playground/validator для структур или protobuf-валидацию.

Защита от перегрузок. Rate limiting на уровне API gateway или внутри сервиса (golang.org/x/time/rate). Таймауты на HTTP-клиенте (context.WithTimeout) и на сервере (http.Server.Timeout). Ретраи с экспоненциальным backoff и jitter, чтобы не создавать лавину запросов.

Секреты и конфигурация. Никогда не храните секреты в коде или env-переменных. Используйте Vault, Kubernetes Secrets или AWS Secrets Manager. В Go - библиотека github.com/hashicorp/vault/api.

Логирование и мониторинг. Все запросы должны логироваться с request ID (корреляция через заголовок X-Request-ID). Это помогает расследовать инциденты.

На практике

Для Go-сервисов типичная схема выглядит так:

  1. Каждый сервис имеет TLS-сертификат, выпущенный внутренним CA.
  2. При старте сервис получает JWT-секрет или публичный ключ для проверки подписей.
  3. HTTP-клиент настраивается с таймаутом, retry и передачей токена в заголовке Authorization.
  4. На стороне сервера - middleware chain: recovery → request ID → auth → rate limit → валидация → handler.
  5. Для gRPC - interceptors: auth, logging, recovery, validation.

Пример структуры middleware для Go:

GO
type contextKey string
func AuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" {
http.Error(w, "missing token", http.StatusUnauthorized)
return
}
// парсим и проверяем JWT
claims, err := parseJWT(token)
if err != nil {
http.Error(w, "invalid token", http.StatusUnauthorized)
return
}
ctx := context.WithValue(r.Context(), contextKey("claims"), claims)
next.ServeHTTP(w, r.WithContext(ctx))
})
}

Для gRPC interceptor:

GO
func AuthInterceptor(publicKey *rsa.PublicKey) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return nil, status.Error(codes.Unauthenticated, "missing metadata")
}
token := md.Get("authorization")
if len(token) == 0 {
return nil, status.Error(codes.Unauthenticated, "missing token")
}
// проверяем JWT
claims, err := validateJWT(token[0], publicKey)
if err != nil {
return nil, status.Error(codes.Unauthenticated, "invalid token")
}
ctx = context.WithValue(ctx, "claims", claims)
return handler(ctx, req)
}
}

Как отвечать на собеседовании

Начните с краткого перечисления уровней: транспорт, аутентификация, авторизация, валидация, защита от перегрузок. Затем раскройте каждый уровень с примерами из Go. Упомяните trade-off между REST и gRPC: gRPC имеет встроенную поддержку interceptors и metadata, что удобнее для аутентификации, но REST проще для отладки и интеграции с внешними системами.

Подчеркните, что безопасность - это процесс, а не разовая настройка. Упомяните service mesh как вариант централизованного управления mTLS и политиками. Если спросят про конкретные библиотеки - назовите golang-jwt, grpc-go, go-playground/validator, golang.org/x/time/rate.

Что проверяет интервьюер

Интервьюер оценивает:

  • Понимание многослойной модели безопасности, а не только шифрования.
  • Практический опыт с Go-экосистемой: middleware, interceptors, контексты.
  • Умение рассуждать о trade-off: например, JWT vs session, mTLS vs TLS.
  • Знание типичных уязвимостей: token leakage, replay attacks, race conditions при rate limiting.
  • Способность предложить конкретные решения, а не абстрактные рассуждения.

Типичные ошибки

  • Сводить безопасность только к HTTPS - это не защищает от неавторизованного доступа внутри сети.
  • Хранить секреты в env-переменных или в коде - это грубая ошибка.
  • Не использовать таймауты и retry - приводит к каскадным отказам и DoS.
  • Проверять JWT только по подписи, но не по сроку действия или issuer.
  • Игнорировать валидацию входных данных на стороне получателя, полагаясь на отправителя.
  • Использовать один и тот же токен для всех сервисов без ограничения scope - увеличивает поверхность атаки.
  • Не логировать запросы с request ID - невозможно расследовать инциденты.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью