IT/DevOps

VPC Flow logs는 네트워크 문제 분석에 활용할 수 있을까?

Aaron's papa 2022. 2. 10. 22:24
반응형

간헐적으로 발생하는 네트워크 이슈 만큼 원인을 추적하기 어려운 이슈는 아마 없을 겁니다. 모든 요청에 대해서 에러가 발생하는 것도 아니고 가끔씩 에러가 발생하면서 수집하는 메트릭에는 특별한 흔적도 남기지 않는 그런 이슈들. 요즘에는 eBPF 기반의 도구를 이용해 네트워크 문제를 분석하는 경우도 많지만 어떤 경우에는 tcpdump와 같은 전통적인 도구가 필요한 경우가 있습니다. 간헐적인 네트워크 이슈들은 전반적인 패킷의 흐름을 수집하고 분석하면서 어느 구간에서 언제 문제가 생기는지를 분석해야 할 필요가 있기 때문 입니다. 하지만 클라우드 환경에서는 tcpdump와 같은 도구를 이용해 패킷을 수집하기 쉽지 않습니다. 그래서 이번 글에서는 AWS에서 제공하는 VPC Flow logs를 네트워크 문제 분석에 어떻게 활용할 수 있을지에 대해서 살펴 보겠습니다.


VPC Flow logs

VPC Flow logs는 VPC 내의 네트워크 트래픽을 수집하고 분석할 수 있는 로그를 제공해 주는 기능 입니다. 전통적인 방식이라면 서버나 네트워크 장비에서 tcpdump 와 같은 도구를 이용해 직접 패킷을 수집 하겠지만 클라우드 환경에서는 아무래도 고객이 직접 접근 가능한 장비의 종류에 한계가 있기 때문에 tcpdump 와 같은 도구를 이용해 패킷을 수집할 수 있는 범위가 한정적 입니다. VPC Flow logs는 이런 환경에서 조금이라도 더 네트워크에 대한 관측 가능성을 높여 주기 위한 기능 입니다. VPC Flow logs는 VPC 콘솔에서 볼 수 있습니다.

VPC 콘솔에서 볼 수 있는 Flow logs

아무래도 Flow logs 기능을 가장 찾기 쉬운 곳이 VPC 메뉴 이다 보니 VPC의 모든 트래픽을 수집하는 기능이라고 오해할 수 있는데요, 그렇지 않습니다. Flow logs는 VPC의 모든 트래픽을 수집할 수도 있지만 특정 서브넷의 트래픽만 수집할 수 있고, 특정 ENI의 트래픽만 수집할 수도 있습니다.

Subnets 메뉴에서 볼 수 있는 Flow logs

그 중에서도 특히 특정 ENI의 트래픽을 수집하는 기능이 아마 실무에서는 가장 많이 사용될 수 있는 기능 일 겁니다. 대부분의 네트워크 문제는 특정 서브넷과 같이 광범위 하게 일어나기 보다는 특정 인스턴스와 같이 작은 범위에서 발생하기 때문 입니다. ENI의 Flow logs는 VPC 관리 콘솔이 아닌 EC2 관리 콘솔에서 볼 수 있기 때문에 찾기 힘들어서 있는지 조차 모르는 경우도 많습니다. 저 역시 이번에 네트워크 이슈를 겪는 와중에 발견한 기능 이었습니다. 그리고 이 기능으로 굉장히 많은 도움을 받았습니다.

EC2 관리 콘솔의 Network Interfaces 메뉴에서 볼 수 있는 Flow logs


Flow logs를 의미있게 수집하기

Flow logs를 수집해야 겠다고 생각하고 수집을 해보면 수집된 데이터가 실제로는 별다른 도움이 되지 못하다는 것을 알게 됩니다. Flow logs를 기본 포맷 그대로 사용하게 되면 아래와 같이 종단 간 주고 무언가를 주고 받았다는 내용만 있지 이걸 가지고는 네트워크 문제를 해결하는데 도움이 되는 정보가 부족하기 때문 입니다.

기본 포맷으로 수집한 Flow logs

먼저 Flow logs가 어떤 데이터를 수집하는지 알아 보기 위해 기본 포맷을 먼저 살펴 보겠습니다. Flow logs가 사용하는 기본 포맷은 아래와 같습니다.

