v1.0. Support for nftables and dnsmasq 2.88.

This commit is contained in:
gSpot
2023-02-06 17:27:15 +03:00
parent c1ad1ab10e
commit 5d2c716795
19 changed files with 671 additions and 640 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
config main 'config'
option proxy_mode '1'
option proxy_local_clients '1'
option ipset_clear_sets '1'
option nftset_clear_sets '1'
option allowed_hosts_mode '0'
option if_vpn 'tun0'
option tor_trans_port '9040'
+1 -1
View File
@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
START=96
START=99
STOP=01
APP_NAME="ruantiblock"
@@ -1,7 +1,7 @@
### Настройки ruantiblock ###
### Директория данных (генерируемые конфиги dnsmasq, ipset и пр.)
### Директория данных (генерируемые конфиги dnsmasq, nftset и пр.)
DATA_DIR="/tmp/ruantiblock"
### Директория модулей
MODULES_DIR="/usr/libexec/ruantiblock"
@@ -12,12 +12,12 @@ DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart"
### Директория для html-страницы статуса (не используется в OpenWrt)
HTML_DIR="/www"
### Режим обработки пакетов в правилах iptables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
### Режим обработки пакетов в правилах nftables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
PROXY_MODE=1
### Применять правила проксификации для трафика локальных сервисов роутера (0 - off, 1 - on)
### Применять правила проксификации для трафика локальных сервисов роутера (0 - выкл, 1 - вкл)
PROXY_LOCAL_CLIENTS=1
### Удаление записей из основных сетов перед началом заполнения временных сетов при обновлении (для освобождения оперативной памяти перед заполнением сетов) (0 - off, 1 - on)
IPSET_CLEAR_SETS=0
### Удаление записей сетов перед началом обновления (для освобождения оперативной памяти перед обновлением сетов) (0 - выкл, 1 - вкл)
NFTSET_CLEAR_SETS=0
### Режим фильтра хостов которым разрешено обходить блокировки (0 - выкл., 1 - только адреса из списка, 2 - любые адреса кроме присутствующих в списке)
ALLOWED_HOSTS_MODE=0
### Список IP адресов хостов для фильтра, через пробел (прим.: 192.168.0.10 192.168.0.15)
@@ -26,7 +26,7 @@ ALLOWED_HOSTS_LIST=""
IF_VPN="tun0"
### Порт прозрачного прокси Tor (параметр TransPort в torrc)
TOR_TRANS_PORT=9040
### Отправлять в Tor UDP-трафик (0 - off, 1 - on)
### Отправлять в Tor UDP-трафик (0 - вкл, 1 - выкл)
TOR_ALLOW_UDP=0
### DNS-сервер для резолвинга в домене .onion (Tor)
ONION_DNS_ADDR="127.0.0.1#9053"
@@ -36,9 +36,9 @@ VPN_PKTS_MARK=8
T_PROXY_PORT_TCP=1100
### UDP порт прокси в режиме прозрачного прокси
T_PROXY_PORT_UDP=1100
### Отправлять в прозрачный прокси UDP-трафик (0 - off, 1 - on)
### Отправлять в прозрачный прокси UDP-трафик (0 - вкл, 1 - выкл)
T_PROXY_ALLOW_UDP=0
### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - off, 1 - on)
### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл)
### В $DATA_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок
### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8)
### Можно комментировать строки (#)
@@ -47,14 +47,22 @@ ADD_USER_ENTRIES=0
USER_ENTRIES_DNS=""
### Файл пользовательских записей
USER_ENTRIES_FILE="/etc/ruantiblock/user_entries"
### Запись событий в syslog (0 - off, 1 - on)
### Запись событий в syslog (0 - выкл, 1 - вкл)
ENABLE_LOGGING=1
### Html-страница с инфо о текущем статусе (0 - off, 1 - on) (не используется в OpenWrt)
### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt)
ENABLE_HTML_INFO=0
### Максимальное кол-во элементов списка ipset
IPSET_MAXELEM=2000000
### Таймаут для записей в сете $IPSET_DNSMASQ
IPSET_DNSMASQ_TIMEOUT=3600
### метка для отбора пакетов в VPN туннель
VPN_PKTS_MARK=8
### Максимальное кол-во элементов списка nftables
#NFTSET_MAXELEM_CIDR=65535
NFTSET_MAXELEM_IP=1000000
NFTSET_MAXELEM_DNSMASQ=65535
### Политика отбора элементов в сетах nftables. "performance" - производительность и большее потребление RAM. "memory" - хуже производительность и меньше потребление RAM
NFTSET_POLICY_CIDR="memory"
NFTSET_POLICY_IP="memory"
NFTSET_POLICY_DNSMASQ="performance"
### Таймаут для записей в сете $NFTSET_DNSMASQ
NFTSET_DNSMASQ_TIMEOUT="1h"
### Кол-во попыток обновления блэклиста (в случае неудачи)
MODULE_RUN_ATTEMPTS=3
### Таймаут между попытками обновления
@@ -66,11 +74,11 @@ BLLIST_MODULE=""
### Настройки модулей-парсеров ###
### Режим обхода блокировок: ruantiblock-ip, ruantiblock-fqdn, zapret-info-ip, zapret-info-fqdn, rublacklist-ip, rublacklist-fqdn, antifilter-ip
### Режим обхода блокировок: ruantiblock-fqdn, ruantiblock-ip, zapret-info-fqdn, zapret-info-ip, rublacklist-fqdn, rublacklist-ip, antifilter-ip
BLLIST_PRESET=""
### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит
BLLIST_MIN_ENTRIES=3000
### Лимит ip адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества ip-адресов пренадлежащих этой сети (0 - off)
### Лимит ip адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества ip-адресов пренадлежащих этой сети (0 - выкл)
BLLIST_IP_LIMIT=0
### Подсети класса C (/24). IP адреса из этих подсетей не группируются при оптимизации (записи д.б. в виде: 68.183.221. 149.154.162. и пр.). Прим.: "68.183.221. 149.154.162."
BLLIST_GR_EXCLUDED_NETS=""
@@ -78,29 +86,29 @@ BLLIST_GR_EXCLUDED_NETS=""
BLLIST_SUMMARIZE_IP=0
### Группировать идущие подряд подсети /24 в диапазоны CIDR
BLLIST_SUMMARIZE_CIDR=0
### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - off, 1 - on)
### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - выкл, 1 - вкл)
BLLIST_IP_FILTER=0
### Тип фильтра IP (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
BLLIST_IP_FILTER_TYPE=0
### Файл с шаблонами ip для опции BLLIST_IP_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
BLLIST_IP_FILTER_FILE="/etc/ruantiblock/ip_filter"
### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - off)
### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл)
BLLIST_SD_LIMIT=16
### SLD не подлежащие группировке при оптимизации (через пробел)
BLLIST_GR_EXCLUDED_SLD="livejournal.com facebook.com vk.com blog.jp msk.ru net.ru org.ru net.ua com.ua org.ua co.uk amazonaws.com"
### Не группировать SLD попадающие под выражения (через пробел) ("[.][a-z]{2,3}[.][a-z]{2}$")
BLLIST_GR_EXCLUDED_MASKS=""
### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - off, 1 - on)
### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - выкл, 1 - вкл)
BLLIST_FQDN_FILTER=0
### Тип фильтра FQDN (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
BLLIST_FQDN_FILTER_TYPE=0
### Файл с шаблонами FQDN для опции BLLIST_FQDN_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
BLLIST_FQDN_FILTER_FILE="/etc/ruantiblock/fqdn_filter"
### Обрезка www[0-9]. в FQDN (0 - off, 1 - on)
### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл)
BLLIST_STRIP_WWW=1
### Преобразование кириллических доменов в punycode (0 - off, 1 - on)
### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл)
BLLIST_ENABLE_IDN=0
### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - off, 1 - on)
### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - выкл, 1 - вкл)
BLLIST_ALT_NSLOOKUP=0
### Альтернативный DNS-сервер
BLLIST_ALT_DNS_ADDR="8.8.8.8"
@@ -112,12 +120,12 @@ ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
#ZI_ALL_URL="https://app.assembla.com/spaces/z-i/git/source/master/dump.csv?_format=raw"
AF_IP_URL="https://antifilter.download/list/allyouneed.lst"
AF_FQDN_URL="https://antifilter.download/list/domains.lst"
RA_IP_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/ruantiblock.ip"
RA_IP_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/ruantiblock.dnsmasq"
RA_IP_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/ip/update_status"
RA_FQDN_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/ruantiblock.ip"
RA_FQDN_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/ruantiblock.dnsmasq"
RA_FQDN_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist/fqdn/update_status"
RA_IP_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/ruantiblock.ip"
RA_IP_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/ruantiblock.dnsmasq"
RA_IP_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/ip/update_status"
RA_FQDN_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/ruantiblock.ip"
RA_FQDN_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/ruantiblock.dnsmasq"
RA_FQDN_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.0/fqdn/update_status"
RBL_ENCODING=""
ZI_ENCODING="CP1251"
AF_ENCODING=""
@@ -1,6 +1,6 @@
AWK_CMD="awk"
UCI_SECTION="ruantiblock.config"
UCI_VARS="proxy_mode proxy_local_clients ipset_clear_sets allowed_hosts_mode allowed_hosts_list if_vpn tor_trans_port tor_allow_udp onion_dns_addr t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp add_user_entries user_entries_dns enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_gr_excluded_nets bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_gr_excluded_sld bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup"
UCI_VARS="proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list if_vpn tor_trans_port tor_allow_udp onion_dns_addr t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp add_user_entries user_entries_dns enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_gr_excluded_nets bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_gr_excluded_sld bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup"
eval `uci show "$UCI_SECTION" | $AWK_CMD -F "=" -v UCI_VARS="$UCI_VARS" '
BEGIN {
@@ -1,66 +1,36 @@
Info() {
local _set
if CheckStatus; then
printf "{\"status\":\"enabled\",\"last_blacklist_update\":{"
if [ -f "$UPDATE_STATUS_FILE" ]; then
$AWK_CMD '{
if(NF < 4)
print "\"status\":false";
else
print "\"status\":true,\"date\":\""$4"\",\"cidr\":\""$1"\",\"ip\":\""$2"\",\"fqdn\":\""$3"\"";
}' "$UPDATE_STATUS_FILE"
else
printf "\"status\":false"
fi
printf "},"
IptListBllistChain | $AWK_CMD '
local _update_status
if [ -f "$UPDATE_STATUS_FILE" ]; then
_update_status=`$AWK_CMD '{
if(NF < 4)
printf "{\"status\":false}";
else
printf "{\"status\":true,\"date\":\""$4"\",\"cidr\":\""$1"\",\"ip\":\""$2"\",\"fqdn\":\""$3"\"}";
}' "$UPDATE_STATUS_FILE"`
else
_update_status="{\"status\":false}"
fi
NftListBllistChainJson 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" '
BEGIN {
printf "\"iptables\":{"
rules_str = "";
}
{
if(NR > 2)
printf "\""(($10 == "!") ? $12 : $11)"\":\""$2"\",";
rules_str = rules_str $0;
}
END {
printf "\"_dummy\":false},";
if(NR == 0) {
printf "{\"status\": \"disabled\"}";
exit 1;
} else {
printf "{\"status\":\"enabled\",\"last_blacklist_update\":%s,\"rules\":%s", UPDATE_STATUS, rules_str;
exit 0;
};
}'
printf "\"ipset\":{";
for _set in "$IPSET_ALLOWED_HOSTS" "$IPSET_ONION" "$IPSET_CIDR_TMP" "$IPSET_CIDR" "$IPSET_IP_TMP" "$IPSET_IP"
do
$IPSET_CMD list "$_set" -terse | $AWK_CMD -F ": " '
{
if($1 ~ /^Name/) {
printf "\""$2"\":[";
}
else if($1 ~ /^Size in memory/) {
printf "\""$2"\",";
}
else if($1 ~ /^Number of entries/) {
printf "\""$2"\"],";
};
}'
done
$IPSET_CMD list "$IPSET_DNSMASQ" | $AWK_CMD -F ": " '
{
if($1 ~ /^Name/) {
printf "\""$2"\":[";
}
else if($1 ~ /^Size in memory/) {
printf "\""$2"\",";
}
else if($1 ~ /^Number of entries/) {
printf "\""$2"\"]},\"dnsmasq\":[";
}
else if($0 ~ /^[0-9]/) {
split($0, a, " ");
printf "[\"" a[1] "\",\"" a[3] "\"],";
};
}
END {
printf "false],";
}'
printf "\"_dummy\":false}"
else
printf "{\"status\": \"disabled\"}"
if [ $? -eq 0 ]; then
printf ",\"dnsmasq\":"
$NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ" 2> /dev/null
printf ",\"dnsmasq_u\":"
$NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ_USER" 2> /dev/null
printf "}"
fi
}
@@ -1,128 +0,0 @@
IP_CMD="ip"
IPT_CMD=`which iptables-legacy`
if [ $? -ne 0 ]; then
IPT_CMD=`which iptables`
if [ $? -ne 0 ]; then
echo " Error! Iptables doesn't exists" >&2
exit 1
fi
fi
IPT_ALLOWED_HOSTS_CHAIN="${NAME}_allowed_hosts"
IPT_BLLIST_CHAIN="${NAME}_blacklist"
IPT_ACTION_CHAIN="${NAME}_action"
IPT_FIRST_CHAIN="PREROUTING"
VPN_ROUTE_TABLE_ID=99
case "$ALLOWED_HOSTS_MODE" in
"1")
IPT_ALLOWED_HOSTS_RULE="-m set --match-set ${IPSET_ALLOWED_HOSTS} src -j ${IPT_BLLIST_CHAIN}"
;;
"2")
IPT_ALLOWED_HOSTS_RULE="-m set ! --match-set ${IPSET_ALLOWED_HOSTS} src -j ${IPT_BLLIST_CHAIN}"
;;
*)
IPT_ALLOWED_HOSTS_RULE="-j ${IPT_BLLIST_CHAIN}"
;;
esac
if [ "$PROXY_MODE" = "2" ]; then
IPT_TABLE="mangle"
else
IPT_TABLE="nat"
fi
IptCmdWrapper() {
local _i=0 _attempts=10 _return_code=1
while [ $_i -lt $_attempts ]
do
if $*; then
_return_code=$?
break
fi
_i=`expr $_i + 1`
done
return $_return_code
}
IptVpnRouteAdd() {
VPN_IP=`$IP_CMD addr list dev $IF_VPN 2> /dev/null | $AWK_CMD '/inet/{sub("/[0-9]{1,2}$", "", $2); print $2; exit}'`
if [ -n "$VPN_IP" ]; then
echo 0 > /proc/sys/net/ipv4/conf/$IF_VPN/rp_filter
IptVpnRouteDel 2> /dev/null
$IP_CMD rule add fwmark $VPN_PKTS_MARK table $VPN_ROUTE_TABLE_ID priority 1000
$IP_CMD route add default via $VPN_IP table $VPN_ROUTE_TABLE_ID
fi
}
IptVpnRouteDel() {
$IP_CMD route flush table $VPN_ROUTE_TABLE_ID
$IP_CMD rule del table $VPN_ROUTE_TABLE_ID
}
IptVpnRouteStatus() {
[ -n "`$IP_CMD route show table $VPN_ROUTE_TABLE_ID 2> /dev/null`" ] && return 0
return 1
}
IptMainAdd() {
local _set
$IPT_CMD -t "$IPT_TABLE" -N "$IPT_ACTION_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -N "$IPT_BLLIST_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -N "$IPT_ALLOWED_HOSTS_CHAIN"
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ALLOWED_HOSTS_CHAIN" $IPT_ALLOWED_HOSTS_RULE
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -I "$IPT_FIRST_CHAIN" 1 -j "$IPT_ALLOWED_HOSTS_CHAIN"
if [ "$PROXY_MODE" = "2" ]; then
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -j MARK --set-mark $VPN_PKTS_MARK
IPT_IPSETS="${IPSET_CIDR} ${IPSET_IP} ${IPSET_DNSMASQ}"
elif [ "$PROXY_MODE" = "3" ]; then
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p tcp -j REDIRECT --to-ports ${T_PROXY_PORT_TCP}
if [ "$T_PROXY_ALLOW_UDP" = "1" ]; then
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p udp -j REDIRECT --to-ports ${T_PROXY_PORT_UDP}
fi
IPT_IPSETS="${IPSET_CIDR} ${IPSET_IP} ${IPSET_DNSMASQ}"
else
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p tcp -j REDIRECT --to-ports ${TOR_TRANS_PORT}
if [ "$TOR_ALLOW_UDP" = "1" ]; then
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_ACTION_CHAIN" -p udp -j REDIRECT --to-ports ${TOR_TRANS_PORT}
fi
IPT_IPSETS="${IPSET_ONION} ${IPSET_CIDR} ${IPSET_IP} ${IPSET_DNSMASQ}"
fi
for _set in $IPT_IPSETS
do
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -A "$IPT_BLLIST_CHAIN" -m set --match-set "$_set" dst -j "$IPT_ACTION_CHAIN"
done
if [ "$PROXY_MODE" = "2" ]; then
IptVpnRouteAdd
fi
}
IptMainDel() {
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -D "$IPT_FIRST_CHAIN" -j "$IPT_ALLOWED_HOSTS_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -F "$IPT_ALLOWED_HOSTS_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -X "$IPT_ALLOWED_HOSTS_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -F "$IPT_BLLIST_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -X "$IPT_BLLIST_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -F "$IPT_ACTION_CHAIN"
$IPT_CMD -t "$IPT_TABLE" -X "$IPT_ACTION_CHAIN"
if [ "$PROXY_MODE" = "2" ]; then
IptVpnRouteDel 2> /dev/null
fi
}
IPT_OUTPUT_FIRST_RULE="-j ${IPT_BLLIST_CHAIN}"
IptLocalClientsAdd() {
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -I OUTPUT 1 $IPT_OUTPUT_FIRST_RULE
}
IptLocalClientsDel() {
IptCmdWrapper $IPT_CMD -t "$IPT_TABLE" -D OUTPUT $IPT_OUTPUT_FIRST_RULE
}
IptListBllistChain() {
$IPT_CMD -t "$IPT_TABLE" -v -L "$IPT_BLLIST_CHAIN"
}
@@ -0,0 +1,118 @@
IP_CMD="ip"
NFT_ALLOWED_HOSTS_CHAIN="allowed_hosts"
NFT_BLLIST_CHAIN="blacklist"
NFT_ACTION_CHAIN="action"
NFT_LOCAL_CLIENTS_CHAIN="local_clients"
VPN_ROUTE_TABLE_ID=99
if [ "$PROXY_MODE" = "2" ]; then
MAIN_CHAIN_TYPE="type filter hook prerouting priority -160; policy accept;"
LOCAL_CLIENTS_CHAIN_TYPE="type route hook output priority -160; policy accept;"
else
MAIN_CHAIN_TYPE="type nat hook prerouting priority -110; policy accept;"
LOCAL_CLIENTS_CHAIN_TYPE="type nat hook output priority -110; policy accept;"
fi
case "$ALLOWED_HOSTS_MODE" in
"1")
IPT_ALLOWED_HOSTS_RULE="ip saddr @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}"
;;
"2")
IPT_ALLOWED_HOSTS_RULE="ip saddr != @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}"
;;
*)
IPT_ALLOWED_HOSTS_RULE="jump ${NFT_BLLIST_CHAIN}"
;;
esac
NftCmdWrapper() {
local _i=0 _attempts=10 _return_code=1
while [ $_i -lt $_attempts ]
do
if $*; then
_return_code=$?
break
fi
_i=`expr $_i + 1`
done
return $_return_code
}
IptVpnRouteDel() {
$IP_CMD route flush table $VPN_ROUTE_TABLE_ID
$IP_CMD rule del table $VPN_ROUTE_TABLE_ID
}
IptVpnRouteAdd() {
VPN_IP=`$IP_CMD addr list dev $IF_VPN 2> /dev/null | $AWK_CMD '/inet/{sub("/[0-9]{1,2}$", "", $2); print $2; exit}'`
if [ -n "$VPN_IP" ]; then
echo 0 > /proc/sys/net/ipv4/conf/$IF_VPN/rp_filter
IptVpnRouteDel 2> /dev/null
$IP_CMD rule add fwmark $VPN_PKTS_MARK table $VPN_ROUTE_TABLE_ID priority 1000
$IP_CMD route add default via $VPN_IP table $VPN_ROUTE_TABLE_ID
fi
}
NftVpnRouteStatus() {
[ -n "`$IP_CMD route show table $VPN_ROUTE_TABLE_ID 2> /dev/null`" ] && return 0
return 1
}
NftMainAdd() {
local _nft_sets="${NFTSET_CIDR} ${NFTSET_CIDR_USER} ${NFTSET_IP} ${NFTSET_IP_USER} ${NFTSET_DNSMASQ} ${NFTSET_DNSMASQ_USER}" _set
$NFT_CMD add chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" { $LOCAL_CLIENTS_CHAIN_TYPE }
$NFT_CMD add chain $NFT_TABLE "$NFT_ACTION_CHAIN"
$NFT_CMD add chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
$NFT_CMD add chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" { $MAIN_CHAIN_TYPE }
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" $IPT_ALLOWED_HOSTS_RULE
if [ "$PROXY_MODE" = "2" ]; then
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" mark set $VPN_PKTS_MARK
elif [ "$PROXY_MODE" = "3" ]; then
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" tcp dport { 0-65535 } redirect to $T_PROXY_PORT_TCP
if [ "$T_PROXY_ALLOW_UDP" = "1" ]; then
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" udp dport { 0-65535 } redirect to $T_PROXY_PORT_UDP
fi
else
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" tcp dport { 0-65535 } redirect to $TOR_TRANS_PORT
if [ "$TOR_ALLOW_UDP" = "1" ]; then
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" udp dport { 0-65535 } redirect to $TOR_TRANS_PORT
fi
_nft_sets="${NFTSET_ONION} ${_nft_sets}"
fi
for _set in $_nft_sets
do
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${_set}" counter goto "$NFT_ACTION_CHAIN"
done
if [ "$PROXY_MODE" = "2" ]; then
IptVpnRouteAdd
fi
}
NftMainDelete() {
$NFT_CMD flush chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN"
$NFT_CMD delete chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN"
$NFT_CMD flush chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN"
$NFT_CMD delete chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN"
$NFT_CMD flush chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
$NFT_CMD delete chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
$NFT_CMD flush chain $NFT_TABLE "$NFT_ACTION_CHAIN"
$NFT_CMD delete chain $NFT_TABLE "$NFT_ACTION_CHAIN"
IptVpnRouteDel 2> /dev/null
}
NftLocalClientsAdd() {
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" jump "$NFT_BLLIST_CHAIN"
}
NftListBllistChain() {
$NFT_CMD -t list chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
}
NftListBllistChainJson() {
$NFT_CMD -t -j list chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
}
NftReturnStatus() {
$NFT_CMD -c add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" continue &> /dev/null
return $?
}