diff --git a/lang/perl-ack/Makefile b/lang/perl-ack/Makefile index 6fee0c87e..fc8202109 100644 --- a/lang/perl-ack/Makefile +++ b/lang/perl-ack/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=perl-ack -PKG_VERSION:=3.6.0 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=3.7.0 +PKG_RELEASE:=1 PKG_SOURCE_URL:=http://www.cpan.org/authors/id/P/PE/PETDANCE/ PKG_SOURCE:=ack-v$(PKG_VERSION).tar.gz -PKG_HASH:=03144d1070649e92f6a1b7d20bdc535e2bb1ac258daabe482e9aa8277b48f005 +PKG_HASH:=ea7caa14f757de083310ed2cba298661ddcca5dee06ec8f18043ea625a79df20 PKG_LICENSE:=Artistic-2.0 PKG_LICENSE_FILE:=LICENSE.md diff --git a/libs/tiff/Makefile b/libs/tiff/Makefile index 3b65ca7c1..39d705232 100644 --- a/libs/tiff/Makefile +++ b/libs/tiff/Makefile @@ -64,7 +64,8 @@ CMAKE_OPTIONS += \ -Dzstd=OFF \ -Dwebp=OFF \ -Djpeg12=OFF \ - -Dcxx=OFF + -Dcxx=OFF \ + -Dlibdeflate=OFF define Build/InstallDev $(call Build/InstallDev/cmake,$(1)) diff --git a/multimedia/yt-dlp/Makefile b/multimedia/yt-dlp/Makefile index ee8e7adc3..1ec3ebaed 100644 --- a/multimedia/yt-dlp/Makefile +++ b/multimedia/yt-dlp/Makefile @@ -1,11 +1,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=yt-dlp -PKG_VERSION:=2023.1.6 +PKG_VERSION:=2023.3.4 PKG_RELEASE:=1 PYPI_NAME:=yt-dlp -PKG_HASH:=3a783a36751ced16368f40b3ba865ab39b30689ed8056f1ee2346aa3839a0b0f +PKG_HASH:=265d5da97a76c15d7d9a4088a67b78acd5dcf6f8cfd8257c52f581ff996ff515 PKG_MAINTAINER:=Michal Vasilek PKG_LICENSE:=Unlicense diff --git a/net/adguardhome/Makefile b/net/adguardhome/Makefile index 309ffec6c..328c1329e 100644 --- a/net/adguardhome/Makefile +++ b/net/adguardhome/Makefile @@ -6,13 +6,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=adguardhome -PKG_VERSION:=0.107.24 +PKG_VERSION:=0.107.25 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_VERSION:=v$(PKG_VERSION) PKG_SOURCE_URL:=https://github.com/AdguardTeam/AdGuardHome -PKG_MIRROR_HASH:=ff5e38d977b8c8f5a546b745ab46894dd4b55f76b447b147287b47d03f6cd507 +PKG_MIRROR_HASH:=609e991f0d03c1541e02fc656f8abea686e64ed350729b85ea87fe25640dd03a PKG_LICENSE:=GPL-3.0-only PKG_LICENSE_FILES:=LICENSE.txt @@ -56,7 +56,7 @@ endef define Build/Compile ( \ pushd $(PKG_BUILD_DIR) ; \ - make js-deps js-build ; \ + NODE_OPTIONS=--openssl-legacy-provider make js-deps js-build ; \ popd ; \ $(call GoPackage/Build/Compile) ; \ ) diff --git a/net/banip/Makefile b/net/banip/Makefile index 1979ede35..be9a6aa03 100644 --- a/net/banip/Makefile +++ b/net/banip/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=banip -PKG_VERSION:=0.8.1 -PKG_RELEASE:=3 +PKG_VERSION:=0.8.2 +PKG_RELEASE:=1 PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Dirk Brenken diff --git a/net/banip/files/README.md b/net/banip/files/README.md index 45d2f4839..56c517a4f 100644 --- a/net/banip/files/README.md +++ b/net/banip/files/README.md @@ -112,7 +112,8 @@ Available commands: disable Disable service autostart enabled Check if service is started on boot report [text|json|mail] Print banIP related set statistics - search [|] Check if an element exists in the banIP sets + search [|] Check if an element exists in a banIP set + survey [] List all elements of a given banIP set running Check if service is running status Service status trace Start with syscall trace @@ -165,6 +166,7 @@ Available commands: | ban_mailsender | option | no-reply@banIP | sender address for banIP related notification E-Mails | | ban_mailtopic | option | banIP notification | topic for banIP related notification E-Mails | | ban_mailprofile | option | ban_notify | mail profile used in 'msmtp' for banIP related notification E-Mails | +| ban_reportelements | option | 1 | list set elements in the report, disable this to speed up the report significantly | | ban_resolver | option | - | external resolver used for DNS lookups | ## Examples @@ -220,7 +222,7 @@ Available commands: ~# /etc/init.d/banip status ::: banIP runtime information + status : active (nft: ✔, monitor: ✔) - + version : 0.8.1-3 + + version : 0.8.2-1 + element_count : 180596 + active_feeds : allowlistvMAC, allowlistv4, allowlistv6, adawayv4, adawayv6, adguardv4, cinsscorev4, adguardv6, countryv6, countryv4, deblv4, deblv6, dohv4, dohv6, firehol1v4, oisdsmallv6, oisdsmallv4, urlvirv4, webclientv4, blocklistvMAC, blocklistv4, @@ -270,6 +272,14 @@ Available commands: 1.15.77.237 [...] ``` +**default regex for logfile parsing** +``` +list ban_logterm 'Exit before auth from' +list ban_logterm 'luci: failed login' +list ban_logterm 'error: maximum authentication attempts exceeded' +list ban_logterm 'sshd.*Connection closed by.*\[preauth\]' +list ban_logterm 'SecurityEvent=\"InvalidAccountID\".*RemoteAddress=' +``` **allow-/blocklist handling** banIP supports local allow and block lists (IPv4, IPv6, CIDR notation or domain names), located in /etc/banip/banip.allowlist and /etc/banip/banip.blocklist. diff --git a/net/banip/files/banip-functions.sh b/net/banip/files/banip-functions.sh index a45a0c260..8ed8a2c9e 100644 --- a/net/banip/files/banip-functions.sh +++ b/net/banip/files/banip-functions.sh @@ -34,6 +34,7 @@ ban_mailsender="no-reply@banIP" ban_mailreceiver="" ban_mailtopic="banIP notification" ban_mailprofile="ban_notify" +ban_reportelements="1" ban_nftpriority="-200" ban_nftexpiry="" ban_loglevel="warn" @@ -448,7 +449,7 @@ f_nftinit() { # handle downloads # f_down() { - local log_input log_forwardwan log_forwardlan start_ts end_ts tmp_raw tmp_load tmp_file split_file input_handles forwardwan_handles forwardlan_handles handle + local log_input log_forwardwan log_forwardlan start_ts end_ts tmp_raw tmp_load tmp_file split_file ruleset_raw handle local cnt_set cnt_dl restore_rc feed_direction feed_rc feed_log feed="${1}" proto="${2}" feed_url="${3}" feed_rule="${4}" feed_flag="${5}" start_ts="$(date +%s)" @@ -479,16 +480,14 @@ f_down() { # chain/rule maintenance # if [ "${ban_action}" = "reload" ] && "${ban_nftcmd}" -t list set inet banIP "${feed}" >/dev/null 2>&1; then - input_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-input 2>/dev/null)" - forwardwan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-forward 2>/dev/null)" - forwardlan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP lan-forward 2>/dev/null)" + ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)" { printf "%s\n" "flush set inet banIP ${feed}" - handle="$(printf "%s\n" "${input_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${feed}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-input handle ${handle}" - handle="$(printf "%s\n" "${forwardwan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${feed}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-forward handle ${handle}" - handle="$(printf "%s\n" "${forwardlan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}")" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${feed}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP lan-forward handle ${handle}" } >"${tmp_flush}" fi @@ -781,44 +780,43 @@ f_restore() { # remove disabled feeds # f_rmset() { - local tmp_del table_sets input_handles forwardwan_handles forwardlan_handles handle sets feed feed_log feed_rc + local tmp_del ruleset_raw table_sets handle set del_set feed_log feed_rc tmp_del="${ban_tmpfile}.final.delete" - table_sets="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null | jsonfilter -qe '@.nftables[*].set.name')" - input_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-input 2>/dev/null)" - forwardwan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP wan-forward 2>/dev/null)" - forwardlan_handles="$("${ban_nftcmd}" -t --handle --numeric list chain inet banIP lan-forward 2>/dev/null)" + ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)" + table_sets="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')" { printf "%s\n\n" "#!/usr/sbin/nft -f" - for feed in ${table_sets}; do - if ! printf "%s" "allowlist blocklist ${ban_feed}" | "${ban_grepcmd}" -q "${feed%v*}"; then - sets="${sets}${feed}/" - rm -f "${ban_backupdir}/banIP.${feed}.gz" - printf "%s\n" "flush set inet banIP ${feed}" - handle="$(printf "%s\n" "${input_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)" + for set in ${table_sets}; do + if ! printf "%s" "allowlist blocklist ${ban_feed}" | "${ban_grepcmd}" -q "${set%v*}"; then + del_set="${del_set}${set}, " + rm -f "${ban_backupdir}/banIP.${set}.gz" + printf "%s\n" "flush set inet banIP ${set}" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${set}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-input handle ${handle}" - handle="$(printf "%s\n" "${forwardwan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${set}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP wan-forward handle ${handle}" - handle="$(printf "%s\n" "${forwardlan_handles}" | "${ban_awkcmd}" "/@${feed} /{print \$NF}" 2>/dev/null)" + handle="$(printf "%s\n" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${set}\"].handle")" [ -n "${handle}" ] && printf "%s\n" "delete rule inet banIP lan-forward handle ${handle}" - printf "%s\n\n" "delete set inet banIP ${feed}" + printf "%s\n\n" "delete set inet banIP ${set}" fi done } >"${tmp_del}" - if [ -n "${sets}" ]; then + if [ -n "${del_set}" ]; then + del_set="${del_set%%??}" feed_log="$("${ban_nftcmd}" -f "${tmp_del}" 2>&1)" feed_rc="${?}" fi rm -f "${tmp_del}" - f_log "debug" "f_rmset ::: sets: ${sets:-"-"}, tmp: ${tmp_del}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}" + f_log "debug" "f_rmset ::: sets: ${del_set:-"-"}, rc: ${feed_rc:-"-"}, log: ${feed_log:-"-"}" } # generate status information # f_genstatus() { - local object duration nft_feeds cnt_elements="0" split="0" status="${1}" + local object duration set table_sets cnt_elements="0" split="0" status="${1}" [ -z "${ban_dev}" ] && f_conf if [ "${status}" = "active" ]; then @@ -826,9 +824,9 @@ f_genstatus() { ban_endtime="$(date "+%s")" duration="$(((ban_endtime - ban_starttime) / 60))m $(((ban_endtime - ban_starttime) % 60))s" fi - nft_feeds="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null | jsonfilter -qe '@.nftables[*].set.name')" - for object in ${nft_feeds}; do - cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${object}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))" + table_sets="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')" + for set in ${table_sets}; do + cnt_elements="$((cnt_elements + $("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)))" done runtime="action: ${ban_action:-"-"}, duration: ${duration:-"-"}, date: $(date "+%Y-%m-%d %H:%M:%S")" fi @@ -847,7 +845,7 @@ f_genstatus() { json_add_string "feed" "-" json_close_object else - for object in ${nft_feeds}; do + for object in ${table_sets}; do json_add_object json_add_string "feed" "${object}" json_close_object @@ -987,7 +985,7 @@ f_lookup() { # table statistics # f_report() { - local report_jsn report_txt set tmp_val nft_raw nft_sets set_cnt set_input set_forwardwan set_forwardlan set_cntinput set_cntforwardwan set_cntforwardlan output="${1}" + local report_jsn report_txt set tmp_val ruleset_raw table_sets set_cnt set_input set_forwardwan set_forwardlan set_cntinput set_cntforwardwan set_cntforwardlan output="${1}" local detail set_details jsnval timestamp autoadd_allow autoadd_block sum_sets sum_setinput sum_setforwardwan sum_setforwardlan sum_setelements sum_cntinput sum_cntforwardwan sum_cntforwardlan [ -z "${ban_dev}" ] && f_conf @@ -997,8 +995,8 @@ f_report() { # json output preparation # - nft_raw="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null)" - nft_sets="$(printf "%s" "${nft_raw}" | jsonfilter -qe '@.nftables[*].set.name')" + ruleset_raw="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null)" + table_sets="$(printf "%s" "${ruleset_raw}" | jsonfilter -qe '@.nftables[@.set.table="banIP"].set.name')" sum_sets="0" sum_setinput="0" sum_setforwardwan="0" @@ -1012,12 +1010,17 @@ f_report() { { printf "%s\n" "{" printf "\t%s\n" '"sets": {' - for set in ${nft_sets}; do - set_cnt="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)" - sum_setelements="$((sum_setelements + set_cnt))" - set_cntinput="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"wan-input\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")" - set_cntforwardwan="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"wan-forward\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")" - set_cntforwardlan="$(printf "%s" "${nft_raw}" | jsonfilter -qe "@.nftables[@.rule.chain=\"lan-forward\"][@.expr[*].match.right=\"@${set}\"].expr[*].counter.packets")" + for set in ${table_sets}; do + set_cntinput="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-input\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")" + set_cntforwardwan="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"wan-forward\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")" + set_cntforwardlan="$(printf "%s" "${ruleset_raw}" | jsonfilter -l1 -qe "@.nftables[@.rule.table=\"banIP\"&&@.rule.chain=\"lan-forward\"][@.expr[0].match.right=\"@${set}\"].expr[*].counter.packets")" + if [ "${ban_reportelements}" = "1" ]; then + set_cnt="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]' | wc -l 2>/dev/null)" + sum_setelements="$((sum_setelements + set_cnt))" + else + set_cnt="" + sum_setelements="n/a" + fi if [ -n "${set_cntinput}" ]; then set_input="OK" sum_setinput="$((sum_setinput + 1))" @@ -1093,11 +1096,11 @@ f_report() { printf "%s\n" " auto-added to allowlist today: ${autoadd_allow}" printf "%s\n\n" " auto-added to blocklist today: ${autoadd_block}" json_select "sets" >/dev/null 2>&1 - json_get_keys nft_sets >/dev/null 2>&1 - if [ -n "${nft_sets}" ]; then + json_get_keys table_sets >/dev/null 2>&1 + if [ -n "${table_sets}" ]; then printf "%-25s%-15s%-24s%-24s%s\n" " Set" "| Elements" "| WAN-Input (packets)" "| WAN-Forward (packets)" "| LAN-Forward (packets)" printf "%s\n" " ---------------------+--------------+-----------------------+-----------------------+------------------------" - for set in ${nft_sets}; do + for set in ${table_sets}; do printf " %-21s" "${set}" json_select "${set}" json_get_keys set_details @@ -1144,7 +1147,7 @@ f_report() { # set search # f_search() { - local nft_sets ip proto run_search search="${1}" + local table_sets ip proto run_search search="${1}" f_system run_search="/var/run/banIP.search" @@ -1156,7 +1159,7 @@ f_search() { [ -n "${ip}" ] && proto="v6" fi if [ -n "${proto}" ]; then - nft_sets="$("${ban_nftcmd}" -tj list table inet banIP 2>/dev/null | jsonfilter -qe "@.nftables[@.set.type=\"ip${proto}_addr\"].set.name")" + table_sets="$("${ban_nftcmd}" -tj list ruleset 2>/dev/null | jsonfilter -qe "@.nftables[@.set.table=\"banIP\"&&@.set.type=\"ip${proto}_addr\"].set.name")" else printf "%s\n%s\n%s\n" ":::" "::: no valid search input (single IPv4/IPv6 address)" ":::" return @@ -1169,7 +1172,7 @@ f_search() { printf "%s\n" " Looking for IP ${ip} on $(date "+%Y-%m-%d %H:%M:%S")" printf "%s\n" " ---" cnt=1 - for set in ${nft_sets}; do + for set in ${table_sets}; do ( if "${ban_nftcmd}" get element inet banIP "${set}" "{ ${ip} }" >/dev/null 2>&1; then printf "%s\n" " IP found in set ${set}" @@ -1188,24 +1191,19 @@ f_search() { # set survey # f_survey() { - local set_survey set="${1}" + local set_elements set="${1}" f_system - if [ -n "${set}" ]; then - if "${ban_nftcmd}" -jt list set inet banIP "${set}" >/dev/null 2>&1; then - set_survey="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]')" - else - printf "%s\n%s\n%s\n" ":::" "::: unknown banIP set (single banIP set name)" ":::" - return - fi - else + [ -n "${set}" ] && set_elements="$("${ban_nftcmd}" -j list set inet banIP "${set}" 2>/dev/null | jsonfilter -qe '@.nftables[*].set.elem[*]')" + + if [ -z "${set}" ] || [ -z "${set_elements}" ]; then printf "%s\n%s\n%s\n" ":::" "::: no valid survey input (single banIP set name)" ":::" return fi printf "%s\n%s\n%s\n" ":::" "::: banIP Survey" ":::" printf "%s\n" " List the elements of set ${set} on $(date "+%Y-%m-%d %H:%M:%S")" printf "%s\n" " ---" - printf "%s\n" "${set_survey}" + printf "%s\n" "${set_elements}" } # send status mails diff --git a/net/banip/files/banip-service.sh b/net/banip/files/banip-service.sh index 7803376bf..6b6d7339f 100755 --- a/net/banip/files/banip-service.sh +++ b/net/banip/files/banip-service.sh @@ -44,7 +44,7 @@ fi # init nft namespace # -if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list table inet banIP >/dev/null 2>&1; then +if [ "${ban_action}" != "reload" ] || ! "${ban_nftcmd}" -t list set inet banIP allowlistvMAC >/dev/null 2>&1; then if f_nftinit "${ban_tmpfile}".init.nft; then f_log "info" "nft namespace initialized" else diff --git a/net/banip/files/banip.init b/net/banip/files/banip.init index 90587bf76..e1cf07043 100755 --- a/net/banip/files/banip.init +++ b/net/banip/files/banip.init @@ -20,7 +20,7 @@ ban_pidfile="/var/run/banip.pid" ban_lock="/var/run/banip.lock" [ "${action}" = "stop" ] && ! /etc/init.d/banip running && exit 0 -[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "lookup" ] || [ "${action}" = "status" ]; } && exit 1 +[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "survey" ] || [ "${action}" = "status" ]; } && exit 1 [ -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && exit 1 [ ! -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && mkdir -p "${ban_lock}" diff --git a/net/v2raya/Makefile b/net/v2raya/Makefile index 18b81d15c..3787374c4 100644 --- a/net/v2raya/Makefile +++ b/net/v2raya/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=v2rayA PKG_VERSION:=1.5.9.1698.1 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)? @@ -37,13 +37,7 @@ define Package/v2raya SUBMENU:=Web Servers/Proxies DEPENDS:=$(GO_ARCH_DEPENDS) \ +ca-bundle \ - +iptables \ - +IPV6:ip6tables \ - +iptables-mod-conntrack-extra \ - +iptables-mod-extra \ - +iptables-mod-filter \ - +iptables-mod-tproxy \ - +kmod-ipt-nat6 \ + +kmod-nft-tproxy \ +xray-core URL:=https://v2raya.org endef diff --git a/net/v2raya/files/v2raya.config b/net/v2raya/files/v2raya.config index d9ff36581..131131cf8 100644 --- a/net/v2raya/files/v2raya.config +++ b/net/v2raya/files/v2raya.config @@ -10,7 +10,11 @@ config v2raya 'config' # Make sure your IPv6 network works fine before you turn it on. # Optional values: auto, on, off. - option ipv6_support 'auto' + option ipv6_support 'on' + + # Experimental feature. Make sure you have installed nftables. + # Optional values: auto, on, off. + option nftables_support 'on' # Optional values: trace, debug, info, warn or error option log_level 'info' diff --git a/net/v2raya/files/v2raya.init b/net/v2raya/files/v2raya.init index 4120e90ff..2b77fa5dc 100755 --- a/net/v2raya/files/v2raya.init +++ b/net/v2raya/files/v2raya.init @@ -42,7 +42,8 @@ start_service() { append_env_arg "config" "address" "0.0.0.0:2017" append_env_arg "config" "config" "/etc/v2raya" - append_env_arg "config" "ipv6_support" "auto" + append_env_arg "config" "ipv6_support" "on" + append_env_arg "config" "nftables_support" "on" append_env_arg "config" "log_level" "info" append_env_arg "config" "log_file" "/var/log/v2raya/v2raya.log" append_env_arg "config" "log_max_days" "3" diff --git a/net/v2raya/patches/019-fix-simple-obfs.patch b/net/v2raya/patches/019-fix-simple-obfs.patch new file mode 100644 index 000000000..e76b49cc8 --- /dev/null +++ b/net/v2raya/patches/019-fix-simple-obfs.patch @@ -0,0 +1,88 @@ +From 58a6cf270e43ec3eaeef7d1c65de76278dd6d349 Mon Sep 17 00:00:00 2001 +From: mzz2017 <2017@duck.com> +Date: Mon, 13 Feb 2023 14:42:07 +0800 +Subject: [PATCH] fix: simple-obfs + +--- + service/pkg/plugin/simpleobfs/http.go | 8 +++++++- + service/pkg/plugin/simpleobfs/tls.go | 7 +++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/pkg/plugin/simpleobfs/http.go ++++ b/pkg/plugin/simpleobfs/http.go +@@ -12,6 +12,7 @@ import ( + "net" + "net/http" + "strings" ++ "sync" + ) + + // HTTPObfs is shadowsocks http simple-obfs implementation +@@ -24,9 +25,13 @@ type HTTPObfs struct { + offset int + firstRequest bool + firstResponse bool ++ rMu sync.Mutex ++ wMu sync.Mutex + } + + func (ho *HTTPObfs) Read(b []byte) (int, error) { ++ ho.rMu.Lock() ++ defer ho.rMu.Unlock() + if ho.buf != nil { + n := copy(b, ho.buf[ho.offset:]) + ho.offset += n +@@ -64,6 +69,8 @@ func (ho *HTTPObfs) Read(b []byte) (int, + } + + func (ho *HTTPObfs) Write(b []byte) (int, error) { ++ ho.wMu.Lock() ++ defer ho.wMu.Unlock() + if ho.firstRequest { + randBytes := make([]byte, 16) + rand.Read(randBytes) +@@ -71,7 +78,6 @@ func (ho *HTTPObfs) Write(b []byte) (int + req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", rand.Int()%54, rand.Int()%2)) + req.Header.Set("Upgrade", "websocket") + req.Header.Set("Connection", "Upgrade") +- req.Host = ho.host + if ho.port != "80" { + req.Host = fmt.Sprintf("%s:%s", ho.host, ho.port) + } +--- a/pkg/plugin/simpleobfs/tls.go ++++ b/pkg/plugin/simpleobfs/tls.go +@@ -8,6 +8,7 @@ import ( + "io" + "math/rand" + "net" ++ "sync" + "time" + ) + +@@ -26,6 +27,8 @@ type TLSObfs struct { + remain int + firstRequest bool + firstResponse bool ++ rMu sync.Mutex ++ wMu sync.Mutex + } + + func (to *TLSObfs) read(b []byte, discardN int) (int, error) { +@@ -54,6 +57,8 @@ func (to *TLSObfs) read(b []byte, discar + } + + func (to *TLSObfs) Read(b []byte) (int, error) { ++ to.rMu.Lock() ++ defer to.rMu.Unlock() + if to.remain > 0 { + length := to.remain + if length > len(b) { +@@ -77,6 +82,8 @@ func (to *TLSObfs) Read(b []byte) (int, + return to.read(b, 3) + } + func (to *TLSObfs) Write(b []byte) (int, error) { ++ to.wMu.Lock() ++ defer to.wMu.Unlock() + length := len(b) + for i := 0; i < length; i += chunkSize { + end := i + chunkSize diff --git a/net/v2raya/patches/020-feat-add-nftables-support.patch b/net/v2raya/patches/020-feat-add-nftables-support.patch new file mode 100644 index 000000000..50ef49b9c --- /dev/null +++ b/net/v2raya/patches/020-feat-add-nftables-support.patch @@ -0,0 +1,624 @@ +From d10cf52839e848870df0ea852d9a818ac03e7aa3 Mon Sep 17 00:00:00 2001 +From: cubercsl <2014cais01@gmail.com> +Date: Thu, 19 Jan 2023 16:43:30 +0800 +Subject: [PATCH 1/5] feat: add nftables support + +fix: use iptables-nft if nftables-support is on +fix: save nft to V2RAYA_CONFIG +fix: tproxy for ipv6 +chore: small change in table format +--- + service/conf/environmentConfig.go | 1 + + service/core/iptables/dropSpoofing.go | 4 +- + service/core/iptables/iptables.go | 7 +- + service/core/iptables/redirect.go | 142 +++++++++++++++++-- + service/core/iptables/tproxy.go | 195 +++++++++++++++++++++++++- + service/core/iptables/utils.go | 23 ++- + service/core/iptables/watcher.go | 1 + + service/core/v2ray/asset/asset.go | 17 ++- + service/core/v2ray/transparent.go | 9 +- + 9 files changed, 367 insertions(+), 32 deletions(-) + +--- a/conf/environmentConfig.go ++++ b/conf/environmentConfig.go +@@ -24,6 +24,7 @@ type Params struct { + WebDir string `id:"webdir" desc:"v2rayA web files directory. use embedded files if not specify."` + VlessGrpcInboundCertKey []string `id:"vless-grpc-inbound-cert-key" desc:"Specify the certification path instead of automatically generating a self-signed certificate. Example: /etc/v2raya/grpc_certificate.crt,/etc/v2raya/grpc_private.key"` + IPV6Support string `id:"ipv6-support" default:"auto" desc:"Optional values: auto, on, off. Make sure your IPv6 network works fine before you turn it on."` ++ NFTablesSupport string `id:"nftables-support" default:"off" desc:"Optional values: auto, on, off. Experimental feature. Make sure you have installed nftables."` + PassCheckRoot bool `desc:"Skip privilege checking. Use it only when you cannot start v2raya but confirm you have root privilege"` + ResetPassword bool `id:"reset-password"` + LogLevel string `id:"log-level" default:"info" desc:"Optional values: trace, debug, info, warn or error"` +--- a/core/iptables/dropSpoofing.go ++++ b/core/iptables/dropSpoofing.go +@@ -34,7 +34,7 @@ ip6tables -w 2 -I FORWARD -j DROP_SPOOFI + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, + } + } + +@@ -54,6 +54,6 @@ ip6tables -w 2 -X DROP_SPOOFING + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, + } + } +--- a/core/iptables/iptables.go ++++ b/core/iptables/iptables.go +@@ -1,11 +1,12 @@ + package iptables + + import ( +- "github.com/v2rayA/v2rayA/common" +- "github.com/v2rayA/v2rayA/common/cmds" + "strings" + "sync" + "time" ++ ++ "github.com/v2rayA/v2rayA/common" ++ "github.com/v2rayA/v2rayA/common/cmds" + ) + + // http://briteming.hatenablog.com/entry/2019/06/18/175518 +@@ -56,6 +57,10 @@ func (c Setter) Run(stopAtError bool) er + if common.IsDocker() { + commands = strings.ReplaceAll(commands, "iptables", "iptables-legacy") + commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-legacy") ++ } else if (!cmds.IsCommandValid("iptables") || IsNFTablesSupported()) && ++ cmds.IsCommandValid("iptables-nft") { ++ commands = strings.ReplaceAll(commands, "iptables", "iptables-nft") ++ commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-nft") + } + var errs []error + if c.PreFunc != nil { +--- a/core/iptables/redirect.go ++++ b/core/iptables/redirect.go +@@ -2,15 +2,34 @@ package iptables + + import ( + "fmt" +- "github.com/v2rayA/v2rayA/common/cmds" ++ "os" + "strings" ++ ++ "github.com/v2rayA/v2rayA/common/cmds" ++ "github.com/v2rayA/v2rayA/core/v2ray/asset" + ) + +-type redirect struct{} ++type redirect interface { ++ AddIPWhitelist(cidr string) ++ RemoveIPWhitelist(cidr string) ++ GetSetupCommands() Setter ++ GetCleanCommands() Setter ++} ++ ++type legacyRedirect struct{} ++type nftRedirect struct{} + + var Redirect redirect + +-func (r *redirect) AddIPWhitelist(cidr string) { ++func init() { ++ if IsNFTablesSupported() { ++ Redirect = &nftRedirect{} ++ } else { ++ Redirect = &legacyRedirect{} ++ } ++} ++ ++func (r *legacyRedirect) AddIPWhitelist(cidr string) { + // avoid duplication + r.RemoveIPWhitelist(cidr) + var commands string +@@ -22,13 +41,13 @@ func (r *redirect) AddIPWhitelist(cidr s + cmds.ExecCommands(commands, false) + } + +-func (r *redirect) RemoveIPWhitelist(cidr string) { ++func (r *legacyRedirect) RemoveIPWhitelist(cidr string) { + var commands string + commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr) + cmds.ExecCommands(commands, false) + } + +-func (r *redirect) GetSetupCommands() Setter { ++func (r *legacyRedirect) GetSetupCommands() Setter { + commands := ` + iptables -w 2 -t nat -N TP_OUT + iptables -w 2 -t nat -N TP_PRE +@@ -84,11 +103,11 @@ ip6tables -w 2 -t nat -A TP_OUT -j TP_RU + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, + } + } + +-func (r *redirect) GetCleanCommands() Setter { ++func (r *legacyRedirect) GetCleanCommands() Setter { + commands := ` + iptables -w 2 -t nat -F TP_OUT + iptables -w 2 -t nat -D OUTPUT -p tcp -j TP_OUT +@@ -112,6 +131,113 @@ ip6tables -w 2 -t nat -X TP_RULE + ` + } + return Setter{ +- Cmds: commands, ++ Cmds: commands, ++ } ++} ++ ++func (t *nftRedirect) AddIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft add element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) ++ } ++ cmds.ExecCommands(command, false) ++} ++ ++func (t *nftRedirect) RemoveIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft delete element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) + } ++ cmds.ExecCommands(command, false) ++} ++ ++func (r *nftRedirect) GetSetupCommands() Setter { ++ // 198.18.0.0/15 and fc00::/7 are reserved for private use but used by fakedns ++ table := ` ++table inet v2raya { ++ set whitelist { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ elements = { ++ 0.0.0.0/32, ++ 10.0.0.0/8, ++ 100.64.0.0/10, ++ 127.0.0.0/8, ++ 169.254.0.0/16, ++ 172.16.0.0/12, ++ 192.0.0.0/24, ++ 192.0.2.0/24, ++ 192.88.99.0/24, ++ 192.168.0.0/16, ++ 198.51.100.0/24, ++ 203.0.113.0/24, ++ 224.0.0.0/4, ++ 240.0.0.0/4 ++ } ++ } ++ ++ set whitelist6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ elements = { ++ ::/128, ++ ::1/128, ++ 64:ff9b::/96, ++ 100::/64, ++ 2001::/32, ++ 2001:20::/28, ++ fe80::/10, ++ ff00::/8 ++ } ++ } ++ ++ set interface { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ } ++ ++ set interface6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ } ++ ++ chain tp_rule { ++ ip daddr @whitelist return ++ ip daddr @interface return ++ ip6 daddr @whitelist6 return ++ ip6 daddr @interface6 return ++ meta mark & 0x80 == 0x80 return ++ meta l4proto tcp redirect to :32345 ++ } ++ ++ chain tp_pre { ++ type nat hook prerouting priority dstnat - 5 ++ meta nfproto { ipv4, ipv6 } meta l4proto tcp jump tp_rule ++ } ++ ++ chain tp_out { ++ type nat hook output priority -105 ++ meta nfproto { ipv4, ipv6 } meta l4proto tcp jump tp_rule ++ } ++} ++` ++ if !IsIPv6Supported() { ++ table = strings.ReplaceAll(table, "meta nfproto { ipv4, ipv6 }", "meta nfproto ipv4") ++ } ++ ++ nftablesConf := asset.GetNFTablesConfigPath() ++ os.WriteFile(nftablesConf, []byte(table), 0644) ++ ++ command := `nft -f ` + nftablesConf ++ ++ return Setter{Cmds: command} ++} ++ ++func (r *nftRedirect) GetCleanCommands() Setter { ++ command := `nft delete table inet v2raya` ++ return Setter{Cmds: command} + } +--- a/core/iptables/tproxy.go ++++ b/core/iptables/tproxy.go +@@ -2,18 +2,36 @@ package iptables + + import ( + "fmt" ++ "os" ++ "strings" ++ + "github.com/v2rayA/v2rayA/common/cmds" ++ "github.com/v2rayA/v2rayA/core/v2ray/asset" + "github.com/v2rayA/v2rayA/db/configure" +- "strings" + ) + +-type tproxy struct { +- watcher *LocalIPWatcher ++type tproxy interface { ++ AddIPWhitelist(cidr string) ++ RemoveIPWhitelist(cidr string) ++ GetSetupCommands() Setter ++ GetCleanCommands() Setter + } + ++type legacyTproxy struct{} ++ ++type nftTproxy struct{} ++ + var Tproxy tproxy + +-func (t *tproxy) AddIPWhitelist(cidr string) { ++func init() { ++ if IsNFTablesSupported() { ++ Tproxy = &nftTproxy{} ++ } else { ++ Tproxy = &legacyTproxy{} ++ } ++} ++ ++func (t *legacyTproxy) AddIPWhitelist(cidr string) { + // avoid duplication + t.RemoveIPWhitelist(cidr) + pos := 7 +@@ -30,7 +48,7 @@ func (t *tproxy) AddIPWhitelist(cidr str + cmds.ExecCommands(commands, false) + } + +-func (t *tproxy) RemoveIPWhitelist(cidr string) { ++func (t *legacyTproxy) RemoveIPWhitelist(cidr string) { + var commands string + commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr) + if !strings.Contains(cidr, ".") { +@@ -40,7 +58,7 @@ func (t *tproxy) RemoveIPWhitelist(cidr + cmds.ExecCommands(commands, false) + } + +-func (t *tproxy) GetSetupCommands() Setter { ++func (t *legacyTproxy) GetSetupCommands() Setter { + commands := ` + ip rule add fwmark 0x40/0xc0 table 100 + ip route add local 0.0.0.0/0 dev lo table 100 +@@ -158,7 +176,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C + } + } + +-func (t *tproxy) GetCleanCommands() Setter { ++func (t *legacyTproxy) GetCleanCommands() Setter { + commands := ` + ip rule del fwmark 0x40/0xc0 table 100 + ip route del local 0.0.0.0/0 dev lo table 100 +@@ -195,3 +213,166 @@ ip6tables -w 2 -t mangle -X TP_MARK + Cmds: commands, + } + } ++ ++func (t *nftTproxy) AddIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft add element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) ++ } ++ cmds.ExecCommands(command, false) ++} ++ ++func (t *nftTproxy) RemoveIPWhitelist(cidr string) { ++ command := fmt.Sprintf("nft delete element inet v2raya interface { %s }", cidr) ++ if !strings.Contains(cidr, ".") { ++ command = strings.Replace(command, "interface", "interface6", 1) ++ } ++ cmds.ExecCommands(command, false) ++} ++ ++func (t *nftTproxy) GetSetupCommands() Setter { ++ // 198.18.0.0/15 and fc00::/7 are reserved for private use but used by fakedns ++ table := ` ++table inet v2raya { ++ set whitelist { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ elements = { ++ 0.0.0.0/32, ++ 10.0.0.0/8, ++ 100.64.0.0/10, ++ 127.0.0.0/8, ++ 169.254.0.0/16, ++ 172.16.0.0/12, ++ 192.0.0.0/24, ++ 192.0.2.0/24, ++ 192.88.99.0/24, ++ 192.168.0.0/16, ++ 198.51.100.0/24, ++ 203.0.113.0/24, ++ 224.0.0.0/4, ++ 240.0.0.0/4 ++ } ++ } ++ ++ set whitelist6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ elements = { ++ ::/128, ++ ::1/128, ++ 64:ff9b::/96, ++ 100::/64, ++ 2001::/32, ++ 2001:20::/28, ++ fe80::/10, ++ ff00::/8 ++ } ++ } ++ ++ set interface { ++ type ipv4_addr ++ flags interval ++ auto-merge ++ } ++ ++ set interface6 { ++ type ipv6_addr ++ flags interval ++ auto-merge ++ } ++ ++ chain tp_out { ++ meta mark & 0x80 == 0x80 return ++ meta l4proto { tcp, udp } fib saddr type local fib daddr type != local jump tp_rule ++ } ++ ++ chain tp_pre { ++ iifname "lo" mark & 0xc0 != 0x40 return ++ meta l4proto { tcp, udp } fib saddr type != local fib daddr type != local jump tp_rule ++ meta l4proto { tcp, udp } mark & 0xc0 == 0x40 tproxy ip to 127.0.0.1:32345 ++ meta l4proto { tcp, udp } mark & 0xc0 == 0x40 tproxy ip6 to [::1]:32345 ++ } ++ ++ chain output { ++ type route hook output priority mangle - 5; policy accept; ++ meta nfproto { ipv4, ipv6 } jump tp_out ++ } ++ ++ chain prerouting { ++ type filter hook prerouting priority mangle - 5; policy accept; ++ meta nfproto { ipv4, ipv6 } jump tp_pre ++ } ++ ++ chain tp_rule { ++ meta mark set ct mark ++ meta mark & 0xc0 == 0x40 return ++ iifname "docker*" return ++ iifname "veth*" return ++ iifname "wg*" return ++ iifname "ppp*" return ++ # anti-pollution ++ ip daddr @interface return ++ ip daddr @whitelist return ++ ip6 daddr @interface6 return ++ ip6 daddr @whitelist6 return ++ jump tp_mark ++ } ++ ++ chain tp_mark { ++ tcp flags & (fin | syn | rst | ack) == syn meta mark set mark | 0x40 ++ meta l4proto udp ct state new meta mark set mark | 0x40 ++ ct mark set mark ++ } ++} ++` ++ if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { ++ table = strings.ReplaceAll(table, "# anti-pollution", ` ++ meta l4proto { tcp, udp } th dport 53 jump tp_mark ++ meta mark & 0xc0 == 0x40 return ++ `) ++ } ++ ++ if !IsIPv6Supported() { ++ // drop ipv6 packets hooks ++ table = strings.ReplaceAll(table, "meta nfproto { ipv4, ipv6 }", "meta nfproto ipv4") ++ } ++ ++ nftablesConf := asset.GetNFTablesConfigPath() ++ os.WriteFile(nftablesConf, []byte(table), 0644) ++ ++ command := ` ++ip rule add fwmark 0x40/0xc0 table 100 ++ip route add local 0.0.0.0/0 dev lo table 100 ++` ++ if IsIPv6Supported() { ++ command += ` ++ip -6 rule add fwmark 0x40/0xc0 table 100 ++ip -6 route add local ::/0 dev lo table 100 ++` ++ } ++ ++ command += `nft -f ` + nftablesConf ++ return Setter{Cmds: command} ++} ++ ++func (t *nftTproxy) GetCleanCommands() Setter { ++ command := ` ++ip rule del fwmark 0x40/0xc0 table 100 ++ip route del local 0.0.0.0/0 dev lo table 100 ++` ++ if IsIPv6Supported() { ++ command += ` ++ip -6 rule del fwmark 0x40/0xc0 table 100 ++ip -6 route del local ::/0 dev lo table 100 ++ ` ++ } ++ ++ command += `nft delete table inet v2raya` ++ if !IsIPv6Supported() { ++ command = strings.Replace(command, "inet", "ip", 1) ++ } ++ return Setter{Cmds: command} ++} +--- a/core/iptables/utils.go ++++ b/core/iptables/utils.go +@@ -1,12 +1,13 @@ + package iptables + + import ( ++ "net" ++ "strconv" ++ + "github.com/v2rayA/v2rayA/common" + "github.com/v2rayA/v2rayA/common/cmds" + "github.com/v2rayA/v2rayA/conf" + "golang.org/x/net/nettest" +- "net" +- "strconv" + ) + + func IPNet2CIDR(ipnet *net.IPNet) string { +@@ -44,3 +45,21 @@ func IsIPv6Supported() bool { + } + return cmds.IsCommandValid("ip6tables") + } ++ ++func IsNFTablesSupported() bool { ++ ++ switch conf.GetEnvironmentConfig().NFTablesSupport { ++ // Warning: ++ // This is an experimental feature for nftables support. ++ // The default value is "off" for now but may be changed to "auto" in the future ++ case "on": ++ return true ++ case "off": ++ return false ++ default: ++ } ++ if common.IsDocker() { ++ return false ++ } ++ return cmds.IsCommandValid("nft") ++} +--- a/core/iptables/watcher.go ++++ b/core/iptables/watcher.go +@@ -10,6 +10,7 @@ type LocalIPWatcher struct { + cidrPool map[string]struct{} + AddedFunc func(cidr string) + RemovedFunc func(cidr string) ++ UpdateFunc func(cidrs []string) + } + + func NewLocalIPWatcher(interval time.Duration, AddedFunc func(cidr string), RemovedFunc func(cidr string)) *LocalIPWatcher { +--- a/core/v2ray/asset/asset.go ++++ b/core/v2ray/asset/asset.go +@@ -3,12 +3,6 @@ package asset + import ( + "errors" + "fmt" +- "github.com/adrg/xdg" +- "github.com/muhammadmuzzammil1998/jsonc" +- "github.com/v2rayA/v2rayA/common/files" +- "github.com/v2rayA/v2rayA/conf" +- "github.com/v2rayA/v2rayA/core/v2ray/where" +- "github.com/v2rayA/v2rayA/pkg/util/log" + "io" + "io/fs" + "net/http" +@@ -17,6 +11,13 @@ import ( + "path/filepath" + "runtime" + "time" ++ ++ "github.com/adrg/xdg" ++ "github.com/muhammadmuzzammil1998/jsonc" ++ "github.com/v2rayA/v2rayA/common/files" ++ "github.com/v2rayA/v2rayA/conf" ++ "github.com/v2rayA/v2rayA/core/v2ray/where" ++ "github.com/v2rayA/v2rayA/pkg/util/log" + ) + + func GetV2rayLocationAssetOverride() string { +@@ -140,6 +141,10 @@ func GetV2rayConfigDirPath() (p string) + return conf.GetEnvironmentConfig().V2rayConfigDirectory + } + ++func GetNFTablesConfigPath() (p string) { ++ return path.Join(conf.GetEnvironmentConfig().Config, "v2raya.nft") ++} ++ + func Download(url string, to string) (err error) { + log.Info("Downloading %v to %v", url, to) + c := http.Client{Timeout: 90 * time.Second} +--- a/core/v2ray/transparent.go ++++ b/core/v2ray/transparent.go +@@ -2,13 +2,14 @@ package v2ray + + import ( + "fmt" ++ "strings" ++ "time" ++ + "github.com/v2rayA/v2rayA/conf" + "github.com/v2rayA/v2rayA/core/iptables" + "github.com/v2rayA/v2rayA/core/specialMode" + "github.com/v2rayA/v2rayA/db/configure" + "github.com/v2rayA/v2rayA/pkg/util/log" +- "strings" +- "time" + ) + + func deleteTransparentProxyRules() { +@@ -45,12 +46,12 @@ func writeTransparentProxyRules() (err e + } + return fmt.Errorf("not support \"tproxy\" mode of transparent proxy: %w", err) + } +- iptables.SetWatcher(&iptables.Tproxy) ++ iptables.SetWatcher(iptables.Tproxy) + case configure.TransparentRedirect: + if err = iptables.Redirect.GetSetupCommands().Run(true); err != nil { + return fmt.Errorf("not support \"redirect\" mode of transparent proxy: %w", err) + } +- iptables.SetWatcher(&iptables.Redirect) ++ iptables.SetWatcher(iptables.Redirect) + case configure.TransparentSystemProxy: + if err = iptables.SystemProxy.GetSetupCommands().Run(true); err != nil { + return fmt.Errorf("not support \"system proxy\" mode of transparent proxy: %w", err)