Amazon Web Services

TCP 통신에서의 플래그 해석 및 VPC Flow Logs 관련 문제 분석 (Level 200)

junoshon 2024. 11. 2. 15:57

 

안녕하세요.

이번 글에서는 TCP 통신에서의 플래그 해석 및 VPC Flow Logs 관련 문제 분석에 대한 글을 작성해보려고 합니다. 

해결해야 할 문제는 아래와 같습니다.

고객은 AWS 환경에서 VPC Flow Logs를 통해 네트워크 트래픽을 모니터링하는 중에, 통신이 정상적으로 이루어진 경우에도 TCP 플래그가 0으로 기록되는 현상을 발견했다. 고객은 RFC 3168에 따른 ECE(ECN-Echo) 플래그와 관련된 내용을 확인하고, TCP 플래그 값이 0으로 찍히는 상황에서 통신이 정상적으로 이루어졌는지에 대해 문의했다.

고객의 로그 분석 요청 사항:

- TCP 플래그 값이 0으로 설정된 상황에서 통신이 정상적으로 이루어진 것으로 간주할 수 있는지 확인하고 싶습니다.
- TCP 플래그 0 상태에서 발생할 수 있는 문제는 무엇인가요?
- ECE 플래그와 관련된 RFC 3168에 따라, 혼잡 통지가 발생했을 때 통신이 정상적으로 이루어진 경우를 어떻게 해석할 수 있나요?


고려해야 할 사항:

1. TCP 플래그 값이 0일 때, 통신이 정상적으로 이루어졌는지 확인할 수 있는 네트워크 상태 및 조건.
2. RFC 3168에 따른 ECN(ECE 플래그)의 동작 방식과 혼잡 통지(Congestion Notification) 처리 과정.
3. 정상적인 통신 과정에서 TCP 플래그 값이 0으로 설정되는 시나리오가 있는지.
4. VPC Flow Logs에서 TCP 플래그 값의 기록 방식에 대한 추가 검토.

이 문제를 해결하기 위한 분석 및 조치를 제시하라.

 

본 글에서는 위 문의사항을 해결하기 위해 알아야 할 지식과 해결 방법에 대해 작성하겠습니다. 글의 너무 길어지면 글을 나누어 작성할 예정입니다.

먼저 TCP 플래그에 대해 알아보겠습니다.

 

TCP Flags

TCP header format

위 그림은 TCP 프로토콜 헤더의 포맷입니다. 주목해야 할 부분은 reserved와 그 뒤의 control flags입니다.  각각 3비트, 9 비트라고 표현되어 있습니다. reserved는 미래에 사용하기 위해 남겨놓은 예약된 공간이고, 플래그들은 TCP 세그먼트의 논리 제어 및 데이터 관리를 위해 사용됩니다.

 

TCP Flags

 

간단히 플래그에 대해 살펴보겠습니다. 이들은 각각 1비트의 공간을 가지며, 0 혹은 1로 표현됩니다. 1이면 참, 0이면 거짓이지요.

각 플래그의 값이 참일 경우 그 TCP 세그먼트는 아래와 같은 역할을 합니다.

 

  • URG (Urgent)
    • 긴급 데이터가 포함되어 있음을 나타내는 플래그
  • ACK (Acknowledgment)
    • 수신한 데이터에 대한 응답을 의미하는 플래그
  • PSH (Push)
    • 데이터를 버퍼링 하지 않고 즉시 전달될 때 사용되는 플래그
  • RST (Reset)
    • 비정상적인 연결을 즉시 종료할 때 사용되는 플래그
  • SYN (Synchronize)
    • 연결 설정을 시작할 때 사용되는 플래그. 
  • FIN (Finish)
    • 연결을 종료할 때 사용되는 플래그

 

그런데 아까 TCP 헤더 포맷에서는 control bits 가 9 bits라고 했는데, 왜 Flags는 6개일까요?

 

RFC 3168

그 정답은 RFC 3168에 있습니다.

RFC 3168 은 TCP/IP 네트워크에서 혼잡 제어 메커니즘을 개선하기 위해 ECN 기능을 도입한 문서입니다.

ECN 은 Explicit Congestion Notification의 약자로, 네트워크 혼잡 상황을 알려주는 방법입니다.

 

ECN 기능은 2001년에 RFC 3168에 소개되었습니다.

미래에 사용하기 위해 예약해 놓은 Reserved 공간 3비트를 이 ECN 기능에 사용합니다. 그렇다면 이 ECN 기능은 왜 사용될까요? ECN 기능이 개발되기 전에는 네트워크의 혼잡 상황을 알 수 없었기 때문일까요?

 

TCP는 네트워크의 상태를 모니터링할 수 없습니다. 만약 네트워크가 혼잡하여 패킷의 전송이 느려지거나, 혹은 손실되면 이 패킷을 기다리다가 재전송을 요구하죠. 손실된 패킷을 기다리는 시간이 아까워지고, 이에 민감한 애플리케이션이 개발되면서 더 효율적인 통신이 요구되었습니다.

 

그래서 나온 기능이 명시적 혼잡 알림, Explicit Congestion Notification입니다. 

이 ECN 기능은 3개의 플래그를 사용합니다. 미래에 사용하려고 남겨놨던 예약된 필드 3비트를 빌려서요. ECN의 각 플래그들에 대해 알아보겠습니다.

 

