diff --git a/binaries/aarch64/tpws b/binaries/aarch64/tpws index ab1076f..1acea76 100755 Binary files a/binaries/aarch64/tpws and b/binaries/aarch64/tpws differ diff --git a/binaries/armhf/tpws b/binaries/armhf/tpws index 83fcf79..8c29627 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 dc4d710..b2d7d85 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 50e3f4d..7c60745 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 9e7eea4..c755c80 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 3e97936..27976d9 100755 Binary files a/binaries/ppc/tpws and b/binaries/ppc/tpws differ diff --git a/binaries/x86/tpws b/binaries/x86/tpws index a227aa9..7259428 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 c6a02b8..414c673 100755 Binary files a/binaries/x86_64/tpws and b/binaries/x86_64/tpws differ diff --git a/config b/config index dd01b8c..d92a0c8 100644 --- a/config +++ b/config @@ -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 diff --git a/docs/changes.txt b/docs/changes.txt index 731a36b..3480174 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -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 diff --git a/docs/readme.txt b/docs/readme.txt index d4a7446..703cd8d 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -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= ; сохранить PID в файл --user= ; менять 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= ; слушать на первом ipv4 интерфейса iface + --bind-iface6= ; слушать на первом ipv6 интерфейса iface. при bind-linklocal определяет интерфейс, откуда брать ipv6 link local --port= ; на каком порту слушать --split-http-req=method|host ; способ разделения http запросов на сегменты : около метода (GET,POST) или около заголовка Host --split-pos= ; делить все посылы на сегменты в указанной позиции. Если отсыл длинее 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. diff --git a/init.d/openwrt/firewall.zapret.nfqws_all b/init.d/openwrt/firewall.zapret.nfqws_all index fb6b9e1..77d7eb6 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_all +++ b/init.d/openwrt/firewall.zapret.nfqws_all @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_all6 b/init.d/openwrt/firewall.zapret.nfqws_all6 new file mode 100644 index 0000000..f39f23f --- /dev/null +++ b/init.d/openwrt/firewall.zapret.nfqws_all6 @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_all_https b/init.d/openwrt/firewall.zapret.nfqws_all_https index dde6af5..5885faf 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_all_https +++ b/init.d/openwrt/firewall.zapret.nfqws_all_https @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_all_https6 b/init.d/openwrt/firewall.zapret.nfqws_all_https6 new file mode 100644 index 0000000..b328e6e --- /dev/null +++ b/init.d/openwrt/firewall.zapret.nfqws_all_https6 @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset b/init.d/openwrt/firewall.zapret.nfqws_ipset index 6490554..81acb4b 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_ipset +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset6 b/init.d/openwrt/firewall.zapret.nfqws_ipset6 new file mode 100644 index 0000000..620193e --- /dev/null +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset6 @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset_https b/init.d/openwrt/firewall.zapret.nfqws_ipset_https index 32aac5c..4a7e911 100644 --- a/init.d/openwrt/firewall.zapret.nfqws_ipset_https +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset_https @@ -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 diff --git a/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 b/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 new file mode 100644 index 0000000..c9fd160 --- /dev/null +++ b/init.d/openwrt/firewall.zapret.nfqws_ipset_https6 @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_all b/init.d/openwrt/firewall.zapret.tpws_all index b524459..0edd8c4 100644 --- a/init.d/openwrt/firewall.zapret.tpws_all +++ b/init.d/openwrt/firewall.zapret.tpws_all @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_all6 b/init.d/openwrt/firewall.zapret.tpws_all6 new file mode 100644 index 0000000..7779a64 --- /dev/null +++ b/init.d/openwrt/firewall.zapret.tpws_all6 @@ -0,0 +1,5 @@ +IPT_FILTER_HTTP="-p tcp --dport 80" + +. /opt/zapret/init.d/openwrt/functions + +fw_tpws6 diff --git a/init.d/openwrt/firewall.zapret.tpws_all_https b/init.d/openwrt/firewall.zapret.tpws_all_https index dd7154d..8e52c53 100644 --- a/init.d/openwrt/firewall.zapret.tpws_all_https +++ b/init.d/openwrt/firewall.zapret.tpws_all_https @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_all_https6 b/init.d/openwrt/firewall.zapret.tpws_all_https6 new file mode 100644 index 0000000..f4cf816 --- /dev/null +++ b/init.d/openwrt/firewall.zapret.tpws_all_https6 @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_hostlist6 b/init.d/openwrt/firewall.zapret.tpws_hostlist6 new file mode 120000 index 0000000..4ce5a8a --- /dev/null +++ b/init.d/openwrt/firewall.zapret.tpws_hostlist6 @@ -0,0 +1 @@ +firewall.zapret.tpws_all6 \ No newline at end of file diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset b/init.d/openwrt/firewall.zapret.tpws_ipset index 3d60618..17703e4 100644 --- a/init.d/openwrt/firewall.zapret.tpws_ipset +++ b/init.d/openwrt/firewall.zapret.tpws_ipset @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset6 b/init.d/openwrt/firewall.zapret.tpws_ipset6 new file mode 100644 index 0000000..73717bf --- /dev/null +++ b/init.d/openwrt/firewall.zapret.tpws_ipset6 @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset_https b/init.d/openwrt/firewall.zapret.tpws_ipset_https index 1aa3746..1b369fa 100644 --- a/init.d/openwrt/firewall.zapret.tpws_ipset_https +++ b/init.d/openwrt/firewall.zapret.tpws_ipset_https @@ -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 diff --git a/init.d/openwrt/firewall.zapret.tpws_ipset_https6 b/init.d/openwrt/firewall.zapret.tpws_ipset_https6 new file mode 100644 index 0000000..331e441 --- /dev/null +++ b/init.d/openwrt/firewall.zapret.tpws_ipset_https6 @@ -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 diff --git a/init.d/openwrt/functions b/init.d/openwrt/functions new file mode 100644 index 0000000..a8e61d4 --- /dev/null +++ b/init.d/openwrt/functions @@ -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 +} diff --git a/init.d/openwrt/zapret b/init.d/openwrt/zapret index c96de3d..4722a9f 100755 --- a/init.d/openwrt/zapret +++ b/init.d/openwrt/zapret @@ -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 } diff --git a/init.d/sysv/zapret b/init.d/sysv/zapret index a2846d3..94cab07 100755 --- a/init.d/sysv/zapret +++ b/init.d/sysv/zapret @@ -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 ;; diff --git a/install_easy.sh b/install_easy.sh index 35e5490..0d012eb 100755 --- a/install_easy.sh +++ b/install_easy.sh @@ -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 } diff --git a/ipset/clear_lists.sh b/ipset/clear_lists.sh new file mode 100755 index 0000000..07fab84 --- /dev/null +++ b/ipset/clear_lists.sh @@ -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"* diff --git a/ipset/create_ipset.sh b/ipset/create_ipset.sh index 950138c..2a2e4b0 100755 --- a/ipset/create_ipset.sh +++ b/ipset/create_ipset.sh @@ -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 diff --git a/ipset/def.sh b/ipset/def.sh index f9083c5..3f63197 100755 --- a/ipset/def.sh +++ b/ipset/def.sh @@ -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" } } diff --git a/ipset/get_reestr.sh b/ipset/get_reestr.sh index b62b9a8..6178c97 100755 --- a/ipset/get_reestr.sh +++ b/ipset/get_reestr.sh @@ -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" diff --git a/tpws/hostlist.c b/tpws/hostlist.c index 33fac9a..cbf979c 100644 --- a/tpws/hostlist.c +++ b/tpws/hostlist.c @@ -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)) { diff --git a/tpws/tpws.c b/tpws/tpws.c index 8bd7095..e0268e6 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -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=|\n" + " --bind-iface4=\t; bind to the first ipv4 addr of interface\n" + " --bind-iface6=\t; bind to the first ipv6 addr of interface\n" + " --bind-linklocal=prefer|force\t; prefer or force ipv6 link local\n" " --port=\n" " --maxconn=\n" " --hostlist=\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(¶ms.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(); diff --git a/uninstall_easy.sh b/uninstall_easy.sh index 39d5ec9..25924bd 100755 --- a/uninstall_easy.sh +++ b/uninstall_easy.sh @@ -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()