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 не найден - выход по ошибке. ; если force и link local не найден - выход по ошибке.
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface --bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface. при bind-linklocal определяет интерфейс, откуда брать ipv6 link local --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> ; на каком порту слушать --port=<port> ; на каком порту слушать
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host --split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb. --split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb.
@ -157,10 +160,16 @@ tpws - это transparent proxy.
; для списка РКН может потребоваться система с 128 Mb памяти ! расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка. ; для списка РКН может потребоваться система с 128 Mb памяти ! расчитывайте требование RAM для процесса как 3-5 кратный размер файла списка.
; по сигналу HUP список будет перечитан при следующем принятом соединении ; по сигналу HUP список будет перечитан при следующем принятом соединении
; список может быть запакован в gzip. формат автоматически распознается и разжимается ; список может быть запакован в gzip. формат автоматически распознается и разжимается
Параметры манипуляции могут сочетаться в любых комбинациях. Параметры манипуляции могут сочетаться в любых комбинациях.
Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи. Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи.
tpws может биндаться только к одному ip или ко всем сразу. tpws может биндаться только к одному ip или ко всем сразу.
Для бинда на все ipv4 укажите "0.0.0.0", на все ipv6 - "::". Без параметров биндаемся на все ipv4 и ipv6. Для бинда на все ipv4 укажите "0.0.0.0", на все ipv6 - "::". Без параметров биндаемся на все ipv4 и ipv6.
Параметры --bind-wait* могут помочь в ситуациях, когда нужно взять IP с интерфейса, но его еще нет, он не поднят
или не сконфигурирован.
В разных системах события ifup ловятся по-разному и не гарантируют, что интерфейс уже получил IP адрес определенного типа.
В общем случае не существует единого механизма повеситься на событие типа "на интерфейсе X появился link local address".
Способы получения списка заблокированных IP Способы получения списка заблокированных 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_nfqws 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_nfqws6 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_nfqws 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_nfqws6 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_tpws 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_tpws6 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_tpws_https 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 . /opt/zapret/init.d/openwrt/functions
create_ipset no-update
fw_tpws_https6 fw_tpws_https6

View File

