태코놀로지

A Simple HTTP Filter Application 본문

IO Visor/BCC Apps

A Simple HTTP Filter Application

태코놀로지 2016. 12. 27. 00:31

Application-layer traffic processing with eBPF: a simple HTTP Filter


 본 포스팅에서 다룰 IO Visor BCC를 활용한 응용 프로그램의 이름은 http_filter_simple이다. 응용 프로그램을 통해 네트워크 인터페이스로 출입하는 HTTP 패킷을 트레이싱할 수 있다. `bcc/examples/networking/http_filter' 경로에 위치한 `http-filter-simple.py` 파이썬 파일 실행하고, 인터넷 브라우저를 통해 웹 서핑을 하면 결과를 확인할 수 있다. 관련된 소스코드는 IO Visor - bcc Github 페이지를 확인하면 된다. 여담이지만, 해당 응용 프로그램 소스 코드를 확인하던 중에 사소한 오타를 발견하고 컨트리뷰션을 하기도 했다.


 응용 프로그램 실행 환경은 Ubuntu-14.04 64bit Desktop 버전을 사용했다. eBPF는 3.15 버전 이상의 커널 의존성을 가지고 있고, BCC의 경우 4.1 버전 이상의 커널 의존성을 띄고 있다. 따라서 응용 프로그램 실행 이전에 BCC 사용을 위해서는 커널 버전 업그레이드가 필요하며, 해당 내용은 IO Visor 설치 가이드 페이지를 통해 확인할 수 있다.



 http-filter-simple 응용 프로그램은 C로 작성된 파일(http-filter-simple.c)과 Python으로 작성된 파일(http-filter-simple.py), 두 가지로 구성되어 있다. 코드에 대해서 세세하게 설명하기는 어렵지만 구분지어서 간략하게 추려보면 아래와 같다.


http-filter-simple.c: eBPF filter

C로 작성된 파일에서는 Raw Socket을 네트워크 인터페이스에 바인딩한다. 그리고 IPv4, TCP 패킷에 대한 체크를 진행하면서, ethernet frame, IP packet, TCP segment의 헤더에 대한 정보(길이)를 추적하여 페이로드(payload)의 시작점(offset)과 길이를 찾는다. 따라서 본 코드를 이해하기 위해서는 기본적인 네트워크 패킷 헤더에 대한 사전 지식이 요구된다. 패킷의 헤더를 뒤져서 찾아낸 정보가 부합한다면(filtering) 해당 패킷의 정보를 파이썬으로 작성된 http-filter-simple.py에 전달하며, 부합하지 않는다면 패킷을 드랍한다. 위 과정은 커널 영역에서 동작한다.


http-filter-simple.py: python code in user space

Python으로 작성된 파일은 BPF를 로드하고, C 파일로부터 걸러진(filtering) 된 패킷의 정보를 가져온다. 그리고 C 파일과 동일하게 패킷의 헤더 길이를 계산하여 페이로드의 시작점과 길이를 파악한 다음, 페이로드 시작점부터 `/r/n/r/n`이 나올 때까지 정보를 표준 출력으로 나타낸다. 위 과정은 유저 스페이스에서 동작한다.


 위 과정을 도식화 해서 표현해보면 아래와 같은 그림이 나온다. 이는 http-filter-simple 예제에만 국한된 그림이 아니라, IO Visor - BCC 대부분에 해당하는 그림이다. 간략하게 설명하자면, C 언어로 작성된 BPF 프로그램이 LLVM(Low Level Virtual Machine)에서 번역되고, 커널 영역에서 로드 및 실행된다. 그리고 커널 영역에서 처리된 내용은 유저 스페이스에서 후킹(hooking)되어 래핑(wrapping) 함수처럼 작성된 Python 파일에 의해서 처리되는 과정을 나타내고 있다.



 실제 BCC를 활용한 응용 프로그램은 Lua 언어로도 작성할 수 있는데, IO Visor 프로젝트 내부에서도 대부분 Python만 사용하고 있다. 위 그림과 달리 아래는 직접 그린 내용으로 BCC 프로그램이 어떻게 구분되고, 어떤 방식으로 동작하는 지 러프하게 표현해봤다.


 지금까지 http-filter-simple 응용 프로그램의 코드 및 기능에 대해서 알아봤다면, 실제로 어떻게 동작하는 지 영상으로 확인해보자. 우측 터미널 창에 http-filter-simple 응용 프로그램을 실행시키고, 좌측 터미널에서 wget 명령어를 통해 웹 페이지를 요청한다. 정상적으로 요청/응답이 행해질 때마다 단발적으로 우측 터미널 창에 추적되는 것을 볼 수 있다. 또한 실제 웹 브라우저를 활용해서 몇 가지 사이트를 접속할 때마다 수 십개의 HTTP GET/POST에 대한 정보들이 출력되는 것을 확인할 수 있다.



 또 한가지 주목할만한 특징은 응용프로그램 코드에서 Usage 부분을 확인해보면, `-i` 옵션을 통해 내가 추적할 네트워크 인터페이스를 설정할 수 있다. 해당 옵션을 사용하지 않으면 디폴트로는 `eth0`가 잡힌다. 이 다음번 포스팅에서는 동일한 응용 프로그램을 조금 다른 환경에서, `-i` 옵션을 활용하여 다양한 실험을 해보려고한다.






Comments