diff --git a/binaries/freebsd-x64/tpws b/binaries/freebsd-x64/tpws index edcb31f..9889d76 100755 Binary files a/binaries/freebsd-x64/tpws and b/binaries/freebsd-x64/tpws differ diff --git a/binaries/freebsd-x64/tpws_pf b/binaries/freebsd-x64/tpws_pf deleted file mode 100755 index e8ead81..0000000 Binary files a/binaries/freebsd-x64/tpws_pf and /dev/null differ diff --git a/binaries/mac64/tpws b/binaries/mac64/tpws index 0b475b8..489ec53 100755 Binary files a/binaries/mac64/tpws and b/binaries/mac64/tpws differ diff --git a/docs/bsd.eng.md b/docs/bsd.eng.md index 44053fb..66a157e 100644 --- a/docs/bsd.eng.md +++ b/docs/bsd.eng.md @@ -16,11 +16,6 @@ To compile sources in FreeBSD use `make`, in OpenBSD - use `make bsd`, in MacOS Compile all programs : `make -C /opt/zapret` -Compile all programs with PF support : `make -C /opt/zapret CFLAGS=-DUSE_PF` - -In FreeBSD enable PF only if you use it. Its undesirable if you don't. -PF is enabled automatically in OpenBSD and MacOS. - Divert sockets are internal type sockets in the BSD kernel. They have no relation to network addresses or network packet exchange. They are identified by a port number `1..65535`. Its like queue number in NFQUEUE. Traffic can be diverted to a divert socket using firewall rule. @@ -147,7 +142,7 @@ ipv4 frames are filtered using 'sockarg'. PF in FreeBSD: The setup is similar to OpenBSD, but there are important nuances. -1) Don't forget to build special PF-enabled version of tpws : make CFLAGS=-DUSE_PF +1) Don't forget to use special tpws parameter `--enable-pf` 2) It's not possible to redirect to ::1. Need to redirect to the link-local address of the incoming interface. Look for fe80:... address in ifconfig and use it for redirection target. 3) pf.conf syntax is a bit different from OpenBSD. @@ -228,11 +223,10 @@ rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 por Autostart '/usr/local/etc/rc.d/zapret.sh' : ``` pfctl -a zapret -f /etc/zapret.anchor -pkill ^tpws_pf$ -tpws_pf --daemon --port=988 --split-http-req=method --split-pos=2 +pkill ^tpws$ +tpws --daemon --port=988 --split-http-req=method --split-pos=2 ``` -Note that the special tpws version is used which supports PF. After reboot check that anchor is created and referred from the main ruleset : ``` [root@pfSense /]# pfctl -s nat diff --git a/docs/bsd.txt b/docs/bsd.txt index 94537f3..522f0f6 100644 --- a/docs/bsd.txt +++ b/docs/bsd.txt @@ -21,9 +21,7 @@ FreeBSD содержит 3 фаервола : IPFilter, ipfw и Packet Filter (P Под FreeBSD tpws и dvtws собираются через "make", под OpenBSD - "make bsd", под MacOS - "make mac". FreeBSD make распознает BSDmakefile , OpenBSD и MacOS - нет. Поэтому там используется отдельный target в Makefile. Сборка всех исходников : make -C /opt/zapret -Сборка всех исходников с поддержкой PF : make -C /opt/zapret CFLAGS=-DUSE_PF -В FreeBSD поддержку PF нужно включать только, если вы его используете. Иначе это нежелательно ! -В OpenBSD и MacOS PF при сборке включается автоматически. +В FreeBSD поддержка PF в tpws отключена по умолчанию. Чтобы ее включить, нужно использовать параметр --enable-pf. divert сокет - внутренний тип сокета ядра BSD. Он не привязывается ни к какому сетевому адресу, не участвует в обмене данными через сеть и идентифицируется по номеру порта 1..65535. Аналогия с номером очереди NFQUEUE. @@ -146,7 +144,7 @@ dvtws в FreeBSD отсылает ipv4 фреймы через raw socket. Та PF в FreeBSD: Настройка аналогична OpenBSD, но есть важные нюансы. -1) Не забыть собрать специальную версию под PF : make CFLAGS=-DUSE_PF +1) Не забыть указать параметр --enable-pf 2) Нельзя сделать ipv6 rdr на ::1. Нужно делать на link-local адрес входящего интерфейса. Смотрите через ifconfig адрес fe80:... и добавляете в правило 3) Синтаксис pf.conf немного отличается. Более новая версия PF. @@ -227,11 +225,10 @@ rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 por Добавьте в автозапуск /usr/local/etc/rc.d/zapret.sh : ----------- pfctl -a zapret -f /etc/zapret.anchor -pkill ^tpws_pf$ -tpws_pf --daemon --port=988 --split-http-req=method --split-pos=2 +pkill ^tpws$ +tpws --daemon --port=988 --enable-pf --split-http-req=method --split-pos=2 ----------- -Обратите внимание, что запускается специальная версия tpws с поддежкой pf. Обычный tpws не работает с PF. После перезагрузки проверьте, что правила создались : ----------- [root@pfSense /]# pfctl -s nat diff --git a/tpws/BSDmakefile b/tpws/BSDmakefile index 373fc4f..cc108cb 100644 --- a/tpws/BSDmakefile +++ b/tpws/BSDmakefile @@ -7,7 +7,6 @@ all: tpws tpws: $(SRC_FILES) $(CC) $(CFLAGS) -Iepoll-shim/include -o $@ $(SRC_FILES) epoll-shim/src/*.c $(LDFLAGS) $(LIBS) - $(CC) $(CFLAGS) -Iepoll-shim/include -o $@_pf $(SRC_FILES) -DUSE_PF epoll-shim/src/*.c $(LDFLAGS) $(LIBS) clean: - rm -f tpws tpws_pf *.o + rm -f tpws *.o diff --git a/tpws/params.h b/tpws/params.h index 546feea..a5122f3 100644 --- a/tpws/params.h +++ b/tpws/params.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "strpool.h" enum splithttpreq { split_none = 0, split_method, split_host }; @@ -46,6 +47,10 @@ struct params_s strpool *hostlist; int debug; + +#if defined(BSD) + bool pf_enable; +#endif }; extern struct params_s params; diff --git a/tpws/redirect.c b/tpws/redirect.c index ee7fc44..aff9ccc 100644 --- a/tpws/redirect.c +++ b/tpws/redirect.c @@ -10,25 +10,19 @@ #include "params.h" #include "helpers.h" -//#if !defined(USE_PF) && defined(__OpenBSD__) -#if !defined(USE_PF) && (defined(__OpenBSD__) || defined(__APPLE__)) - #define USE_PF 1 -#endif - #ifdef __linux__ #include #ifndef IP6T_SO_ORIGINAL_DST #define IP6T_SO_ORIGINAL_DST 80 #endif #endif -#ifdef USE_PF - #include - #include -#endif +#if defined(BSD) + +#include +#include -#if defined(USE_PF) static int redirector_fd=-1; void redir_close() @@ -54,7 +48,7 @@ static bool redir_open_private(const char *fname, int flags) } bool redir_init() { - return redir_open_private("/dev/pf", O_RDONLY); + return params.pf_enable ? redir_open_private("/dev/pf", O_RDONLY) : true; } static bool destination_from_pf(const struct sockaddr *accept_sa, struct sockaddr_storage *orig_dst) @@ -209,8 +203,8 @@ bool get_dest_addr(int sockfd, const struct sockaddr *accept_sa, struct sockaddr } if (orig_dst->ss_family==AF_INET6) ((struct sockaddr_in6*)orig_dst)->sin6_scope_id=0; // or MacOS will not connect() -#ifdef USE_PF - if (!destination_from_pf(accept_sa, orig_dst)) +#ifdef BSD + if (params.pf_enable && !destination_from_pf(accept_sa, orig_dst)) DBGPRINT("pf filter destination_from_pf failed"); #endif #ifdef __linux__ diff --git a/tpws/tpws.c b/tpws/tpws.c index 06cbade..f4872b3 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -139,6 +139,9 @@ static void exithelp() " --pidfile=\t\t; write pid to file\n" " --user=\t\t; drop root privs\n" " --uid=uid[:gid]\t\t; drop root privs\n" +#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__) + " --enable-pf\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n" +#endif " --debug=0|1|2\t\t\t; 0(default)=silent 1=verbose 2=debug\n" "\nTAMPERING:\n" " --hostlist=\t\t; only act on host in the list (one host per line, subdomains auto apply)\n" @@ -205,6 +208,9 @@ void parse_params(int argc, char *argv[]) params.maxconn = DEFAULT_MAX_CONN; params.max_orphan_time = DEFAULT_MAX_ORPHAN_TIME; params.binds_last = -1; +#if defined(__OpenBSD__) || defined(__APPLE__) + params.pf_enable = true; // OpenBSD and MacOS have no other choice +#endif if (can_drop_root()) { params.uid = params.gid = 0x7FFFFFFF; // default uid:gid @@ -252,6 +258,9 @@ void parse_params(int argc, char *argv[]) { "socks",no_argument,0,0 },// optidx=37 { "no-resolve",no_argument,0,0 },// optidx=38 { "skip-nodelay",no_argument,0,0 },// optidx=39 +#if defined(BSD) && !defined(__OpenBSD__) && !defined(__APPLE__) + { "enable-pf",no_argument,0,0 },// optidx=40 +#endif { NULL,0,NULL,0 } }; while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) @@ -485,6 +494,11 @@ void parse_params(int argc, char *argv[]) case 39: /* skip-nodelay */ params.skip_nodelay = true; break; +#if defined(BSD) && !defined(__OpenBSD__) + case 40: /* enable-pf */ + params.pf_enable = true; + break; +#endif } } if (!params.bind_wait_only && !params.port)