서론
https://istio.io/latest/docs/concepts/traffic-management/
Traffic Management
Describes the various Istio features focused on traffic routing and control.
istio.io
Istio의 트래픽 관리 정책에 따르면, 서비스 메시에서 트래픽을 유도할 때에는 기본적으로 쿠버네티스 클러스터의 서비스 디스커버리와 엔드포인트를 활용한다고 되어 있다.
Istio와 Kiali를 구축하게 된다면, mTLS에 대한 부분을 아래 사진과 같이 확인할 수 있다.
nginx-1이라는 파드에서 nginx-2라는 서비스를 호출하여 nginx-2라는 파드를 호출하는 그래프를 나타낸 것인데, 각 초록선에 잠긴 자물쇠가 mTLS가 적용됐다는 것을 의미한다.
하지만 이것만으로는 패킷이 암호화됐다고 판단하기 애매하다고 생각하여, 패킷에 대한 mTLS 검증을 해 보았다.
본론
다음은 nginx라는 파드를 두 개 생성하여 mTLS가 적용되지 않은 패킷과 적용이 된 패킷을 비교할 것이다.
순서는 아래와 같다.
1. 파드 직접 호출(mTLS 미적용)
2. 서비스를 통한 파드 호출(mTLS 적용)
1. 파드 직접 호출
서론에서 보는 것과 다르게 kiali에서 자물쇠가 없는 것을 볼 수 있고, 자세한 내역을 본다면 아래와 같이 HTTP에서 mTLS가 disabled라고 되어 있다는 것을 볼 수 있다.
nginx-1 파드에서 nginx-2 파드의 아이피를 직접 호출했을 때를 나타낸 케이스이고 파드 IP를 직접 호출하면서, 이제 해당 통신 과정에서의 패킷을 tcpdump를 활용하여 덤프를 떠서 와이어샤크로 패킷을 확인해 볼 것이다.
1) nginx-2 파드 아이피로 해당 파드의 네트워크 인터페이스 획득
파드의 아이피로, 노드에 접속하여 해당 파드의 네트워크 인터페이스를 간단하게 확인할 수 있다.
해당 파드가 있는 노드 접속 후 다음 명령어 실행
# Bash
route -n | grep <파드 IP>
명령어 실행 시 사진과 같이 출력이 되는 것을 볼 수 있고, 현재 클러스터에서는 CNI로 calico를 사용하고 있어 cali2feb0dad56a라는 네트워크 인터페이스를 가진 파드가 있는 것을 볼 수 있다.
2) 획득한 네트워크 인터페이스를 tcpdump로 패킷 덤프
tcpdump가 없다면 별도로 설치를 해줘야 하며, root권한이 필요하다.
아래 명령어를 통해 해당 네트워크 인터페이스의 패킷을 파일로 저장할 수 있다.
# Bash
# 예시) tcpdump -i cali2feb0dad56a -w test_packet.pcap
tcpdump -i <네트워크 인터페이스> -w <파일 명>
3) nginx-2 파드 호출
nginx-1 파드 접속 후 nginx-2 파드 IP를 직접 호출을 몇 번 해주고, tcpdump를 종료해 준다.
# nginx-1 파드에서
curl <nginx-2 파드 IP>
4) 와이어 샤크로 pcap파일 확인
여기서 패킷을 확인해 본다면, 우측 하단에서 보이는 것처럼, nginx의 html과 같은 내용이 훤하게 다 보인다는 것을 볼 수 있다.
아래 사진에서 nginx-1에서 요청한 내용과 캡처된 패킷의 내용을 동일하게 확인할 수 있다는 것을 볼 수 있다.
즉, 파드 IP로 직접 요청하게 된 패킷은 mTLS 적용이 되지 않는 것이 맞고 패킷을 누군가 캡처한다면 내용을 확인할 수 있다는 것이며, 보안 상 취약한 부분이 된다.
2. 파드를 서비스를 통하여 호출
이번에는 서론에서 본 사진과 같이 서비스를 경유하여 파드를 호출하게 됐을 때, mTLS가 제대로 적용되는지 확인해 볼 것이다.
파드를 직접 호출하는 과정과 대부분 같다.
1) nginx-2 파드 아이피로 해당 파드의 네트워크 인터페이스 획득 [기존과 동일]
2) 획득한 네트워크 인터페이스를 tcpdump로 패킷 덤프 [기존과 동일]
3) nginx-2 파드의 서비스 생성
# Bash
kubectl expose pod/nginx-2 --port=80 --target-port=80 --protocol=TCP
4) nginx-2 서비스 호출
nginx-1 파드 접속 후 nginx-2 파드로 이어지는 서비스 호출을 몇 번 해주고, tcpdump를 종료해 준다.
# nginx-1 파드에서
curl <nginx-2 서비스 명 또는 서비스 IP>
5) 와이어 샤크로 pcap파일 확인
와이어 샤크로 파일을 확인하게 된다면, 가장 큰 차이는 파드 IP를 직접 호출하는 케이스는 HTTP로 표기되었던 부분에서, 모든 트래픽이 TCP로 나타나는 것을 볼 수 있고, 여러 패킷을 확인해 봐도 우측 하단과 같이 암호화된 것을 볼 수 있다.
그리고 kiali에서도 확인해 보면, HTTP라는 프로토콜에 자물쇠가 채워져 있는 것을 볼 수 있다.
결론
위 과정을 통하여 직접 패킷을 확인하면서 mTLS의 적용 여부에 따라 암호화가 되는지 안되는지를 볼 수 있었다.
아키텍처를 확인하면, Envoy Proxy를 활용하여 mTLS를 구현하는 것을 볼 수 있으며, Ingress로 들어오는 Inbound 트래픽과 Egress로 나가는 Outbound 트래픽을 모두 관리할 수 있다.
이 외에도 관측 가능성과 확장성에도 유리한 측면이 있지만, 많은 기능들로 인한 관리 포인트의 증가와 아키텍처가 복잡해지며 발생하는 어려움이 다소 있는 것 같다.