ipv6 support

This commit is contained in:
bolvan 2019-05-13 18:27:16 +03:00
parent 3a5bf861b9
commit 561c82bf79
39 changed files with 885 additions and 356 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.

12
config
View File

@ -16,15 +16,21 @@ TPWS_OPT_HTTP="--hostspell=HOST --split-http-req=method"
TPWS_OPT_HTTPS="--split-pos=3"
# for routers based on desktop linux only. has not effect in openwrt.
# CHOSE NETWORK INTERFACE BEHIND NAT (LAN)
# or leave it commented if its not router
#SLAVE_ETH=eth0
# CHOOSE LAN and WAN NETWORK INTERFACES
# or leave them commented if its not router
#IFACE_LAN=eth0
#IFACE_WAN=eth1
# should init scripts apply firewall rules ?
# set to 0 if firewall control system is present
# openwrt uses fw3 firewall , init never touch fw
INIT_APPLY_FW=1
# do not work with ipv4
#DISABLE_IPV4=1
# do not work with ipv6
DISABLE_IPV6=1
# select which init script will be used to get ip or host list
# possible values : get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh
# comment if not required

View File

@ -128,3 +128,8 @@ v25
init : move to native systemd units
use links to units, init scripts and firewall includes, no more copying
v26
ipv6 support
tpws : advanced bind options

View File

@ -91,6 +91,20 @@ transparent proxy (TPROXY или DNAT). TPROXY не работает с соед
iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to 127.0.0.1:1188
iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to 127.0.0.1:1188
Особенности применения ip6tables
--------------------------------
ip6tables работают почти точно так же, как и ipv4, но есть ряд важных нюансов.
В DNAT следует брать адрес --to в квадратные скобки. Например :
iptables -t nat -I OUTPUT -p tcp --dport 80 -m owner ! --uid-owner tpws -j DNAT --to [::1]:1188
Параметра route_localnet не существует для ipv6.
DNAT на localhost (::1) возможен только в цепочке OUTPUT.
В цепочке PREROUTING DNAT возможен на любой global address или на link local address того же интерфейса,
откуда пришел пакет.
NFQUEUE работает без изменений.
nfqws
-----
@ -113,6 +127,11 @@ tpws - это transparent proxy.
--pidfile=<file> ; сохранить PID в файл
--user=<username> ; менять uid процесса
--bind-addr ; на каком адресе слушать. может быть ipv4 или ipv6 адрес. если не указано, то слушает на всех адресах ipv4 и ipv6
; если указан ipv6 link local, то требуется указать с какого он интерфейса через --bind-iface6
--bind-linklocal=prefer|force ; если prefer, то найти link local от iface6. если не найдено - использовать первый адрес любого типа.
; если force и link local не найден - выход по ошибке.
--bind-iface4=<iface> ; слушать на первом ipv4 интерфейса iface
--bind-iface6=<iface> ; слушать на первом ipv6 интерфейса iface. при bind-linklocal определяет интерфейс, откуда брать ipv6 link local
--port=<port> ; на каком порту слушать
--split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host
--split-pos=<offset> ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 8Kb (размер буфера приема), то будет разделен каждый блок по 8Kb.
@ -131,6 +150,8 @@ tpws - это transparent proxy.
; список может быть запакован в gzip. формат автоматически распознается и разжимается
Параметры манипуляции могут сочетаться в любых комбинациях.
Есть исключения : split-pos заменяет split-http-req. hostdot и hosttab взаимоисключающи.
tpws может биндаться только к одному ip или ко всем сразу.
Для бинда на все ipv4 укажите "0.0.0.0", на все ipv6 - "::". Без параметров биндаемся на все ipv4 и ipv6.
Способы получения списка заблокированных IP
-------------------------------------------
@ -184,6 +205,12 @@ get_reestr.sh может использовать мультипоточный
в отдельный ipset "ipban". Он может использоваться для принудительного завертывания всех
соединений на прозрачный proxy "redsocks" или на VPN.
IPV6 : если включен ipv6, то дополнительно создаются листы с таким же именем, но с "6" на конце перед расширением.
zapret-ip.txt => zapret-ip6.txt
Создаются ipset-ы zapret6 и ipban6.
Реестр РКН не содержит список ipv6 адресов. Возможен только самостоятельный ресолвинг юзер листа или
листа доменов РКН. get_user.sh и get_reestr.sh создают списки ipv6.
Фильтрация по именам доменов
----------------------------
@ -251,11 +278,17 @@ TPWS_OPT_HTTPS="--split-pos=3"
Поместите сюда название скрипта, который будете использовать для обновления листов.
Если не нужно, то параметр следует закомментировать.
Можно индивидуально отключить ipv4 или ipv6. Если параметр закомментирован или не равен "1",
использование протокола разрешено.
#DISABLE_IPV4=1
DISABLE_IPV6=1
Следующие настройки не актуальны для openwrt :
Если ваша система работает как роутер, то нужно раскомментировать параметр SLAVE_ETH и вписать в него
название внутреннего сетевого интерфейса (LAN).
Если ваша система работает как роутер, то нужно вписать названия внутреннего и внешнего интерфейсов :
IFACE_LAN=eth0
IFACE_WAN=eth1
Параметр INIT_APPLY_FW=1 разрешает init скрипту самостоятельно применять правила iptables.
При иных значениях или если параметр закомментирован, правила применены не будут.
@ -288,7 +321,7 @@ TPWS_OPT_HTTPS="--split-pos=3"
ln -fs /opt/zapret/init.d/systemd/zapret.service /lib/systemd/system
Удалить старые листы, если они были созданы ранее :
rm /opt/zapret/ipset/zapret-ip.txt* /opt/zapret/ipset/zapret-ip-user.txt* /opt/zapret/ipset/zapret-ip-ipban.txt* /opt/zapret/ipset/zapret-ip-user-ipban.txt* /opt/zapret/ipset/zapret-hosts.txt*
/opt/zapret/ipset/clear_lists.sh
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
Выполнить скрипт обновления листа :
/opt/zapret/ipset/get_config.sh
@ -387,7 +420,7 @@ git и curl по умолчанию могут присутствовать, ips
АЛЬТЕРНАТИВА : зайти в tpws,nfq,ip2net,mdig, в каждом выполнить make. Получите динамические бинарики под вашу ось.
Удалить старые листы, если они были созданы ранее :
rm /opt/zapret/ipset/zapret-ip.txt* /opt/zapret/ipset/zapret-ip-user.txt* /opt/zapret/ipset/zapret-ip-ipban.txt* /opt/zapret/ipset/zapret-ip-user-ipban.txt* /opt/zapret/ipset/zapret-hosts.txt*
/opt/zapret/ipset/clear_lists.sh
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
Выполнить скрипт обновления листа :
/opt/zapret/ipset/get_config.sh
@ -530,7 +563,7 @@ ipset можно выкинуть, если не будем пользовать
Настроить параметры согласно разделу "Выбор параметров".
Удалить старые листы, если они были созданы ранее :
rm /opt/zapret/ipset/zapret-ip.txt* /opt/zapret/ipset/zapret-ip-user.txt* /opt/zapret/ipset/zapret-ip-ipban.txt* /opt/zapret/ipset/zapret-ip-user-ipban.txt* /opt/zapret/ipset/zapret-hosts.txt*
/opt/zapret/ipset/clear_lists.sh
По желанию прописать в /opt/zapret/ipset/zapret-hosts-user.txt свои домены.
Выполнить скрипт обновления листа :
/opt/zapret/ipset/get_config.sh
@ -542,19 +575,37 @@ ipset можно выкинуть, если не будем пользовать
/etc/init.d/zapret enable
/etc/init.d/zapret start
В зависимости от выбранного в файле config MODE скопировать нужный файл настроек фаервола :
cp /opt/zapret/init.d/openwrt/firewall.zapret.$MODE /etc/firewall.zapret
Если не включен параметр DISABLE_IPV4 :
В зависимости от выбранного в файле config MODE создать ссылку на нужный файл настроек фаервола :
ln -fs /opt/zapret/init.d/openwrt/firewall.zapret.$MODE /etc/firewall.zapret
Например :
cp /opt/zapret/init.d/openwrt/firewall.zapret.tpws_ipset_https /etc/firewall.zapret
ln -fs /opt/zapret/init.d/openwrt/firewall.zapret.tpws_ipset_https /etc/firewall.zapret
Проверить была ли создана ранее запись о firewall include :
uci show firewall | grep firewall.zapret
Если ничего не вывело, значит добавить :
Если firewall.zapret нет, значит добавить :
uci add firewall include
uci set firewall.@include[-1].path="/etc/firewall.zapret"
uci set firewall.@include[-1].reload="1"
uci commit firewall
Перезапустить фаервол :
fw3 restart
Если не включен параметр DISABLE_IPV6 :
В зависимости от выбранного в файле config MODE создать ссылку на нужный файл настроек фаервола :
ln -fs /opt/zapret/init.d/openwrt/firewall.zapret.${MODE}6 /etc/firewall.zapret6
Например :
ln -fs /opt/zapret/init.d/openwrt/firewall.zapret.tpws_ipset_https6 /etc/firewall.zapret6
Проверить была ли создана ранее запись о firewall include :
uci show firewall | grep firewall.zapret6
Если firewall.zapret6 нет, значит добавить :
uci add firewall include
uci set firewall.@include[-1].path="/etc/firewall.zapret6"
uci set firewall.@include[-1].reload="1"
uci commit firewall
Перезапустить фаервол :
fw3 restart
Если не включен параметр DISABLE_IPV6,
Посмотреть через iptables -nL или через luci вкладку "firewall" появились ли нужные правила.
ЭКОНОМИЯ МЕСТА : если его мало, то можно оставить в директории zapret лишь подкаталог ipset, файл config и init.d/openwrt.

