Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
root committed Sep 5, 2016
0 parents commit d491497
Show file tree
Hide file tree
Showing 39 changed files with 5,784 additions and 0 deletions.
674 changes: 674 additions & 0 deletions COPYING

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src include
EXTRA_DIST = COPYING etc
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
extFilter
===========
Программа для блокирования сайтов из списка РКН с использованием DPDK и nDPI.

Функционал
----------
Программа осуществляет блокировку сайтов путем анализа зеркалированного трафика от пользователей.
В случае нахождения вызываемого абонентом HTTP ресурса в списке блокировки, пользователю отсылается редирект на специальную страницу или сбрасывается соединение.
Блокировка HTTPS ресурсов осуществляется на основе имени сервера в client hello запросе от пользователя или ip адреса сервера, если имени сервера нет в client hello запросе.
В случае нахождения вызываемого абонентом HTTPS ресурса в списке блокировки, соединение с данными ресурсом будет сброшено.

Требования
----------
Для сборки программы необходимы следующие библиотеки и программы:

Poco >= 1.6
nDPI = git dev (устанавливается автоматически)
PcapPlusPlus = git master (устанавливается автоматически)
DPDK = 16.07
git

Сборка
------
- [Установить DPDK](http://dpdk.org/doc/quick-start)
- Сгенерировать configure
```bash
./autogen.sh
```
- Запустить configure
```bash
./configure --with-dpdk_target=<target> --with-dpdk_home=<path_to_compiled_dpdk>
```bash
- Скомпилировать программу
```bash
make
```

Настройка DPDK
--------------
Для работы DPDK необходимо настроить huge-pages и подключить необходимые сетевые адаптеры в DPDK.

Запуск
------
Параметры работы программы задаются в конфигурационном файле.
Для запуска программы необходимо указать путь к конфигурационному .ini файлу (--config-file в командой строке). Для запуска в режиме daemon необходимо указать ключи --daemon и --pidfile=/path/to/file.pid

Файлы списков блокировки
------------------------
Файлы с данными для блокировки (домены, url и т.д.) должны быть в формате [nfqfilter](https://github.com/max197616/nfqfilter).

6 changes: 6 additions & 0 deletions autogen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

rm -f configure

autoreconf -ivf

245 changes: 245 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.69])
AC_INIT(extFilter, 0.1, [email protected])

PPP_HOME=./PcapPlusPlus
DPDK_HOME=
DPDK_TARGET=

NDPI_HOME=./nDPI
NDPI_GIT_VERSION=dev

AM_INIT_AUTOMAKE()

m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES(no)])

AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADERS([include/config.h])

AC_LANG([C++])
AC_LANG_PUSH([C++])

# store current user given compiler flags to avoid default setup via AC_PROG_CXX
OLD_CXXFLAGS=$CXXFLAGS
OLD_CFLAGS=$CFLAGS

# Checks for programs.
AC_PROG_CXX
AC_PROG_CC

CXXFLAGS=$OLD_CXXFLAGS
CFLAGS=$OLD_CFLAGS

CFLAGS="$CFLAGS --pedantic -Wall -O2"

AC_ARG_ENABLE(debug,
AS_HELP_STRING(
[--enable-debug],
[enable debugging, default: no]),
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
esac],
[debug=false])

AC_MSG_CHECKING([for debug enabled])


if test x"$debug" = x"true"; then
CXXFLAGS="$CXXFLAGS -std=c++0x -O0 -g -Wall -pthread"
else
CXXFLAGS="$CXXFLAGS -std=c++0x -O2 -pthread"
fi

AC_COMPILE_IFELSE([AC_LANG_SOURCE(
[[template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
typedef check<check<bool>> right_angle_brackets;
int a;
decltype(a) b;
typedef check<int> check_type;
check_type c;
check_type&& cr = static_cast<check_type&&>(c);]])],,
AC_MSG_FAILURE(['$CXX $CXXFLAGS' does not accept ISO C++11]))




# Checks for libraries.

# Checks for header files.
AC_CHECK_HEADERS([netinet/in.h stdint.h])

# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL

# Checks for library functions.
AC_FUNC_ERROR_AT_LINE
AC_CHECK_FUNCS([strerror])

