1) Hyperscan 필요성 및 소개
오픈소스 기반 IDS/IPS를 학습이나 테스트 용도가 아닌 실무에서 활용하는데는 여러가지 어려움이 존재하는데 그 중 하나가 높은 CPU 비용을 필요로 하는 패턴매칭 작업으로 인한 성능저하 이슈(그로 인한 트래픽 누수, 탐지누락, 하드웨어 투자비용 증가)입니다. 이런 이유로 IDS/IPS에서 패턴매치 알고리즘은 매우 중요한 부분을 차지하는데 Hyperscan을 활용하면 추가적인 하드웨어 증설 없이 소프트웨어 적으로 성능 개선에 도움을 줄 수 있습니다.
Hyperscan은 Intel에서 개발한 오픈소스(BSD) 패턴매치 라이브러리로 글 작성 시점에 오픈소스 IDS/IPS(Snort, Suricata)에서 사용(Intel CPU 기준, 소프트웨어 방식)가능한 가장 뛰어난 성능을 보여주는 패턴매칭 알고리즘입니다.
아래는 Intel 홈페이지에 공개된 Hyperscan 소개와 Snort 및 Suricata에 Hyperscan 적용 전후 성능 테스트 결과 및 참고할 만한 내용을 포함한 링크입니다.
Hyperscan 소개
https://www.intel.co.kr/content/www/kr/ko/communications/hyperscan.html
Suricata + Hyperscan
Snort + Hyperscan
https://software.intel.com/en-us/articles/hyperscan-and-snort-integration
2) 설치하기
(1) 의존성 패키지 사전 설치
# yum install cmake gcc-c++ python-devel
(2) ragel 설치 (http://www.colm.net/open-source/ragel/)
wget http://www.colm.net/files/ragel/ragel-6.10.tar.gz
tar zxf ragel-6.10.tar.gz
cd ragel-6.10/
./configure
make
make install
cd ..
(3) Boost 설치 (https://dl.bintray.com/boostorg/release/1.68.0/source/)
wget https://dl.bintray.com/boostorg/release/1.68.0/source/boost_1_68_0.tar.gz
tar zxf boost_1_68_0.tar.gz
cd boost_1_68_0
./bootstrap.sh
./b2
cd ..
(4) Hyperscan 설치 (https://01.org/group/3655/downloads)
wget https://github.com/01org/hyperscan/archive/v4.5.0.tar.gz
tar zxf v4.5.0.tar.gz
cd hyperscan-4.5.0/
mkdir build
cd build
cmake -DBUILD_STATIC_AND_SHARED=1 -DBOOST_ROOT=/home/user1/src/boost_1_68_0/ ../
This is due to overloaded distance function between standard C++ library and boost.
We'll have a fix patch in next release. To quickly fix this issue, please change distance to std::distance for below 2 lines.
983 return verify_u32(distance(squash.begin(), it));
1010 u32 offset = verify_u32(distance(begin(reports), it));
make
make install
vi /etc/ld.so.conf.d/hs.conf
/usr/local/lib64/
ldconfig
3) 이슈해결
(1) hyperscan 'make' 작업시 아래 내용으로 에러가 발생하는 경우
- 에러내용
[ 26%] Building CXX object CMakeFiles/hs.dir/src/nfa/mcsheng_compile.cpp.o
[ 26%] Building CXX object CMakeFiles/hs.dir/src/nfa/limex_compile.cpp.o
/home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.cpp: In function ‘u32 ue2::{anonymous}::addSquashMask(const ue2::{anonymous}::build_info&, const NFAVertex&, std::vector<boost::dynamic_bitset<> >&)’:
/home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.cpp:979:54: error: call of overloaded ‘distance(std::vector<boost::dynamic_bitset<> >::iterator, __gnu_cxx::__normal_iterator<boost::dynamic_bitset<>*, std::vector<boost::dynamic_bitset<> > >&)’ is ambiguous
return verify_u32(distance(squash.begin(), it));
^
/home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.cpp:979:54: note: candidates are:
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:66:0,
from /usr/include/c++/4.8.2/bits/stl_tree.h:61,
from /usr/include/c++/4.8.2/map:60,
from /home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.h:37,
from /home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.cpp:34:
/usr/include/c++/4.8.2/bits/stl_iterator_base_funcs.h:114:5: note: typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<boost::dynamic_bitset<>*, std::vector<boost::dynamic_bitset<> > >; typename std::iterator_traits<_Iterator>::difference_type = long int]
distance(_InputIterator __first, _InputIterator __last)
^
In file included from /home/user1/src/boost_1_68_0/boost/range/distance.hpp:18:0,
from /home/user1/src/boost_1_68_0/boost/range/functions.hpp:21,
from /home/user1/src/boost_1_68_0/boost/range/iterator_range_core.hpp:38,
from /home/user1/src/boost_1_68_0/boost/range/iterator_range.hpp:13,
from /home/user1/src/hyperscan-4.5.0/src/util/graph_range.h:54,
from /home/user1/src/hyperscan-4.5.0/src/util/ue2_graph.h:33,
from /home/user1/src/hyperscan-4.5.0/src/nfagraph/ng_holder.h:44,
from /home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.h:41,
from /home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.cpp:34:
/home/user1/src/boost_1_68_0/boost/iterator/distance.hpp:49:9: note: typename boost::iterators::iterator_difference<Iterator>::type boost::iterators::distance_adl_barrier::distance(SinglePassIterator, SinglePassIterator) [with SinglePassIterator = __gnu_cxx::__normal_iterator<boost::dynamic_bitset<>*, std::vector<boost::dynamic_bitset<> > >; typename boost::iterators::iterator_difference<Iterator>::type = long int]
distance(SinglePassIterator first, SinglePassIterator last)
^
make[2]: *** [CMakeFiles/hs.dir/src/nfa/limex_compile.cpp.o] Error 1
make[1]: *** [CMakeFiles/hs.dir/all] Error 2
make: *** [all] Error 2
- 해결방법
Standard C++ 라이브러리와 boost간의 distance 함수 오버로드 이슈로 인한 에러이며
임시적으로 아래와 같은 방법으로 해결 가능합니다.
- limex_compile.cpp 파일 열기
vi /home/user1/src/hyperscan-4.5.0/src/nfa/limex_compile.cpp
- 아래 2개 라인에서 distance를 std::distance로 변경합니다.
983 줄
return verify_u32(distance(squash.begin(), it));
983 return verify_u32(std::distance(squash.begin(), it));
1010 줄
u32 offset = verify_u32(distance(begin(reports), it));
u32 offset = verify_u32(std::distance(begin(reports), it));
※ 이 글은 CentOS7기준으로 작성하였습니다.
'IT보안 > Suricata' 카테고리의 다른 글
수리카타 사용자 가이드 (Suricata User Guide 번역) (0) | 2019.08.29 |
---|
댓글