mirror of
https://github.com/gSpotx2f/ruantiblock_openwrt.git
synced 2026-05-13 14:10:59 +00:00
1365 lines
55 KiB
Bash
Executable File
1365 lines
55 KiB
Bash
Executable File
#!/bin/sh
|
||
|
||
########################################################################
|
||
#
|
||
# Ruantiblock
|
||
# (с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||
#
|
||
########################################################################
|
||
|
||
export NAME="ruantiblock"
|
||
export APP_EXEC="$0"
|
||
export APP_NAME="$(basename $0)"
|
||
export LANG="en_US.UTF-8"
|
||
export LANGUAGE="en"
|
||
|
||
#################### Platform-specific settings ########################
|
||
|
||
CONFIG_DIR="/etc/${NAME}"
|
||
CONFIG_FILE="${CONFIG_DIR}/${NAME}.conf"
|
||
SCRIPTS_DIR="/usr/share/${NAME}"
|
||
export DATA_DIR="/var/${NAME}"
|
||
export MODULES_DIR="/usr/libexec/${NAME}"
|
||
RUN_FILES_DIR="/var/run"
|
||
### Директория доп. конфигов dnsmasq
|
||
export DNSMASQ_CONFDIR="/var/dnsmasq.d"
|
||
### Команда для перезапуска dnsmasq
|
||
export DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart"
|
||
### Директория для html-страницы статуса (не используется в OpenWrt)
|
||
export HTML_DIR="/www"
|
||
|
||
########################## Default Settings ############################
|
||
|
||
### Режим обработки пакетов в правилах nftables (1 - Tor, 2 - VPN, 3 - Прозрачный прокси)
|
||
export PROXY_MODE=1
|
||
### Применять правила проксификации для трафика локальных сервисов роутера (0 - выкл, 1 - вкл)
|
||
export PROXY_LOCAL_CLIENTS=0
|
||
### Удаление записей сетов перед началом обновления (для освобождения оперативной памяти перед обновлением сетов) (0 - выкл, 1 - вкл)
|
||
export NFTSET_CLEAR_SETS=0
|
||
### Исключить из обхода блокировок пакеты, у которых адрес назначения совпадает с любым IP адресом любого из интерфейсов роутера (0 - выкл, 1 - вкл)
|
||
export IGNORE_LOCAL_IP=1
|
||
### Режим фильтра хостов которым разрешено обходить блокировки (0 - выкл., 1 - только адреса из списка, 2 - любые адреса кроме присутствующих в списке)
|
||
export ALLOWED_HOSTS_MODE=0
|
||
### Список IP адресов хостов для фильтра, через пробел (прим.: 192.168.0.10 192.168.0.15)
|
||
export ALLOWED_HOSTS_LIST=""
|
||
### Порт прозрачного прокси Tor (параметр TransPort в torrc)
|
||
export TOR_TRANS_PORT=9040
|
||
### DNS-сервер для резолвинга в домене .onion (Tor)
|
||
export ONION_DNS_ADDR="127.0.0.1#9053"
|
||
### VPN интерфейс для правил маршрутизации
|
||
export IF_VPN="tun0"
|
||
### IP адрес шлюза для VPN конфигурации. Если не задан, используется адрес VPN интерфейса (или адрес пира для протоколов PPP)
|
||
export VPN_GW_IP=""
|
||
### Начальный номер таблицы маршрутизации для отправки пакетов в VPN туннель
|
||
export VPN_ROUTE_TABLE_ID_START=149
|
||
### Начальный номер таблицы маршрутизации для отправки локальных пакетов в tproxy
|
||
export TPROXY_ROUTE_TABLE_ID_START=201
|
||
### Приоритет правила отбора пакетов при маршрутизации в VPN-интерфейс
|
||
export VPN_RULE_PRIO=1000
|
||
### Приоритет правила отбора пакетов при маршрутизации в lo интерфейс
|
||
export LO_RULE_PRIO=1000
|
||
### Способ добавления в таблицу маршрутизации правила для отправки пакетов в VPN туннель (0 - hotplug.d, 1 - скрипт ruab_route_check)
|
||
export VPN_ROUTE_CHECK=0
|
||
### Тип прозрачного прокси (0 - redirect, 1 - tproxy)
|
||
export T_PROXY_TYPE=0
|
||
### TCP порт прокси в режиме прозрачного прокси
|
||
export T_PROXY_PORT_TCP=1100
|
||
### UDP порт прокси в режиме прозрачного прокси
|
||
export T_PROXY_PORT_UDP=1100
|
||
### Отправлять в прозрачный прокси UDP-трафик (0 - выкл, 1 - вкл)
|
||
export T_PROXY_ALLOW_UDP=0
|
||
### Начальное значение метки для отбора пакетов в фильтрах
|
||
export PKTS_MARK_START=8
|
||
### Запись событий в syslog (0 - выкл, 1 - вкл)
|
||
export ENABLE_LOGGING=1
|
||
### Вывод дополнительных сообщений в лог (0 - выкл, 1, 2)
|
||
export DEBUG=0
|
||
### Файл для вывода некоторых отладочных сообщений
|
||
export DEBUG_FILE="/tmp/${NAME}.debug"
|
||
### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt)
|
||
export ENABLE_HTML_INFO=0
|
||
### Максимальное кол-во элементов списка nftables
|
||
export NFTSET_MAXELEM_CIDR=65535
|
||
export NFTSET_MAXELEM_IP=1000000
|
||
export NFTSET_MAXELEM_DNSMASQ=65535
|
||
export NFTSET_MAXELEM_BYPASS_IP=65535
|
||
export NFTSET_MAXELEM_BYPASS_FQDN=65535
|
||
### Политика отбора элементов в сетах nftables. "performance" - производительность и большее потребление RAM. "memory" - хуже производительность и меньше потребление RAM
|
||
export NFTSET_POLICY_CIDR="memory"
|
||
export NFTSET_POLICY_IP="memory"
|
||
export NFTSET_POLICY_DNSMASQ="performance"
|
||
### Таймаут для записей в сете $NFTSET_DNSMASQ
|
||
export NFTSET_DNSMASQ_TIMEOUT="150m"
|
||
### Динамическое обновление таймаута записей в сете $NFTSET_DNSMASQ (0 - выкл, 1 - вкл)
|
||
export NFTSET_DNSMASQ_TIMEOUT_UPDATE=1
|
||
### Приоритет правил отбора пакетов nftables
|
||
export NFT_PRIO=-140
|
||
### Приоритет правил отбора пакетов nftables для трафика локальных клиентов
|
||
export NFT_PRIO_LOCAL=-140
|
||
### Кол-во попыток скачивания удаленного файла записей пользователя (в случае неудачи)
|
||
export USER_ENTRIES_REMOTE_DOWNLOAD_ATTEMPTS=3
|
||
### Таймаут между попытками скачивания
|
||
export USER_ENTRIES_REMOTE_DOWNLOAD_TIMEOUT=60
|
||
### Директория конфигов экземпляров записей пользователя
|
||
export USER_INSTANCES_DIR="${CONFIG_DIR}/user_instances"
|
||
### Директория списков записей пользователя
|
||
export USER_LISTS_DIR="${CONFIG_DIR}/user_lists"
|
||
### Переменные экземпляров записей пользователя
|
||
export USER_INSTANCE_VARS="U_ENABLED U_NAME U_PROXY_MODE U_TOR_TRANS_PORT U_ONION_DNS_ADDR U_IF_VPN U_VPN_GW_IP U_T_PROXY_TYPE U_T_PROXY_PORT_TCP U_T_PROXY_PORT_UDP U_T_PROXY_ALLOW_UDP U_USER_ENTRIES_DNS U_USER_ENTRIES_REMOTE U_ENABLE_ENTRIES_REMOTE_PROXY U_ENABLE_FPROXY U_FPROXY_LIST"
|
||
### Кол-во экземпляров записей пользователя (не более 50!)
|
||
export USER_INSTANCES_MAX=5
|
||
### Режим списка IP адресов исключаемых из обхода блокировок (0 - выкл, 1 - вкл)
|
||
export BYPASS_MODE=0
|
||
### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет
|
||
export BYPASS_ENTRIES_DNS=""
|
||
### Файл исключаемых записей
|
||
export BYPASS_ENTRIES_FILE="${CONFIG_DIR}/bypass_entries"
|
||
### Включение режима полного прокси (0 - выкл, 1 - вкл)
|
||
export ENABLE_FPROXY=0
|
||
### Список IP адресов хостов для режима полного прокси, через пробел (прим.: 192.168.0.10 192.168.0.15)
|
||
export FPROXY_LIST=""
|
||
### Список приватных сетей для режима полного прокси, через пробел
|
||
export FPROXY_PRIVATE_NETS="192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 100.64.0.0/10 169.254.0.0/16"
|
||
### Режим безопасного обновления блэклиста. Скачивание во временный файл и затем замена основного. Увеличивает потребление памяти (0 - выкл, 1 - вкл)
|
||
export ENABLE_TMP_DOWNLOADS=0
|
||
### Скачивать блэклисты через прокси
|
||
export ENABLE_BLLIST_PROXY=0
|
||
### Список хостов источников блэклиста
|
||
export BLLIST_HOSTS="reestr.rublacklist.net raw.githubusercontent.com app.assembla.com antifilter.download blockedin.org"
|
||
### Кол-во попыток обновления блэклиста (в случае неудачи)
|
||
export MODULE_RUN_ATTEMPTS=3
|
||
### Таймаут между попытками обновления
|
||
export MODULE_RUN_TIMEOUT=60
|
||
### Модули для получения и обработки блэклиста
|
||
export BLLIST_MODULE=""
|
||
#export BLLIST_MODULE="${MODULES_DIR}/ruab_parser.lua"
|
||
#export BLLIST_MODULE="${MODULES_DIR}/ruab_parser.py"
|
||
|
||
##############################
|
||
|
||
### Режим обхода блокировок: ruantiblock-ip, ruantiblock-fqdn, zapret-info-ip, zapret-info-fqdn, zapret-info-fqdn-only, rublacklist-ip, rublacklist-fqdn, rublacklist-fqdn-only, antifilter-ip, antifilter-fqdn, antifilter-fqdn-only, fz-ip, fz-fqdn, fz-fqdn-only
|
||
export BLLIST_PRESET=""
|
||
### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит
|
||
export BLLIST_MIN_ENTRIES=3000
|
||
### Лимит IP адресов. При достижении, в конфиг nftables будет добавлена вся подсеть /24 вместо множества IP адресов пренадлежащих этой сети (0 - выкл)
|
||
export BLLIST_IP_LIMIT=0
|
||
### Файл с подсетями класса C (/24). IP адреса из этих подсетей не группируются при оптимизации (записи д.б. в виде: 68.183.221. 149.154.162. и пр. Одна запись на строку)
|
||
export BLLIST_GR_EXCLUDED_NETS_FILE="${CONFIG_DIR}/gr_excluded_nets"
|
||
### Группировать идущие подряд IP адреса в подсетях /24 в диапазоны CIDR
|
||
export BLLIST_SUMMARIZE_IP=0
|
||
### Группировать идущие подряд подсети /24 в диапазоны CIDR
|
||
export BLLIST_SUMMARIZE_CIDR=0
|
||
### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига nftables (0 - выкл, 1 - вкл)
|
||
export BLLIST_IP_FILTER=0
|
||
### Тип фильтра IP (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
|
||
export BLLIST_IP_FILTER_TYPE=0
|
||
### Файл с шаблонами IP для опции BLLIST_IP_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
|
||
export BLLIST_IP_FILTER_FILE="${CONFIG_DIR}/ip_filter"
|
||
### Включение опции исключения IP/CIDR из блэклиста
|
||
export BLLIST_IP_EXCLUDED_ENABLE=0
|
||
### Файл с записями IP/CIDR для опции BLLIST_IP_EXCLUDED_ENABLE
|
||
export BLLIST_IP_EXCLUDED_FILE="${CONFIG_DIR}/ip_excluded"
|
||
### Включение опции исключения IP входящих в подсети CIDR
|
||
export BLLIST_CIDR_EXCLUDED_ENABLE=0
|
||
### Файл с записями IP/CIDR для опции BLLIST_CIDR_EXCLUDED_ENABLE
|
||
export BLLIST_CIDR_EXCLUDED_FILE="${CONFIG_DIR}/cidr_excluded"
|
||
### Лимит субдоменов для группировки. При достижении, в конфиг dnsmasq будет добавлен весь домен 2-го ур-ня вместо множества субдоменов (0 - выкл)
|
||
export BLLIST_SD_LIMIT=0
|
||
### Файл с SLD не подлежащими группировке при оптимизации (одна запись на строку)
|
||
export BLLIST_GR_EXCLUDED_SLD_FILE="${CONFIG_DIR}/gr_excluded_sld"
|
||
### Файл с масками SLD не подлежащими группировке при оптимизации (одна запись на строку)
|
||
export BLLIST_GR_EXCLUDED_SLD_MASKS_FILE="${CONFIG_DIR}/gr_excluded_sld_mask"
|
||
### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - выкл, 1 - вкл)
|
||
export BLLIST_FQDN_FILTER=0
|
||
### Тип фильтра FQDN (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
|
||
export BLLIST_FQDN_FILTER_TYPE=0
|
||
### Файл с шаблонами FQDN для опции BLLIST_FQDN_FILTER (каждый шаблон в отдельной строке. # в первом символе строки - комментирует строку)
|
||
export BLLIST_FQDN_FILTER_FILE="${CONFIG_DIR}/fqdn_filter"
|
||
### Включение опции исключения FQDN из блэклиста
|
||
export BLLIST_FQDN_EXCLUDED_ENABLE=0
|
||
### Файл с записями FQDN для опции BLLIST_FQDN_EXCLUDED_ENABLE
|
||
export BLLIST_FQDN_EXCLUDED_FILE="${CONFIG_DIR}/fqdn_excluded"
|
||
### Включение опции исключения записей определённых гос.органов из блэклиста
|
||
export BLLIST_ORG_EXCLUDED_ENABLE=0
|
||
### Файл с записями для опции BLLIST_ORG_EXCLUDED_ENABLE
|
||
export BLLIST_ORG_EXCLUDED_FILE="${CONFIG_DIR}/org_excluded"
|
||
### Обрезка www[0-9]. в FQDN (0 - выкл, 1 - вкл)
|
||
export BLLIST_STRIP_WWW=1
|
||
### Преобразование кириллических доменов в punycode (0 - выкл, 1 - вкл)
|
||
export BLLIST_ENABLE_IDN=0
|
||
### Перенаправлять DNS-запросы на альтернативный DNS-сервер для заблокированных FQDN (0 - выкл, 1 - вкл)
|
||
export BLLIST_ALT_NSLOOKUP=0
|
||
### Альтернативный DNS-сервер
|
||
export BLLIST_ALT_DNS_ADDR="8.8.8.8"
|
||
|
||
########################## Instances defaults ##########################
|
||
|
||
INSTANCES_DEF_PROXY_MODE=$PROXY_MODE
|
||
INSTANCES_DEF_TOR_TRANS_PORT=$TOR_TRANS_PORT
|
||
INSTANCES_DEF_IF_VPN=$IF_VPN
|
||
INSTANCES_DEF_T_PROXY_TYPE=$T_PROXY_TYPE
|
||
INSTANCES_DEF_T_PROXY_PORT_TCP=$T_PROXY_PORT_TCP
|
||
INSTANCES_DEF_T_PROXY_PORT_UDP=$T_PROXY_PORT_UDP
|
||
INSTANCES_DEF_T_PROXY_ALLOW_UDP=$T_PROXY_ALLOW_UDP
|
||
INSTANCES_DEF_ENABLE_BLLIST_PROXY=$ENABLE_BLLIST_PROXY
|
||
INSTANCES_DEF_ENABLE_FPROXY=$ENABLE_FPROXY
|
||
|
||
############################ Configuration #############################
|
||
|
||
### External config
|
||
[ -f "$CONFIG_FILE" ] && . "$CONFIG_FILE"
|
||
|
||
CONFIG_SCRIPT="${SCRIPTS_DIR}/config_script"
|
||
export USER_INSTANCES_COMMON="${SCRIPTS_DIR}/user_instances_common"
|
||
export CONFIG_SCRIPT_USER_INSTANCES="${SCRIPTS_DIR}/config_script_user_instances"
|
||
BLLIST_SOURCES_SCRIPT="${SCRIPTS_DIR}/blacklist_sources"
|
||
|
||
### Event scripts
|
||
POST_START_SCRIPT="${MODULES_DIR}/post_start_script"
|
||
POST_STOP_SCRIPT="${MODULES_DIR}/post_stop_script"
|
||
PRE_UPDATE_SCRIPT="${MODULES_DIR}/pre_update_script"
|
||
POST_UPDATE_SCRIPT="${MODULES_DIR}/post_update_script"
|
||
|
||
### Config script
|
||
[ -f "$CONFIG_SCRIPT" ] && . "$CONFIG_SCRIPT"
|
||
|
||
export DNSMASQ_DATA_FILE_BYPASS="${DNSMASQ_CONFDIR}/00-${NAME}_bypass.dnsmasq"
|
||
export DNSMASQ_DATA_FILE_USER_INSTANCES="${DNSMASQ_CONFDIR}/01-${NAME}_user_instances.dnsmasq"
|
||
export DNSMASQ_DATA_FILE="${DNSMASQ_CONFDIR}/02-${NAME}.dnsmasq"
|
||
|
||
### Utilities
|
||
export AWK_CMD="awk"
|
||
NFT_CMD="$(which nft)"
|
||
if [ $? -ne 0 ]; then
|
||
echo " Error! Nftables doesn't exists" >&2
|
||
exit 1
|
||
fi
|
||
LOGGER_CMD="$(which logger)"
|
||
if [ "$ENABLE_LOGGING" = "1" -a $? -ne 0 ]; then
|
||
echo " Logger doesn't exists" >&2
|
||
ENABLE_LOGGING=0
|
||
fi
|
||
export LOGGER_CMD
|
||
export LOGGER_PARAMS="-t ${APP_NAME}"
|
||
WGET_CMD="$(which wget)"
|
||
if [ $? -ne 0 ]; then
|
||
echo " Error! Wget doesn't exists" >&2
|
||
exit 1
|
||
fi
|
||
export WGET_CMD
|
||
export WGET_PARAMS="--no-check-certificate -q -O"
|
||
NSLOOKUP_CMD="$(which nslookup)"
|
||
if [ $? -ne 0 ]; then
|
||
echo " Error! Nslookup doesn't exists" >&2
|
||
exit 1
|
||
fi
|
||
IP_CMD="$(which ip)"
|
||
if [ $? -ne 0 ]; then
|
||
echo " Error! Iproute2 doesn't exists" >&2
|
||
exit 1
|
||
fi
|
||
export IP_CMD
|
||
USER_ENTRIES_PARSER="${MODULES_DIR}/ruab_parser_user_entries"
|
||
ROUTE_CHECK_EXEC="${MODULES_DIR}/ruab_route_check"
|
||
export IP_DATA_FILE="${DATA_DIR}/${NAME}.ip"
|
||
export IP_DATA_FILE_BYPASS="${DATA_DIR}/${NAME}_bypass.ip"
|
||
export IP_DATA_FILE_USER_INSTANCES="${DATA_DIR}/${NAME}_user_instances.ip"
|
||
export NFT_TABLE="ip r"
|
||
export NFT_TABLE_DNSMASQ="4#ip#r"
|
||
export NFTSET_LOCAL_IP="local_ip"
|
||
export NFTSET_ALLOWED_HOSTS="allowed_ip"
|
||
export NFTSET_BYPASS_IP="bi"
|
||
export NFTSET_BYPASS_FQDN="bd"
|
||
export NFTSET_FPROXY="fproxy"
|
||
export NFTSET_FPROXY_LOCAL="fproxy_local"
|
||
export NFTSET_BLLIST_PROXY="bllist_proxy"
|
||
export NFTSET_ONION="onion"
|
||
export NFTSET_CIDR="c"
|
||
export NFTSET_IP="i"
|
||
export NFTSET_DNSMASQ="d"
|
||
export NFTSET_LOCAL_IP_TYPE="ipv4_addr"
|
||
export NFTSET_ALLOWED_HOSTS_TYPE="ipv4_addr"
|
||
export NFTSET_BYPASS_IP_TYPE="ipv4_addr"
|
||
export NFTSET_BYPASS_FQDN_TYPE="ipv4_addr"
|
||
export NFTSET_FPROXY_TYPE="ipv4_addr"
|
||
export NFTSET_FPROXY_LOCAL_TYPE="ipv4_addr"
|
||
export NFTSET_BLLIST_PROXY_TYPE="ipv4_addr"
|
||
export NFTSET_CIDR_TYPE="ipv4_addr"
|
||
export NFTSET_IP_TYPE="ipv4_addr"
|
||
export NFTSET_DNSMASQ_TYPE="ipv4_addr"
|
||
export NFTSET_CIDR_PATTERN="set %s {type ${NFTSET_CIDR_TYPE};size ${NFTSET_MAXELEM_CIDR};policy ${NFTSET_POLICY_CIDR};flags interval;auto-merge;"
|
||
export NFTSET_IP_PATTERN="set %s {type ${NFTSET_IP_TYPE};size ${NFTSET_MAXELEM_IP};policy ${NFTSET_POLICY_IP};flags dynamic;"
|
||
export NFTSET_CIDR_STRING_MAIN=$(printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}")
|
||
export NFTSET_IP_STRING_MAIN=$(printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}")
|
||
export NFTSET_BYPASS_IP_STRING="set ${NFTSET_BYPASS_IP} {type ${NFTSET_BYPASS_IP_TYPE};size ${NFTSET_MAXELEM_BYPASS_IP};policy ${NFTSET_POLICY_CIDR};flags interval;auto-merge;"
|
||
export UPDATE_STATUS_FILE="${DATA_DIR}/update_status"
|
||
export USER_ENTRIES_STATUS_FILE="${DATA_DIR}/user_entries_status"
|
||
U_PID_FILE="${RUN_FILES_DIR}/${NAME}_update.pid"
|
||
START_PID_FILE="${RUN_FILES_DIR}/${NAME}_start.pid"
|
||
TOKEN_FILE="${RUN_FILES_DIR}/${NAME}.token"
|
||
export HTML_OUTPUT="${HTML_DIR}/${NAME}.html"
|
||
NFT_FUNCTIONS="${SCRIPTS_DIR}/nft_functions"
|
||
INFO_OUTPUT_FUNCTION="${SCRIPTS_DIR}/info_output"
|
||
export IP_DATA_FILE_TMP="${IP_DATA_FILE}.tmp"
|
||
export IP_DATA_FILE_USER_INSTANCES_TMP="${IP_DATA_FILE_USER_INSTANCES}.tmp"
|
||
export DNSMASQ_DATA_FILE_USER_INSTANCES_TMP="${DNSMASQ_DATA_FILE_USER_INSTANCES}.tmp"
|
||
export DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
|
||
export UPDATE_STATUS_FILE_TMP="${UPDATE_STATUS_FILE}.tmp"
|
||
export USER_ENTRIES_STATUS_FILE_TMP="${USER_ENTRIES_STATUS_FILE}.tmp"
|
||
export USER_INSTANCES_ALL=""
|
||
export USER_INSTANCES_ALL_FNAMES=""
|
||
export USER_INSTANCES_VPN=""
|
||
export USER_INSTANCES_VPN_FNAMES=""
|
||
export USER_INSTANCES_CFG=""
|
||
export USER_INSTANCES_CFG_FNAMES=""
|
||
INSTANCES_CACHE="${RUN_FILES_DIR}/${NAME}.instances"
|
||
DL_IPSET_URL=""
|
||
DL_DMASK_URL=""
|
||
DL_STAT_URL=""
|
||
|
||
######################### External functions ###########################
|
||
|
||
. "$NFT_FUNCTIONS"
|
||
. "$USER_INSTANCES_COMMON"
|
||
if [ -f "$INFO_OUTPUT_FUNCTION" ]; then
|
||
. "$INFO_OUTPUT_FUNCTION"
|
||
else
|
||
ENABLE_HTML_INFO=0
|
||
fi
|
||
|
||
############################## Functions ###############################
|
||
|
||
Help() {
|
||
cat << EOF
|
||
Usage: ${APP_NAME} start|force-start|stop|destroy|restart|reload|update|force-update|blacklist-files|status|raw-status|html-info|help
|
||
start : Start
|
||
force-start : Removing the PID-file before running
|
||
stop : Stop
|
||
destroy : Stop, remove nft table and clear all data files
|
||
restart : Restart
|
||
reload : Renew nftables configuration
|
||
update : Update blacklist
|
||
force-update : Force update blacklist
|
||
blacklist-files : Create ${IP_DATA_FILE}, ${IP_DATA_FILE_USER_INSTANCES}, ${DNSMASQ_DATA_FILE}, ${DNSMASQ_DATA_FILE_USER_INSTANCES}, ${IP_DATA_FILE_BYPASS}, ${DNSMASQ_DATA_FILE_BYPASS} (without network functions)
|
||
status : Status & some info
|
||
raw-status : Return code: 0 - enabled, 1 - error, 2 - disabled, 3 - starting, 4 - updating
|
||
html-info : Return the html-info output
|
||
-h|--help|help : This message
|
||
Examples:
|
||
${APP_NAME} start
|
||
${APP_NAME} force-start
|
||
${APP_NAME} stop
|
||
${APP_NAME} destroy
|
||
${APP_NAME} restart
|
||
${APP_NAME} reload
|
||
${APP_NAME} update
|
||
${APP_NAME} force-update
|
||
${APP_NAME} blacklist-files
|
||
${APP_NAME} status
|
||
${APP_NAME} raw-status
|
||
${APP_NAME} html-info
|
||
EOF
|
||
}
|
||
|
||
MakeLogRecord() {
|
||
if [ "$ENABLE_LOGGING" = "1" ]; then
|
||
$LOGGER_CMD $LOGGER_PARAMS -p "user.${1}" "$2"
|
||
fi
|
||
}
|
||
|
||
Download() {
|
||
if [ $DEBUG -ge 1 ]; then
|
||
echo " ruantiblock.Download ${1} ${2}" >&2
|
||
MakeLogRecord "debug" "ruantiblock.Download ${1} ${2}"
|
||
fi
|
||
|
||
$WGET_CMD $WGET_PARAMS "$1" "$2"
|
||
if [ $? -ne 0 ]; then
|
||
echo " Downloading failed! Connection error (${2})" >&2
|
||
MakeLogRecord "err" "Downloading failed! Connection error (${2})"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
DownloadNativeBlacklist() {
|
||
local _ip_data_file _dnsmasq_data_file _update_status_file _return_code=0
|
||
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
|
||
_ip_data_file="$IP_DATA_FILE_TMP"
|
||
_dnsmasq_data_file="$DNSMASQ_DATA_FILE_TMP"
|
||
_update_status_file="$UPDATE_STATUS_FILE_TMP"
|
||
rm -f "$_ip_data_file" "$_dnsmasq_data_file" "$_update_status_file"
|
||
else
|
||
_ip_data_file="$IP_DATA_FILE"
|
||
_dnsmasq_data_file="$DNSMASQ_DATA_FILE"
|
||
_update_status_file="$UPDATE_STATUS_FILE"
|
||
fi
|
||
if [ -n "$DL_IPSET_URL" -a -n "$DL_DMASK_URL" -a -n "$DL_STAT_URL" ]; then
|
||
Download "$_ip_data_file" "$DL_IPSET_URL"
|
||
if [ $? -ne 0 ]; then
|
||
_return_code=1
|
||
else
|
||
Download "$_dnsmasq_data_file" "$DL_DMASK_URL"
|
||
if [ $? -ne 0 ]; then
|
||
_return_code=1
|
||
else
|
||
Download "$_update_status_file" "$DL_STAT_URL"
|
||
if [ $? -ne 0 ]; then
|
||
_return_code=1
|
||
fi
|
||
fi
|
||
fi
|
||
else
|
||
echo " Native blacklist configuration error (${1})" >&2
|
||
MakeLogRecord "err" "Native blacklist configuration error (${1})"
|
||
exit 1
|
||
fi
|
||
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
|
||
if [ $_return_code -eq 0 ]; then
|
||
mv -f "$_ip_data_file" "$IP_DATA_FILE"
|
||
mv -f "$_dnsmasq_data_file" "$DNSMASQ_DATA_FILE"
|
||
mv -f "$_update_status_file" "$UPDATE_STATUS_FILE"
|
||
else
|
||
rm -f "$_ip_data_file" "$_dnsmasq_data_file" "$_update_status_file"
|
||
fi
|
||
fi
|
||
return $_return_code
|
||
}
|
||
|
||
RestartDnsmasq() {
|
||
eval $(echo "$DNSMASQ_RESTART_CMD")
|
||
}
|
||
|
||
FlushNftSets() {
|
||
local _set
|
||
for _set in "$@"
|
||
do
|
||
$NFT_CMD flush set $NFT_TABLE "$_set" &> /dev/null
|
||
done
|
||
}
|
||
|
||
FlushInstancesNftSets() {
|
||
local _arg="$1" _name
|
||
for _name in $USER_INSTANCES_ALL " "
|
||
do
|
||
if [ "$_name" = " " ]; then
|
||
_name=""
|
||
else
|
||
_name=".${_name}"
|
||
fi
|
||
case "$_arg" in
|
||
bllist)
|
||
FlushNftSets "${NFTSET_CIDR}${_name}" "${NFTSET_IP}${_name}" "${NFTSET_DNSMASQ}${_name}" "${NFTSET_ONION}${_name}"
|
||
;;
|
||
*)
|
||
FlushNftSets "${NFTSET_FPROXY}${_name}" "${NFTSET_BLLIST_PROXY}${_name}" "${NFTSET_CIDR}${_name}" "${NFTSET_IP}${_name}" "${NFTSET_DNSMASQ}${_name}" "${NFTSET_ONION}${_name}"
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
FormatNftSetElemsList() {
|
||
printf "$1" | $AWK_CMD '{gsub(/[ ]+/, ",", $0); printf $0;}'
|
||
}
|
||
|
||
UpdateLocalIpSets() {
|
||
local _local_ips _fproxy_private
|
||
_local_ips=$($IP_CMD -4 addr list 2> /dev/null | $AWK_CMD '/inet/{if($2 !~ /^(127|0)/) printf $2 ","}')
|
||
FlushNftSets "$NFTSET_LOCAL_IP"
|
||
if [ -n "$_local_ips" ]; then
|
||
$NFT_CMD add element $NFT_TABLE "$NFTSET_LOCAL_IP" { "$_local_ips" }
|
||
fi
|
||
FlushNftSets "$NFTSET_FPROXY_LOCAL"
|
||
_fproxy_private=$(FormatNftSetElemsList "$FPROXY_PRIVATE_NETS")
|
||
if [ -n "$_fproxy_private" ]; then
|
||
$NFT_CMD add element $NFT_TABLE "$NFTSET_FPROXY_LOCAL" { "$_fproxy_private" }
|
||
fi
|
||
if [ -n "$_local_ips" ]; then
|
||
$NFT_CMD add element $NFT_TABLE "$NFTSET_FPROXY_LOCAL" { "$_local_ips" }
|
||
fi
|
||
}
|
||
|
||
AddBaseNftSets() {
|
||
local _allowed_hosts
|
||
$NFT_CMD add set $NFT_TABLE "$NFTSET_LOCAL_IP" { type "$NFTSET_LOCAL_IP_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||
$NFT_CMD add set $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { type "$NFTSET_ALLOWED_HOSTS_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||
_allowed_hosts=$(FormatNftSetElemsList "$ALLOWED_HOSTS_LIST")
|
||
if [ -n "$_allowed_hosts" ]; then
|
||
$NFT_CMD add element $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { "$_allowed_hosts" }
|
||
fi
|
||
$NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_IP" { type "$NFTSET_BYPASS_IP_TYPE"\; size $NFTSET_MAXELEM_BYPASS_IP\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||
$NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_FQDN" { type "$NFTSET_BYPASS_FQDN_TYPE"\; size $NFTSET_MAXELEM_BYPASS_FQDN\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
|
||
$NFT_CMD add set $NFT_TABLE "$NFTSET_FPROXY_LOCAL" { type "$NFTSET_FPROXY_LOCAL_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||
UpdateLocalIpSets
|
||
}
|
||
|
||
MakeInstanceNftSets() {
|
||
local _name="$1" _fproxy_list="$2" _fproxy_hosts
|
||
if [ "$_name" = " " ]; then
|
||
_name=""
|
||
else
|
||
_name=".${_name}"
|
||
fi
|
||
$NFT_CMD add set $NFT_TABLE "${NFTSET_CIDR}${_name}" { type "$NFTSET_CIDR_TYPE"\; size $NFTSET_MAXELEM_CIDR\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||
$NFT_CMD add set $NFT_TABLE "${NFTSET_IP}${_name}" { type "$NFTSET_IP_TYPE"\; size $NFTSET_MAXELEM_IP\; policy "$NFTSET_POLICY_IP"\; flags dynamic\; }
|
||
$NFT_CMD add set $NFT_TABLE "${NFTSET_DNSMASQ}${_name}" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
|
||
$NFT_CMD add set $NFT_TABLE "${NFTSET_ONION}${_name}" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
|
||
$NFT_CMD add set $NFT_TABLE "${NFTSET_FPROXY}${_name}" { type "$NFTSET_FPROXY_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||
_fproxy_hosts=$(FormatNftSetElemsList "$_fproxy_list")
|
||
if [ -n "$_fproxy_hosts" ]; then
|
||
$NFT_CMD add element $NFT_TABLE "${NFTSET_FPROXY}${_name}" { "$_fproxy_hosts" }
|
||
fi
|
||
$NFT_CMD add set $NFT_TABLE "${NFTSET_BLLIST_PROXY}${_name}" { type "$NFTSET_BLLIST_PROXY_TYPE"\; policy "$NFTSET_POLICY_IP"\; flags dynamic\; }
|
||
}
|
||
|
||
AddInstancesNftSets() {
|
||
local _inst
|
||
for _inst in $USER_INSTANCES_ALL_FNAMES
|
||
do
|
||
IncludeUserInstanceVars "$_inst"
|
||
MakeInstanceNftSets "$U_NAME" "$U_FPROXY_LIST"
|
||
ClearUserInstanceVars
|
||
done
|
||
MakeInstanceNftSets " " "$FPROXY_LIST"
|
||
}
|
||
|
||
UpdateBllistProxySet() {
|
||
local _name="$1" _urls="$2" _host _ip_string=""
|
||
if [ "$_name" = " " ]; then
|
||
_name=""
|
||
else
|
||
_name=".${_name}"
|
||
fi
|
||
for _host in $(echo "$_urls" | $AWK_CMD '
|
||
BEGIN {
|
||
RS = " ";
|
||
}
|
||
{
|
||
gsub("\n", "", $0);
|
||
sub(/^https?:\/\//, "", $0);
|
||
sub(/\/.*$/, "", $0);
|
||
sub(/:[0-9]{2,5}$/, "", $0);
|
||
if($0 ~ /^([a-z0-9._-]+[.])+([a-z]{2,}|xn--[a-z0-9]+)$/ || $0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}$/) {
|
||
hosts_arr[$0];
|
||
};
|
||
}
|
||
END {
|
||
for(i in hosts_arr) {
|
||
printf i " ";
|
||
};
|
||
}')
|
||
do
|
||
if printf "$_host" | $AWK_CMD '{exit ($0 ~ /^([0-9]{1,3}.){3}[0-9]{1,3}$/) ? 0 : 1}'; then
|
||
_ip_string="${_ip_string}${_host} "
|
||
else
|
||
_ip_string="${_ip_string}$($NSLOOKUP_CMD $_host 2> /dev/null | $AWK_CMD '/^Address: ([0-9]{1,3}.){3}[0-9]{1,3}$/ {printf $2" "}')"
|
||
fi
|
||
done
|
||
_ip_string=$(FormatNftSetElemsList "$_ip_string")
|
||
|
||
if [ $DEBUG -ge 1 ]; then
|
||
echo " ruantiblock.UpdateBllistProxySet()._ip_string=${_ip_string}; _name=${_name}" >&2
|
||
MakeLogRecord "debug" "ruantiblock.UpdateBllistProxySet()._ip_string=${_ip_string}; _name=${_name}"
|
||
fi
|
||
|
||
if [ -n "$_ip_string" ]; then
|
||
$NFT_CMD add element $NFT_TABLE "${NFTSET_BLLIST_PROXY}${_name}" { "$_ip_string" }
|
||
fi
|
||
}
|
||
|
||
UpdateBllistSets() {
|
||
local _return_code=0
|
||
if [ -f "$IP_DATA_FILE" -a -f "$IP_DATA_FILE_USER_INSTANCES" -a -f "$IP_DATA_FILE_BYPASS" ]; then
|
||
echo " Updating nft sets..."
|
||
$NFT_CMD -f "$IP_DATA_FILE_BYPASS"
|
||
_return_code=$?
|
||
if [ $_return_code -eq 0 ]; then
|
||
$NFT_CMD -f "$IP_DATA_FILE_USER_INSTANCES"
|
||
_return_code=$?
|
||
if [ $_return_code -eq 0 ]; then
|
||
$NFT_CMD -f "$IP_DATA_FILE"
|
||
_return_code=$?
|
||
fi
|
||
fi
|
||
if [ $_return_code -eq 0 ]; then
|
||
echo " Ok"
|
||
else
|
||
echo " Error! Nft set wasn't updated" >&2
|
||
MakeLogRecord "err" "Error! Nft set wasn't updated"
|
||
fi
|
||
fi
|
||
return $_return_code
|
||
}
|
||
|
||
AddUserInstancesNftRules() {
|
||
local _pkts_mark=$PKTS_MARK_START _inst _vpn_route_table_id=$VPN_ROUTE_TABLE_ID_START _tproxy_route_table_id=$TPROXY_ROUTE_TABLE_ID_START _route_table_id
|
||
for _inst in $USER_INSTANCES_ALL_FNAMES
|
||
do
|
||
IncludeUserInstanceVars "$_inst"
|
||
if [ "$U_PROXY_MODE" = "2" ]; then
|
||
_vpn_route_table_id=$(($_vpn_route_table_id + 1))
|
||
_route_table_id=$_vpn_route_table_id
|
||
elif [ "$U_PROXY_MODE" = "3" -a "$U_T_PROXY_TYPE" = "1" ]; then
|
||
_tproxy_route_table_id=$(($_tproxy_route_table_id + 1))
|
||
_route_table_id=$_tproxy_route_table_id
|
||
else
|
||
_route_table_id=0
|
||
fi
|
||
_pkts_mark=$(($_pkts_mark + 1))
|
||
NftInstanceAdd "\"$U_NAME\"" $_pkts_mark ${U_PROXY_MODE:=$INSTANCES_DEF_PROXY_MODE} ${U_TOR_TRANS_PORT:=$INSTANCES_DEF_TOR_TRANS_PORT} $_route_table_id "\"${U_IF_VPN:=$INSTANCES_DEF_IF_VPN}\"" ${U_T_PROXY_TYPE:=$INSTANCES_DEF_T_PROXY_TYPE} ${U_T_PROXY_PORT_TCP:=$INSTANCES_DEF_T_PROXY_PORT_TCP} ${U_T_PROXY_PORT_UDP:=$INSTANCES_DEF_T_PROXY_PORT_UDP} ${U_T_PROXY_ALLOW_UDP:=$INSTANCES_DEF_T_PROXY_ALLOW_UDP} ${U_ENABLE_ENTRIES_REMOTE_PROXY:=$INSTANCES_DEF_ENABLE_BLLIST_PROXY} ${U_ENABLE_FPROXY:=$INSTANCES_DEF_ENABLE_FPROXY} "\"$U_VPN_GW_IP\""
|
||
ClearUserInstanceVars
|
||
done
|
||
}
|
||
|
||
DeleteUserInstancesNftRules() {
|
||
local _inst _i=1 _j=1
|
||
for _inst in $USER_INSTANCES_CFG_FNAMES
|
||
do
|
||
IncludeUserInstanceVars "$_inst"
|
||
NftInstanceDelete "$U_NAME" 2> /dev/null
|
||
if [ "$U_PROXY_MODE" = "2" ]; then
|
||
NftRouteDelete $(($VPN_ROUTE_TABLE_ID_START + $_i)) 2> /dev/null
|
||
_i=$(($_i + 1))
|
||
elif [ "$U_PROXY_MODE" = "3" -a "$U_T_PROXY_TYPE" = "1" ]; then
|
||
NftRouteDelete $(($TPROXY_ROUTE_TABLE_ID_START + $_j)) 2> /dev/null
|
||
_j=$(($_j + 1))
|
||
fi
|
||
ClearUserInstanceVars
|
||
done
|
||
}
|
||
|
||
AddNftRules() {
|
||
local _chain_prio_first _chain_prio_local _chain_prio_fproxy _chain_prio_action _route_table_id
|
||
_chain_prio_first=$NFT_PRIO
|
||
_chain_prio_local=$NFT_PRIO_LOCAL
|
||
_chain_prio_fproxy=$(($NFT_PRIO + 1))
|
||
_chain_prio_action=$(($NFT_PRIO + 2))
|
||
if [ "$PROXY_MODE" = "2" ]; then
|
||
_route_table_id=$VPN_ROUTE_TABLE_ID_START
|
||
elif [ "$PROXY_MODE" = "3" -a "$T_PROXY_TYPE" = "1" ]; then
|
||
_route_table_id=$TPROXY_ROUTE_TABLE_ID_START
|
||
else
|
||
_route_table_id=0
|
||
fi
|
||
NftAddBaseChains $_chain_prio_first $_chain_prio_local $_chain_prio_fproxy
|
||
NftAddActionChains $_chain_prio_action
|
||
AddUserInstancesNftRules
|
||
NftInstanceAdd "\" \"" $PKTS_MARK_START ${PROXY_MODE:=$INSTANCES_DEF_PROXY_MODE} ${TOR_TRANS_PORT:=$INSTANCES_DEF_TOR_TRANS_PORT} $_route_table_id "\"${IF_VPN:=$INSTANCES_DEF_IF_VPN}\"" ${T_PROXY_TYPE:=$INSTANCES_DEF_T_PROXY_TYPE} ${T_PROXY_PORT_TCP:=$INSTANCES_DEF_T_PROXY_PORT_TCP} ${T_PROXY_PORT_UDP:=$INSTANCES_DEF_T_PROXY_PORT_UDP} ${T_PROXY_ALLOW_UDP:=$INSTANCES_DEF_T_PROXY_ALLOW_UDP} ${ENABLE_BLLIST_PROXY:=$INSTANCES_DEF_ENABLE_BLLIST_PROXY} ${ENABLE_FPROXY:=$INSTANCES_DEF_ENABLE_FPROXY} "\"$VPN_GW_IP\""
|
||
if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
|
||
NftAddLocalClientsRule
|
||
fi
|
||
}
|
||
|
||
DeleteNftRules() {
|
||
NftDeleteActionChains
|
||
NftDeleteBaseChains
|
||
NftInstanceDelete " "
|
||
DeleteUserInstancesNftRules
|
||
if [ "$PROXY_MODE" = "2" ]; then
|
||
NftRouteDelete $VPN_ROUTE_TABLE_ID_START 2> /dev/null
|
||
elif [ "$PROXY_MODE" = "3" -a "$T_PROXY_TYPE" = "1" ]; then
|
||
NftRouteDelete $TPROXY_ROUTE_TABLE_ID_START 2> /dev/null
|
||
fi
|
||
}
|
||
|
||
SetNetConfig() {
|
||
$NFT_CMD add table $NFT_TABLE
|
||
AddBaseNftSets
|
||
AddInstancesNftSets
|
||
AddNftRules
|
||
}
|
||
|
||
DropNetConfig() {
|
||
DeleteNftRules
|
||
FlushInstancesNftSets
|
||
FlushNftSets "$NFTSET_LOCAL_IP" "$NFTSET_ALLOWED_HOSTS" "$NFTSET_FPROXY_LOCAL" "$NFTSET_BLLIST_PROXY" "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"
|
||
}
|
||
|
||
DestroyNetConfig() {
|
||
$NFT_CMD flush table $NFT_TABLE &> /dev/null
|
||
$NFT_CMD delete table $NFT_TABLE &> /dev/null
|
||
}
|
||
|
||
CheckStatus() {
|
||
NftReturnStatus
|
||
return $?
|
||
}
|
||
|
||
GetVpnRouteStatus() {
|
||
local _inst _i=1 _ret_val=0
|
||
for _inst in $USER_INSTANCES_VPN_FNAMES
|
||
do
|
||
if ! NftRouteStatus $(($VPN_ROUTE_TABLE_ID_START + $_i)); then
|
||
_ret_val=1
|
||
break
|
||
fi
|
||
_i=$(($_i + 1))
|
||
done
|
||
if [ "$PROXY_MODE" = "2" ] && ! NftRouteStatus $VPN_ROUTE_TABLE_ID_START; then
|
||
_ret_val=1
|
||
fi
|
||
return $_ret_val
|
||
}
|
||
|
||
ClearDataFiles() {
|
||
local _arg="$1"
|
||
if [ -d "$DATA_DIR" ]; then
|
||
if [ -z "$_arg" -o "$_arg" = "main_instance" ]; then
|
||
printf "" > "$IP_DATA_FILE"
|
||
printf "0 0 0" > "$UPDATE_STATUS_FILE"
|
||
fi
|
||
if [ -z "$_arg" -o "$_arg" = "user_instances" ]; then
|
||
printf "" > "$IP_DATA_FILE_USER_INSTANCES"
|
||
printf "" > "$USER_ENTRIES_STATUS_FILE"
|
||
fi
|
||
if [ -z "$_arg" ]; then
|
||
printf "" > "$IP_DATA_FILE_BYPASS"
|
||
fi
|
||
fi
|
||
if [ -d "$DNSMASQ_CONFDIR" ]; then
|
||
if [ -z "$_arg" -o "$_arg" = "main_instance" ]; then
|
||
printf "" > "$DNSMASQ_DATA_FILE"
|
||
fi
|
||
if [ -z "$_arg" -o "$_arg" = "user_instances" ]; then
|
||
printf "" > "$DNSMASQ_DATA_FILE_USER_INSTANCES"
|
||
fi
|
||
if [ -z "$_arg" ]; then
|
||
printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
PreStartCheck() {
|
||
[ -d "$DATA_DIR" ] || mkdir -p "$DATA_DIR"
|
||
[ "$ENABLE_HTML_INFO" = "1" -a ! -d "$HTML_DIR" ] && mkdir -p "$HTML_DIR"
|
||
### Костыль для старта dnsmasq
|
||
if [ -d "$DNSMASQ_CONFDIR" ]; then
|
||
[ -e "$DNSMASQ_DATA_FILE" ] || printf "" > "$DNSMASQ_DATA_FILE"
|
||
[ -e "$DNSMASQ_DATA_FILE_BYPASS" ] || printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
|
||
[ -e "$DNSMASQ_DATA_FILE_USER_INSTANCES" ] || printf "" > "$DNSMASQ_DATA_FILE_USER_INSTANCES"
|
||
fi
|
||
}
|
||
|
||
AddBypassEntries() {
|
||
if [ -d "$DATA_DIR" ]; then
|
||
printf "" > "$DNSMASQ_DATA_FILE_BYPASS"
|
||
printf "" > "$IP_DATA_FILE_BYPASS"
|
||
printf "flush set %s %s\nflush set %s %s\n" "$NFT_TABLE" "$NFTSET_BYPASS_IP" "$NFT_TABLE" "$NFTSET_BYPASS_FQDN" >> "$IP_DATA_FILE_BYPASS"
|
||
fi
|
||
FlushNftSets "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"
|
||
if [ "$BYPASS_MODE" = "1" ]; then
|
||
if [ -f "$BYPASS_ENTRIES_FILE" ]; then
|
||
$AWK_CMD '
|
||
BEGIN {
|
||
delete ip_array;
|
||
delete fqdn_array;
|
||
}
|
||
function writeIpList(array, _str) {
|
||
for(i in array) {
|
||
_str = _str i ",";
|
||
};
|
||
return _str;
|
||
};
|
||
function writeDNSData(val, dns) {
|
||
if(length(dns) == 0 && length(ENVIRON["BYPASS_ENTRIES_DNS"]) > 0) {
|
||
dns = ENVIRON["BYPASS_ENTRIES_DNS"];
|
||
};
|
||
if(length(dns) > 0) {
|
||
printf "server=/%s/%s\n", val, dns >> ENVIRON["DNSMASQ_DATA_FILE_BYPASS"];
|
||
};
|
||
printf "nftset=/%s/%s#%s\n", val, ENVIRON["NFT_TABLE_DNSMASQ"], ENVIRON["NFTSET_BYPASS_FQDN"] >> ENVIRON["DNSMASQ_DATA_FILE_BYPASS"];
|
||
};
|
||
function writeFqdnEntries() {
|
||
for(i in fqdn_array) {
|
||
split(i, a, " ");
|
||
writeDNSData(a[1], a[2]);
|
||
};
|
||
};
|
||
($0 !~ /^([\040\011]*$|#)/) {
|
||
sub("\015", "", $0);
|
||
if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}([\057][0-9]{1,2})?$/) {
|
||
ip_array[$0];
|
||
}
|
||
else if($0 ~ /^([a-z0-9._-]+[.])*([a-z]{2,}|xn--[a-z0-9]+)([ ][0-9]{1,3}([.][0-9]{1,3}){3}([#][0-9]{2,5})?)?$/) {
|
||
fqdn_array[$0];
|
||
};
|
||
}
|
||
END {
|
||
printf "table %s {\n%s", ENVIRON["NFT_TABLE"], ENVIRON["NFTSET_BYPASS_IP_STRING"] >> ENVIRON["IP_DATA_FILE_BYPASS"];
|
||
if(length(ip_array) > 0) {
|
||
printf "elements={%s};", writeIpList(ip_array) >> ENVIRON["IP_DATA_FILE_BYPASS"];
|
||
};
|
||
printf "}\n}\n" >> ENVIRON["IP_DATA_FILE_BYPASS"];
|
||
writeFqdnEntries();
|
||
}' "$BYPASS_ENTRIES_FILE"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
AddUserEntries() {
|
||
local _inst _url _return_code=0 _instance_return_code=0 _attempt=1 _instance_entries_file _ip_data_file_user_instances _dnsmasq_data_file_user_instances _user_entries_status_file _str _update_string
|
||
|
||
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
|
||
_ip_data_file_user_instances="$IP_DATA_FILE_USER_INSTANCES_TMP"
|
||
_dnsmasq_data_file_user_instances="$DNSMASQ_DATA_FILE_USER_INSTANCES_TMP"
|
||
_user_entries_status_file="$USER_ENTRIES_STATUS_FILE_TMP"
|
||
rm -f "$_ip_data_file_user_instances" "$_dnsmasq_data_file_user_instances" "$_user_entries_status_file"
|
||
else
|
||
_ip_data_file_user_instances="$IP_DATA_FILE_USER_INSTANCES"
|
||
_dnsmasq_data_file_user_instances="$DNSMASQ_DATA_FILE_USER_INSTANCES"
|
||
_user_entries_status_file="$USER_ENTRIES_STATUS_FILE"
|
||
fi
|
||
|
||
if [ "$ENABLE_TMP_DOWNLOADS" != "1" ]; then
|
||
ClearDataFiles user_instances
|
||
fi
|
||
|
||
for _inst in $USER_INSTANCES_ALL_FNAMES
|
||
do
|
||
IncludeUserInstanceVars "$_inst"
|
||
_instance_entries_file="${USER_LISTS_DIR}/${_inst}"
|
||
|
||
if [ $DEBUG -ge 1 ]; then
|
||
echo " ruantiblock.AddUserEntries._instance_entries_file=${_instance_entries_file}" >&2
|
||
MakeLogRecord "debug" "ruantiblock.AddUserEntries._instance_entries_file=${_instance_entries_file}"
|
||
fi
|
||
|
||
printf "flush set %s %s\nflush set %s %s\n" "$NFT_TABLE" "${NFTSET_CIDR}.${U_NAME}" "$NFT_TABLE" "${NFTSET_IP}.${U_NAME}" >> "$_ip_data_file_user_instances"
|
||
|
||
if [ "$U_PROXY_MODE" != "2" -a "$U_PROXY_MODE" != "3" ]; then
|
||
### Запись для .onion
|
||
printf "server=/onion/%s\nnftset=/onion/%s#%s\n" "$U_ONION_DNS_ADDR" "$NFT_TABLE_DNSMASQ" "${NFTSET_ONION}.${U_NAME}" >> "$_dnsmasq_data_file_user_instances"
|
||
fi
|
||
|
||
if [ "$U_ENABLE_ENTRIES_REMOTE_PROXY" = "1" ]; then
|
||
for _url in $U_ENTRIES_REMOTE
|
||
do
|
||
UpdateBllistProxySet "$U_NAME" "$_url"
|
||
done
|
||
fi
|
||
|
||
export U_NAME
|
||
export U_ENTRIES_REMOTE
|
||
export U_ENTRIES_DNS
|
||
export I_NFTSET_CIDR_STRING="$(printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}.${U_NAME}")"
|
||
export I_NFTSET_IP_STRING="$(printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}.${U_NAME}")"
|
||
export I_NFTSET_DNSMASQ="${NFTSET_DNSMASQ}.${U_NAME}"
|
||
export I_IP_DATA_FILE="$_ip_data_file_user_instances"
|
||
export I_DNSMASQ_DATA_FILE="$_dnsmasq_data_file_user_instances"
|
||
export I_USER_ENTRIES_STATUS_FILE="$_user_entries_status_file"
|
||
export I_INSTANCE_ENTRIES_FILE="$_instance_entries_file"
|
||
|
||
$USER_ENTRIES_PARSER
|
||
_instance_return_code=$?
|
||
|
||
unset I_NFTSET_CIDR_STRING
|
||
unset I_NFTSET_IP_STRING
|
||
unset I_NFTSET_DNSMASQ
|
||
unset I_IP_DATA_FILE
|
||
unset I_DNSMASQ_DATA_FILE
|
||
unset I_USER_ENTRIES_STATUS_FILE
|
||
unset I_INSTANCE_ENTRIES_FILE
|
||
|
||
if [ "$U_ENABLE_ENTRIES_REMOTE_PROXY" = "1" ]; then
|
||
FlushNftSets "${NFTSET_BLLIST_PROXY}.${U_NAME}"
|
||
fi
|
||
|
||
if [ $_instance_return_code -ne 0 ]; then
|
||
_return_code=$_instance_return_code
|
||
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
|
||
break
|
||
fi
|
||
fi
|
||
ClearUserInstanceVars
|
||
done
|
||
|
||
if [ "$ENABLE_TMP_DOWNLOADS" = "1" ]; then
|
||
if [ $_return_code -eq 0 ]; then
|
||
ClearDataFiles user_instances
|
||
if [ -e "$_ip_data_file_user_instances" ]; then
|
||
cat "$_ip_data_file_user_instances" >> "$IP_DATA_FILE_USER_INSTANCES"
|
||
fi
|
||
if [ -e "$_dnsmasq_data_file_user_instances" ]; then
|
||
cat "$_dnsmasq_data_file_user_instances" >> "$DNSMASQ_DATA_FILE_USER_INSTANCES"
|
||
fi
|
||
if [ -e "$_user_entries_status_file" ]; then
|
||
mv -f "$_user_entries_status_file" "$USER_ENTRIES_STATUS_FILE"
|
||
fi
|
||
fi
|
||
rm -f "$_ip_data_file_user_instances" "$_dnsmasq_data_file_user_instances" "$_user_entries_status_file"
|
||
fi
|
||
if [ "$ENABLE_TMP_DOWNLOADS" != "1" ] || [ "$ENABLE_TMP_DOWNLOADS" = "1" -a $_return_code -eq 0 ]; then
|
||
while read _str
|
||
do
|
||
_update_string=$(printf "$_str" | $AWK_CMD '{
|
||
if(NF == 4) {
|
||
printf "User entries (%s): CIDR: %s, IP: %s, FQDN: %s", $4, $1, $2, $3;
|
||
};
|
||
}')
|
||
if [ -n "$_update_string" ]; then
|
||
### STDOUT
|
||
echo " ${_update_string}"
|
||
MakeLogRecord "notice" "${_update_string}"
|
||
fi
|
||
done < "$USER_ENTRIES_STATUS_FILE"
|
||
fi
|
||
|
||
return $_return_code
|
||
}
|
||
|
||
ToggleUPIDFile() {
|
||
if [ "$1" = "del" ]; then
|
||
rm -f "$U_PID_FILE"
|
||
else
|
||
echo "$$" > "$U_PID_FILE"
|
||
fi
|
||
}
|
||
|
||
GetMainInstanceEntries() {
|
||
local _return_code=1 _attempt=1 _update_string
|
||
PreStartCheck
|
||
if [ -n "$BLLIST_PRESET" -a -n "$BLLIST_MODULE" ]; then
|
||
while :
|
||
do
|
||
if [ "$ENABLE_BLLIST_PROXY" = "1" ]; then
|
||
UpdateBllistProxySet " " "$BLLIST_HOSTS"
|
||
fi
|
||
|
||
if [ $DEBUG -ge 1 ]; then
|
||
echo " ruantiblock.GetMainInstanceEntries: BLLIST_MODULE=${BLLIST_MODULE} MODULE_RUN_TIMEOUT=${MODULE_RUN_TIMEOUT} _attempt=${_attempt}" >&2
|
||
MakeLogRecord "debug" "ruantiblock.GetMainInstanceEntries: BLLIST_MODULE=${BLLIST_MODULE} MODULE_RUN_TIMEOUT=${MODULE_RUN_TIMEOUT} _attempt=${_attempt}"
|
||
|
||
echo "BLLIST_MODULE=${BLLIST_MODULE}" > "$DEBUG_FILE"
|
||
$BLLIST_MODULE >> "$DEBUG_FILE" 2>&1
|
||
_return_code=$?
|
||
|
||
echo " ruantiblock.GetMainInstanceEntries._return_code=${_return_code}" >&2
|
||
MakeLogRecord "debug" "ruantiblock.GetMainInstanceEntries._return_code=${_return_code}"
|
||
else
|
||
$BLLIST_MODULE
|
||
_return_code=$?
|
||
fi
|
||
|
||
[ $_return_code -eq 0 ] && break
|
||
### STDOUT
|
||
echo " Module run attempt ${_attempt}: failed [${BLLIST_MODULE}]" >&2
|
||
MakeLogRecord "err" "Module run attempt ${_attempt}: failed [${BLLIST_MODULE}]"
|
||
_attempt=$(($_attempt + 1))
|
||
[ $_attempt -gt $MODULE_RUN_ATTEMPTS ] && break
|
||
sleep $MODULE_RUN_TIMEOUT
|
||
done
|
||
if [ "$ENABLE_BLLIST_PROXY" = "1" ]; then
|
||
FlushNftSets "$NFTSET_BLLIST_PROXY"
|
||
fi
|
||
if [ $_return_code -eq 0 ]; then
|
||
_update_string=$($AWK_CMD '{
|
||
printf "Received entries: %s\n", (NF < 3) ? "No data" : "CIDR: "$1", IP: "$2", FQDN: "$3;
|
||
exit;
|
||
}' "$UPDATE_STATUS_FILE")
|
||
### STDOUT
|
||
echo " ${_update_string}"
|
||
MakeLogRecord "notice" "${_update_string}"
|
||
printf " $(date +%d.%m.%Y-%H:%M)\n" >> "$UPDATE_STATUS_FILE"
|
||
fi
|
||
elif [ -z "$BLLIST_PRESET" -a -z "$BLLIST_MODULE" ]; then
|
||
ClearDataFiles main_instance
|
||
_return_code=3
|
||
else
|
||
_return_code=2
|
||
return $_return_code
|
||
fi
|
||
if [ $_return_code -eq 0 ]; then
|
||
if [ "$PROXY_MODE" = "2" -o "$PROXY_MODE" = "3" ]; then
|
||
printf "" >> "$DNSMASQ_DATA_FILE"
|
||
else
|
||
### Запись для .onion в $DNSMASQ_DATA_FILE
|
||
printf "server=/onion/%s\nnftset=/onion/%s#%s\n" "$ONION_DNS_ADDR" "$NFT_TABLE_DNSMASQ" "$NFTSET_ONION" >> "$DNSMASQ_DATA_FILE"
|
||
fi
|
||
fi
|
||
return $_return_code
|
||
}
|
||
|
||
GetBlacklistFiles() {
|
||
local _return_code=0 _user_entries_ret_code=1
|
||
AddBypassEntries
|
||
GetMainInstanceEntries
|
||
case $? in
|
||
0)
|
||
echo " Blacklist updated"
|
||
MakeLogRecord "notice" "Blacklist updated"
|
||
;;
|
||
2)
|
||
echo " Error! Blacklist update error" >&2
|
||
MakeLogRecord "err" "Error! Blacklist update error"
|
||
_return_code=1
|
||
;;
|
||
3)
|
||
:
|
||
;;
|
||
*)
|
||
echo " Module error! [${BLLIST_MODULE}]" >&2
|
||
MakeLogRecord "err" "Module error! [${BLLIST_MODULE}]"
|
||
_return_code=1
|
||
;;
|
||
esac
|
||
AddUserEntries
|
||
_user_entries_ret_code=$?
|
||
if [ $_return_code -eq 0 ]; then
|
||
_return_code=$_user_entries_ret_code
|
||
fi
|
||
return $_return_code
|
||
}
|
||
|
||
MakeInstancesCache() {
|
||
printf "USER_INSTANCES_ALL=\"${USER_INSTANCES_ALL}\"\nUSER_INSTANCES_ALL_FNAMES=\"${USER_INSTANCES_ALL_FNAMES}\"\nUSER_INSTANCES_VPN=\"${USER_INSTANCES_VPN}\"\nUSER_INSTANCES_VPN_FNAMES=\"${USER_INSTANCES_VPN_FNAMES}\"\nUSER_INSTANCES_CFG=\"${USER_INSTANCES_CFG}\"\nUSER_INSTANCES_CFG_FNAMES=\"${USER_INSTANCES_CFG_FNAMES}\"\n" > "$INSTANCES_CACHE"
|
||
}
|
||
|
||
DeleteInstancesCache() {
|
||
rm -f "$INSTANCES_CACHE"
|
||
}
|
||
|
||
Init() {
|
||
local _arg="$1"
|
||
. "$BLLIST_SOURCES_SCRIPT"
|
||
if [ -e "$INSTANCES_CACHE" ]; then
|
||
. "$INSTANCES_CACHE"
|
||
|
||
if [ $DEBUG -ge 2 ]; then
|
||
echo " ruantiblock.Init(): read from INSTANCES_CACHE" >&2
|
||
MakeLogRecord "debug" "ruantiblock.Init(): read from INSTANCES_CACHE"
|
||
fi
|
||
|
||
else
|
||
SetUserInstancesItems
|
||
fi
|
||
}
|
||
|
||
MakeToken() {
|
||
date +%s > "$TOKEN_FILE"
|
||
}
|
||
|
||
CheckDnsmasqConfDir() {
|
||
if [ ! -d "$DNSMASQ_CONFDIR" ]; then
|
||
echo " Error! DNSMASQ_CONFDIR (${DNSMASQ_CONFDIR}) does not exists" >&2
|
||
MakeLogRecord "err" "Error! DNSMASQ_CONFDIR (${DNSMASQ_CONFDIR}) does not exists"
|
||
return 1
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
Update() {
|
||
local _arg="$1" _return_code=0 _upd_sets_ret_code=0
|
||
MakeToken
|
||
if [ -e "$U_PID_FILE" ] && [ "$_arg" != "force-update" ]; then
|
||
echo " ${NAME} ${_arg} - Error! Another instance of update is already running" >&2
|
||
MakeLogRecord "err" "${_arg} - Error! Another instance of update is already running"
|
||
_return_code=2
|
||
else
|
||
ToggleUPIDFile add
|
||
### Pre-update script
|
||
[ -x "$PRE_UPDATE_SCRIPT" ] && $PRE_UPDATE_SCRIPT
|
||
echo " ${NAME} ${_arg}..."
|
||
MakeLogRecord "notice" "${_arg}..."
|
||
if [ "$NFTSET_CLEAR_SETS" = "1" ]; then
|
||
FlushInstancesNftSets bllist
|
||
fi
|
||
GetBlacklistFiles
|
||
_return_code=$?
|
||
FlushInstancesNftSets bllist
|
||
UpdateBllistSets
|
||
_upd_sets_ret_code=$?
|
||
if [ $_return_code -eq 0 ]; then
|
||
_return_code=$_upd_sets_ret_code
|
||
fi
|
||
RestartDnsmasq
|
||
ToggleUPIDFile del
|
||
### Post-update script
|
||
[ -x "$POST_UPDATE_SCRIPT" ] && $POST_UPDATE_SCRIPT &
|
||
fi
|
||
MakeToken
|
||
return $_return_code
|
||
}
|
||
|
||
Start() {
|
||
local _arg="$1" _return_code=1
|
||
if [ -e "$START_PID_FILE" ]; then
|
||
echo " ${NAME} is currently starting..." >&2
|
||
return 1
|
||
else
|
||
echo "$$" > "$START_PID_FILE"
|
||
fi
|
||
MakeToken
|
||
Init
|
||
if CheckStatus; then
|
||
echo " ${NAME} is already running" >&2
|
||
_return_code=1
|
||
else
|
||
echo " ${NAME} ${_arg}..."
|
||
MakeLogRecord "info" "${_arg}..."
|
||
DropNetConfig &> /dev/null
|
||
SetNetConfig
|
||
PreStartCheck
|
||
UpdateBllistSets
|
||
_return_code=$?
|
||
if [ "$VPN_ROUTE_CHECK" = "1" -a -x "$ROUTE_CHECK_EXEC" ] && [ "$PROXY_MODE" = "2" -o -n "$USER_INSTANCES_VPN" ]; then
|
||
$ROUTE_CHECK_EXEC start &> /dev/null &
|
||
fi
|
||
MakeInstancesCache
|
||
### Post-start script
|
||
[ -x "$POST_START_SCRIPT" ] && $POST_START_SCRIPT &
|
||
fi
|
||
rm -f "$START_PID_FILE"
|
||
MakeToken
|
||
return $_return_code
|
||
}
|
||
|
||
Stop() {
|
||
local _arg="$1" _return_code=1
|
||
if CheckStatus; then
|
||
MakeToken
|
||
echo " ${NAME} ${_arg}..."
|
||
MakeLogRecord "info" "${_arg}..."
|
||
DropNetConfig &> /dev/null
|
||
_return_code=$?
|
||
if [ -x "$ROUTE_CHECK_EXEC" ]; then
|
||
$ROUTE_CHECK_EXEC stop &> /dev/null
|
||
fi
|
||
### Post-stop script
|
||
[ -x "$POST_STOP_SCRIPT" ] && $POST_STOP_SCRIPT &
|
||
MakeToken
|
||
else
|
||
echo " ${NAME} does not running" >&2
|
||
fi
|
||
DeleteInstancesCache
|
||
return $_return_code
|
||
}
|
||
|
||
Reload() {
|
||
local _i=0 _attempts=60
|
||
if CheckStatus; then
|
||
MakeToken
|
||
while [ -e "$START_PID_FILE" ]
|
||
do
|
||
if [ $_i -ge $_attempts ]; then
|
||
return 1
|
||
fi
|
||
_i=$(($_i + 1))
|
||
|
||
if [ $DEBUG -ge 1 ]; then
|
||
echo " ruantiblock.Reload._i=${_i}" >&2
|
||
MakeLogRecord "debug" "ruantiblock.Reload._i ${_i}"
|
||
fi
|
||
|
||
sleep 1
|
||
done
|
||
|
||
if [ $DEBUG -ge 1 ]; then
|
||
echo " ruantiblock.Reload()" >&2
|
||
MakeLogRecord "debug" "ruantiblock.Reload()"
|
||
fi
|
||
|
||
echo " ${NAME} reload..."
|
||
DeleteNftRules &> /dev/null
|
||
AddNftRules &> /dev/null
|
||
UpdateLocalIpSets
|
||
MakeToken
|
||
else
|
||
echo " ${NAME} does not running" >&2
|
||
fi
|
||
}
|
||
|
||
Status() {
|
||
local _update_status _user_entries_status _vpn_error
|
||
if [ -f "$UPDATE_STATUS_FILE" ]; then
|
||
_update_status=$($AWK_CMD '{
|
||
update_string=(NF < 4) ? "No data" : $4" (CIDR: "$1" | IP: "$2" | FQDN: "$3")";
|
||
printf "Last blacklist update: %s", update_string;
|
||
}' "$UPDATE_STATUS_FILE")
|
||
else
|
||
_update_status="Last blacklist update: No data"
|
||
fi
|
||
|
||
if [ -f "$USER_ENTRIES_STATUS_FILE" ]; then
|
||
_user_entries_status=$($AWK_CMD '{
|
||
if(NF == 4) {
|
||
printf " User entries (%s): CIDR: %s | IP: %s | FQDN: %s\n", $4, $1, $2, $3;
|
||
};
|
||
}' "$USER_ENTRIES_STATUS_FILE")
|
||
fi
|
||
|
||
if ! GetVpnRouteStatus; then
|
||
_vpn_error="\033[1;31mVPN ROUTING ERROR! (NEED THE RESTART)\033[m"
|
||
fi
|
||
NftListBllistChain 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" -v USER_ENTRIES_STATUS="$_user_entries_status" -v VPN_ERROR="$_vpn_error" '
|
||
BEGIN {
|
||
rules_str = "";
|
||
nftset = "";
|
||
bytes = "";
|
||
}
|
||
/@/ {
|
||
if(match($0, /@[^ ]+/) != 0) {
|
||
nftset = substr($0, RSTART+1, RLENGTH-1);
|
||
if(match($0, /bytes [^ ]+/) != 0) {
|
||
bytes = substr($0, RSTART+6, RLENGTH-6);
|
||
};
|
||
rules_str = rules_str " Match-set: " nftset "\n Bytes: " bytes "\n\n";
|
||
};
|
||
}
|
||
END {
|
||
if(NR == 0) {
|
||
printf "\n \033[1m" ENVIRON["NAME"] " status\033[m: \033[1mDisabled\033[m\n\n";
|
||
exit 2;
|
||
};
|
||
printf "\n \033[1m" ENVIRON["NAME"] " status\033[m: \033[1;32mEnabled\033[m\n\n PROXY_MODE: " ENVIRON["PROXY_MODE"] "\n PROXY_LOCAL_CLIENTS: " ENVIRON["PROXY_LOCAL_CLIENTS"] "\n BLLIST_PRESET: " ENVIRON["BLLIST_PRESET"] "\n BLLIST_MODULE: " ENVIRON["BLLIST_MODULE"] "\n";
|
||
printf "\n "UPDATE_STATUS"\n";
|
||
if(length(USER_ENTRIES_STATUS) > 0) {
|
||
printf "\n"USER_ENTRIES_STATUS"\n";
|
||
};
|
||
if(length(VPN_ERROR) > 0) {
|
||
printf "\n "VPN_ERROR"\n";
|
||
};
|
||
printf "\n \033[4mNftables rules\033[m:\n\n";
|
||
printf rules_str;
|
||
}'
|
||
}
|
||
|
||
StatusOutput() {
|
||
if [ "$ENABLE_HTML_INFO" = "1" -a -d "$HTML_DIR" ]; then
|
||
Info
|
||
fi
|
||
}
|
||
|
||
############################ Main section ##############################
|
||
|
||
return_code=1
|
||
case "$1" in
|
||
start|force-start)
|
||
[ "$1" = "force-start" ] && rm -f "$START_PID_FILE"
|
||
Start "$1"
|
||
return_code=$?
|
||
StatusOutput
|
||
;;
|
||
stop)
|
||
Init
|
||
Stop "$1"
|
||
return_code=$?
|
||
StatusOutput
|
||
;;
|
||
restart|delayed-restart)
|
||
if [ "$1" = "delayed-restart" -a -n "$2" ]; then
|
||
{
|
||
echo "$$" > "$START_PID_FILE"
|
||
sleep $2 &> /dev/null
|
||
rm -f "$START_PID_FILE"
|
||
Init
|
||
Stop "stop"
|
||
Start "start"
|
||
return_code=$?
|
||
StatusOutput
|
||
exit $return_code;
|
||
} &> /dev/null &
|
||
return_code=0
|
||
else
|
||
Init
|
||
Stop "stop"
|
||
Start "start"
|
||
return_code=$?
|
||
StatusOutput
|
||
fi
|
||
;;
|
||
reload)
|
||
Init
|
||
Reload
|
||
return_code=$?
|
||
StatusOutput
|
||
;;
|
||
destroy)
|
||
Init
|
||
Stop "$1" &> /dev/null
|
||
DestroyNetConfig
|
||
ClearDataFiles
|
||
return_code=$?
|
||
ToggleUPIDFile del
|
||
RestartDnsmasq
|
||
StatusOutput
|
||
;;
|
||
update|force-update)
|
||
Init
|
||
if CheckStatus; then
|
||
:
|
||
else
|
||
echo " ${NAME} ${_arg} - Error! ${NAME} does not running or another error has occurred" >&2
|
||
exit 1
|
||
fi
|
||
UpdateLocalIpSets
|
||
if CheckDnsmasqConfDir; then
|
||
Update "$1"
|
||
return_code=$?
|
||
StatusOutput
|
||
else
|
||
return_code=1
|
||
fi
|
||
;;
|
||
blacklist-files)
|
||
Init
|
||
if [ -e "$U_PID_FILE" ] && [ "$1" != "force-update" ]; then
|
||
echo " ${NAME} - Error! Another instance of update is already running" >&2
|
||
exit 2
|
||
else
|
||
if CheckDnsmasqConfDir; then
|
||
GetBlacklistFiles
|
||
return_code=$?
|
||
else
|
||
return_code=1
|
||
fi
|
||
fi
|
||
;;
|
||
status)
|
||
Init
|
||
Status
|
||
return_code=$?
|
||
;;
|
||
raw-status)
|
||
Init
|
||
CheckStatus
|
||
return_code=$?
|
||
case $return_code in
|
||
0)
|
||
if [ -e "$START_PID_FILE" ]; then
|
||
return_code=3
|
||
echo 3
|
||
elif [ -e "$U_PID_FILE" ]; then
|
||
return_code=4
|
||
echo 4
|
||
else
|
||
echo 0
|
||
fi
|
||
;;
|
||
*)
|
||
return_code=2
|
||
echo 2
|
||
;;
|
||
esac
|
||
;;
|
||
vpn-route-status)
|
||
Init
|
||
GetVpnRouteStatus
|
||
return_code=$?
|
||
echo $return_code
|
||
;;
|
||
html-info)
|
||
Init
|
||
Info
|
||
return_code=$?
|
||
;;
|
||
-h|--help|help)
|
||
Help
|
||
exit 0
|
||
;;
|
||
*)
|
||
Help
|
||
exit 1
|
||
;;
|
||
esac
|
||
|
||
exit $return_code;
|