3-Way Handshake

송윤재·2024년 8월 19일

3-Way Handshake는 TCP(Transmission Control Protocol)에서 두 네트워크 장치(주로 클라이언트와 서버) 간에 신뢰할 수 있는 연결을 설정하기 위해 사용하는 절차입니다. 이 과정은 연결을 설정하고, 데이터를 안전하게 전송할 수 있는 상태를 만들기 위해 필요합니다. 3-Way Handshake는 세 단계로 이루어지며, 다음과 같은 절차를 거칩니다.

1. SYN (Synchronize) - 클라이언트가 서버에 요청

  • 클라이언트가 서버와의 연결을 시작하기 위해, TCP 헤더의 SYN 플래그를 설정한 패킷을 서버에 전송합니다. 이 패킷은 클라이언트의 초기 순서 번호(Initial Sequence Number, ISN)를 포함합니다.
    이 단계에서 클라이언트는 서버가 연결을 수락할 준비가 되었는지 확인하기 위해 손을 내미는 것과 같습니다.

2. SYN-ACK (Synchronize-Acknowledge) - 서버의 응답

  • 서버는 클라이언트로부터 SYN 패킷을 수신하면, 이를 수락할 준비가 되었다면 SYN과 ACK 플래그가 설정된 패킷으로 응답합니다.
    이 패킷에는 서버의 초기 순서 번호(ISN)가 포함되며, 클라이언트의 SYN 패킷에 대한 응답으로 ACK 번호를 설정합니다.
    이 단계에서 서버는 클라이언트의 요청을 받아들이고, 자신도 준비되었음을 알리는 응답을 보내는 것입니다.

3. ACK (Acknowledge) - 클라이언트의 확인

  • 클라이언트는 서버로부터 SYN-ACK 패킷을 수신한 후, 연결이 성공적으로 설정되었음을 확인하기 위해 ACK 플래그가 설정된 패킷을 서버로 다시 전송합니다.
    이 패킷에는 서버의 초기 순서 번호에 1을 더한 ACK 번호가 포함됩니다.
    이로써 클라이언트와 서버 간의 연결이 확립되며, 이제 양측은 데이터를 주고받을 준비가 완료된 것입니다.

ACK, SYN 같은 정보는 어떻게 전달할까?

ACK, SYN과 같은 정보는 TCP (Transmission Control Protocol) 헤더의 특정 필드를 통해 전달됩니다.

TCP 헤더 구조

  • 발신지 포트 주소 : 패킷을 보내는 프로세스의 포트번호

  • 목적지 포트 주소 : 패킷을 받는 상대 프로세스의 포트번호

  • Sequence Number : 세그먼트에 포함된 데이터의 첫 번째 바이트에 부여된 번호

    • 패킷의 순서 번호를 나타내기 위한 필드
    • 순서 번호(Sequence Number)가 필요한 이유: 네트워크 상에서 패킷이 전송될 때 전송 루트가 일정하지 않아 목적지에 도착하는 패킷의 순서가 역전되는 경우가 많기 때문. 따라서 목적지에 패킷의 순서가 뒤죽박죽으로 전달되더라도 순서 번호를 이용하여 데이터를 올바른 순서로 재배열 할 수 있음.
    • 순서 번호 부여 방식: '0' 또는 랜덤한 값에서 최대값까지 값을 증가시키는 방향으로 순서 번호가 부여됨. (최대값 이후에는 다시 '0'부터 시작)
  • Acknowledgement Number : 수신 측에서 앞으로 받고자 하는 바이트의 Sequence Number

    • 수신 성공 데이터의 Sequence Number+1
    • 송신측에 데이터를 어디까지 전달 받았는지 알리기 위한 필드
  • HLEN : 헤더의 길이

    • 헤더의 길이를 32bits 단위로 나타냄. (헤더의 길이/32=HLEN)
    • 따라서 최소 필드 값은 5 (5*32bits=160bits or 20byte → 20byte가 TCP 헤더의 최소 길이)
    • 최대 필드 값은 15 (15*32bits=480bits or 60byte → 60byte가 TCP 헤더의 최대 길이)
  • 예약(Reserved) : 미래에 사용하기 위해 남겨둔 예비 필드. 0으로 채워져야 함.

  • Window Size : 수신 가능한 데이터 양의 최대값

    • TCP 흐름 제어를 위해 송신자에게 자신의 수신 버퍼(메모리) 여유 용량 크기를 지속적으로 통보
    • 가용 수신 버퍼의 크기를 바이트 단위로 나타냄.
  • Checksum : TCP 헤더와 데이터를 포함한 세그먼트 전체에 대해 계산한 값으로 에러를 체크할 때 사용

  • Urgent Pointer : TCP 세그먼트에 포함된 긴급 데이터의 마지막 바이트 Sequence Number

    • Urgent Pointer 값을 설정하면 URG 플래그를 '1'로 설정
    • 현대의 프로토콜에서 많이 사용되지는 않음.
  • Options : TCP 연결 관리 기능을 확장시키는데 주로 사용되는 옵션 필드

    • 최대 40byte까지 옵션 데이터 포함 가능

