본문 바로가기
클라우드/Istio

[Istio] 우리 집 문단속하기 🚪: 외부 트래픽 전면 차단과 허용 (ALLOW_ANY vs REGISTRY_ONLY)

by gasbugs 2025. 11. 29.

안녕하세요! 오늘은 Istio를 도입할 때 보안 측면에서 가장 먼저 고민해야 할 'Egress(아웃바운드) 트래픽 제어'에 대해 깊이 파보려고 합니다.

 

쿠버네티스 파드(Pod) 안에 몰래 숨어든 악성코드가 외부 해커 서버로 데이터를 전송한다면? 😱 상상만 해도 끔찍하죠. Istio는 아주 간단한 설정 변경만으로 이런 '데이터 유출' 시도를 원천 봉쇄할 수 있습니다.

 

기본 설정(ALLOW_ANY)과 보안 설정(REGISTRY_ONLY)의 차이, 그리고 실전 설정 방법까지 함께 알아봅시다! 🚀


1. Istio의 기본 동작: "문이 활짝 열려있다?" 🔓

Istio가 설치된 파드에서 외부 인터넷(예: google.com, api.slack.com)으로 요청을 보내면 어떻게 될까요?

별다른 설정을 하지 않았다면, 기본적으로 통신이 성공합니다.

  • 설정값: outboundTrafficPolicy.mode = ALLOW_ANY
  • 동작: 사이드카 프록시(Envoy)는 자신이 모르는 목적지(Service Registry에 없는 주소)로 가는 요청이 오면, "일단 통과(Passthrough)" 시킵니다.
  • 장점: 개발할 때 편합니다. 외부 API를 맘대로 호출할 수 있으니까요.
  • 단점: 보안에 취약합니다. 해킹당한 파드가 외부의 C&C 서버(공격자 서버)와 통신하는 것을 막을 수 없습니다.

2. 보안 강화: "등록된 곳만 갈 수 있어!" 🛡️

보안이 중요한 프로덕션 환경(Production)에서는 화이트리스트(Whitelist) 방식을 사용해야 합니다. 즉, "내가 허락한 곳 외에는 아무 데도 못 가!"라고 선언하는 것이죠.

  • 설정값: outboundTrafficPolicy.mode = REGISTRY_ONLY
  • 동작: 사이드카 프록시는 요청 목적지를 확인합니다. Istio의 내부 서비스 레지스트리(Service Registry)에 등록된 곳이면 보내주고, 아니면 가차 없이 차단합니다.
  • 장점: 데이터 유출 방지 및 강력한 Egress 보안.
  • 단점: 외부 통신이 필요할 때마다 ServiceEntry를 일일이 등록해줘야 하는 번거로움이 있습니다.

3. 실습: 보안 정책 적용해보기 👨‍💻

직접 istioctl을 사용하여 클러스터 전체의 아웃바운드 정책을 바꿔보겠습니다.

Step 1: 현재 상태 확인 (ALLOW_ANY)

현재는 기본 설정 상태입니다. 테스트용 파드(tester)에서 외부 서비스인 httpbin.org로 접속해 봅니다.

kubectl exec tester -- \
    curl -sS -o /dev/null -D - http://httpbin.org/status/200 | \
    grep "HTTP/"

# 결과: HTTP/1.1 200 OK (성공!)

 

아무런 제약 없이 외부 통신이 잘 됩니다.

Step 2: 정책 변경 (REGISTRY_ONLY로 전환) 🔥

이제 istioctl install 명령어를 사용하여 전역 설정을 변경합니다. meshConfig를 수정하여 모르는 트래픽은 차단하도록 설정합니다.

istioctl install --set profile=demo \
    -y --manifests=/root/istio-${ISTIO_VERSION}/manifests \
    --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY
  • --set meshConfig.outboundTrafficPolicy.mode=REGISTRY_ONLY: 이 옵션이 핵심입니다!

Step 3: 차단 확인 🚫

설정이 적용될 때까지 몇 초 기다린 후, 다시 똑같이 접속을 시도해 봅니다.

Bash

kubectl exec tester -- \
    curl -sS -o /dev/null -D - http://httpbin.org/status/200 | \
    grep "HTTP/"

 

결과:

curl: (56) Recv failure: Connection reset by peer
command terminated with exit code 56

보셨나요? 200 OK 대신 Connection reset by peer 에러가 떴습니다. 이것은 네트워크가 끊긴 게 아니라, Istio 사이드카 프록시가 "너, 등록 안 된 곳으로 가려고 하네? 안 돼!" 하고 연결을 강제로 끊어버린(TCP Reset) 것입니다.


4. 그럼 이제 외부 통신은 어떻게 해요? 🤔

"네이버도, 구글도 못 가면 우리 서비스는 어떻게 하죠?"

걱정 마세요! REGISTRY_ONLY 모드에서는 우리가 가야 할 외부 목적지를 ServiceEntry라는 리소스를 통해 Istio에게 "여기는 믿을만한 곳이야"라고 알려주면 됩니다.

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: external-httpbin
spec:
  hosts:
  - httpbin.org  # 허용할 외부 도메인 등록
  ports:
  - number: 80
    name: http
    protocol: HTTP

 

이렇게 등록해주면 httpbin.org는 "아는 사이트"가 되어 다시 접속이 가능해집니다. 이게 바로 진정한 Zero Trust 보안의 시작이죠!


🏁 마무리

편리함을 위해 ALLOW_ANY를 쓸 것인가, 보안을 위해 REGISTRY_ONLY를 쓰고 관리 비용을 감수할 것인가?

정답은 여러분의 환경에 달려있지만, 보안 사고는 예고 없이 찾아온다는 점을 기억하세요. 조금 귀찮더라도 REGISTRY_ONLY와 ServiceEntry 조합을 사용하는 것이 안전한 클러스터를 만드는 지름길입니다. 🛣️

오늘 실습도 고생 많으셨습니다! 다음엔 ServiceEntry를 다루는 법을 더 자세히 가져올게요. 안녕! 👋