ECN Flags

  • NS (Nonce Sum)
    • 송신자가 ECN 신호를 반영하고 있는지 확인하기 위한 보안용 플래그
    • ECN의 무결성을 보장하기 위해 사용
  • CWR (Congestion Window Reduced)
    • 송신 측이 혼잡 상태를 감지하고 윈도 크기를 줄였음을 수신 측에 알리는 플래그
  • ECE (ECN-Echo)
    • 혼잡 상태가 감지되었음을 송신 측에 알리기 위한 플래그

이처럼 송신 측에서는 ECE 플래그를 1로 설정해 네트워크가 혼잡함을 알립니다. 그럼 수신 측에서는 이를 보고 네트워크가 혼잡하므로 송신 윈도를 줄입니다. 그리고 CWR 플래그를 1로 설정해서 윈도를 줄였음을 알립니다.

 

RFC 3168의 ECN의 동작 방식과 혼잡 통지 처리 과정은 이런 식으로 동작합니다.

 

다음으로, VPC Flowlogs에 대해 알아보겠습니다.

 

VPC Flow Logs

VPC Flow Logs는 VPC의 네트워크 인터페이스에서 전송되고 수신되는 IP 트래픽에 대한 정보를 수집할 수 있는 기능입니다. 흐름 로그 데이터가 게시될 수 있는 위치는 Amazon CloudWatch Logs, Amazon S3 또는 Amazon Data Firehose입니다. 흐름 로그를 생성하면 구성한 로그 그룹, 버킷 또는 전송 스트림의 흐름 로그 레코드를 검색하고 볼 수 있습니다.

- 출처 : aws docs -

 

아마존 공식문서에서 설명하고 있는 것처럼, VPC Flow Logs를 사용하면 VPC의 ENI에서 흐르는 트래픽을 모니터링하고 수집할 수 있습니다. 수집된 데이터는 CloudWatch Logs나 S3, Kinesis Firehose 등으로 모아볼 수 있습니다.

 

VPC Flow Logs에서는 interface-id, instance-id, srcport, srcaddr, dstport, dstaddr, protocol, tcp-flags 등의 필드를 사용해 네트워크 흐름을 감시할 수 있습니다.

아래와 같이 기록될 레코드를 조정할 수 있습니다. AWS에서 제공하는 기본 형식을 사용할 수도 있고, 필요하다면 사용자가 지정한 형식으로 기록할 수 있습니다.

VPC Flow Logs Record

여기서 고객의 요구사항은 tcp-flags에 따른 분석입니다.

사용자 지정 형식에 tcp-flags를 추가해 패킷 모니터링 결과를 CloudWatch Logs로 전송해 보겠습니다.

CloudWatch Logs Event

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

 

저는 위와 같은 형식으로 로그를 기록했으므로 그에 맞는 레코드가 전송되었습니다. 가장 마지막 action 앞의 숫자가 바로 VPC Flow Logs 가 기록한 tcp-flags입니다.

아마존에서 설명하는 VPC Flow Logs Docs에 따르면 플래그에 따라 비트 마스크 값을 표기합니다.

  • FIN - 1
  • SYN - 2
  • RST - 4
  • SYN-ACK - 18

그런데 이 플래그들과는 다른 숫자도 몇 보입니다. 0,6,19 등의 숫자는 어떤 플래그를 의미하는 걸까요?

AWS의 TCP 플래그 시퀀스 docs에서는 매우 짧은 연결(몇 초)의 경우 Flow Logs에서 같은 줄에 플래그가 설정될 수 있다고 밝히고 있습니다. 즉, 19라는 값은 SYN-ACK 메시지가 전송된 후 몇 초 이내에 FIN 메시지가 전송되었기 때문에, VPC Flow Logs에서는 이를 한 줄에 표시해 18 + 1 = 19의 결과가 표기된 겁니다. 6도 마찬가지겠지요. 

 

그렇다면 tcp-flags 값이 0인 경우는 뭘까요? 

출처 : https://www.cloudflare.com/ko-kr/learning/ssl/what-happens-in-a-tls-handshake/

여러 가지 경우가 있겠지만, VPC FlowLogs에서는 Docs에서 언급한 플래그가 아니면 TCP Flags를 0으로 기록합니다.

즉 수 초 내에 FIN, SYN, RST, SYN-ACK 플래그가 기록된 패킷이 아니면 tcp-flags를 0으로 기록하지요. 심지어는 ACK 도 기록하지 않습니다. TCP 3-way handshake 과정의 마지막 과정인 ACK 플래그를 기록하지 않기 때문에 FlowLogs에서는 tcp-flags 값이 0으로 기록될 것이고, 이는 정상적인 통신으로 기록됩니다.

VPC FlowLogs가 지원하지 않는 tcp-flags에는 RFC 3168에서 설명하는 ECE, CWR, NS 플래그도 포함됩니다.

 

마치며

출처 : https://www.mgt-commerce.com/blog/virtual-private-cloud-aws/

TCP 프로토콜은 많은 응용 계층 프로토콜의 하위 프로토콜로 사용됩니다. 주로 신뢰성이 중요한 통신에서 많이 사용하지요.

따라서 수신지와 연결되었음을 확실히 하기 위해 Flags를 사용해 패킷에 표시합니다.

 

이번 글에서는 TCP Flags에 대해 알아보고, AWS의 VPC FlowLogs에서의 TCP Flags를 해석에 대해 알아봤습니다.

질문 및 지적은 댓글로 부탁드립니다.

긴 글 읽어주셔서 감사합니다.

'Amazon Web Services' 카테고리의 다른 글

AWS 3-Tier Architecture 실전 사례 - 1  (1) 2024.10.24