View File

@ -1,11 +1,6 @@
QNUM=200
IPT_FILTER_PRE="-p tcp --sport 80"
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK --sport 80"
IPT_FILTER_POST="-p tcp --dport 80"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
ipt PREROUTING -t raw $IPT_FILTER_PRE -j NFQUEUE --queue-num $QNUM --queue-bypass
ipt POSTROUTING -t mangle $IPT_FILTER_POST -j NFQUEUE --queue-num $QNUM --queue-bypass
fw_nfqws

View File

@ -0,0 +1,6 @@
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK --sport 80"
IPT_FILTER_POST="-p tcp --dport 80"
. /opt/zapret/init.d/openwrt/functions
fw_nfqws6

View File

@ -1,11 +1,6 @@
QNUM=200
IPT_FILTER_PRE="-p tcp -m multiport --sports 80,443"
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK -m multiport --sports 80,443"
IPT_FILTER_POST="-p tcp --dport 80"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
ipt PREROUTING -t raw $IPT_FILTER_PRE -j NFQUEUE --queue-num $QNUM --queue-bypass
ipt POSTROUTING -t mangle $IPT_FILTER_POST -j NFQUEUE --queue-num $QNUM --queue-bypass
fw_nfqws

View File

@ -0,0 +1,6 @@
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK -m multiport --sports 80,443"
IPT_FILTER_POST="-p tcp --dport 80"
. /opt/zapret/init.d/openwrt/functions
fw_nfqws6

View File

@ -1,11 +1,6 @@
QNUM=200
IPT_FILTER_PRE="-p tcp --sport 80 -m set --match-set zapret src"
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK --sport 80 -m set --match-set zapret src"
IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret dst"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
ipt PREROUTING -t raw $IPT_FILTER_PRE -j NFQUEUE --queue-num $QNUM --queue-bypass
ipt POSTROUTING -t mangle $IPT_FILTER_POST -j NFQUEUE --queue-num $QNUM --queue-bypass
fw_nfqws

View File

@ -0,0 +1,6 @@
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK --sport 80 -m set --match-set zapret6 src"
IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret6 dst"
. /opt/zapret/init.d/openwrt/functions
fw_nfqws6

View File

@ -1,11 +1,6 @@
QNUM=200
IPT_FILTER_PRE="-p tcp -m multiport --sports 80,443 -m set --match-set zapret src"
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK -m multiport --sports 80,443 -m set --match-set zapret src"
IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret dst"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
ipt PREROUTING -t raw $IPT_FILTER_PRE -j NFQUEUE --queue-num $QNUM --queue-bypass
ipt POSTROUTING -t mangle $IPT_FILTER_POST -j NFQUEUE --queue-num $QNUM --queue-bypass
fw_nfqws

View File

@ -0,0 +1,6 @@
IPT_FILTER_PRE="-p tcp --tcp-flags SYN,ACK SYN,ACK -m multiport --sports 80,443 -m set --match-set zapret6 src"
IPT_FILTER_POST="-p tcp --dport 80 -m set --match-set zapret6 dst"
. /opt/zapret/init.d/openwrt/functions
fw_nfqws6

View File

@ -1,21 +1,5 @@
TPPORT_HTTP=1188
TPWS_USER=daemon
IPT_FILTER_HTTP="-p tcp --dport 80"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
. /lib/functions/network.sh
network_find_wan wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
done
network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
fw_tpws

View File

@ -0,0 +1,5 @@
IPT_FILTER_HTTP="-p tcp --dport 80"
. /opt/zapret/init.d/openwrt/functions
fw_tpws6

View File

@ -1,25 +1,6 @@
TPPORT_HTTP=1188
TPPORT_HTTPS=1189
TPWS_USER=daemon
IPT_FILTER_HTTP="-p tcp --dport 80"
IPT_FILTER_HTTPS="-p tcp --dport 443"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
. /lib/functions/network.sh
network_find_wan wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTPS -j DNAT --to 127.0.0.1:$TPPORT_HTTPS
done
network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTPS -j DNAT --to 127.0.0.1:$TPPORT_HTTPS
fw_tpws_https

View File

@ -0,0 +1,6 @@
IPT_FILTER_HTTP="-p tcp --dport 80"
IPT_FILTER_HTTPS="-p tcp --dport 443"
. /opt/zapret/init.d/openwrt/functions
fw_tpws_https6

View File

@ -0,0 +1 @@
firewall.zapret.tpws_all6

View File

@ -1,21 +1,5 @@
TPPORT_HTTP=1188
TPWS_USER=daemon
IPT_FILTER_HTTP="-p tcp --dport 80 -m set --match-set zapret dst"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
. /lib/functions/network.sh
network_find_wan wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
done
network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
fw_tpws

View File

@ -0,0 +1,5 @@
IPT_FILTER_HTTP="-p tcp --dport 80 -m set --match-set zapret6 dst"
. /opt/zapret/init.d/openwrt/functions
fw_tpws6

View File

@ -1,25 +1,6 @@
TPPORT_HTTP=1188
TPPORT_HTTPS=1189
TPWS_USER=daemon
IPT_FILTER_HTTP="-p tcp --dport 80 -m set --match-set zapret dst"
IPT_FILTER_HTTPS="-p tcp --dport 443 -m set --match-set zapret dst"
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
. /opt/zapret/init.d/openwrt/functions
. /lib/functions/network.sh
network_find_wan wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTPS -j DNAT --to 127.0.0.1:$TPPORT_HTTPS
done
network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTPS -j DNAT --to 127.0.0.1:$TPPORT_HTTPS
fw_tpws_https

View File

@ -0,0 +1,6 @@
IPT_FILTER_HTTP="-p tcp --dport 80 -m set --match-set zapret6 dst"
IPT_FILTER_HTTPS="-p tcp --dport 443 -m set --match-set zapret6 dst"
. /opt/zapret/init.d/openwrt/functions
fw_tpws_https6

157
init.d/openwrt/functions Normal file
View File

