운영하고 있던 서비스의 요청/응답이 느려지는 사건이 발생하였습니다.
갑작스레 발생한 사건에 몇 시간 동안 원인을 분석해보니 Syn Flooding이 발생했던 사례였습니다.
이번 사건을 통해 Syn Flooding이 어떻게 발생하였는지, 그리고 대응방안은 무엇인지 알게되었던 것 같습니다.
Syn Flooding
Syn Flooding은 TCP 연결과정(3-way handshaking)에서 발생하는 공격입니다.
보통 http 프로토콜을 이용한 요청(REST API)은 TCP 프로토콜 위에 요청됩니다.
TCP 연결이 필요하기 때문에 3-way handshake 과정이 반드시 필요합니다.
우선 3-way handshak이 무엇인지 알아보도록 하죠.
3-way handshake
1. Client는 특별한 세그먼트(SYN)를 Server에게 전달합니다.
2. Server는 특별한 세그먼트(SYN + ACK)을 Client에게 전달합니다.
3. Client는 특별한 세그먼트(ACK)을 Server에게 전달함으로써 TCP연결을 설정합니다.
2번 과정에서 Server는 로그백 큐에 TCP 연결정보를 관리합니다.
2번 과정 후 3번 과정이 진행되어야 로그백 큐에 있던 TCP 연결정보가 삭제되는데(이동) 3번 과정이 진행되지 않았을경우 Syn Flooding이 발생합니다.
즉, 로그백 큐가 TCP 연결정보로 꽉 차 서비스가 더 이상 작동하기 어려운 상황을 발생시킵니다.
그렇다면 이에 대한 해결책은 무엇일까요?
Syn cookies 설정
SYN을 받고, 이에 대한 응답으로 SYN Cookie(TCP 연결정보)를 포함한 SYN+ACK를 보내는 방법입니다. 일정기간 동안 SYN+ACK에 대한 정상적인 응답인 ACK(Cookie값 검증을 통과한)가 오지 않는다면 방화벽에서 연결을 차단시켜버리며, 정상적인 응답이 올 경우 통신할 수 있습니다.
TCP 연결정보를 로그백 큐에 저장하지 않아 Syn Flooding을 방지할 수 있지만 Cookie에 TCP 연결정보를 담는 과정과 이를 인증하는 과정에 대한 오버헤드가 존재합니다.
리눅스에서 Syn cookies 설정 명령어
# sysctl -w net.ipv4.tcp_syncookie=1
Syn Proxy 설정
Proxy란 대리자라는 뜻을 의미하는데요. Proxy란 용어 그대로 클라이언트는 첫 연결과정인 3-way handshake 과정을 TCP서버가 아닌 Syn Proxy와 맺습니다. 정상적으로 연결이 되었다면 Proxy는 클라이언트때와 마찬가지로 TCP 서버와 3-way handshake 연결을 합니다. 방화벽과 마찬가지로 정상적으로 연결되지 않는다면 서버와 연결될 수 없습니다.
Syn Proxy는 리눅스 커널 netfilter 모듈입니다. 이것의 진정한 효과는 공격을 받는 와중에도 실제 서버가 어떠한 변화도 감지하지 못하기 때문에 Syn Flooding 뿐만 아니라 DDOS 공격으로부터 TCP서버를 보호할 수 있습니다.
참조