${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${action} ${log-status}

하지만 특정 ENI에서 수집한다면 ${account-id}${interface-id} 같은 정보는 필요하지 않습니다. 그리고 기본 포맷에는 아주 중요한 필드가 하나 빠져 있습니다. 바로 ${tcp-flags} 필드 입니다. 이 필드는 커스텀 포맷을 사용해서 직접 추가를 해줘야 합니다. 그래서 tcpdump의 데이터와 유사한 수준으로 의미 있게 사용할 수 있는 포맷은 아래와 같습니다.

${pkt-srcaddr} ${srcaddr} ${srcport} ${pkt-dstaddr} ${dstaddr} ${dstport} ${tcp-flags} ${action}

패킷의 출발지 주소와 포트, 목적지 주소와 포트, 그리고 ${tcp-flags}로 표현되는 패킷의 플래그. 이 정도 데이터들이 분석을 하기 위해 필요한 정보들 입니다. 그리고 이렇게 커스텀 포맷을 사용하면 수집되는 데이터가 아래와 같이 변합니다.

${tcp-flags}를 수집하는 Flow logs의 데이터

어디에서 출발한 패킷인지, 그리고 이 패킷이 SYN 패킷인지, ACK 패킷인지, 패킷의 플래그를 통해 알 수 있습니다. 이 정도의 데이터는 있어야 종단간 3 way handshake는 맺었는지, 어떤 패킷들을 주고 받았는지, RST 패킷은 없었는지 등등 네트워크 문제를 분석하기 위해 필요한 정보들을 얻을 수 있습니다.


${tcp-flags} 해석하기

Flow logs에서 수집하는 ${tcp-flags}는 패킷의 플래그 값을 10진수로 표현한 숫자 입니다. 그리고 TCP 패킷의 플래그는 아래 그림과 같습니다.

TCP 패킷 플래그

TCP 플래그를 표현하기 위한 비트에는 총 6개의 비트가 있습니다. 그리고 각각이 1이 되었을 때의 10진수 값을 ${tcp-flags} 필드에 넣어서 출력 합니다. 이렇게 설명하면 이해하기가 어려우니 SYN 패킷이 있다고 가정해 보겠습니다. 그럼 다섯번째 비트가 1이 되어야 하기 때문에 플래그 값이 000010 이 됩니다. 그리고 이 값은 10진수로 2가 됩니다. 같은 방식으로 FIN 패킷은 1, ACK 패킷은 16, SYN + ACK 패킷은 18이 됩니다.

TCP 플래그 값을 10진수로 변환

아래와 같은 Flow log는 10.255.78.140 에서 10.200.235.55로 SYN+ACK 패킷을 보냈다는 것을 의미 합니다.

SYN+ACK 패킷에 대한 로그

이렇게 Flow logs에 패킷의 플래그가 포함되기 시작하면 네트워크 문제를 분석하기 위한 도구로 사용될 수 있습니다.


Flow logs의 단점

하지만 Flow logs에도 단점이 있습니다. 바로 패킷의 순서가 보장되지 않는다는 건데요, 아무래도 수집되는 데이터가 초 단위로 밖에 볼 수 없다 보니 Flow logs를 볼 때 SYN 패킷 보다 SYN + ACK 패킷이 먼저 보이는 경우도 있습니다.

순서가 바뀐 Flow logs

위 데이터는 누가 봐도 10.200.235.55가 먼저 보낸 SYN에 대해 10.255.78.140이 SYN+ACK로 응답을 한 흐름이지만, Flow logs 상으로는 SYN+ACK가 먼저 보이게 됩니다. 하지만 SYN+ACK 가 먼저 보내질 일은 없으니 전체 Flow logs를 보고 흐름을 파악하면 됩니다.

그리고 가장 큰 단점 이겠지만 꽤 비용이 많이 발생 합니다. 저도 정확하게 측정은 해보지 않았지만 트래픽이 많을 경우 수집하는 Flow logs의 크기가 순식간에 GB 를 넘겨 버릴 수도 있기 때문에 비용이 많이 발생할 수 있다고 합니다.


마치며

만약 AWS 환경에서 네트워크 이슈가 발생 했고 tcpdump를 이용해 패킷 덤프를 생성하기 어려운 상황이라면 VPC Flow logs를 활용해보는 것은 좋은 선택 입니다. Flow logs를 이용하면 운영 중인 워크로드에 부담을 주지 않으면서도 패킷의 플래그 수준까지 데이터를 수집할 수 있기 때문 입니다. 하지만 제법 많은 비용이 발생할 수 있기 때문에 가급적 짧은 시간 동안만, 그리고 문제가 발생하는 구간만을 대상으로 필요한 로그만 수집하는 게 좋습니다. 마지막으로 이 글이 클라우드 환경에서 네트워크 이슈로 어려움을 겪고 계신 분들에게 도움이 되었으면 좋겠습니다.

반응형