#keywords Strongswan,charon,libstrongswan,eap,xauth,ipsec,ike,certification,pem,crt,event,starter,secrets,plugins,gmp,dh,vpn,cipher,encrypt,decrypt,ah,esp,ipcomp,natt,500,4500 #title Strongswan 분석 [wiki:Home 대문] / [wiki:CategoryProgramming 프로그래밍] / [wiki:AnalysisStrongswan Strongswan 분석] ---- == [wiki:AnalysisStrongswan Strongswan 분석] == * 작성자 조재혁([mailto:minzkn@minzkn.com]) * 고친과정 2016년 12월 29일 : 처음씀 [[TableOfContents]] === Overview === * Strongswan은 IPsec 기반 VPN Solution으로 주로 Key를 관리하고 Linux Kernel과 Netlink로 교류한다. [[attachment:00-analysis-flow-v1-20161229-strongswan-overview.png]] * strongswan 빌드 예시 (Ubuntu 배포판 환경 기준) * 기본(최소) 의존성 패키지 설치 또는 직접 빌드하여 설치 {{{#!plain $ apt-get install -y \ ca-certificates \ ssl-cert \ openssl \ iproute2 \ iputils-ping \ libgmp10 }}} * strongSwan 빌드 및 설치 (수동 빌드 설치) {{{#!plain $ VERSION="5.9.8" && \ DEV_PACKAGES="wget bzip2 make gcc libssl-dev libgmp-dev" && \ apt-get install -y $DEV_PACKAGES && \ mkdir -p strongswan-build && \ cd strongswan-build && \ wget --no-check-certificate https://download.strongswan.org/strongswan-$VERSION.tar.bz2 && \ tar -xjf strongswan-$VERSION.tar.bz2 && \ cd strongswan-$VERSION && \ ./configure --prefix=/usr --sysconfdir=/etc \ --enable-charon --enable-ikev2 --enable-nonce --enable-random \ --enable-openssl --enable-pem --enable-x509 --enable-pubkey \ --enable-constraints --enable-pki --enable-socket-default \ --enable-kernel-netlink --enable-swanctl --enable-resolve \ --enable-eap-identity --enable-eap-md5 --enable-eap-mschapv2 --enable-eap-dynamic \ --enable-eap-tls --enable-updown --enable-vici \ --enable-silent-rules && \ make -j4 all && make install && \ ln -s /usr/libexec/ipsec/charon charon }}} * 빌드 설치 확인 {{{#!plain $ ipsec version Linux strongSwan U5.9.8/K5.15.0-53-generic University of Applied Sciences Rapperswil, Switzerland => 이후 "/etc/strongswan.d/charon.conf" (기본 값 사용해도 무관), "/etc/ipsec.secrets" (IKE ID에 따른 Pre-shared key 등), "/etc/ipsec.conf" (SA1, SA2설정) 을 적절히 수정 => 다음과 같은 명령으로 debug 실행할 수 있음. $ /usr/sbin/ipsec start --nofork --debug-all => 일반 데몬 실행은 다음과 같이 실행할 수 있음. $ /usr/sbin/ipsec start => 재시작 명령 $ /usr/sbin/ipsec restart => 종료 명령 $ /usr/sbin/ipsec stop }}} === starter === * starter 는 charon daemon을 실행 및 관리(재시작, 종료)해주는 기능 "ipsec.conf" 설정파일을 관리함 * charon 을 실행관리하고 설정파일을 charon에 넘겨주는(stroke protocol) 역할 [[attachment:01-analysis-flow-v1-20161229-strongswan-starter(launcher).png]] === charon === * charon 는 starter에 의해서 실행되며 IKE key를 관리하는 strongswan daemon의 main 에 해당함. * 실제 각 동작부들(libcharon의 plugin)는 기능의 확장(추가)를 위한 addon부분과 Worker thread-pool를 사용한 작업처리부로 구현된 집합의 동작이라고 볼 수 있음. [[attachment:02-analysis-flow-v1-20161229-strongswan-charon(main).png]] === libcharon === * charon에 의해서 구동되며 실제 libcharon/plugins/* 들을 초기화 및 Worker-thread-pool을 통해서 Multiple Core를 효율적으로 구동하도록 고안됨 [[attachment:03-analysis-flow-v1-20161229-strongswan-libcharon.png]] * 내부 Worker thread의 갯수는 DEFAULT_THREADS 값을 통해서 사용함. * 기본값은 16이지만 최적은 CPU 갯수 * 2 로 맞추는게 좋음. * 통상적인 일반상황에서 최적의 Thread 갯수는 CPU갯수 및 Task/Job구현(비동기적 구현의 고려)에 따라 상이할 수 있음. * jobs 배열로 이루어진 linked list는 get_job() 함수에 의해서 각 Thread에 Conditional 접근을 통해서 Assign(할당)되고 Active(execute 활성) 됨. * job handler의 반환값에 따라서 다시 queue되거나 active 또는 1회 호출 후 종료되는등의 제어를 하게 됨. (위 flow 그림 참고) * 이러한 Worker thread(Thread-pool)와 Event (Timer, Multi-select, job, task등) 을 처리하는 방식에 대해서는 하기 링크의 libevent(libev) library 구현부에 대하여 먼저 보시면 도움이 될듯 합니다. (특히 chrome browser, node-js 에서 구현하는 방식) 결국 Multi-core 환경에서 가장 효율적으로 Core를 분배하여 사용하기 위한 하나의 개발에 대한 페러다임 방식이라고 할 수 있습니다. Proxy server등에서도 이러한 구조를 많이 도입합니다. * [^http://www.ibm.com/developerworks/aix/library/au-libev/ Boost network performance with libevent and libev] * [^http://libevent.org/ libevent(an event notification library) project home page] * [^http://www.wangafu.net/~nickm/libevent-book/ Programming with Libevent documentation] * [^http://monkey.org/~provos/libevent/event3.html libevent man page] * [^https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/W5fe5344f8b4f_4651_b0cd_4d270afdc036/page/libevent%20%EB%B0%8F%20libev%EB%A1%9C%20%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%20%EC%84%B1%EB%8A%A5%20%ED%96%A5%EC%83%81 libevent 및 libev로 네트워크 성능 향상] * [^https://github.com/danielconnor/chrome-node/blob/master/np_node/deps/uv/src/unix/ev/event.c Chrome browser 에서 사용하는 event.c] * strongswan에서 그러면 fork에 의한 Process 와 pthread(POSIX Threads)에 의한 Thread 중에서 둘다 사용하는가? * 둘다 사용합니다. 다만 fork&execv에 의한 Process는 starter에서 charon daemon을 띄우기 위한 Launcher(process 감시기능)으로만 사용합니다. * 나머지 실제 모든 동작은 Thread pool (DEFAULT_THREADS 로 정의된 Thread 갯수만큼)을 job/task구조의 handler로 Assign하여 실행하는 구조라고 보시면 됩니다. === chunk 구조 === * libstrongswan 에는 pointer와 length 정보를 가진 binary 를 다루기 위한 구조를 다루기 위해서 chunk 구조를 가질 수 있습니다. * 암/복호화에는 수 많은 binary 들을 효율적으로 가르키고 얼마나 다루어야 하고 copy/merge/modify/wipe 등을 구행하는 작업이 많을 수 밖에 없습니다. 이것을 다루기 위한 함수 또는 매크로를 제공합니다. 이 때 할당된 chunk 인지 구분을 신중하게 확인하여야 메모리 누수를 막을 수 있습니다. === leak detective 방안 (메모리 누수 방지 방안) === * strongswan 은 기본적으로 C언어기반의 객체지향 기법구현을 전반적으로 사용합니다. 때문에 객체생성과 소멸에 메모리 할당/해제를 많이 하게 됩니다. * 할당/해제 (malloc/free/...) 속도는 이러한 strongswan의 성능에 매우 큰 영향을 갖는다는 것도 인지할 필요가 있습니다. 때문에 성능 향상 도모를 위해서 jemalloc 같은 할당자로 대체해볼 수 있습니다. * 자칫 메모리 누수가 일어나기 쉬운 구조라고 볼 수 있는데 이것을 방어하고자 leak detective 방안이 고려되어 있습니다. (libstrongswan의 leak_detective 객체 구현 참고) 이를 잘 활용하면 꽤 대부분의 실수로 인한 누수를 찾을 수 있습니다. 물론 만능은 아니지만 이 구현을 잘 이용하면 메모리 누수를 예방할 수 있는 범위가 증가합니다. === printf_hook 구조 === * 일반적인 문자열 가공에 있어서 sprintf 계열 함수들은 C 언어에서 일반적으로 많이 사용합니다. * 하지만 객체를 문자열화하는데 있어서는 여러가지로 귀찮은 요소들이 있을 수 있는데 strongswan 은 hook 을 통한 구현으로 확장된 치환자들을 제공합니다. === stroke 통신 구조 === * strongswan은 크게 주요한것 구분으로 본다면 libstrongswan, libcharon, plugins, charon daemon, swanctl, starter, stroke command 등으로 나눌 수 있습니다. * stroke 통신제어부는 사용자가 별도의 통신으로 구현하여 교체할 수 있는 구조입니다. 전반적으로 libcharon을 어떻게 제어하는지 예제로써도 참고할 주요 분석 대상입니다. * 실제 핵심은 libcharon 과 libcharon-plugins 로 볼 수 있으며 기초부분은 libstrongswan 및 libstrongswan-plugins 들이 이를 받쳐줍니다. * charon daemon은 libcharon을 관장하는 main 함수라고 할 수 있습니다. * starter daemon은 charon daemon을 감시하고 실행해주는 launcher 역할과 설정파일을 읽어서 libcharon 의 stroke plugin 으로 이러한 설정 및 제어요소를 stroke protocol 로 전달하는 역할을 합니다. * stroke protocol은 매우 단순한 구조로써 요청과 응답을 구조를 가지고 있습니다. * 원한다면 starter를 내가 원하는 완전히 다른 설정 및 제어구조를 갖는 프로그램으로 교체하고 stroke 통신만 맞춰주면 새로운 설정 구조 및 제어구조를 가질 수도 있는 가능성을 제공합니다. * swanctl, stroke 명령어 구현을 참고할 수 있습니다. === task 구조 === * task 자료구조는 일종의 작업단위 문맥으로 나뉘어진 구현들의 job 들의 집합입니다. * libcharon 내의 task구현은 대부분 build_i, process_i, build_r, process_r method 를 구현하게 됩니다. 이는 다음과 같은 흐름에서의 구현집합을 의미합니다. 주로 message_t 자료구조를 통하여 패킷을 송/수신처리합니다. {{{#!plain Initiator(행위의 시작) Responder(행위를 받는 입장) TASK->build_i =====================message===================> TASK->process_r TASK->build_r <====================message==================== TASK->process_i }}} * build_i : 요청할 작업을 준비하고 패킷을 만드는 과정들을 구현 * process_r : 요청받은 패킷을 해석하고 이에 따르는 작업들을 준비하며 build_r 을 호출될 수 있는 Trigger 작업들 구현 * build_r : 요청에 응답을 준비하고 응답패킷을 만드는 과정들을 구현 * process_i : 응답받은 패킷을 해석하고 이에 따르는 작업들을 준비하고 완료 작업 또는 다음 단계를 Trigger 하는 작업들 구현 === 참고자료 === * [wiki:VirtualPrivateNetwork VPN(Virtual Private Network, 가상사설망)] * [wiki:GenerateCertificate 인증서 만들기] * [^https://wiki.strongswan.org/projects/strongswan/wiki/PublicKeySpeed strongSwan에서 지원하는 crypto] * [^https://gmplib.org/ GMP - The GNU Multiple Precision Arithmetic Library] * [^http://zlib.net/ ZLIB - A Massively Spiffy Yet Delicately Unobtrusive Compression Library] * [^https://www.openssl.org/ OpenSSL - Cryptography and SSL/TLS Toolkit] * [^http://www.openldap.org/ OpenLDAP Software] * [^https://curl.haxx.se/ CURL library - command line tool and library for transferring data with URLs] * [^https://openvpn.net/ OpenVPN] * [^https://www.openswan.org/ Openswan(IPsec implementation for Linux)] * [^https://www.strongswan.org/ strongSwan(OpenSource IPsec implementation.)] * [^https://www.strongswan.org/apidoc/ strongSwan Source Code Documentation (doxygen)] * [^http://wiki.strongswan.org/projects/strongswan/wiki/KernelModules Required Kernel Modules - strongSwan] * [^https://www.strongswan.org/docs/install2.htm strongSwan 2.8 - Installation] * [^https://www.strongswan.org/docs/install42.htm strongSwan 4.2 - Installation] * [^https://wiki.strongswan.org/projects/strongswan/wiki/Autoconf Autoconf options for the most current strongSwan release] * [^https://en.wikipedia.org/wiki/StrongSwan] * [^https://raymii.org/s/tutorials/IPSEC_vpn_with_Ubuntu_16.04.html IPSEC VPN on Ubuntu 16.04 with StrongSwan] * [^http://www.cakesolutions.net/teamblogs/connecting-aws-virtual-private-clouds-using-vpn-strongswan Connecting AWS Virtual Private Clouds using VPN 'Strongswan'] * [^https://www.purplesrl.com/en/connect-two-docker-hosts-using-ipsec/ Connect Containers From Two Docker Hosts Using IPsec]