TCP Flag (Control bits)

TCP 헤더에선 특수한 목적의 패킷을 위한 6개의 제어 플래그를 가진다.

  • URG(Urgent) : 긴급 데이터 플래그

    • Urgent Pointer 필드에 값이 채워져 있으면 1, 그렇지 않으면 0

    • URG가 1로 설정된 경우 패킷의 순서에 상관없이 먼저 송신됨.

  • ACK(Acknowledgement) : 응답 플래그

    • Acknowledgement Number 필드에 유효한 값이 채워져 있으면 1, 그렇지 않으면 0

    • 0으로 설정된 경우 Acknowledgement Number 필드 무시됨.

    • SYN 세그먼트 전송 이후(TCP 연결 시작 후) 모든 세그먼트에는 항상 이 비트가 1로 수신됨.

  • PSH(Push) : 넣기 플래그

    • 버퍼링 된 데이터를 가능한 빨리 상위 계층 응용프로그램에 즉시 전달하라는 것을 알리기 위한 컨트롤 비트

    • 수신 측은 버퍼(수신용 메모리)가 찰 때까지 기다리지 않고 수신 즉시 버퍼링된 데이터를 응용 프로그램에 전달

    • 때로는 서버측에서 더이상 전송할 데이터가 없음을 나타낼 때 사용

  • RST(Reset) : 연결 재설정 플래그

    • 강제로 연결을 초기화하기 위한 컨트롤 비트

    • RST 플래그를 '1'로 설정한 TCP 세그먼트를 송출한 경우

      ① LISTEN, SYN_RCVD 상태일 때 RST 수신 → LISTEN 상태

      ② 그 밖의 상태일 때 RST 수신 → CLOSED 상태

  • SYN(Synchronize) : 연결 요청 플래그

    • 연결을 시작하기 위한 컨트롤 비트

    • TCP 3-way handshaking

      ① 연결 요청: SYN=1, ACK=0 (SYN 세그먼트)

      ② 연결 허락: SYN=1, ACK=1 (SYN+ACK 세그먼트)

      ③ 연결 설정: ACK=1 (ACK 세그먼트)

  • FIN(Finish) : 연결 종료 플래그

    • 연결을 종료하기 위한 컨트롤 비트

    • 송신기가 데이터 보내는 것을 끝마침

      ① 종결 요청: FIN=1

      ② 종결 응담: FIN=1, ACK=1


2-Way Handshake를 하지 않는 이유?

2-Way Handshake은 두 단계로 이루어진 연결 설정 방식입니다

  1. SYN: 클라이언트가 서버에 연결 요청(SYN 패킷)을 보냅니다.
  2. ACK: 서버가 요청을 받아들이고 확인 응답(ACK 패킷)을 클라이언트에게 보냅니다.
  • 3-Way Handshake와 차이점은 마지막에 클라이언트에서 서버에게 ACK 패킷을 보내는 과정이 생략되는 것이다.
  • 이렇게 되면 서버의 경우 자신은 클라이언트에게 패킷을 전달 받을 수 있지만, 자신이 클라이언트에게 패킷을 전달할 수 있는지에 대한 확인을 받지 못했기 때문에 상대방에게 패킷을 전달 가능한지 알 수 없다.
  • 즉, 서버는 신뢰할 수 없는 통신이 되는 것이다.

SYN Flooding은 무엇인가?

SYN Flood는 반개방 공격이라고도 하며, 보낸 SYN 요청에 대한 서버의 SYN-ACK에 응답하지 않고 SYN 요청만 마구잡이로 보내는 네트워크 계층 공격입니다. 결과적으로 많은 수의 열린 TCP Connection으로 인하여 서버의 리소스가 과도하게 소모되어 정상 트래픽의 처리를 어렵게 하면서 정상적인 새로운 Connection을 열 수 없으며, 이미 연결된 사용자의 Connection의 경우에도 서버가 올바르게 작동하기 어렵게 됩니다.