@ -0,0 +1,157 @@
. /lib/functions/network.sh
QNUM=200
TPPORT_HTTP=1188
TPPORT_HTTPS=1189
TPWS_USER=daemon
exists()
{
which $1 >/dev/null 2>/dev/null
}
# can be multiple ipv6 outgoing interfaces
# uplink from isp, tunnelbroker, vpn, ...
# want them all. who knows what's the real one that blocks sites
# dont want any manual configuration - want to do it automatically
# standard network_find_wan[6] return only the first
# we use low level function from network.sh to avoid this limitation
# it can change theoretically and stop working
network_find_wan_all()
{
__network_ifstatus "$1" "" "[@.route[@.target='0.0.0.0' && !@.table]].interface" "" 10 2>/dev/null && return
network_find_wan $1
}
network_find_wan6_all()
{
__network_ifstatus "$1" "" "[@.route[@.target='::' && !@.table]].interface" "" 4 2>/dev/null && return
network_find_wan6 $1
}
ipt()
{
iptables -C $@ 2>/dev/null || iptables -I $@
}
ipt6()
{
ip6tables -C $@ 2>/dev/null || ip6tables -I $@
}
# there's no route_localnet for ipv6
# the best we can is to route to link local of the incoming interface
# OUTPUT - can DNAT to ::1
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
# not a good idea to expose tpws to the world (bind to ::)
get_ipv6_linklocal()
{
# $1 - interface name. if empty - any interface
if exists ip ; then
local dev
[ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1
else
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Link.*$/\1/;t;d' | head -n 1
fi
}
get_ipv6_global()
{
# $1 - interface name. if empty - any interface
if exists ip ; then
local dev
[ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1
else
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Global.*$/\1/;t;d' | head -n 1
fi
}
dnat6_target()
{
# get target ip address for DNAT. prefer link locals
# tpws should be as inaccessible from outside as possible
[ -n "$DNAT6_TARGET" ] || {
local DEVICE
network_get_device DEVICE lan
DNAT6_TARGET=$(get_ipv6_linklocal $DEVICE)
[ -z "$DNAT6_TARGET" ] && DNAT6_TARGET=$(get_ipv6_global $DEVICE)
}
}
fw_nfqws()
{
local DEVICE wan_iface
network_find_wan_all wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt POSTROUTING -t mangle -o $DEVICE $IPT_FILTER_POST -j NFQUEUE --queue-num $QNUM --queue-bypass
ipt PREROUTING -t raw -i $DEVICE $IPT_FILTER_PRE -j NFQUEUE --queue-num $QNUM --queue-bypass
done
}
fw_nfqws6()
{
local DEVICE wan_iface
network_find_wan6_all wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt6 POSTROUTING -t mangle -o $DEVICE $IPT_FILTER_POST -j NFQUEUE --queue-num $QNUM --queue-bypass
ipt6 PREROUTING -t raw -i $DEVICE $IPT_FILTER_PRE -j NFQUEUE --queue-num $QNUM --queue-bypass
done
}
fw_tpws()
{
local DEVICE wan_iface
network_find_wan_all wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
done
network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
}
fw_tpws_https()
{
local DEVICE wan_iface
network_find_wan_all wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
ipt OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTPS -j DNAT --to 127.0.0.1:$TPPORT_HTTPS
done
network_get_device DEVICE lan
sysctl -w net.ipv4.conf.$DEVICE.route_localnet=1
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTP -j DNAT --to 127.0.0.1:$TPPORT_HTTP
ipt prerouting_lan_rule -t nat $IPT_FILTER_HTTPS -j DNAT --to 127.0.0.1:$TPPORT_HTTPS
}
fw_tpws6()
{
local DEVICE wan_iface ip6
network_find_wan6_all wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt6 OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to [::1]:$TPPORT_HTTP
done
network_get_device DEVICE lan
dnat6_target
ipt6 PREROUTING -t nat -i $DEVICE $IPT_FILTER_HTTP -j DNAT --to [$DNAT6_TARGET]:$TPPORT_HTTP
}
fw_tpws_https6()
{
local DEVICE wan_iface ip6
network_find_wan6_all wan_iface
for ext_iface in $wan_iface; do
network_get_device DEVICE $ext_iface
ipt6 OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTP -j DNAT --to [::1]:$TPPORT_HTTP
ipt6 OUTPUT -t nat -o $DEVICE -m owner ! --uid-owner $TPWS_USER $IPT_FILTER_HTTPS -j DNAT --to [::1]:$TPPORT_HTTPS
done
network_get_device DEVICE lan
dnat6_target
ipt6 PREROUTING -t nat -i $DEVICE $IPT_FILTER_HTTP -j DNAT --to [$DNAT6_TARGET]:$TPPORT_HTTP
ipt6 PREROUTING -t nat -i $DEVICE $IPT_FILTER_HTTPS -j DNAT --to [$DNAT6_TARGET]:$TPPORT_HTTPS
}

View File

@ -4,6 +4,8 @@ USE_PROCD=1
# start betfore firewall - we need ipset populated
START=18
. /lib/functions/network.sh
ZAPRET_BASE=/opt/zapret
# SHOULD EDIT config
. "$ZAPRET_BASE/config"
@ -17,15 +19,17 @@ QNUM=200
NFQWS=$ZAPRET_BASE/nfq/nfqws
NFQWS_OPT_BASE="--qnum=$QNUM"
TPWS_USER=daemon
TPPORT_HTTP=1188
TPPORT_HTTPS=1189
TPWS=$ZAPRET_BASE/tpws/tpws
TPWS_USER=daemon
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_BASE_HTTP="--port=$TPPORT_HTTP $TPWS_OPT_BASE"
TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS $TPWS_OPT_BASE"
TPWS_OPT_BASE6="--user=$TPWS_USER --bind-addr=::1"
TPWS_OPT_BASE6_PRE="--user=$TPWS_USER --bind-linklocal=prefer"
TPWS_OPT_BASE_HTTP="--port=$TPPORT_HTTP"
TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS"
run_daemon()
@ -48,36 +52,54 @@ create_ipset()
$IPSET_CR
}
run_tpws()
{
[ "$DISABLE_IPV4" != "1" ] && run_daemon $1 $TPWS "$TPWS_OPT_BASE $2"
[ "$DISABLE_IPV6" != "1" ] && {
run_daemon $((60+$1)) $TPWS "$TPWS_OPT_BASE6 $2"
network_get_device DEVICE lan
[ -n "$DEVICE" ] && run_daemon $((660+$1)) $TPWS "$TPWS_OPT_BASE6_PRE --bind-iface6=$DEVICE $2"
}
}
stop_tpws()
{
[ "$DISABLE_IPV4" != "1" ] && stop_daemon $1 $TPWS
[ "$DISABLE_IPV6" != "1" ] && {
stop_daemon $((60+$1)) $TPWS
stop_daemon $((660+$1)) $TPWS
}
}
start_service() {
case "${MODE}" in
tpws_hostlist)
run_daemon 1 $TPWS "$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)
create_ipset
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;;
create_ipset
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;;
tpws_ipset_https|tpws_all_https)
create_ipset
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
run_daemon 2 $TPWS "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_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"
;;
create_ipset
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
nfqws_all|nfqws_all_https)
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
ipset)
create_ipset
;;
create_ipset
;;
custom)
# PLACEHOLDER
echo !!! NEED ATTENTION !!!
echo Start daemon\(s\)
echo Study how other sections work
;;
# PLACEHOLDER
echo !!! NEED ATTENTION !!!
echo Start daemon\(s\)
echo Study how other sections work
;;
esac
}

View File

