복잡하게 얽힌 마이크로서비스(MSA) 환경에서 수많은 서비스들이 서로 통신하고 있습니다. 이때 이런 질문이 떠오릅니다.
"지금 내 서비스에 요청을 보낸 저 녀석, 믿을 수 있는 녀석인가?" 🤔
마치 우리 집 현관문처럼, 아무나 들여보내서는 안 되겠죠. 서비스 메시의 대표주자 Istio는 이런 보안 문제를 해결하기 위해 아주 깐깐하고 체계적인 '신원 조회' 시스템을 갖추고 있습니다. 바로 피어 인증(Peer Authentication)과 요청 인증(Request Authentication)입니다.
이 두 가지가 어떻게 우리의 서비스를 안전하게 지켜주는지, 전체적인 그림과 함께 상세히 파헤쳐 보겠습니다.
🗺️ 큰 그림 먼저 보기: 누구를 위한 인증인가?
Istio의 인증 전략을 이해하는 가장 쉬운 방법은 '인증 대상'이 누구인지 구분하는 것입니다.
- 서비스 🤝 서비스 (기계 간 통신): 내부에 있는 서비스들끼리 서로를 믿고 통신할 수 있을까?
- 사용자 👩💻➡️ 서비스 (사람/외부 시스템의 통신): 서비스를 사용하는 최종 사용자나 외부 시스템이 보낸 요청을 믿을 수 있을까?
Istio는 이 두 가지 시나리오에 맞춰 각각 다른 인증 방식을 제공합니다. 바로 이것이 피어 인증과 요청 인증의 핵심적인 차이입니다.
(Source: istio.io)
1️⃣ 피어 인증 (Peer Authentication): "우리끼리는 암호로 말해" 🤫
서비스 메쉬 내부에 있는 워크로드(파드, 서비스)들이 서로 통신할 때 사용하는 인증 방식입니다. 즉, 서비스 간(Service-to-Service) 통신의 신뢰성을 보장하죠.
마치 첩보 영화에서 요원들이 서로를 확인하기 위해 암호를 대는 것과 같습니다. 이 암호가 바로 상호 TLS (mTLS)입니다.
✨ 어떻게 동작하나요? (mTLS)
mTLS는 클라이언트와 서버가 서로에게 인증서를 제시하여 신원을 확인하는 방식입니다.
- reviews 서비스가 ratings 서비스에 요청을 보냅니다.
- reviews와 ratings는 통신을 시작하기 전, Istio가 발급한 인증서(certificate)를 서로 교환합니다.
- 서로의 인증서가 유효한지 확인하고, 신원이 증명되면 안전한 암호화 터널(TLS)을 생성합니다. 🔒
- 이 터널을 통해 모든 통신 내용은 암호화되어 안전하게 전달됩니다.
YAML 코드로 살펴보기
PeerAuthentication 정책을 통해 특정 네임스페이스에 mTLS를 강제할 수 있습니다.
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: "default"
namespace: "production" # 'production' 네임스페이스에 적용
spec:
mtls:
mode: STRICT # 오직 mTLS 통신만 허용!
- mode: STRICT: "암호(mTLS)를 모르는 녀석은 절대 통신 불가!" 라는 의미입니다. production 네임스페이스의 모든 서비스들은 mTLS로만 통신해야 합니다. 일반 텍스트(HTTP) 요청은 차단됩니다.
- mode: PERMISSIVE: 기존 서비스와의 호환성을 위해 mTLS와 일반 텍스트 통신을 모두 허용하는 모드입니다. 점진적으로 mTLS를 도입할 때 유용합니다.
2️⃣ 요청 인증 (Request Authentication): "신분증(JWT) 좀 보여주시죠?" 🎟️
서비스 메쉬의 입구(Ingress Gateway)에서 최종 사용자(End-User)나 외부 시스템이 보낸 요청을 인증할 때 사용됩니다.
콘서트장에 들어갈 때 입구에서 티켓을 검사하는 것과 같습니다. 이때 사용되는 표준 디지털 티켓이 바로 JWT(JSON Web Token)입니다.
✨ 어떻게 동작하나요? (JWT)
JWT는 사용자의 정보(누구인지, 어떤 권한이 있는지 등)와 서명을 담고 있는 암호화된 토큰입니다.
- 사용자가 로그인을 통해 인증 서버로부터 JWT를 발급받습니다.
- 사용자는 API를 요청할 때마다 HTTP 헤더(e.g., Authorization: Bearer )에 이 JWT를 포함하여 보냅니다.
- Istio Ingress Gateway는 RequestAuthentication 정책에 따라 이 JWT가 유효한지 검증합니다.
- 서명이 유효하고, 만료되지 않았으며, 발급자가 신뢰할 수 있다면 요청을 내부 서비스로 전달합니다.
YAML 코드와 Raw 데이터로 살펴보기
RequestAuthentication 정책은 JWT 발급자(issuer)와 공개키(JWKS) 위치를 지정합니다.
apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
name: "jwt-example"
namespace: istio-system
spec:
selector:
matchLabels:
istio: ingressgateway
jwtRules:
- issuer: "https://accounts.google.com" # JWT 발급자
jwksUri: "https://www.googleapis.com/oauth2/v3/certs" # 공개키 위치
이 정책은 istio-ingressgateway로 들어오는 요청에 대해, 발급자가 https://accounts.google.com인 JWT가 있는지 확인하라는 의미입니다.
- 샘플 JWT Raw 데이터:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIiwic3ViIjoidXNlcjEyMyIsImV4cCI6MTY3ODg4NjQwMCwiZW1haWwiOiJ0ZXN0QGV4YW1wbGUuY29tIn0.SIG_PART
(위 토큰은 3부분으로 구성됩니다: Header.Payload.Signature)
- 디코딩된 Payload:
{
"iss": "https://example.com",
"sub": "user123",
"exp": 1678886400,
"email": "test@example.com"
}
Istio는 이 Payload의 내용을 보고 iss(발급자)가 정책과 일치하는지, exp(만료시간)가 지나지 않았는지 등을 검증합니다.
🤔 흔한 오해 바로잡기
- "API Key만으로 인증하면 안 되나요?"
- API Key는 주로 '어떤 애플리케이션'이 요청했는지 식별하는 데 사용됩니다. 반면 JWT는 '어떤 사용자'가 요청했는지, 그 사용자의 역할은 무엇인지 등 훨씬 풍부한 정보를 담을 수 있어 사용자 중심의 인증에 더 적합하고 표준적입니다.
- "내부망이니까 서비스끼리는 그냥 HTTP로 통신해도 안전하지 않나요?"
- 절대 아닙니다! 🙅♂️ '제로 트러스트(Zero Trust)' 보안 모델에 따르면, 내부 네트워크라고 해서 무조건 신뢰해서는 안 됩니다. 만약 서비스 하나가 해킹당하면, 그 서비스를 통해 내부의 다른 모든 서비스로 공격이 확산될 수 있습니다. 피어 인증(mTLS)은 이런 내부 확산을 막는 가장 중요한 방어선입니다.
🏁 정리하며
Istio의 두 가지 인증 방식을 다시 한번 요약해 보겠습니다.
- 피어 인증 (Peer Authentication): 서비스 간 통신을 mTLS로 암호화하고 서로의 신원을 확인합니다. (내부 보안 강화🛡️)
- 요청 인증 (Request Authentication): 최종 사용자의 요청을 JWT로 검증하여 인가된 사용자만 접근하도록 허용합니다. (외부 경계 보안🚪)
이 두 가지 인증 매커니즘은 함께 작동하며, 외부로부터의 침입과 내부에서의 무단 접근을 모두 차단하는 강력한 다층 방어 체계를 구축합니다. Istio를 통해 서비스의 보안을 한 단계 업그레이드해 보세요!
'클라우드 > Istio' 카테고리의 다른 글
| 내 서비스만 암호화? 🔒 Istio mTLS, 무작정 STRICT 모드 쓰면 큰일나는 이유 (0) | 2025.11.28 |
|---|---|
| ⚠️ 서비스 장애 없이 신규 버전 배포하는 방법, 이것 모르면 후회합니다! (0) | 2025.11.28 |
| Istio 프로덕션 환경, '이것'만은 꼭 확인하세요: 설치 프로필의 비밀 🤫 (0) | 2025.11.28 |
| Istio, 너 혹시 텔레파시 쓰니? Envoy와 Istiod의 비밀 통신 방법 🤫 (0) | 2025.11.28 |
| Istio 인가 정책, 혹시 아직도 ‘활성화’하고 계신가요? (ft. 우리만 몰랐던 진실) 😲 (0) | 2025.11.28 |