# Check for methods in library and check for header files
AC_CHECK_HEADERS([Poco/Foundation.h Poco/Net/HTTPCookie.h Poco/Util/Timer.h],
[],
AC_MSG_ERROR([Poco include files not found.])
)

AC_CHECK_LIB([PocoFoundation],[main],[HAVE_POCOFOUNDATION=1],AC_MSG_ERROR([PocoFoundation library not found.]))
if test "$HAVE_POCOFOUNDATION"; then
save_libs="${LIBS}"
LIBS="-lPocoFoundation"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include "Poco/UnicodeConverter.h"],
[std::wstring wstr; Poco::UnicodeConverter::toUTF16("hello", wstr);]
)],
[LIBS="$LIBS $save_libs"],
[AC_MSG_ERROR([linking with PocoFoundation failed.])]
)
fi

AC_CHECK_LIB([PocoUtil],[main],[HAVE_POCOUTIL=1],AC_MSG_ERROR([PocoUtil library not found.]))
if test "$HAVE_POCOUTIL"; then
save_libs="${LIBS}"
LIBS="-lPocoUtil"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include "Poco/Util/Option.h"],
[Poco::Util::Option();]
)],
[LIBS="$LIBS $save_libs"],
[AC_MSG_ERROR([linking with PocoUtil failed.])]
)
fi

AC_CHECK_LIB([PocoNet],[main],[HAVE_POCONET=1],AC_MSG_ERROR([PocoNet library not found.]))
if test "$HAVE_POCONET"; then
save_libs="${LIBS}"
LIBS="-lPocoNet"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include "Poco/Net/HTTPClientSession.h"],
[Poco::Net::HTTPClientSession();]
)],
[LIBS="$LIBS $save_libs"],
[AC_MSG_ERROR([linking with PocoNET failed.])]
)
fi

AC_ARG_WITH(
[ppp_home],
AS_HELP_STRING(
[--with-ppp_home=DIR],
[Path to PcapPlusPlus library]
),
[PPP_HOME="$withval"]
)

dnl PcapPlusPlus checks...
AC_MSG_CHECKING(for PcapPlusPlus $PPP_HOME)
if test -d "$PPP_HOME" ; then :
AC_MSG_RESULT(found in $PPP_HOME)
else
AC_MSG_RESULT(not found)
AC_MSG_NOTICE(Getting PPP from git)
git clone -b master https://github.com/max197616/PcapPlusPlus.git $PPP_HOME; cd $PPP_HOME; cd -
# git clone -b master https://github.com/seladb/PcapPlusPlus.git $PPP_HOME; cd $PPP_HOME; cd -
AC_MSG_CHECKING(for PPP $PPP_HOME)
if test -d "$PPP_HOME" ; then :
AC_MSG_RESULT(found in $PPP_HOME)
else
AC_MSG_ERROR(Install PcapPlusPlus manually!)
fi
fi

PPP_LIB=$PPP_HOME/Dist/libCommon++.a
AC_MSG_CHECKING(for $PPP_LIB)
if test -f "$PPP_LIB" ; then :
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT([not found, compiling...])
cd $PPP_HOME; ./configure-linux.sh --dpdk --dpdk-home $DPDK_HOME --dpdk-target $DPDK_TARGET; make; cd -
fi

AC_ARG_WITH(
[dpdk_home],
AS_HELP_STRING(
[--with-dpdk_home=DIR],
[Path to DPDK library]
),
[DPDK_HOME="$withval"]
)

AC_ARG_WITH(
[dpdk_target],
AS_HELP_STRING(
[--with-dpdk_target=target],
[DPDK target]
),
[DPDK_TARGET="$withval"]
)

if test -z "$DPDK_TARGET"; then
AC_MSG_ERROR([dpdk_target must be set])
fi

if test -z "$DPDK_HOME"; then
AC_MSG_ERROR([dpdk_home must be set])
fi

AC_SUBST(DPDK_LIB,$DPDK_HOME/$DPDK_TARGET/lib)
AC_SUBST(PPP_LIB,$PPP_HOME/Dist)
AC_SUBST(PPP_HEADER,$PPP_LIB/header)

