diff --git a/binaries/aarch64/tpws b/binaries/aarch64/tpws index 1acea76..fb13713 100755 Binary files a/binaries/aarch64/tpws and b/binaries/aarch64/tpws differ diff --git a/binaries/armhf/tpws b/binaries/armhf/tpws index 8c29627..50cdba8 100755 Binary files a/binaries/armhf/tpws and b/binaries/armhf/tpws differ diff --git a/binaries/mips32r1-lsb/tpws b/binaries/mips32r1-lsb/tpws index b2d7d85..9f855ad 100755 Binary files a/binaries/mips32r1-lsb/tpws and b/binaries/mips32r1-lsb/tpws differ diff --git a/binaries/mips32r1-msb/tpws b/binaries/mips32r1-msb/tpws index 7c60745..1cbef9c 100755 Binary files a/binaries/mips32r1-msb/tpws and b/binaries/mips32r1-msb/tpws differ diff --git a/binaries/mips64r2-msb/tpws b/binaries/mips64r2-msb/tpws index c755c80..46be48c 100755 Binary files a/binaries/mips64r2-msb/tpws and b/binaries/mips64r2-msb/tpws differ diff --git a/binaries/ppc/tpws b/binaries/ppc/tpws index 27976d9..324eae4 100755 Binary files a/binaries/ppc/tpws and b/binaries/ppc/tpws differ diff --git a/binaries/x86/tpws b/binaries/x86/tpws index 7259428..80f5499 100755 Binary files a/binaries/x86/tpws and b/binaries/x86/tpws differ diff --git a/binaries/x86_64/tpws b/binaries/x86_64/tpws index 414c673..da15171 100755 Binary files a/binaries/x86_64/tpws and b/binaries/x86_64/tpws differ diff --git a/docs/readme.txt b/docs/readme.txt index 772fee2..9b222ae 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -141,6 +141,9 @@ tpws - это transparent proxy. ; если force и link local не найден - выход по ошибке. --bind-iface4= ; слушать на первом ipv4 интерфейса iface --bind-iface6= ; слушать на первом ipv6 интерфейса iface. при bind-linklocal определяет интерфейс, откуда брать ipv6 link local + --bind-wait-ifup= ; ждать до N секунд появления и поднятия интерфейса + --bind-wait-ip= ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса) + --bind-wait-ip-linklocal ; (только если заданы --bind-wait-ip и --bind-linklocal=prefer) согласиться на global address после N секунд --port= ; на каком порту слушать --split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host --split-pos= ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb. @@ -157,10 +160,16 @@ tpws - это transparent proxy. ; для списка РКН может потребоваться система с 128 Mb памяти ! расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка. ; по сигналу HUP список будет перечитан при следующем принятом соединении ; список может быть запакован в gzip. формат автоматически распознается и разжимается + Параметры манипуляции могут сочетаться в любых комбинациях. Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи. + tpws может биндаться только к одному ip или ко всем сразу. Для бинда на все ipv4 укажите "0.0.0.0", на все ipv6 - "::". Без параметров биндаемся на все ipv4 и ipv6. +Параметры --bind-wait* могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят +или не сконфигурирован. +В разных системах события ifup ловятся по-разному и не гарантируют, что интерфейс уже получил IP адрес определенного типа. +В общем случае не существует единого механизма повеситься на событие типа "на интерфейсе X появился link local address". Способы получения списка заблокированных IP ------------------------------------------- diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset b/init.d/openwrt/firewall.zapret.nfqws_ipset index 81acb4b..f506771 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_ipset +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset @@ -3,4 +3,5 @@ IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_nfqws diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset6 b/init.d/openwrt/firewall.zapret.nfqws_ipset6 index 620193e..492107f 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_ipset6 +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset6 @@ -3,4 +3,5 @@ IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret6 dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_nfqws6 diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset_https b/init.d/openwrt/firewall.zapret.nfqws_ipset_https index 4a7e911..0828ccf 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_ipset_https +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset_https @@ -3,4 +3,5 @@ IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_nfqws diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 b/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 index c9fd160..ac4e9ae 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 @@ -3,4 +3,5 @@ IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret6 dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_nfqws6 diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset b/init.d/openwrt/firewall.zapret.tpws_ipset index 17703e4..9ee1a8a 100644 --- a/init.d/openwrt/firewall.zapret.tpws_ipset +++ b/init.d/openwrt/firewall.zapret.tpws_ipset @@ -2,4 +2,5 @@ IPT_FILTER_HTTP="-p tcp --dport 80 -m set --match-set zapret dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_tpws diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset6 b/init.d/openwrt/firewall.zapret.tpws_ipset6 index 73717bf..9894937 100644 --- a/init.d/openwrt/firewall.zapret.tpws_ipset6 +++ b/init.d/openwrt/firewall.zapret.tpws_ipset6 @@ -2,4 +2,5 @@ IPT_FILTER_HTTP="-p tcp --dport 80 -m set --match-set zapret6 dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_tpws6 diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset_https b/init.d/openwrt/firewall.zapret.tpws_ipset_https index 1b369fa..23a83ea 100644 --- a/init.d/openwrt/firewall.zapret.tpws_ipset_https +++ b/init.d/openwrt/firewall.zapret.tpws_ipset_https @@ -3,4 +3,5 @@ IPT_FILTER_HTTPS="-p tcp --dport 443 -m set --match-set zapret dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_tpws_https diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset_https6 b/init.d/openwrt/firewall.zapret.tpws_ipset_https6 index 331e441..8dffe3f 100644 --- a/init.d/openwrt/firewall.zapret.tpws_ipset_https6 +++ b/init.d/openwrt/firewall.zapret.tpws_ipset_https6 @@ -3,4 +3,5 @@ IPT_FILTER_HTTPS="-p tcp --dport 443 -m set --match-set zapret6 dst" . /opt/zapret/init.d/openwrt/functions +create_ipset no-update fw_tpws_https6 diff --git a/init.d/openwrt/functions b/init.d/openwrt/functions index 6c09846..9aad1a0 100644 --- a/init.d/openwrt/functions +++ b/init.d/openwrt/functions @@ -5,6 +5,12 @@ TPPORT_HTTP=1188 TPPORT_HTTPS=1189 TPWS_USER=daemon +# max wait time for the link local ipv6 on the LAN interface +LINKLOCAL_WAIT_SEC=5 + +[ -n "$ZAPRET_BASE" ] || ZAPRET_BASE=/opt/zapret +IPSET_CR=$ZAPRET_BASE/ipset/create_ipset.sh + exists() { which $1 >/dev/null 2>/dev/null @@ -71,16 +77,32 @@ dnat6_target() { # get target ip address for DNAT. prefer link locals # tpws should be as inaccessible from outside as possible + # link local address can appear not immediately after ifup [ -n "$DNAT6_TARGET" ] || { + # no reason to query if its down + network_is_up lan || return + local DEVICE network_get_device DEVICE lan - DNAT6_TARGET=$(get_ipv6_linklocal $DEVICE) - [ -z "$DNAT6_TARGET" ] && DNAT6_TARGET=$(get_ipv6_global $DEVICE) + + local ct=0 + while + DNAT6_TARGET=$(get_ipv6_linklocal $DEVICE) + [ -n "$DNAT6_TARGET" ] && break + [ "$ct" -ge "$LINKLOCAL_WAIT_SEC" ] && break + echo waiting for the link local for another $(($LINKLOCAL_WAIT_SEC - $ct)) seconds ... + ct=$(($ct+1)) + sleep 1 + do :; done + + [ -z "$DNAT6_TARGET" ] && { + echo no link local. getting global + DNAT6_TARGET=$(get_ipv6_global $DEVICE) + } } } - fw_nfqws() { local DEVICE wan_iface @@ -150,3 +172,11 @@ fw_tpws_https6() { __fw_tpws6 1 } + + + +create_ipset() +{ + echo "Creating ipset" + "$IPSET_CR" $1 +} diff --git a/init.d/openwrt/zapret b/init.d/openwrt/zapret index 4722a9f..3a667ac 100755 --- a/init.d/openwrt/zapret +++ b/init.d/openwrt/zapret @@ -1,8 +1,8 @@ #!/bin/sh /etc/rc.common USE_PROCD=1 -# start betfore firewall - we need ipset populated -START=18 +# after network +START=21 . /lib/functions/network.sh @@ -13,7 +13,6 @@ ZAPRET_BASE=/opt/zapret # !!!!! in openwrt firewall rules are configured separately PIDDIR=/var/run -IPSET_CR=$ZAPRET_BASE/ipset/create_ipset.sh QNUM=200 NFQWS=$ZAPRET_BASE/nfq/nfqws @@ -27,7 +26,8 @@ TPWS_HOSTLIST=$ZAPRET_BASE/ipset/zapret-hosts.txt.gz [ -f "$TPWS_HOSTLIST" ] || TPWS_HOSTLIST=$ZAPRET_BASE/ipset/zapret-hosts-user.txt TPWS_OPT_BASE="--user=$TPWS_USER --bind-addr=127.0.0.1" TPWS_OPT_BASE6="--user=$TPWS_USER --bind-addr=::1" -TPWS_OPT_BASE6_PRE="--user=$TPWS_USER --bind-linklocal=prefer" +# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case +TPWS_OPT_BASE6_PRE="--user=$TPWS_USER --bind-linklocal=prefer --bind-wait-ifup=30 --bind-wait-ip=30 --bind-wait-ip-linklocal=3" TPWS_OPT_BASE_HTTP="--port=$TPPORT_HTTP" TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS" @@ -46,12 +46,6 @@ run_daemon() procd_close_instance } -create_ipset() -{ - echo "Creating ipset" - $IPSET_CR -} - run_tpws() { [ "$DISABLE_IPV4" != "1" ] && run_daemon $1 $TPWS "$TPWS_OPT_BASE $2" @@ -77,16 +71,13 @@ start_service() { run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP --hostlist=$TPWS_HOSTLIST" ;; tpws_ipset|tpws_all) - create_ipset run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" ;; tpws_ipset_https|tpws_all_https) - create_ipset run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" run_tpws 2 "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS" ;; nfqws_ipset|nfqws_ipset_https) - create_ipset run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT" ;; nfqws_all|nfqws_all_https) diff --git a/init.d/sysv/functions b/init.d/sysv/functions index e632a68..f29c605 100644 --- a/init.d/sysv/functions +++ b/init.d/sysv/functions @@ -20,7 +20,8 @@ TPWS_HOSTLIST=$ZAPRET_BASE/ipset/zapret-hosts.txt.gz [ -f "$TPWS_HOSTLIST" ] || TPWS_HOSTLIST=$ZAPRET_BASE/ipset/zapret-hosts-user.txt TPWS_OPT_BASE="--user=$TPWS_USER --bind-addr=127.0.0.1" TPWS_OPT_BASE6="--user=$TPWS_USER --bind-addr=::1" -TPWS_OPT_BASE6_PRE="--user=$TPWS_USER --bind-linklocal=prefer" +# first wait for lan to ifup, then wait for bind-wait-ip-linklocal seconds for link local address and bind-wait-ip for any ipv6 as the worst case +TPWS_OPT_BASE6_PRE="--user=$TPWS_USER --bind-linklocal=prefer --bind-wait-ifup=30 --bind-wait-ip=30 --bind-wait-ip-linklocal=3" TPWS_OPT_BASE_HTTP="--port=$TPPORT_HTTP" TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS" @@ -28,6 +29,9 @@ TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS" [ -n "$IFACE_WAN" ] && IPT_IWAN="-i $IFACE_WAN" [ -n "$IFACE_LAN" ] && IPT_ILAN="-i $IFACE_LAN" +# max wait time for the link local ipv6 on the LAN interface +LINKLOCAL_WAIT_SEC=5 + exists() { which $1 >/dev/null 2>/dev/null @@ -70,17 +74,54 @@ get_ipv6_global() [ -n "$1" ] && dev="dev $1" ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1 } + +iface_is_up() +{ + # $1 - interface name + [ -f /sys/class/net/$1/operstate ] || return + local state + read state /dev/null || ipset create $2 $IPSTYPE $IPSET_OPT +ipset create $2 $IPSTYPE $IPSET_OPT 2>/dev/null || { + [ "$NO_UPDATE" = "1" ] && return +} +ipset flush $2 for f in "$3" "$4" do zzexist "$f" && { @@ -44,7 +49,10 @@ return 0 create_ipset6() { local IPSTYPE=$1 -ipset flush $2 2>/dev/null || ipset create $2 $IPSTYPE $IPSET_OPT family inet6 +ipset create $2 $IPSTYPE $IPSET_OPT family inet6 2>/dev/null || { + [ "$NO_UPDATE" = "1" ] && return +} +ipset flush $2 for f in "$3" "$4" do zzexist "$f" && { diff --git a/ipset/def.sh b/ipset/def.sh index 3f63197..c567f04 100755 --- a/ipset/def.sh +++ b/ipset/def.sh @@ -21,7 +21,7 @@ ZIPLIST_USER_IPBAN6=$EXEDIR/zapret-ip-user-ipban6.txt ZUSERLIST_IPBAN=$EXEDIR/zapret-hosts-user-ipban.txt MDIG=$EXEDIR/../mdig/mdig -MDIG_THREADS=30 +[ -z "$MDIG_THREADS" ] && MDIG_THREADS=30 zzexist() {