fixing lots of problems with getting link local address after reboot

This commit is contained in:
bolvan 2019-05-14 18:26:09 +03:00
parent b0f0cd1c75
commit 38d5b639de
23 changed files with 114 additions and 24 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -141,6 +141,9 @@ tpws - это transparent proxy.
; если force и link local не найден - выход по ошибке.
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface. при bind-linklocal определяет интерфейс, откуда брать ipv6 link local
--bind-wait-ifup=<sec> ; ждать до N секунд появления и поднятия интерфейса
--bind-wait-ip=<sec> ; ждать до N секунд получения IP адреса (если задан --bind-wait-ifup - время идет после поднятия интерфейса)
--bind-wait-ip-linklocal ; (только если заданы --bind-wait-ip и --bind-linklocal=prefer) согласиться на global address после N секунд
--port=<port> ; на каком порту слушать
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 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
-------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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)

View File

@ -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 </sys/class/net/$1/operstate
[ "$state" != "down" ]
}
wait_ifup()
{
# $1 - interface name
local ct=0
while
iface_is_up $1 && return
[ "$ct" -ge "$IFUP_WAIT_SEC" ] && break
echo waiting for ifup of $1 for another $(($IFUP_WAIT_SEC - $ct)) seconds ...
ct=$(($ct+1))
sleep 1
do :; done
false
}
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" ] || {
DNAT6_TARGET=$(get_ipv6_linklocal $IFACE_LAN)
[ -z "$DNAT6_TARGET" ] && DNAT6_TARGET=$(get_ipv6_global $IFACE_LAN)
local ct=0
while
DNAT6_TARGET=$(get_ipv6_linklocal $IFACE_LAN)
[ -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 $IFACE_LAN)
}
}
}
fw_tpws_add()
{
# $1 - iptable filter for ipv4

View File

@ -650,7 +650,10 @@ install_sysv_init()
{
echo \* installing init script
[ -x "$INIT_SCRIPT" ] && "$INIT_SCRIPT" stop
[ -x "$INIT_SCRIPT" ] && {
"$INIT_SCRIPT" stop
"$INIT_SCRIPT" disable
}
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
"$INIT_SCRIPT" enable
}

View File

@ -1,5 +1,6 @@
#!/bin/sh
# create ipset from resolved ip's
# $1=no-update - do not update ipset, only create if its absent
SCRIPT=$(readlink -f "$0")
EXEDIR=$(dirname "$SCRIPT")
@ -8,6 +9,7 @@ IP2NET=$EXEDIR/../ip2net/ip2net
. "$EXEDIR/def.sh"
[ "$1" = "no-update" ] && NO_UPDATE=1
create_ipset()
{
@ -17,7 +19,10 @@ if [ -x "$IP2NET" ]; then
else
IPSTYPE=$1
fi
ipset flush $2 2>/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" && {

View File

@ -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()
{