dnl nDPI checks...
AC_MSG_CHECKING(for nDPI $NDPI_HOME)
if test -d "$NDPI_HOME" ; then :
AC_MSG_RESULT(found in $NDPI_HOME)
else
AC_MSG_RESULT(not found)
AC_MSG_NOTICE(Getting nDPI from git)
git clone -b $NDPI_GIT_VERSION https://github.com/ntop/nDPI.git $NDPI_HOME; cd $NDPI_HOME; cd -
AC_MSG_CHECKING(for nDPI $NDPI_HOME)
if test -d "$NDPI_HOME" ; then :
AC_MSG_RESULT(found in $NDPI_HOME)
else
AC_MSG_ERROR(Install nDPI 1.7-stable: git clone -b $NDPI_GIT_VERSION https://github.com/ntop/nDPI.git $NDPI_HOME; cd $NDPI_HOME; patch -p1 < ../nDPI-1.7-bugfixes.patch ; ./autogen.sh; make; cd - )
fi
fi

NDPI_LIB=$NDPI_HOME/src/lib/.libs/libndpi.a
AC_MSG_CHECKING(for $NDPI_LIB)
if test -f "$NDPI_LIB" ; then :

else
AC_MSG_RESULT([not found, compiling...])
cd $NDPI_HOME; ./autogen.sh; make; cd -
fi
AC_MSG_RESULT(yes)

save_flags="${CXXFLAGS}"
CXXFLAGS="${CXXFLAGS} -I${NDPI_HOME}/src/include"
AC_MSG_CHECKING(for compiling with nDPI)
save_libs="${LIBS}"
LIBS="$NDPI_LIB"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[#include "ndpi_api.h"],
[ndpi_revision();]
)],
[LIBS="$save_libs"],
[AC_MSG_ERROR([Linking with nDPI failed!])]
)
AC_MSG_RESULT(yes)
CXXFLAGS="$save_flags"


AC_OUTPUT(Makefile src/Makefile include/Makefile)
60 changes: 60 additions & 0 deletions etc/extfilter.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
; Переводить имя хоста в прописные буквы.
lower_host = true

domainlist = /usr/local/etc/extfilter/domains
urllist = /usr/local/etc/extfilter/urls
ssllist = /usr/local/etc/extfilter/ssl_host

; Файл с портами для nDPI.
protocols = /usr/local/etc/extfilter/protos

; Список ip адресов/сетей для блокировки ssl если нет server_name в ssl hello пакете. Загружается если block_undetected_ssl = true.
sslips = /usr/local/etc/extfilter/ssl_ips

; если false, то будет послан rst пакет вместо редиректа. Default: false
http_redirect = true

redirect_url = http://notify.tushino.com/?reason=5&

; HTTP код ответа. default: 302 Moved Temporarily
http_code = 302 Found

; Что добавлять в redirect_url, line - строка из файла url, url - запрещенный url, none - ничего
url_additional_info=line


; посылать tcp rst в сторону сервера от имени клиента. Default: false
rst_to_server = false

; Default: 0 - disable
statistic_interval = 300

; Default: false
match_url_exactly = false

; Default: false
block_undetected_ssl = false

; dpdk порт(ы), где анализировать трафик
dpdk_ports = 0

; количество входящих очередей
rx_queues = 1

; размер пула mbuf. Default: 4095
;mbuf_pool_size = 4095

; Какие ядра использовать. Default: все ядра, кроме management.
; core_mask = 7

[logging]
loggers.root.level = information
;loggers.root.level = debug
loggers.root.channel = fileChannel
channels.fileChannel.class = FileChannel
channels.fileChannel.path = /var/log/extFilter.log
channels.fileChannel.rotation = 1 M
channels.fileChannel.archive = timestamp
channels.fileChannel.formatter.class = PatternFormatter
channels.fileChannel.formatter.pattern = %Y-%m-%d %H:%M:%S.%i [%P] %p %s - %t
channels.fileChannel.formatter.times = local
12 changes: 12 additions & 0 deletions etc/systemd/extfilter.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=extFilter is a daemon for filtering traffic using DPDK
Requires=network.target
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/extFilter --daemon --pidfile=/var/run/extFilter.pid --config-file /usr/local/etc/extfilter.ini
PIDFile=/var/run/extFilter.pid

[Install]
WantedBy=multi-user.target
6 changes: 6 additions & 0 deletions etc/systemd/install_service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

cp extfilter.service /etc/systemd/system/
systemctl daemon-reload
#systemctl enable extfilter
#systemctl start extfilter
Loading

0 comments on commit d491497

Please sign in to comment.