@ -5,6 +5,12 @@ TPPORT_HTTP=1188
TPPORT_HTTPS=1189 TPPORT_HTTPS=1189
TPWS_USER=daemon 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() exists()
{ {
which $1 >/dev/null 2>/dev/null which $1 >/dev/null 2>/dev/null
@ -71,16 +77,32 @@ dnat6_target()
{ {
# get target ip address for DNAT. prefer link locals # get target ip address for DNAT. prefer link locals
# tpws should be as inaccessible from outside as possible # tpws should be as inaccessible from outside as possible
# link local address can appear not immediately after ifup
[ -n "$DNAT6_TARGET" ] || { [ -n "$DNAT6_TARGET" ] || {
# no reason to query if its down
network_is_up lan || return
local DEVICE local DEVICE
network_get_device DEVICE lan 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() fw_nfqws()
{ {
local DEVICE wan_iface local DEVICE wan_iface
@ -150,3 +172,11 @@ fw_tpws_https6()
{ {
__fw_tpws6 1 __fw_tpws6 1
} }
create_ipset()
{
echo "Creating ipset"
"$IPSET_CR" $1
}

View File

@ -1,8 +1,8 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
USE_PROCD=1 USE_PROCD=1
# start betfore firewall - we need ipset populated # after network
START=18 START=21
. /lib/functions/network.sh . /lib/functions/network.sh
@ -13,7 +13,6 @@ ZAPRET_BASE=/opt/zapret
# !!!!! in openwrt firewall rules are configured separately # !!!!! in openwrt firewall rules are configured separately
PIDDIR=/var/run PIDDIR=/var/run
IPSET_CR=$ZAPRET_BASE/ipset/create_ipset.sh
QNUM=200 QNUM=200
NFQWS=$ZAPRET_BASE/nfq/nfqws 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 [ -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_BASE="--user=$TPWS_USER --bind-addr=127.0.0.1"
TPWS_OPT_BASE6="--user=$TPWS_USER --bind-addr=::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_HTTP="--port=$TPPORT_HTTP"
TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS" TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS"
@ -46,12 +46,6 @@ run_daemon()
procd_close_instance procd_close_instance
} }
create_ipset()
{
echo "Creating ipset"
$IPSET_CR
}
run_tpws() run_tpws()
{ {
[ "$DISABLE_IPV4" != "1" ] && run_daemon $1 $TPWS "$TPWS_OPT_BASE $2" [ "$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" run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP --hostlist=$TPWS_HOSTLIST"
;; ;;
tpws_ipset|tpws_all) tpws_ipset|tpws_all)
create_ipset
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;; ;;
tpws_ipset_https|tpws_all_https) tpws_ipset_https|tpws_all_https)
create_ipset
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP" run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
run_tpws 2 "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS" run_tpws 2 "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS"
;; ;;
nfqws_ipset|nfqws_ipset_https) nfqws_ipset|nfqws_ipset_https)
create_ipset
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT" run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;; ;;
nfqws_all|nfqws_all_https) 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 [ -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_BASE="--user=$TPWS_USER --bind-addr=127.0.0.1"
TPWS_OPT_BASE6="--user=$TPWS_USER --bind-addr=::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_HTTP="--port=$TPPORT_HTTP"
TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS" 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_WAN" ] && IPT_IWAN="-i $IFACE_WAN"
[ -n "$IFACE_LAN" ] && IPT_ILAN="-i $IFACE_LAN" [ -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() exists()
{ {
which $1 >/dev/null 2>/dev/null which $1 >/dev/null 2>/dev/null
@ -70,17 +74,54 @@ get_ipv6_global()
[ -n "$1" ] && dev="dev $1" [ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 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() dnat6_target()
{ {
# get target ip address for DNAT. prefer link locals # get target ip address for DNAT. prefer link locals
# tpws should be as inaccessible from outside as possible # tpws should be as inaccessible from outside as possible
# link local address can appear not immediately after ifup
[ -n "$DNAT6_TARGET" ] || { [ -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() fw_tpws_add()
{ {
# $1 - iptable filter for ipv4 # $1 - iptable filter for ipv4

View File

@ -650,7 +650,10 @@ install_sysv_init()
{ {
echo \* installing init script 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" ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
"$INIT_SCRIPT" enable "$INIT_SCRIPT" enable
} }

View File

@ -1,5 +1,6 @@
#!/bin/sh #!/bin/sh
# create ipset from resolved ip's # create ipset from resolved ip's
# $1=no-update - do not update ipset, only create if its absent
SCRIPT=$(readlink -f "$0") SCRIPT=$(readlink -f "$0")
EXEDIR=$(dirname "$SCRIPT") EXEDIR=$(dirname "$SCRIPT")
@ -8,6 +9,7 @@ IP2NET=$EXEDIR/../ip2net/ip2net
. "$EXEDIR/def.sh" . "$EXEDIR/def.sh"
[ "$1" = "no-update" ] && NO_UPDATE=1
create_ipset() create_ipset()
{ {
@ -17,7 +19,10 @@ if [ -x "$IP2NET" ]; then
else else
IPSTYPE=$1 IPSTYPE=$1
fi 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" for f in "$3" "$4"
do do
zzexist "$f" && { zzexist "$f" && {
@ -44,7 +49,10 @@ return 0
create_ipset6() create_ipset6()
{ {
local IPSTYPE=$1 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" for f in "$3" "$4"
do do
zzexist "$f" && { 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 ZUSERLIST_IPBAN=$EXEDIR/zapret-hosts-user-ipban.txt
MDIG=$EXEDIR/../mdig/mdig MDIG=$EXEDIR/../mdig/mdig
MDIG_THREADS=30 [ -z "$MDIG_THREADS" ] && MDIG_THREADS=30
zzexist() zzexist()
{ {