@ -21,15 +21,21 @@ QNUM=200
NFQWS=$ZAPRET_BASE/nfq/nfqws
NFQWS_OPT_BASE="--qnum=$QNUM"
TPWS_USER=tpws
TPPORT_HTTP=1188
TPPORT_HTTPS=1189
TPWS=$ZAPRET_BASE/tpws/tpws
TPWS_USER=tpws
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_BASE_HTTP="--port=$TPPORT_HTTP $TPWS_OPT_BASE"
TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS $TPWS_OPT_BASE"
TPWS_OPT_BASE6="--user=$TPWS_USER --bind-addr=::1"
TPWS_OPT_BASE6_PRE="--user=$TPWS_USER --bind-linklocal=prefer"
TPWS_OPT_BASE_HTTP="--port=$TPPORT_HTTP"
TPWS_OPT_BASE_HTTPS="--port=$TPPORT_HTTPS"
[ -n "$IFACE_WAN" ] && IPT_OWAN="-o $IFACE_WAN"
[ -n "$IFACE_WAN" ] && IPT_IWAN="-i $IFACE_WAN"
[ -n "$IFACE_LAN" ] && IPT_ILAN="-i $IFACE_LAN"
exists()
{
@ -38,61 +44,149 @@ exists()
ipt()
{
if [ "$INIT_APPLY_FW" = "1" ]; then
iptables -C $@ 2>/dev/null || iptables -I $@
fi
iptables -C $@ 2>/dev/null || iptables -I $@
}
ipt_del()
{
[ "$INIT_APPLY_FW" = "1" ] && iptables -C $@ 2>/dev/null && iptables -D $@
iptables -C $@ 2>/dev/null && iptables -D $@
}
ipt6()
{
ip6tables -C $@ 2>/dev/null || ip6tables -I $@
}
ipt6_del()
{
ip6tables -C $@ 2>/dev/null && ip6tables -D $@
}
# there's no route_localnet for ipv6
# the best we can is to route to link local of the incoming interface
# OUTPUT - can DNAT to ::1
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
# not a good idea to expose tpws to the world (bind to ::)
get_ipv6_linklocal()
{
# $1 - interface name. if empty - any interface
local dev
[ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1
}
get_ipv6_global()
{
# $1 - interface name. if empty - any interface
local dev
[ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1
}
dnat6_target()
{
# get target ip address for DNAT. prefer link locals
# tpws should be as inaccessible from outside as possible
[ -n "$DNAT6_TARGET" ] || {
DNAT6_TARGET=$(get_ipv6_linklocal $IFACE_LAN)
[ -z "$DNAT6_TARGET" ] && DNAT6_TARGET=$(get_ipv6_global $IFACE_LAN)
}
}
fw_tpws_add()
{
# $1 - iptable filter
# $2 - tpws port
echo "Adding iptables rule for tpws : $1"
[ -n "$SLAVE_ETH" ] && {
ipt PREROUTING -t nat -i $SLAVE_ETH -p tcp $1 -j DNAT --to 127.0.0.1:$2
}
ipt OUTPUT -t nat -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$2
# $1 - iptable filter for ipv4
# $2 - iptable filter for ipv6
# $3 - tpws port
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV4" != "1" ] && {
echo "Adding iptables rule for tpws : $1"
[ -n "$IFACE_LAN" ] && {
ipt PREROUTING -t nat $IPT_ILAN -p tcp $1 -j DNAT --to 127.0.0.1:$3
}
ipt OUTPUT -t nat $IPT_OWAN -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$3
}
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV6" != "1" ] && {
echo "Adding ip6tables rule for tpws : $2"
[ -n "$IFACE_LAN" ] && {
dnat6_target
ipt6 PREROUTING -t nat $IPT_ILAN -p tcp $2 -j DNAT --to [$DNAT6_TARGET]:$3
}
ipt6 OUTPUT -t nat $IPT_OWAN -m owner ! --uid-owner $TPWS_USER -p tcp $2 -j DNAT --to [::1]:$3
}
}
fw_tpws_del()
{
# $1 - iptable filter
# $2 - tpws port
echo "Deleting iptables rule for tpws : $1"
[ -n "$SLAVE_ETH" ] && {
ipt PREROUTING -t nat -i $SLAVE_ETH -p tcp $1 -j DNAT --to 127.0.0.1:$2
# $1 - iptable filter for ipv4
# $2 - iptable filter for ipv6
# $3 - tpws port
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV4" != "1" ] && {
echo "Deleting iptables rule for tpws : $1"
[ -n "$IFACE_LAN" ] && {
ipt_del PREROUTING -t nat $IPT_ILAN -p tcp $1 -j DNAT --to 127.0.0.1:$3
}
ipt_del OUTPUT -t nat $IPT_OWAN -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$3
}
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV6" != "1" ] && {
echo "Deleting ip6tables rule for tpws : $2"
[ -n "$IFACE_LAN" ] && {
dnat6_target
ipt6_del PREROUTING -t nat $IPT_ILAN -p tcp $2 -j DNAT --to [$DNAT6_TARGET]:$3
}
ipt6_del OUTPUT -t nat $IPT_OWAN -m owner ! --uid-owner $TPWS_USER -p tcp $2 -j DNAT --to [::1]:$3
}
ipt_del OUTPUT -t nat -m owner ! --uid-owner $TPWS_USER -p tcp $1 -j DNAT --to 127.0.0.1:$2
}
fw_nfqws_add_pre()
{
# $1 - iptable filter
echo "Adding iptables rule for nfqws prerouting : $1"
ipt PREROUTING -t raw -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
# $1 - iptable filter for ipv4
# $2 - iptable filter for ipv6
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV4" != "1" ] && {
echo "Adding iptables rule for nfqws prerouting : $1"
ipt PREROUTING -t raw $IPT_IWAN -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV6" != "1" ] && {
echo "Adding ip6tables rule for nfqws prerouting : $2"
ipt6 PREROUTING -t raw $IPT_IWAN -p tcp --tcp-flags SYN,ACK SYN,ACK $2 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
}
fw_nfqws_del_pre()
{
# $1 - iptable filter
echo "Deleting iptables rule for nfqws prerouting : $1"
ipt_del PREROUTING -t raw -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
# $1 - iptable filter for ipv4
# $2 - iptable filter for ipv6
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV4" != "1" ] && {
echo "Deleting iptables rule for nfqws prerouting : $1"
ipt_del PREROUTING -t raw $IPT_IWAN -p tcp --tcp-flags SYN,ACK SYN,ACK $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV6" != "1" ] && {
echo "Deleting ip6tables rule for nfqws prerouting : $2"
ipt6_del PREROUTING -t raw $IPT_IWAN -p tcp --tcp-flags SYN,ACK SYN,ACK $2 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
}
fw_nfqws_add_post()
{
# $1 - iptable filter
echo "Adding iptables rule for nfqws postrouting : $1"
ipt POSTROUTING -t mangle -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
# $1 - iptable filter for ipv4
# $2 - iptable filter for ipv6
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV4" != "1" ] && {
echo "Adding iptables rule for nfqws postrouting : $1"
ipt POSTROUTING -t mangle $IPT_OWAN -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV6" != "1" ] && {
echo "Adding ip6tables rule for nfqws postrouting : $2"
ipt6 POSTROUTING -t mangle $IPT_OWAN -p tcp $2 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
}
fw_nfqws_del_post()
{
# $1 - iptable filter
echo "Deleting iptables rule for nfqws postrouting : $1"
ipt_del POSTROUTING -t mangle -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
# $1 - iptable filter for ipv4
# $2 - iptable filter for ipv6
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV4" != "1" ] && {
echo "Deleting iptables rule for nfqws postrouting : $1"
ipt_del POSTROUTING -t mangle $IPT_OWAN -p tcp $1 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
[ "$INIT_APPLY_FW" = "1" ] && [ "$DISABLE_IPV6" != "1" ] && {
echo "Deleting ip6tables rule for nfqws postrouting : $2"
ipt6_del POSTROUTING -t mangle $IPT_OWAN -p tcp $2 -j NFQUEUE --queue-num $QNUM --queue-bypass
}
}
run_daemon()
{
# $1 - daemon number : 1,2,3,...
@ -151,6 +245,23 @@ prepare_tpws()
for iface in /proc/sys/net/ipv4/conf/*; do sysctl -qw net.ipv4.conf.$(basename $iface).route_localnet=1; done
}
run_tpws()
{
[ "$DISABLE_IPV4" != "1" ] && run_daemon $1 $TPWS "$TPWS_OPT_BASE $2"
[ "$DISABLE_IPV6" != "1" ] && {
run_daemon $((60+$1)) $TPWS "$TPWS_OPT_BASE6 $2"
[ -n "$IFACE_LAN" ] && run_daemon $((660+$1)) $TPWS "$TPWS_OPT_BASE6_PRE --bind-iface6=$IFACE_LAN $2"
}
}
stop_tpws()
{
[ "$DISABLE_IPV4" != "1" ] && stop_daemon $1 $TPWS
[ "$DISABLE_IPV6" != "1" ] && {
stop_daemon $((60+$1)) $TPWS
[ -n "$IFACE_LAN" ] && stop_daemon $((660+$1)) $TPWS
}
}
create_ipset()
{
@ -162,121 +273,121 @@ case "$1" in
start)
case "${MODE}" in
tpws_hostlist)
prepare_tpws
fw_tpws_add "--dport 80" $TPPORT_HTTP
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP --hostlist=$TPWS_HOSTLIST"
;;
prepare_tpws
fw_tpws_add "--dport 80" "--dport 80" $TPPORT_HTTP
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP --hostlist=$TPWS_HOSTLIST"
;;
tpws_ipset)
create_ipset
prepare_tpws
fw_tpws_add "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;;
create_ipset
prepare_tpws
fw_tpws_add "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst" $TPPORT_HTTP
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;;
tpws_ipset_https)
create_ipset
prepare_tpws
fw_tpws_add "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP
fw_tpws_add "--dport 443 -m set --match-set zapret dst" $TPPORT_HTTPS
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
run_daemon 2 $TPWS "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS"
;;
create_ipset
prepare_tpws
fw_tpws_add "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst" $TPPORT_HTTP
fw_tpws_add "--dport 443 -m set --match-set zapret dst" "--dport 443 -m set --match-set zapret6 dst" $TPPORT_HTTPS
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
run_tpws 2 "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS"
;;
tpws_all)
prepare_tpws
fw_tpws_add "--dport 80" $TPPORT_HTTP
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;;
prepare_tpws
fw_tpws_add "--dport 80" "--dport 80" $TPPORT_HTTP
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
;;
tpws_all_https)
prepare_tpws
fw_tpws_add "--dport 80" $TPPORT_HTTP
fw_tpws_add "--dport 443" $TPPORT_HTTPS
run_daemon 1 $TPWS "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
run_daemon 2 $TPWS "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS"
;;
prepare_tpws
fw_tpws_add "--dport 80" "--dport 80" $TPPORT_HTTP
fw_tpws_add "--dport 443" "--dport 443" $TPPORT_HTTPS
run_tpws 1 "$TPWS_OPT_BASE_HTTP $TPWS_OPT_HTTP"
run_tpws 2 "$TPWS_OPT_BASE_HTTPS $TPWS_OPT_HTTPS"
;;
nfqws_ipset)
create_ipset
fw_nfqws_add_pre "--sport 80 -m set --match-set zapret src"
fw_nfqws_add_post "--dport 80 -m set --match-set zapret dst"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
create_ipset
fw_nfqws_add_pre "--sport 80 -m set --match-set zapret src" "--sport 80 -m set --match-set zapret6 src"
fw_nfqws_add_post "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
nfqws_ipset_https)
create_ipset
fw_nfqws_add_pre "-m multiport --sports 80,443 -m set --match-set zapret src"
fw_nfqws_add_post "--dport 80 -m set --match-set zapret dst"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
create_ipset
fw_nfqws_add_pre "-m multiport --sports 80,443 -m set --match-set zapret src" "-m multiport --sports 80,443 -m set --match-set zapret6 src"
fw_nfqws_add_post "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
nfqws_all)
fw_nfqws_add_pre "--sport 80"
fw_nfqws_add_post "--dport 80"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
fw_nfqws_add_pre "--sport 80" "--sport 80"
fw_nfqws_add_post "--dport 80" "--dport 80"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
nfqws_all_https)
fw_nfqws_add_pre "-m multiport --sports 80,443"
fw_nfqws_add_post "--dport 80"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
fw_nfqws_add_pre "-m multiport --sports 80,443" "-m multiport --sports 80,443"
fw_nfqws_add_post "--dport 80" "--dport 80"
run_daemon 1 $NFQWS "$NFQWS_OPT_BASE $NFQWS_OPT"
;;
ipset)
create_ipset
;;
create_ipset
;;
custom)
# PLACEHOLDER
echo !!! NEED ATTENTION !!!
echo Configure iptables for required actions
echo Start daemon\(s\)
echo Study how other sections work
run_daemon 1 /bin/sleep 20
;;
# PLACEHOLDER
echo !!! NEED ATTENTION !!!
echo Configure iptables for required actions
echo Start daemon\(s\)
echo Study how other sections work
run_daemon 1 /bin/sleep 20
;;
esac
;;
stop)
case "${MODE}" in
tpws_hostlist|tpws_all)
fw_tpws_del "--dport 80" $TPPORT_HTTP
stop_daemon 1 $TPWS
;;
fw_tpws_del "--dport 80" "--dport 80" $TPPORT_HTTP
stop_tpws 1
;;
tpws_ipset)
fw_tpws_del "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP
stop_daemon 1 $TPWS
;;
fw_tpws_del "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst" $TPPORT_HTTP
stop_tpws 1
;;
tpws_ipset_https)
fw_tpws_del "--dport 80 -m set --match-set zapret dst" $TPPORT_HTTP
fw_tpws_del "--dport 443 -m set --match-set zapret dst" $TPPORT_HTTPS
stop_daemon 1 $TPWS
stop_daemon 2 $TPWS
;;
fw_tpws_del "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst" $TPPORT_HTTP
fw_tpws_del "--dport 443 -m set --match-set zapret dst" "--dport 443 -m set --match-set zapret6 dst" $TPPORT_HTTPS
stop_tpws 1
stop_tpws 2
;;
tpws_all_https)
fw_tpws_del "--dport 80" $TPPORT_HTTP
fw_tpws_del "--dport 443" $TPPORT_HTTPS
stop_daemon 1 $TPWS
stop_daemon 2 $TPWS
;;
fw_tpws_del "--dport 80" "--dport 80" $TPPORT_HTTP
fw_tpws_del "--dport 443" "--dport 443" $TPPORT_HTTPS
stop_tpws 1
stop_tpws 2
;;
nfqws_ipset)
fw_nfqws_del_pre "--sport 80 -m set --match-set zapret src"
fw_nfqws_del_post "--dport 80 -m set --match-set zapret dst"
stop_daemon 1 $NFQWS
;;
fw_nfqws_del_pre "--sport 80 -m set --match-set zapret src" "--sport 80 -m set --match-set zapret6 src"
fw_nfqws_del_post "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst"
stop_daemon 1 $NFQWS
;;
nfqws_ipset_https)
fw_nfqws_del_pre "-m multiport --sports 80,443 -m set --match-set zapret src"
fw_nfqws_del_post "--dport 80 -m set --match-set zapret dst"
stop_daemon 1 $NFQWS
;;
fw_nfqws_del_pre "-m multiport --sports 80,443 -m set --match-set zapret src" "-m multiport --sports 80,443 -m set --match-set zapret6 src"
fw_nfqws_del_post "--dport 80 -m set --match-set zapret dst" "--dport 80 -m set --match-set zapret6 dst"
stop_daemon 1 $NFQWS
;;
nfqws_all)
fw_nfqws_del_pre "--sport 80"
fw_nfqws_del_post "--dport 80"
stop_daemon 1 $NFQWS
;;
fw_nfqws_del_pre "--sport 80" "--sport 80"
fw_nfqws_del_post "--dport 80" "--dport 80"
stop_daemon 1 $NFQWS
;;
nfqws_all_https)
fw_nfqws_del_pre "-m multiport --sports 80,443"
fw_nfqws_del_post "--dport 80"
stop_daemon 1 $NFQWS
;;
fw_nfqws_del_pre "-m multiport --sports 80,443" "-m multiport --sports 80,443"
fw_nfqws_del_post "--dport 80" "--dport 80"
stop_daemon 1 $NFQWS
;;
custom)
# PLACEHOLDER
echo !!! NEED ATTENTION !!!
echo Clear firewall rules here. Remove iptables changes made previously.
echo Stop daemon\(s\) previously started.
echo Study how other sections work.
;;
# PLACEHOLDER
echo !!! NEED ATTENTION !!!
echo Clear firewall rules here. Remove iptables changes made previously.
echo Stop daemon\(s\) previously started.
echo Study how other sections work.
;;
esac
;;

View File

@ -348,9 +348,7 @@ download_list()
echo \* downloading blocked ip/host list
# can be txt or txt.gz
rm -f "$EXEDIR/ipset/zapret-ip.txt"* "$EXEDIR/ipset/zapret-ip-user.txt"* \
"$EXEDIR/ipset/zapret-ip-ipban.txt"* "$EXEDIR/ipset/zapret-ip-user-ipban.txt"* \
"$EXEDIR/ipset/zapret-hosts.txt"*
"$EXEDIR/ipset/clear_lists.sh"
"$GET_LIST" || {
echo could not download ip list
exitp 25
@ -437,12 +435,13 @@ check_packages_openwrt()
check_prerequisites_openwrt()
{
echo \* checking prerequisites
local PKGS="iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt ipset curl"
[ "$DISABLE_IPV6" != "1" ] && PKGS="$PKGS kmod-ipt-nat6"
local UPD=0
# in recent lede/openwrt iptable_raw in separate package
if check_kmod iptable_raw && check_packages_openwrt $PKGS ; then
if ([ "$DISABLE_IPV6" = "1" ] || check_kmod ip6table_nat) && check_kmod iptable_raw && check_packages_openwrt $PKGS ; then
echo everything is present
else
echo \* installing prerequisites
@ -488,6 +487,7 @@ check_prerequisites_openwrt()
openwrt_fw_section_find()
{
# $1 - fw include postfix
# echoes section number
i=0
@ -495,9 +495,8 @@ openwrt_fw_section_find()
do
path=$(uci -q get firewall.@include[$i].path)
[ -n "$path" ] || break
[ "$path" == "$OPENWRT_FW_INCLUDE" ] && {
[ "$path" == "$OPENWRT_FW_INCLUDE$1" ] && {
echo $i
true
return
}
i=$(($i+1))
@ -507,27 +506,30 @@ openwrt_fw_section_find()
}
openwrt_fw_section_add()
{
# $1 - fw include postfix
# echoes section number
openwrt_fw_section_find ||
openwrt_fw_section_find $1 ||
{
uci add firewall include >/dev/null || return
echo -1
true
}
}
openwrt_fw_section_del()
{
local id=$(openwrt_fw_section_find)
# $1 - fw include postfix
local id=$(openwrt_fw_section_find $1)
[ -n "$id" ] && {
uci delete firewall.@include[$id] && uci commit firewall
rm -f "$OPENWRT_FW_INCLUDE$1"
}
}
openwrt_fw_section_configure()
{
local id=$(openwrt_fw_section_add)
# $1 - fw include postfix
local id=$(openwrt_fw_section_add $1)
[ -z "$id" ] ||
! uci set firewall.@include[$id].path="$OPENWRT_FW_INCLUDE" ||
! uci set firewall.@include[$id].path="$OPENWRT_FW_INCLUDE$1" ||
! uci set firewall.@include[$id].reload="1" ||
! uci commit firewall &&
{
@ -538,24 +540,39 @@ openwrt_fw_section_configure()
install_openwrt_firewall()
{
echo \* installing firewall script
# $1 - fw include postfix
echo \* installing firewall script $1
[ -n "MODE" ] || {
echo should specify MODE in $ZAPRET_CONFIG
exitp 7
}
local FW_SCRIPT_SRC="$FW_SCRIPT_SRC_DIR.$MODE"
local FW_SCRIPT_SRC="$FW_SCRIPT_SRC_DIR.$MODE$1"
[ -f "$FW_SCRIPT_SRC" ] || {
echo firewall script $FW_SCRIPT_SRC not found. removing firewall include
openwrt_fw_section_del
rm -f "$OPENWRT_FW_INCLUDE"
return
}
echo "linking : $FW_SCRIPT_SRC => $OPENWRT_FW_INCLUDE"
ln -fs "$FW_SCRIPT_SRC" "$OPENWRT_FW_INCLUDE"
echo "linking : $FW_SCRIPT_SRC => $OPENWRT_FW_INCLUDE$1"
ln -fs "$FW_SCRIPT_SRC" "$OPENWRT_FW_INCLUDE$1"
openwrt_fw_section_configure
openwrt_fw_section_configure $1
}
install_openwrt_firewall_all()
{
if [ "$DISABLE_IPV4" = "1" ] ; then
openwrt_fw_section_del
else
install_openwrt_firewall
fi
if [ "$DISABLE_IPV6" = "1" ] ; then
openwrt_fw_section_del 6
else
install_openwrt_firewall 6
fi
}
restart_openwrt_firewall()
@ -568,6 +585,14 @@ restart_openwrt_firewall()
}
}
remove_openwrt_firewall()
{
echo \* removing firewall script
openwrt_fw_section_del
openwrt_fw_section_del 6
}
install_sysv_init()
{
echo \* installing init script
@ -600,11 +625,14 @@ install_openwrt()
install_binaries
ask_config
install_sysv_init
# can be previous firewall preventing access
remove_openwrt_firewall
restart_openwrt_firewall
download_list
# router system : works 24/7. night is the best time
crontab_add 0 6
service_start_sysv
install_openwrt_firewall
install_openwrt_firewall_all
restart_openwrt_firewall
}

8
ipset/clear_lists.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
SCRIPT=$(readlink -f "$0")
EXEDIR=$(dirname "$SCRIPT")
. "$EXEDIR/def.sh"
rm -f "$ZIPLIST"* "$ZIPLIST6"* "$ZIPLIST_USER" "$ZIPLIST_USER6" "$ZIPLIST_IPBAN"* "$ZIPLIST_IPBAN6"* "$ZIPLIST_USER_IPBAN" "$ZIPLIST_USER_IPBAN6" "$ZHOSTLIST"*

View File

@ -23,15 +23,15 @@ do
zzexist "$f" && {
if [ -x "$IP2NET" ]; then
echo Adding to ipset $2 \($IPSTYPE , ip2net\) : $f
if [ -f "$ZIPLIST_EXCLUDE" ] ; then
zzcat "$f" | grep -vxFf "$ZIPLIST_EXCLUDE" | "$IP2NET" | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
if [ -f "$5" ] ; then
zzcat "$f" | grep -vxFf "$5" | "$IP2NET" | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
else
zzcat "$f" | "$IP2NET" | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
fi
else
echo Adding to ipset $2 \($IPSTYPE\) : $f
if [ -f "$ZIPLIST_EXCLUDE" ] ; then
zzcat "$f" | grep -vxFf "$ZIPLIST_EXCLUDE" | sort -u | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
if [ -f "$5" ] ; then
zzcat "$f" | grep -vxFf "$5" | sort -u | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
else
zzcat "$f" | sort -u | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
fi
@ -41,5 +41,32 @@ done
return 0
}
create_ipset hash:ip $ZIPSET "$ZIPLIST" "$ZIPLIST_USER"
create_ipset hash:ip $ZIPSET_IPBAN "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN"
create_ipset6()
{
local IPSTYPE=$1
ipset flush $2 2>/dev/null || ipset create $2 $IPSTYPE $IPSET_OPT family inet6
for f in "$3" "$4"
do
zzexist "$f" && {
echo Adding to ipset $2 \($IPSTYPE\) : $f
if [ -f "$5" ] ; then
zzcat "$f" | grep -vxFf "$5" | sort -u | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
else
zzcat "$f" | sort -u | sed -nre "s/^.+$/add $2 &/p" | ipset -! restore
fi
}
done
return 0
}
[ "$DISABLE_IPV4" != "1" ] && {
create_ipset hash:ip $ZIPSET "$ZIPLIST" "$ZIPLIST_USER" "$ZIPLIST_EXCLUDE"
create_ipset hash:ip $ZIPSET_IPBAN "$ZIPLIST_IPBAN" "$ZIPLIST_USER_IPBAN" "$ZIPLIST_EXCLUDE"
}
[ "$DISABLE_IPV6" != "1" ] && {
create_ipset6 hash:ip $ZIPSET6 "$ZIPLIST6" "$ZIPLIST_USER6" "$ZIPLIST_EXCLUDE6"
create_ipset6 hash:ip $ZIPSET_IPBAN6 "$ZIPLIST_IPBAN6" "$ZIPLIST_USER_IPBAN6" "$ZIPLIST_EXCLUDE6"
}
true

View File

@ -1,14 +1,23 @@
. "$EXEDIR/../config"
TMPDIR=/tmp
ZIPSET=zapret
ZIPSET6=zapret6
ZIPLIST=$EXEDIR/zapret-ip.txt
ZIPLIST6=$EXEDIR/zapret-ip6.txt
ZIPLIST_EXCLUDE=$EXEDIR/zapret-ip-exclude.txt
ZIPLIST_EXCLUDE6=$EXEDIR/zapret-ip-exclude6.txt
ZIPLIST_USER=$EXEDIR/zapret-ip-user.txt
ZIPLIST_USER6=$EXEDIR/zapret-ip-user6.txt
ZUSERLIST=$EXEDIR/zapret-hosts-user.txt
ZHOSTLIST=$EXEDIR/zapret-hosts.txt
ZIPSET_IPBAN=ipban
ZIPSET_IPBAN6=ipban6
ZIPLIST_IPBAN=$EXEDIR/zapret-ip-ipban.txt
ZIPLIST_IPBAN6=$EXEDIR/zapret-ip-ipban6.txt
ZIPLIST_USER_IPBAN=$EXEDIR/zapret-ip-user-ipban.txt
ZIPLIST_USER_IPBAN6=$EXEDIR/zapret-ip-user-ipban6.txt
ZUSERLIST_IPBAN=$EXEDIR/zapret-hosts-user-ipban.txt
MDIG=$EXEDIR/../mdig/mdig
@ -33,30 +42,38 @@ zz()
digger()
{
>&2 echo digging "$1" : domains=$(wc -l <"$1")
# $1 - hostlist
# $2 - family (4|6)
>&2 echo digging $(wc -l <"$1") ipv$2 domains : "$1"
if [ -x "$MDIG" ]; then
zzcat "$1" | "$MDIG" --family=4 --threads=$MDIG_THREADS --stats=1000
zzcat "$1" | "$MDIG" --family=$2 --threads=$MDIG_THREADS --stats=1000
else
zzcat "$1" | dig A +short +time=8 +tries=2 -f - | grep -E '^[^;].*[^\.]$'
local A=A
[ "$2" = "6" ] && A=AAAA
zzcat "$1" | dig $A +short +time=8 +tries=2 -f - | grep -E '^[^;].*[^\.]$'
fi
}
cut_local()
{
grep -vE '^192\.168\.[0-9]+\.[0-9]+$' |
grep -vE '^127\.[0-9]+\.[0-9]+\.[0-9]+$' |
grep -vE '^10\.[0-9]+\.[0-9]+\.[0-9]+$'
grep -vE '^192\.168\.|^127\.|^10\.'
}
cut_local6()
{
grep -vE '^::|fc..:|fd..:'
}
getuser()
{
[ -f "$ZUSERLIST" ] && {
digger "$ZUSERLIST" | cut_local | sort -u > "$ZIPLIST_USER"
[ "$DISABLE_IPV4" != "1" ] && digger "$ZUSERLIST" 4 | cut_local | sort -u > "$ZIPLIST_USER"
[ "$DISABLE_IPV6" != "1" ] && digger "$ZUSERLIST" 6 | cut_local6 | sort -u > "$ZIPLIST_USER6"
}
[ -f "$ZUSERLIST_IPBAN" ] && {
digger "$ZUSERLIST_IPBAN" | cut_local | sort -u > "$ZIPLIST_USER_IPBAN"
[ "$DISABLE_IPV4" != "1" ] && digger "$ZUSERLIST_IPBAN" 4 | cut_local | sort -u > "$ZIPLIST_USER_IPBAN"
[ "$DISABLE_IPV6" != "1" ] && digger "$ZUSERLIST_IPBAN" 6 | cut_local6 | sort -u > "$ZIPLIST_USER_IPBAN6"
}
}

View File

@ -14,6 +14,9 @@ ZURL=https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv
getuser
# both disabled
[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && exit 0
curl -k --fail --max-time 150 --connect-timeout 5 --retry 3 --max-filesize 62914560 "$ZURL" >"$ZREESTR" ||
{
echo reestr list download failed
@ -29,12 +32,24 @@ echo preparing dig list ..
#sed -nre 's/^[^;]*;([^;|\\]{4,250})\;.*$/\1/p' $ZREESTR | sort | uniq >$ZDIG
cut -f2 -d ';' "$ZREESTR" | grep -avE '^$|\*|:' >"$ZDIG"
rm -f "$ZREESTR"
echo digging started. this can take long ...
digger "$ZDIG" | cut_local >"$ZIPLISTTMP" || {
rm -f "$ZDIG"
exit 1
[ "$DISABLE_IPV4" != "1" ] && {
digger "$ZDIG" 4 | cut_local >"$ZIPLISTTMP" || {
rm -f "$ZDIG"
exit 1
}
sort -u "$ZIPLISTTMP" | zz "$ZIPLIST"
rm -f "$ZIPLISTTMP"
}
[ "$DISABLE_IPV6" != "1" ] && {
digger "$ZDIG" 6 | cut_local6 >"$ZIPLISTTMP" || {
rm -f "$ZDIG"
exit 1
}
sort -u "$ZIPLISTTMP" | zz "$ZIPLIST6"
rm -f "$ZIPLISTTMP"
}
rm -f "$ZDIG"
sort -u "$ZIPLISTTMP" | zz "$ZIPLIST"
rm -f "$ZIPLISTTMP"
"$EXEDIR/create_ipset.sh"

View File

@ -72,7 +72,7 @@ bool LoadHostList(strpool **hostlist, char *filename)
}
else
{
printf("loading plain text list\n",r);
printf("loading plain text list\n");
while (fgets(s, 256, F))
{

View File

@ -5,6 +5,8 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
@ -30,7 +32,8 @@ enum splithttpreq { split_none = 0, split_method, split_host };
struct params_s
{
char bindaddr[64];
char bindaddr[64],bindiface4[16],bindiface6[16];
bool bindll,bindll_force;
uid_t uid;
gid_t gid;
uint16_t port;
@ -502,6 +505,9 @@ void exithelp()
{
printf(
" --bind-addr=<ipv4_addr>|<ipv6_addr>\n"
" --bind-iface4=<interface_name>\t; bind to the first ipv4 addr of interface\n"
" --bind-iface6=<interface_name>\t; bind to the first ipv6 addr of interface\n"
" --bind-linklocal=prefer|force\t; prefer or force ipv6 link local\n"
" --port=<port>\n"
" --maxconn=<max_connections>\n"
" --hostlist=<filename>\t; only act on host in the list (one host per line, subdomains auto apply)\n"
@ -552,22 +558,25 @@ void parse_params(int argc, char *argv[])
{ "help",no_argument,0,0 },// optidx=0
{ "h",no_argument,0,0 },// optidx=1
{ "bind-addr",required_argument,0,0 },// optidx=2
{ "port",required_argument,0,0 },// optidx=3
{ "daemon",no_argument,0,0 },// optidx=4
{ "user",required_argument,0,0 },// optidx=5
{ "maxconn",required_argument,0,0 },// optidx=6
{ "hostcase",no_argument,0,0 },// optidx=7
{ "hostspell",required_argument,0,0 },// optidx=8
{ "hostdot",no_argument,0,0 },// optidx=9
{ "hostnospace",no_argument,0,0 },// optidx=10
{ "split-http-req",required_argument,0,0 },// optidx=11
{ "split-pos",required_argument,0,0 },// optidx=12
{ "methodspace",no_argument,0,0 },// optidx=13
{ "methodeol",no_argument,0,0 },// optidx=14
{ "hosttab",no_argument,0,0 },// optidx=15
{ "unixeol",no_argument,0,0 },// optidx=16
{ "hostlist",required_argument,0,0 },// optidx=17
{ "pidfile",required_argument,0,0 },// optidx=18
{ "bind-iface4",required_argument,0,0 },// optidx=3
{ "bind-iface6",required_argument,0,0 },// optidx=4
{ "bind-linklocal",required_argument,0,0 },// optidx=5
{ "port",required_argument,0,0 },// optidx=6
{ "daemon",no_argument,0,0 },// optidx=7
{ "user",required_argument,0,0 },// optidx=8
{ "maxconn",required_argument,0,0 },// optidx=9
{ "hostcase",no_argument,0,0 },// optidx=10
{ "hostspell",required_argument,0,0 },// optidx=11
{ "hostdot",no_argument,0,0 },// optidx=12
{ "hostnospace",no_argument,0,0 },// optidx=13
{ "split-http-req",required_argument,0,0 },// optidx=14
{ "split-pos",required_argument,0,0 },// optidx=15
{ "methodspace",no_argument,0,0 },// optidx=16
{ "methodeol",no_argument,0,0 },// optidx=17
{ "hosttab",no_argument,0,0 },// optidx=18
{ "unixeol",no_argument,0,0 },// optidx=19
{ "hostlist",required_argument,0,0 },// optidx=20
{ "pidfile",required_argument,0,0 },// optidx=21
{ NULL,0,NULL,0 }
};
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
@ -583,7 +592,35 @@ void parse_params(int argc, char *argv[])
strncpy(params.bindaddr, optarg, sizeof(params.bindaddr));
params.bindaddr[sizeof(params.bindaddr) - 1] = 0;
break;
case 3: /* qnum */
case 3: /* bind-iface4 */
if (*params.bindiface6)
{
fprintf(stderr, "can bind only to single ip address\n");
exit_clean(1);
}
strncpy(params.bindiface4, optarg, sizeof(params.bindiface4));
params.bindiface4[sizeof(params.bindiface4) - 1] = 0;
break;
case 4: /* bind-iface6 */
if (*params.bindiface4)
{
fprintf(stderr, "can bind only to single ip address\n");
exit_clean(1);
}
strncpy(params.bindiface6, optarg, sizeof(params.bindiface6));
params.bindiface6[sizeof(params.bindiface6) - 1] = 0;
break;
case 5: /* bind-linklocal */
params.bindll = true;
if (!strcmp(optarg, "force"))
params.bindll_force=true;
else if (strcmp(optarg, "prefer"))
{
fprintf(stderr, "invalid parameter in bind-linklocal : %s\n",optarg);
exit_clean(1);
}
break;
case 6: /* port */
i = atoi(optarg);
if (i <= 0 || i > 65535)
{
@ -592,10 +629,10 @@ void parse_params(int argc, char *argv[])
}
params.port = (uint16_t)i;
break;
case 4: /* daemon */
case 7: /* daemon */
params.daemon = true;
break;
case 5: /* user */
case 8: /* user */
{
struct passwd *pwd = getpwnam(optarg);
if (!pwd)
@ -607,7 +644,7 @@ void parse_params(int argc, char *argv[])
params.gid = pwd->pw_gid;
break;
}
case 6: /* maxconn */
case 9: /* maxconn */
params.maxconn = atoi(optarg);
if (params.maxconn <= 0)
{
@ -615,10 +652,10 @@ void parse_params(int argc, char *argv[])
exit_clean(1);
}
break;
case 7: /* hostcase */
case 10: /* hostcase */
params.hostcase = true;
break;
case 8: /* hostspell */
case 11: /* hostspell */
if (strlen(optarg) != 4)
{
fprintf(stderr, "hostspell must be exactly 4 chars long\n");
@ -627,13 +664,13 @@ void parse_params(int argc, char *argv[])
params.hostcase = true;
memcpy(params.hostspell, optarg, 4);
break;
case 9: /* hostdot */
case 12: /* hostdot */
params.hostdot = true;
break;
case 10: /* hostnospace */
case 13: /* hostnospace */
params.hostnospace = true;
break;
case 11: /* split-http-req */
case 14: /* split-http-req */
if (!strcmp(optarg, "method"))
params.split_http_req = split_method;
else if (!strcmp(optarg, "host"))
@ -644,7 +681,7 @@ void parse_params(int argc, char *argv[])
exit_clean(1);
}
break;
case 12: /* split-pos */
case 15: /* split-pos */
i = atoi(optarg);
if (i)
params.split_pos = i;
@ -654,25 +691,25 @@ void parse_params(int argc, char *argv[])
exit_clean(1);
}
break;
case 13: /* methodspace */
case 16: /* methodspace */
params.methodspace = true;
break;
case 14: /* methodeol */
case 17: /* methodeol */
params.methodeol = true;
break;
case 15: /* hosttab */
case 18: /* hosttab */
params.hosttab = true;
break;
case 16: /* unixeol */
case 19: /* unixeol */
params.unixeol = true;
break;
case 17: /* hostlist */
case 20: /* hostlist */
if (!LoadHostList(&params.hostlist, optarg))
exit_clean(1);
strncpy(params.hostfile,optarg,sizeof(params.hostfile));
params.hostfile[sizeof(params.hostfile)-1]='\0';
break;
case 18: /* pidfile */
case 21: /* pidfile */
strncpy(params.pidfile,optarg,sizeof(params.pidfile));
params.pidfile[sizeof(params.pidfile)-1]='\0';
break;
@ -748,24 +785,37 @@ int main(int argc, char *argv[]) {
int r;
struct sockaddr_storage salisten;
socklen_t salisten_len;
int ipv6_only;
int ipv6_only=0,if_index6=0;
parse_params(argc, argv);
memset(&salisten, 0, sizeof(salisten));
if (*params.bindiface4)
{
if (!if_nametoindex(params.bindiface4))
{
printf("bad iface %s\n",params.bindiface4);
goto exiterr;
}
}
if (*params.bindiface6)
{
if_index6 = if_nametoindex(params.bindiface6);
if (!if_index6)
{
printf("bad iface %s\n",params.bindiface6);
goto exiterr;
}
}
if (*params.bindaddr)
{
if (inet_pton(AF_INET, params.bindaddr, &((struct sockaddr_in*)&salisten)->sin_addr))
{
salisten.ss_family = AF_INET;
((struct sockaddr_in*)&salisten)->sin_port = htons(params.port);
salisten_len = sizeof(struct sockaddr_in);
}
else if (inet_pton(AF_INET6, params.bindaddr, &((struct sockaddr_in6*)&salisten)->sin6_addr))
{
salisten.ss_family = AF_INET6;
((struct sockaddr_in6*)&salisten)->sin6_port = htons(params.port);
salisten_len = sizeof(struct sockaddr_in6);
ipv6_only = 1;
}
else
@ -776,11 +826,83 @@ int main(int argc, char *argv[]) {
}
else
{
salisten.ss_family = AF_INET6;
((struct sockaddr_in6*)&salisten)->sin6_port = htons(params.port);
if (*params.bindiface4 || *params.bindiface6 || params.bindll)
{
struct ifaddrs *addrs,*a;
bool found=0;
if (getifaddrs(&addrs)<0)
{
printf("getifaddrs failed\n");
goto exiterr;
}
for (;;)
{
a = addrs;
while (a)
{
if (a->ifa_addr)
{
if (a->ifa_addr->sa_family==AF_INET &&
*params.bindiface4 && !strcmp(a->ifa_name, params.bindiface4))
{
salisten.ss_family = AF_INET;
memcpy(&((struct sockaddr_in*)&salisten)->sin_addr, &((struct sockaddr_in*)a->ifa_addr)->sin_addr, sizeof(struct in_addr));
found=1;
break;
}
// ipv6 links locals are fe80::/10
else if (a->ifa_addr->sa_family==AF_INET6
&&
(!*params.bindiface6 && params.bindll ||
*params.bindiface6 && !strcmp(a->ifa_name, params.bindiface6))
&&
(!params.bindll ||
((struct sockaddr_in6*)a->ifa_addr)->sin6_addr.s6_addr[0]==0xFE &&
(((struct sockaddr_in6*)a->ifa_addr)->sin6_addr.s6_addr[1] & 0xC0)==0x80))
{
salisten.ss_family = AF_INET6;
memcpy(&((struct sockaddr_in6*)&salisten)->sin6_addr, &((struct sockaddr_in6*)a->ifa_addr)->sin6_addr, sizeof(struct in6_addr));
if_index6 = if_nametoindex(a->ifa_name);
ipv6_only = 1;
found=1;
break;
}
}
a = a->ifa_next;
}
if (!found && params.bindll && !params.bindll_force)
{
params.bindll=false;
// give it another try without bindll
continue;
}
break;
}
freeifaddrs(addrs);
if (!found)
{
printf("suitable ip address not found\n");
goto exiterr;
}
}
else
{
salisten.ss_family = AF_INET6;
// leave sin6_addr zero
}
}
if (salisten.ss_family == AF_INET6)
{
salisten_len = sizeof(struct sockaddr_in6);
ipv6_only = 0;
// leave sin6_addr zero
((struct sockaddr_in6*)&salisten)->sin6_port = htons(params.port);
((struct sockaddr_in6*)&salisten)->sin6_scope_id = if_index6;
}
else
{
salisten_len = sizeof(struct sockaddr_in);
((struct sockaddr_in*)&salisten)->sin_port = htons(params.port);
}
if (params.daemon) daemonize();

View File

@ -125,6 +125,7 @@ remove_systemd()
openwrt_fw_section_find()
{
# $1 - fw include postfix
# echoes section number
i=0
@ -132,9 +133,8 @@ openwrt_fw_section_find()
do
path=$(uci -q get firewall.@include[$i].path)
[ -n "$path" ] || break
[ "$path" == "$OPENWRT_FW_INCLUDE" ] && {
[ "$path" == "$OPENWRT_FW_INCLUDE$1" ] && {
echo $i
true
return
}
i=$(($i+1))
@ -144,9 +144,12 @@ openwrt_fw_section_find()
}
openwrt_fw_section_del()
{
local id=$(openwrt_fw_section_find)
# $1 - fw include postfix
local id=$(openwrt_fw_section_find $1)
[ -n "$id" ] && {
uci delete firewall.@include[$id] && uci commit firewall
rm -f "$OPENWRT_FW_INCLUDE$1"
}
}
@ -155,7 +158,7 @@ remove_openwrt_firewall()
echo \* removing firewall script
openwrt_fw_section_del
rm -f "$OPENWRT_FW_INCLUDE"
openwrt_fw_section_del 6
}
restart_openwrt_firewall()