방어 방법

1. 서버 자체에서 막는 방법

  • 서버에서 Time_Wait 즉 ACK를 기다리는 시간을 짧게한다. RAM을 확보했다가 ACK가 없으면 다시 리소스를 돌려 놓아 다른 세션에 대해 사용할 수 있도록 하는 방법

2. 방화벽에서 막는 방법

  • 2-1 SYN Cookie
    - 방화벽 단에서 SYN을 먼저 받고, SYN Cookie를 포함한 SYN+ACK를 보내는 방법이 있습니다.
    - 일정 시간동안 SYN Cookie에 대한 정상적인 응답패킷이 들어오지 않으면 방화벽에서 차단
    - 정상적인 패킷이 들어오면 통신이 가능하게끔 해주는 방식

  • 2-2 SYN Proxy

    • 방화벽 단에서 정상적인 3-way-handshake과정이 이루어지면, 그 연결을 다시 서버에게 재현시켜주는 방식입니다.
    • SYN Proxy도 역시, SYN Cookie를 이용해 정상적인 3-Way Handshake 인지를 확인합니다.
    • Client와 방화벽 사이에 맺은 3-Way Handshake를 방화벽이 Server에게 다시 재현해주기 때문에 세션을 새로 맺을 필요가 없습니다.


이동 수를 줄이는 0-RTT기법이란?

0-RTT(Zero Round Trip Time Resumption)는 TLS 1.3에서 도입된 기능으로, 클라이언트와 서버 간의 연결을 재개할 때 보안 핸드셰이크 과정을 줄여 연결 속도를 높이는 방식입니다. 이 기능은 특히 반복적으로 연결을 설정해야 하는 환경에서 유용하며, 첫 번째 연결 이후 재연결할 때 시간이 거의 소요되지 않습니다.

  • 기본 개념

    • 첫 번째 연결 : 클라이언트와 서버는 일반적인 TLS 핸드셰이크 과정을 거칩니다. 이 과정에서 클라이언트는 서버 인증서를 확인하고, 서버는 클라이언트와 세션 키를 협상합니다. 이 세션 키는 다음 연결에서 재사용될 수 있도록 클라이언트와 서버에 저장됩니다.

    • 재연결 (0-RTT) : 클라이언트가 이전에 저장한 세션 키를 사용하여 서버에 요청을 보낼 수 있습니다. 이 과정에서 클라이언트는 서버와의 새로운 핸드셰이크 과정을 생략하고, 데이터를 곧바로 전송할 수 있습니다. 서버는 클라이언트가 보낸 세션 키를 확인하고 유효하다면, 데이터를 받아 처리합니다.

    • 장점 : 연결 재개 시 추가적인 핸드셰이크 과정이 생략되기 때문에 지연 시간이 감소하여, 빠른 데이터 전송이 가능합니다.

    • 단점 : 0-RTT 데이터는 암호화되지만, 재전송 공격의 위험이 있습니다. 즉, 이전에 전송된 데이터를 공격자가 재전송하여 서버에 다시 처리하게 할 수 있습니다. 이를 방지하기 위해 서버는 0-RTT 데이터를 일단 수신한 후 나중에 검증할 수 있는 방식을 사용합니다.

  • 0-RTT의 도입 이전

    0-RTT가 도입되기 전에는, 매번 새로운 TLS 핸드셰이크를 수행해야 했고, 이로 인해 초기 데이터 전송이 지연되는 상황이 발생했습니다. 0-RTT는 이러한 문제를 해결하기 위해, 이전에 설정된 세션 정보를 재사용하여 TLS 핸드셰이크 과정을 단축하고, 초기 데이터 전송을 거의 지연 없이 시작할 수 있도록 한 기술입니다.
    결론적으로, 0-RTT 이전에는 반드시 완전한 TLS 핸드셰이크가 완료된 후에야 데이터를 전송할 수 있었으며, 이로 인해 초기 연결 설정 시 지연이 발생했습니다.


출처

https://ohcodingdiary.tistory.com/12
https://blog.naver.com/ak0402/221539958656
https://jeongkyun-it.tistory.com/180
https://pat.im/1330
https://blog.naver.com/yeopil-yoon/221335811255
https://www.f5.com/ko_kr/glossary/syn-flood-attack
https://sata.kr/entry/DOSDDOS-SYN-Flooding-%EA%B3%B5%EA%B2%A9%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90

profile
CS 공부를 해봅시다

0개의 댓글