v2.0. Multi proxy for user entries. TProxy support.
@@ -7,11 +7,12 @@ PROXY_MODE=1
|
|||||||
BLACKLIST=0
|
BLACKLIST=0
|
||||||
LUA_MODULE=0
|
LUA_MODULE=0
|
||||||
LUCI_APP=1
|
LUCI_APP=1
|
||||||
|
HTTPS_DNS_PROXY=1
|
||||||
|
|
||||||
OWRT_VERSION="22.03"
|
OWRT_VERSION="current"
|
||||||
RUAB_VERSION="0.9.7-1"
|
RUAB_VERSION="2.0.0-r1"
|
||||||
RUAB_MOD_LUA_VERSION="0.9.7-1"
|
RUAB_MOD_LUA_VERSION="2.0.0-r1"
|
||||||
RUAB_LUCI_APP_VERSION="0.9.7-0"
|
RUAB_LUCI_APP_VERSION="2.0.0-1"
|
||||||
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
|
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
|
||||||
PKG_DIR="/tmp"
|
PKG_DIR="/tmp"
|
||||||
|
|
||||||
@@ -27,33 +28,36 @@ URL_MOD_LUA_PKG="${BASE_URL}/${OWRT_VERSION}/ruantiblock-mod-lua_${RUAB_MOD_LUA_
|
|||||||
URL_LUCI_APP_PKG="${BASE_URL}/${OWRT_VERSION}/luci-app-ruantiblock_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
URL_LUCI_APP_PKG="${BASE_URL}/${OWRT_VERSION}/luci-app-ruantiblock_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
||||||
URL_LUCI_APP_RU_PKG="${BASE_URL}/${OWRT_VERSION}/luci-i18n-ruantiblock-ru_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
URL_LUCI_APP_RU_PKG="${BASE_URL}/${OWRT_VERSION}/luci-i18n-ruantiblock-ru_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
||||||
### tor
|
### tor
|
||||||
URL_TORRC="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_openwrt/0.9/tor/etc/tor/torrc"
|
URL_TORRC="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_openwrt/master/tor/etc/tor/torrc"
|
||||||
### ruantiblock-mod-lua
|
### ruantiblock-mod-lua
|
||||||
URL_LUA_IPTOOL="https://raw.githubusercontent.com/gSpotx2f/iptool-lua/master/5.1/iptool.lua"
|
|
||||||
URL_LUA_IDN="https://raw.githubusercontent.com/haste/lua-idn/master/idn.lua"
|
URL_LUA_IDN="https://raw.githubusercontent.com/haste/lua-idn/master/idn.lua"
|
||||||
|
|
||||||
### Local files
|
### Local files
|
||||||
|
|
||||||
RUAB_CFG_DIR="${PREFIX}/etc/ruantiblock"
|
CONFIG_DIR="${PREFIX}/etc/ruantiblock"
|
||||||
|
USER_LISTS_DIR="${CONFIG_DIR}/user_lists"
|
||||||
EXEC_DIR="${PREFIX}/usr/bin"
|
EXEC_DIR="${PREFIX}/usr/bin"
|
||||||
BACKUP_DIR="${RUAB_CFG_DIR}/autoinstall.bak.`date +%s`"
|
BACKUP_DIR="${CONFIG_DIR}/autoinstall.bak.`date +%s`"
|
||||||
### packages
|
### packages
|
||||||
FILE_RUAB_PKG="${PKG_DIR}/ruantiblock_${RUAB_VERSION}_all.ipk"
|
FILE_RUAB_PKG="${PKG_DIR}/ruantiblock_${RUAB_VERSION}_all.ipk"
|
||||||
FILE_MOD_LUA_PKG="${PKG_DIR}/ruantiblock-mod-lua_${RUAB_MOD_LUA_VERSION}_all.ipk"
|
FILE_MOD_LUA_PKG="${PKG_DIR}/ruantiblock-mod-lua_${RUAB_MOD_LUA_VERSION}_all.ipk"
|
||||||
FILE_LUCI_APP_PKG="${PKG_DIR}/luci-app-ruantiblock_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
FILE_LUCI_APP_PKG="${PKG_DIR}/luci-app-ruantiblock_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
||||||
FILE_LUCI_APP_RU_PKG="${PKG_DIR}/luci-i18n-ruantiblock-ru_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
FILE_LUCI_APP_RU_PKG="${PKG_DIR}/luci-i18n-ruantiblock-ru_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
||||||
### ruantiblock
|
### ruantiblock
|
||||||
FILE_CONFIG="${RUAB_CFG_DIR}/ruantiblock.conf"
|
FILE_CONFIG="${CONFIG_DIR}/ruantiblock.conf"
|
||||||
FILE_FQDN_FILTER="${RUAB_CFG_DIR}/fqdn_filter"
|
FILE_FQDN_FILTER="${CONFIG_DIR}/fqdn_filter"
|
||||||
FILE_IP_FILTER="${RUAB_CFG_DIR}/ip_filter"
|
FILE_IP_FILTER="${CONFIG_DIR}/ip_filter"
|
||||||
FILE_USER_ENTRIES="${RUAB_CFG_DIR}/user_entries"
|
FILE_USER_ENTRIES="${CONFIG_DIR}/user_entries"
|
||||||
|
FILE_BYPASS_ENTRIES="${CONFIG_DIR}/bypass_entries"
|
||||||
|
FILE_GR_EXCLUDED_SLD="${CONFIG_DIR}/gr_excluded_sld"
|
||||||
|
FILE_GR_EXCLUDED_NETS="${CONFIG_DIR}/gr_excluded_nets"
|
||||||
FILE_UCI_CONFIG="${PREFIX}/etc/config/ruantiblock"
|
FILE_UCI_CONFIG="${PREFIX}/etc/config/ruantiblock"
|
||||||
FILE_INIT_SCRIPT="${PREFIX}/etc/init.d/ruantiblock"
|
FILE_INIT_SCRIPT="${PREFIX}/etc/init.d/ruantiblock"
|
||||||
FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
|
FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
|
||||||
### tor
|
### tor
|
||||||
FILE_TORRC="${PREFIX}/etc/tor/torrc"
|
FILE_TORRC="${PREFIX}/etc/tor/torrc"
|
||||||
### ruantiblock-mod-lua
|
### ruantiblock-mod-lua
|
||||||
FILE_LUA_IPTOOL="${PREFIX}/usr/lib/lua/iptool.lua"
|
#FILE_LUA_IPTOOL="${PREFIX}/usr/lib/lua/iptool.lua"
|
||||||
FILE_LUA_IDN="${PREFIX}/usr/lib/lua/idn.lua"
|
FILE_LUA_IDN="${PREFIX}/usr/lib/lua/idn.lua"
|
||||||
|
|
||||||
AWK_CMD="awk"
|
AWK_CMD="awk"
|
||||||
@@ -121,9 +125,13 @@ BackupFile() {
|
|||||||
BackupCurrentConfig() {
|
BackupCurrentConfig() {
|
||||||
local _file
|
local _file
|
||||||
MakeDir "$BACKUP_DIR"
|
MakeDir "$BACKUP_DIR"
|
||||||
for _file in "$FILE_CONFIG" "$FILE_FQDN_FILTER" "$FILE_IP_FILTER" "$FILE_USER_ENTRIES" "$FILE_UCI_CONFIG" "$FILE_TORRC"
|
for _file in `ls -1 "$CONFIG_DIR" | grep -v "$(basename $BACKUP_DIR)"`
|
||||||
do
|
do
|
||||||
[ -e "$_file" ] && cp -f "$_file" "${BACKUP_DIR}/`basename ${_file}`"
|
cp -af "${CONFIG_DIR}/${_file}" "${BACKUP_DIR}/${_file}"
|
||||||
|
done
|
||||||
|
for _file in "$FILE_UCI_CONFIG" "$FILE_TORRC"
|
||||||
|
do
|
||||||
|
[ -e "$_file" ] && cp -af "$_file" "${BACKUP_DIR}/`basename ${_file}`"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,11 +144,6 @@ AppStop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AppStart() {
|
AppStart() {
|
||||||
modprobe ip_set > /dev/null
|
|
||||||
modprobe ip_set_hash_ip > /dev/null
|
|
||||||
modprobe ip_set_hash_net > /dev/null
|
|
||||||
modprobe ip_set_list_set > /dev/null
|
|
||||||
modprobe xt_set > /dev/null
|
|
||||||
$FILE_INIT_SCRIPT start
|
$FILE_INIT_SCRIPT start
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,10 +177,11 @@ InstallPackages() {
|
|||||||
|
|
||||||
InstallBaseConfig() {
|
InstallBaseConfig() {
|
||||||
_return_code=1
|
_return_code=1
|
||||||
InstallPackages "ipset" "kmod-ipt-ipset" "dnsmasq-full"
|
InstallPackages "dnsmasq-full" "kmod-nft-tproxy"
|
||||||
RemoveFile "$FILE_RUAB_PKG" > /dev/null
|
RemoveFile "$FILE_RUAB_PKG" > /dev/null
|
||||||
DlFile "$URL_RUAB_PKG" "$FILE_RUAB_PKG" && $OPKG_CMD install "$FILE_RUAB_PKG" > /dev/null
|
DlFile "$URL_RUAB_PKG" "$FILE_RUAB_PKG" && $OPKG_CMD install "$FILE_RUAB_PKG" > /dev/null
|
||||||
_return_code=$?
|
_return_code=$?
|
||||||
|
# костыль для остановки сервиса, который запускается автоматически после установки пакета!
|
||||||
AppStop
|
AppStop
|
||||||
return $_return_code
|
return $_return_code
|
||||||
}
|
}
|
||||||
@@ -219,6 +223,7 @@ InstallTorConfig() {
|
|||||||
TorrcSettings
|
TorrcSettings
|
||||||
$UCI_CMD set ruantiblock.config.proxy_mode="1"
|
$UCI_CMD set ruantiblock.config.proxy_mode="1"
|
||||||
$UCI_CMD commit ruantiblock
|
$UCI_CMD commit ruantiblock
|
||||||
|
# dnsmasq rebind protection
|
||||||
$UCI_CMD set dhcp.@dnsmasq[0].rebind_domain='onion'
|
$UCI_CMD set dhcp.@dnsmasq[0].rebind_domain='onion'
|
||||||
$UCI_CMD commit dhcp
|
$UCI_CMD commit dhcp
|
||||||
}
|
}
|
||||||
@@ -227,7 +232,6 @@ InstallLuaModule() {
|
|||||||
InstallPackages "lua" "luasocket" "luasec" "luabitop"
|
InstallPackages "lua" "luasocket" "luasec" "luabitop"
|
||||||
RemoveFile "$FILE_MOD_LUA_PKG" > /dev/null
|
RemoveFile "$FILE_MOD_LUA_PKG" > /dev/null
|
||||||
DlFile "$URL_MOD_LUA_PKG" "$FILE_MOD_LUA_PKG" && $OPKG_CMD install "$FILE_MOD_LUA_PKG"
|
DlFile "$URL_MOD_LUA_PKG" "$FILE_MOD_LUA_PKG" && $OPKG_CMD install "$FILE_MOD_LUA_PKG"
|
||||||
FileExists "$FILE_LUA_IPTOOL" || DlFile "$URL_LUA_IPTOOL" "$FILE_LUA_IPTOOL"
|
|
||||||
FileExists "$FILE_LUA_IDN" || DlFile "$URL_LUA_IDN" "$FILE_LUA_IDN"
|
FileExists "$FILE_LUA_IDN" || DlFile "$URL_LUA_IDN" "$FILE_LUA_IDN"
|
||||||
$UCI_CMD set ruantiblock.config.bllist_module="/usr/libexec/ruantiblock/ruab_parser.lua"
|
$UCI_CMD set ruantiblock.config.bllist_module="/usr/libexec/ruantiblock/ruab_parser.lua"
|
||||||
$UCI_CMD commit ruantiblock
|
$UCI_CMD commit ruantiblock
|
||||||
@@ -243,6 +247,10 @@ InstallLuciApp() {
|
|||||||
/etc/init.d/uhttpd restart
|
/etc/init.d/uhttpd restart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InstallHttpsDnsProxy() {
|
||||||
|
InstallPackages "https-dns-proxy" "luci-app-https-dns-proxy" "luci-i18n-https-dns-proxy-ru"
|
||||||
|
}
|
||||||
|
|
||||||
PrintBold() {
|
PrintBold() {
|
||||||
printf "\033[1m - ${1}\033[0m\n"
|
printf "\033[1m - ${1}\033[0m\n"
|
||||||
}
|
}
|
||||||
@@ -279,7 +287,7 @@ ConfirmProxyMode() {
|
|||||||
|
|
||||||
ConfirmBlacklist() {
|
ConfirmBlacklist() {
|
||||||
local _reply
|
local _reply
|
||||||
printf " Select blacklist [ 1: User entries only | 2: RKN blacklist ] (default: 1, quit: q) > "
|
printf " Select blacklist [ 1: User entries only | 2: Full blacklist ] (default: 1, quit: q) > "
|
||||||
read _reply
|
read _reply
|
||||||
case $_reply in
|
case $_reply in
|
||||||
1|"")
|
1|"")
|
||||||
@@ -343,6 +351,28 @@ ConfirmLuciApp() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfirmHttpsDnsProxy() {
|
||||||
|
local _reply
|
||||||
|
printf " Would you like to install the https-dns-proxy? [ y | n ] (default: y, quit: q) > "
|
||||||
|
read _reply
|
||||||
|
case $_reply in
|
||||||
|
y|Y|"")
|
||||||
|
HTTPS_DNS_PROXY=1
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
n|N)
|
||||||
|
HTTPS_DNS_PROXY=0
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
q|Q)
|
||||||
|
printf "Bye...\n"; exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
InputError ConfirmHttpsDnsProxy
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
ConfirmProcessing() {
|
ConfirmProcessing() {
|
||||||
local _reply
|
local _reply
|
||||||
printf " Next, the installation will begin... Continue? [ y | n ] (default: y, quit: q) > "
|
printf " Next, the installation will begin... Continue? [ y | n ] (default: y, quit: q) > "
|
||||||
@@ -364,11 +394,13 @@ ConfirmProxyMode
|
|||||||
ConfirmBlacklist
|
ConfirmBlacklist
|
||||||
#ConfirmLuaModule
|
#ConfirmLuaModule
|
||||||
ConfirmLuciApp
|
ConfirmLuciApp
|
||||||
|
ConfirmHttpsDnsProxy
|
||||||
ConfirmProcessing
|
ConfirmProcessing
|
||||||
AppStop
|
AppStop
|
||||||
PrintBold "Updating packages list..."
|
PrintBold "Updating packages list..."
|
||||||
UpdatePackagesList
|
UpdatePackagesList
|
||||||
PrintBold "Saving current configuration..."
|
PrintBold "Saving current configuration..."
|
||||||
|
#BackupCurrentConfig
|
||||||
PrintBold "Installing basic configuration..."
|
PrintBold "Installing basic configuration..."
|
||||||
InstallBaseConfig
|
InstallBaseConfig
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
@@ -388,7 +420,7 @@ if [ $? -eq 0 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $BLACKLIST = 2 ]; then
|
if [ $BLACKLIST = 2 ]; then
|
||||||
PrintBold "Set RKN blacklist..."
|
PrintBold "Set full blacklist..."
|
||||||
EnableBlacklist
|
EnableBlacklist
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -402,6 +434,11 @@ if [ $? -eq 0 ]; then
|
|||||||
InstallLuciApp
|
InstallLuciApp
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $HTTPS_DNS_PROXY = 1 ]; then
|
||||||
|
PrintBold "Installing https-dns-proxy..."
|
||||||
|
InstallHttpsDnsProxy
|
||||||
|
fi
|
||||||
|
|
||||||
RunAtStartup
|
RunAtStartup
|
||||||
SetCronTask
|
SetCronTask
|
||||||
else
|
else
|
||||||
@@ -4,19 +4,27 @@ PREFIX=""
|
|||||||
|
|
||||||
### Local files
|
### Local files
|
||||||
|
|
||||||
RUAB_CFG_DIR="${PREFIX}/etc/ruantiblock"
|
CONFIG_DIR="${PREFIX}/etc/ruantiblock"
|
||||||
|
USER_LISTS_DIR="${CONFIG_DIR}/user_lists"
|
||||||
EXEC_DIR="${PREFIX}/usr/bin"
|
EXEC_DIR="${PREFIX}/usr/bin"
|
||||||
BACKUP_DIR="${RUAB_CFG_DIR}/autoinstall.bak.`date +%s`"
|
BACKUP_DIR="${CONFIG_DIR}/autoinstall.bak.`date +%s`"
|
||||||
HTDOCS_VIEW="${PREFIX}/www/luci-static/resources/view"
|
HTDOCS_VIEW="${PREFIX}/www/luci-static/resources/view"
|
||||||
HTDOCS_RUAB="${HTDOCS_VIEW}/ruantiblock"
|
HTDOCS_RUAB="${HTDOCS_VIEW}/ruantiblock"
|
||||||
CRONTAB_FILE="/etc/crontabs/root"
|
CRONTAB_FILE="/etc/crontabs/root"
|
||||||
DATA_DIR="/tmp/ruantiblock"
|
DATA_DIR="/tmp/ruantiblock"
|
||||||
DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/ruantiblock.dnsmasq"
|
DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq"
|
||||||
|
DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
|
||||||
|
DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq"
|
||||||
|
SCRIPTS_DIR="/usr/share/ruantiblock"
|
||||||
|
MODULES_DIR="/usr/libexec/ruantiblock"
|
||||||
### ruantiblock
|
### ruantiblock
|
||||||
FILE_CONFIG="${RUAB_CFG_DIR}/ruantiblock.conf"
|
FILE_CONFIG="${CONFIG_DIR}/ruantiblock.conf"
|
||||||
FILE_FQDN_FILTER="${RUAB_CFG_DIR}/fqdn_filter"
|
FILE_FQDN_FILTER="${CONFIG_DIR}/fqdn_filter"
|
||||||
FILE_IP_FILTER="${RUAB_CFG_DIR}/ip_filter"
|
FILE_IP_FILTER="${CONFIG_DIR}/ip_filter"
|
||||||
FILE_USER_ENTRIES="${RUAB_CFG_DIR}/user_entries"
|
FILE_USER_ENTRIES="${CONFIG_DIR}/user_entries"
|
||||||
|
FILE_BYPASS_ENTRIES="${CONFIG_DIR}/bypass_entries"
|
||||||
|
FILE_GR_EXCLUDED_SLD="${CONFIG_DIR}/gr_excluded_sld"
|
||||||
|
FILE_GR_EXCLUDED_NETS="${CONFIG_DIR}/gr_excluded_nets"
|
||||||
FILE_UCI_CONFIG="${PREFIX}/etc/config/ruantiblock"
|
FILE_UCI_CONFIG="${PREFIX}/etc/config/ruantiblock"
|
||||||
FILE_INIT_SCRIPT="${PREFIX}/etc/init.d/ruantiblock"
|
FILE_INIT_SCRIPT="${PREFIX}/etc/init.d/ruantiblock"
|
||||||
FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
|
FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
|
||||||
@@ -52,9 +60,13 @@ RemoveFile() {
|
|||||||
BackupCurrentConfig() {
|
BackupCurrentConfig() {
|
||||||
local _file
|
local _file
|
||||||
MakeDir "$BACKUP_DIR"
|
MakeDir "$BACKUP_DIR"
|
||||||
for _file in "$FILE_CONFIG" "$FILE_FQDN_FILTER" "$FILE_IP_FILTER" "$FILE_USER_ENTRIES" "$FILE_UCI_CONFIG" "$FILE_TORRC"
|
for _file in `ls -1 "$CONFIG_DIR" | grep -v "$(basename $BACKUP_DIR)"`
|
||||||
do
|
do
|
||||||
[ -e "$_file" ] && cp -f "$_file" "${BACKUP_DIR}/`basename ${_file}`"
|
cp -af "${CONFIG_DIR}/${_file}" "${BACKUP_DIR}/${_file}"
|
||||||
|
done
|
||||||
|
for _file in "$FILE_UCI_CONFIG" "$FILE_TORRC"
|
||||||
|
do
|
||||||
|
[ -e "$_file" ] && cp -af "$_file" "${BACKUP_DIR}/`basename ${_file}`"
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,10 +79,12 @@ DisableStartup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RemoveCronTask() {
|
RemoveCronTask() {
|
||||||
$AWK_CMD -v FILE_MAIN_SCRIPT="$FILE_MAIN_SCRIPT" '$0 !~ FILE_MAIN_SCRIPT {
|
if [ -e "$CRONTAB_FILE" ]; then
|
||||||
print $0;
|
$AWK_CMD -v FILE_MAIN_SCRIPT="$FILE_MAIN_SCRIPT" '$0 !~ FILE_MAIN_SCRIPT {
|
||||||
}' "$CRONTAB_FILE" > "${CRONTAB_FILE}.tmp" && mv -f "${CRONTAB_FILE}.tmp" "$CRONTAB_FILE"
|
print $0;
|
||||||
/etc/init.d/cron restart
|
}' "$CRONTAB_FILE" > "${CRONTAB_FILE}.tmp" && mv -f "${CRONTAB_FILE}.tmp" "$CRONTAB_FILE"
|
||||||
|
/etc/init.d/cron restart
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreTorConfig() {
|
RestoreTorConfig() {
|
||||||
@@ -85,9 +99,25 @@ RestoreTorConfig() {
|
|||||||
RemoveAppFiles() {
|
RemoveAppFiles() {
|
||||||
RestoreTorConfig
|
RestoreTorConfig
|
||||||
$OPKG_CMD remove ruantiblock-mod-py ruantiblock-mod-lua luci-i18n-ruantiblock-ru luci-app-ruantiblock ruantiblock
|
$OPKG_CMD remove ruantiblock-mod-py ruantiblock-mod-lua luci-i18n-ruantiblock-ru luci-app-ruantiblock ruantiblock
|
||||||
|
RemoveFile "$FILE_UCI_CONFIG"
|
||||||
|
RemoveFile "$FILE_CONFIG"
|
||||||
|
RemoveFile "$FILE_FQDN_FILTER"
|
||||||
|
RemoveFile "$FILE_IP_FILTER"
|
||||||
|
RemoveFile "$FILE_USER_ENTRIES"
|
||||||
|
RemoveFile "$FILE_BYPASS_ENTRIES"
|
||||||
|
RemoveFile "$FILE_GR_EXCLUDED_SLD"
|
||||||
|
RemoveFile "$FILE_GR_EXCLUDED_NETS"
|
||||||
|
RemoveFile "${FILE_UCI_CONFIG}.opkg"
|
||||||
|
RemoveFile "${FILE_CONFIG}.opkg"
|
||||||
|
RemoveFile "${FILE_FQDN_FILTER}.opkg"
|
||||||
|
RemoveFile "${FILE_IP_FILTER}.opkg"
|
||||||
|
RemoveFile "${FILE_USER_ENTRIES}.opkg"
|
||||||
|
RemoveFile "${FILE_BYPASS_ENTRIES}.opkg"
|
||||||
rm -f "$DNSMASQ_DATA_FILE"
|
rm -f "$DNSMASQ_DATA_FILE"
|
||||||
|
rm -f "$DNSMASQ_DATA_FILE_BYPASS"
|
||||||
rm -rf "$DATA_DIR"/*
|
rm -rf "$DATA_DIR"/*
|
||||||
rmdir "${RUAB_CFG_DIR}/scripts" 2> /dev/null
|
rm -rf "$USER_LISTS_DIR"
|
||||||
|
rmdir "$SCRIPTS_DIR" "$MODULES_DIR" 2> /dev/null
|
||||||
rmdir "$HTDOCS_RUAB" 2> /dev/null
|
rmdir "$HTDOCS_RUAB" 2> /dev/null
|
||||||
rm -f /tmp/luci-modulecache/* /tmp/luci-indexcache*
|
rm -f /tmp/luci-modulecache/* /tmp/luci-indexcache*
|
||||||
/etc/init.d/rpcd restart
|
/etc/init.d/rpcd restart
|
||||||
@@ -117,7 +147,7 @@ ConfirmRemove() {
|
|||||||
|
|
||||||
ConfirmRemove
|
ConfirmRemove
|
||||||
AppStop
|
AppStop
|
||||||
#BackupCurrentConfig
|
BackupCurrentConfig
|
||||||
DisableStartup
|
DisableStartup
|
||||||
RemoveCronTask
|
RemoveCronTask
|
||||||
RemoveAppFiles
|
RemoveAppFiles
|
||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_VERSION:=1.6.0-r1
|
PKG_NAME:=luci-app-ruantiblock
|
||||||
|
PKG_VERSION:=2.0.0
|
||||||
|
PKG_RELEASE:=1
|
||||||
LUCI_TITLE:=LuCI support for ruantiblock
|
LUCI_TITLE:=LuCI support for ruantiblock
|
||||||
LUCI_DEPENDS:=+ruantiblock
|
LUCI_DEPENDS:=+ruantiblock
|
||||||
LUCI_PKGARCH:=all
|
LUCI_PKGARCH:=all
|
||||||
|
|||||||
@@ -10,26 +10,26 @@ return view.extend({
|
|||||||
|
|
||||||
currentCrontabLines: [],
|
currentCrontabLines: [],
|
||||||
|
|
||||||
toDD: function(n){
|
toDD(n){
|
||||||
return String(n).replace(/^(\d)$/, "0$1");
|
return String(n).replace(/^(\d)$/, "0$1");
|
||||||
},
|
},
|
||||||
|
|
||||||
cronStatusString: function(s) {
|
cronStatusString(s) {
|
||||||
return s || _('No Sсhedule');
|
return s || _('No Sсhedule');
|
||||||
},
|
},
|
||||||
|
|
||||||
stringifyRuabTasks: function(str_array) {
|
stringifyRuabTasks(str_array) {
|
||||||
let current_tasks = str_array.filter(s => s.match(this.crontabRegexp));
|
let current_tasks = str_array.filter(s => s.match(this.crontabRegexp));
|
||||||
return current_tasks.join('\n');
|
return current_tasks.join('\n');
|
||||||
},
|
},
|
||||||
|
|
||||||
setCronStatus: function(value) {
|
setCronStatus(value) {
|
||||||
document.getElementById('cron_status').value = this.cronStatusString(value);
|
document.getElementById('cron_status').value = this.cronStatusString(value);
|
||||||
document.getElementById("btn_cron_del").style.visibility = (value) ?
|
document.getElementById("btn_cron_del").style.visibility = (value) ?
|
||||||
'visible' : 'hidden';
|
'visible' : 'hidden';
|
||||||
},
|
},
|
||||||
|
|
||||||
writeCronFile: function() {
|
writeCronFile() {
|
||||||
let btn_cron_add = document.getElementById('btn_cron_add');
|
let btn_cron_add = document.getElementById('btn_cron_add');
|
||||||
let btn_cron_del = document.getElementById('btn_cron_del');
|
let btn_cron_del = document.getElementById('btn_cron_del');
|
||||||
let crontab_string = this.currentCrontabLines.join('\n');
|
let crontab_string = this.currentCrontabLines.join('\n');
|
||||||
@@ -53,17 +53,17 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
delRuabShedules: function() {
|
delRuabShedules() {
|
||||||
this.currentCrontabLines = this.currentCrontabLines.filter(
|
this.currentCrontabLines = this.currentCrontabLines.filter(
|
||||||
s => s.match(this.crontabRegexp) ? false : true);
|
s => s.match(this.crontabRegexp) ? false : true);
|
||||||
},
|
},
|
||||||
|
|
||||||
delCronSchedule: function(ev) {
|
delCronSchedule(ev) {
|
||||||
this.delRuabShedules();
|
this.delRuabShedules();
|
||||||
return this.writeCronFile();
|
return this.writeCronFile();
|
||||||
},
|
},
|
||||||
|
|
||||||
setCronSchedule: function(ev) {
|
setCronSchedule(ev) {
|
||||||
let hour_interval = document.getElementById('cron_hour_interval').value;
|
let hour_interval = document.getElementById('cron_hour_interval').value;
|
||||||
let day_interval = document.getElementById('cron_day_interval').value;
|
let day_interval = document.getElementById('cron_day_interval').value;
|
||||||
let hour = document.getElementById('cron_hour').value;
|
let hour = document.getElementById('cron_hour').value;
|
||||||
@@ -88,7 +88,7 @@ return view.extend({
|
|||||||
return this.writeCronFile();
|
return this.writeCronFile();
|
||||||
},
|
},
|
||||||
|
|
||||||
onchangeHourInterval: function(e) {
|
onchangeHourInterval(e) {
|
||||||
let value = e.target.value;
|
let value = e.target.value;
|
||||||
let bool = (value != '');
|
let bool = (value != '');
|
||||||
let cron_hour = document.getElementById('cron_hour');
|
let cron_hour = document.getElementById('cron_hour');
|
||||||
@@ -106,7 +106,7 @@ return view.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function() {
|
load() {
|
||||||
return fs.lines(tools.crontabFile).catch(e => {
|
return fs.lines(tools.crontabFile).catch(e => {
|
||||||
ui.addNotification(null, E('p', _('Unable to read the contents')
|
ui.addNotification(null, E('p', _('Unable to read the contents')
|
||||||
+ ': %s [ %s ]'.format(
|
+ ': %s [ %s ]'.format(
|
||||||
@@ -115,7 +115,7 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(content) {
|
render(content) {
|
||||||
this.currentCrontabLines = content;
|
this.currentCrontabLines = content;
|
||||||
let current_task = this.stringifyRuabTasks(content);
|
let current_task = this.stringifyRuabTasks(content);
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ document.head.append(E('style', {'type': 'text/css'},
|
|||||||
return view.extend({
|
return view.extend({
|
||||||
pollInterval : L.env.pollinterval,
|
pollInterval : L.env.pollinterval,
|
||||||
|
|
||||||
secToTimeString: function(value) {
|
secToTimeString(value) {
|
||||||
let string = '';
|
let string = '';
|
||||||
if(/^\d+$/.test(value)) {
|
if(/^\d+$/.test(value)) {
|
||||||
value = Number(value);
|
value = Number(value);
|
||||||
@@ -42,50 +42,103 @@ return view.extend({
|
|||||||
return string;
|
return string;
|
||||||
},
|
},
|
||||||
|
|
||||||
formatNftJson: function(data) {
|
formatNftJson(data) {
|
||||||
let output = { 'rules': [] };
|
let output = { 'sink': [] };
|
||||||
if(data.rules.nftables && data.rules.nftables.length > 1) {
|
if(data.sink.nftables && data.sink.nftables.length > 1) {
|
||||||
for(let i of data.rules.nftables) {
|
let rules = [];
|
||||||
if(!i.rule) continue;
|
|
||||||
let set, bytes;
|
|
||||||
i.rule.expr.forEach(e => {
|
|
||||||
if(e.match && e.match.left && e.match.left.payload) {
|
|
||||||
set = e.match.right.replace('@', '');
|
|
||||||
}
|
|
||||||
else if(e.counter) {
|
|
||||||
bytes = e.counter.bytes;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
output.rules.push([ set, bytes ]);
|
|
||||||
};
|
|
||||||
|
|
||||||
function parseDnsmasqData(set) {
|
for(let i of data.sink.nftables) {
|
||||||
let sArray = [];
|
if(i.rule) {
|
||||||
if(data[set].nftables && data[set].nftables.length > 1) {
|
let instance = (i.rule.comment === ' ') ? '-main-' : i.rule.comment;
|
||||||
data[set].nftables.forEach(e => {
|
let proto, bytes;
|
||||||
if(e.set && e.set.elem) {
|
i.rule.expr.forEach(e => {
|
||||||
e.set.elem.forEach(i => {
|
if(e.match && e.match.left && e.match.left.meta && e.match.left.meta.key && e.match.left.meta.key == "l4proto") {
|
||||||
if(i.elem) {
|
proto = e.match.right;
|
||||||
sArray.push([ i.elem.val, i.elem.expires ]);
|
}
|
||||||
};
|
else if(e.counter) {
|
||||||
});
|
bytes = e.counter.bytes;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
rules.push([ instance, proto, bytes ]);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
};
|
};
|
||||||
return sArray;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(data.dnsmasq) {
|
if(rules.length > 0) {
|
||||||
output.dnsmasq = parseDnsmasqData('dnsmasq');
|
output.sink = rules;
|
||||||
};
|
};
|
||||||
if(data.dnsmasq_bypass) {
|
};
|
||||||
output.dnsmasq_bypass = parseDnsmasqData('dnsmasq_bypass');
|
|
||||||
|
if(data.sink_local && data.sink_local.nftables && data.sink_local.nftables.length > 1) {
|
||||||
|
output.sink_local = [];
|
||||||
|
let rules = [];
|
||||||
|
|
||||||
|
for(let i of data.sink_local.nftables) {
|
||||||
|
if(i.rule) {
|
||||||
|
let instance = (i.rule.comment === ' ') ? '-main-' : i.rule.comment;
|
||||||
|
let proto, bytes;
|
||||||
|
i.rule.expr.forEach(e => {
|
||||||
|
if(e.match && e.match.left && e.match.left.meta && e.match.left.meta.key && e.match.left.meta.key == "l4proto") {
|
||||||
|
proto = e.match.right;
|
||||||
|
}
|
||||||
|
else if(e.counter) {
|
||||||
|
bytes = e.counter.bytes;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
rules.push([ instance, proto, bytes ]);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if(rules.length > 0) {
|
||||||
|
output.sink_local = rules;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function parseDnsmasqData(set) {
|
||||||
|
let sArray = [];
|
||||||
|
if(set.nftables && set.nftables.length > 1) {
|
||||||
|
set.nftables.forEach(e => {
|
||||||
|
if(e.set && e.set.elem) {
|
||||||
|
e.set.elem.forEach(i => {
|
||||||
|
if(i.elem) {
|
||||||
|
sArray.push([ i.elem.val, i.elem.expires ]);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return sArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(data.dnsmasq) {
|
||||||
|
output.dnsmasq = parseDnsmasqData(data.dnsmasq);
|
||||||
|
};
|
||||||
|
if(data.dnsmasq_bypass) {
|
||||||
|
output.dnsmasq_bypass = parseDnsmasqData(data.dnsmasq_bypass);
|
||||||
|
};
|
||||||
|
if(data.dnsmasq_user_instances) {
|
||||||
|
output.dnsmasq_user_instances = [];
|
||||||
|
if(data.dnsmasq_user_instances && data.dnsmasq_user_instances.length > 1) {
|
||||||
|
for(let i of data.dnsmasq_user_instances) {
|
||||||
|
if(i.nftables) {
|
||||||
|
let name;
|
||||||
|
i.nftables.forEach(e => {
|
||||||
|
if(e.set) {
|
||||||
|
name = e.set.name;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
output.dnsmasq_user_instances.push([ name, parseDnsmasqData(i) ]);
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return output;
|
return output;
|
||||||
},
|
},
|
||||||
|
|
||||||
makeDnsmasqTable: function(ipDataArray) {
|
makeDnsmasqTable(ipDataArray, title) {
|
||||||
let lines = `<tr class="tr"><td class="td center">${_('No entries available...')}</td></tr>`;
|
let lines = `<tr class="tr"><td class="td center">${_('No entries available...')}</td></tr>`;
|
||||||
let ipTable = E('table', { 'id': 'ipTable', 'class': 'table' });
|
let ipTable = E('table', { 'id': 'ipTable', 'class': 'table' });
|
||||||
|
|
||||||
@@ -122,6 +175,7 @@ return view.extend({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return E([
|
return E([
|
||||||
|
E('h3', {}, title),
|
||||||
E('div', { 'class': 'log-entries-count' },
|
E('div', { 'class': 'log-entries-count' },
|
||||||
`${_('Entries')}: ${ipDataArray.length}`
|
`${_('Entries')}: ${ipDataArray.length}`
|
||||||
),
|
),
|
||||||
@@ -129,7 +183,7 @@ return view.extend({
|
|||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
pollInfo: function() {
|
pollInfo() {
|
||||||
return fs.exec_direct(tools.execPath, [ 'html-info' ], 'json').catch(e => {
|
return fs.exec_direct(tools.execPath, [ 'html-info' ], 'json').catch(e => {
|
||||||
ui.addNotification(null, E('p', _('Unable to execute or read contents')
|
ui.addNotification(null, E('p', _('Unable to execute or read contents')
|
||||||
+ ': %s [ %s ]'.format(e.message, tools.execPath)
|
+ ': %s [ %s ]'.format(e.message, tools.execPath)
|
||||||
@@ -174,11 +228,20 @@ return view.extend({
|
|||||||
|
|
||||||
let nft_data = this.formatNftJson(data);
|
let nft_data = this.formatNftJson(data);
|
||||||
|
|
||||||
if(nft_data.rules.length > 0) {
|
if(nft_data.sink.length > 0) {
|
||||||
for(let [set, bytes] of nft_data.rules) {
|
for(let i of nft_data.sink) {
|
||||||
let elem = document.getElementById('rules.' + set);
|
let elem = document.getElementById('sink.' + i[0] + '.' + (i[1] || 'all'));
|
||||||
if(elem) {
|
if(elem) {
|
||||||
elem.textContent = bytes;
|
elem.textContent = i[2];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if(nft_data.sink_local && nft_data.sink_local.length > 0) {
|
||||||
|
for(let i of nft_data.sink_local) {
|
||||||
|
let elem = document.getElementById('sink_local.' + i[0] + '.' + (i[1] || 'all'));
|
||||||
|
if(elem) {
|
||||||
|
elem.textContent = i[2];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -186,15 +249,16 @@ return view.extend({
|
|||||||
let rdTableWrapper = document.getElementById('rdTableWrapper');
|
let rdTableWrapper = document.getElementById('rdTableWrapper');
|
||||||
if(rdTableWrapper) {
|
if(rdTableWrapper) {
|
||||||
rdTableWrapper.innerHTML = '';
|
rdTableWrapper.innerHTML = '';
|
||||||
rdTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq));
|
rdTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq, _('Dnsmasq')));
|
||||||
};
|
};
|
||||||
|
|
||||||
let rdbTableWrapper = document.getElementById('rdbTableWrapper');
|
let rdsTableWrapper = document.getElementById('rdsTableWrapper');
|
||||||
if(rdbTableWrapper) {
|
if(rdsTableWrapper) {
|
||||||
rdbTableWrapper.innerHTML = '';
|
rdsTableWrapper.innerHTML = '';
|
||||||
rdbTableWrapper.append(this.makeDnsmasqTable(nft_data.dnsmasq_bypass));
|
for(let i of nft_data.dnsmasq_user_instances) {
|
||||||
|
rdsTableWrapper.append(this.makeDnsmasqTable(i[1], _('Dnsmasq') + ' ' + i[0]));
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if(poll.active()) {
|
if(poll.active()) {
|
||||||
poll.stop();
|
poll.stop();
|
||||||
@@ -203,7 +267,7 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function() {
|
load() {
|
||||||
return fs.exec_direct(tools.execPath, [ 'html-info' ], 'json').catch(e => {
|
return fs.exec_direct(tools.execPath, [ 'html-info' ], 'json').catch(e => {
|
||||||
ui.addNotification(null, E('p', _('Unable to execute or read contents')
|
ui.addNotification(null, E('p', _('Unable to execute or read contents')
|
||||||
+ ': %s [ %s ]'.format(e.message, tools.execPath)
|
+ ': %s [ %s ]'.format(e.message, tools.execPath)
|
||||||
@@ -211,7 +275,7 @@ return view.extend({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
if(!data) {
|
if(!data) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -220,11 +284,12 @@ return view.extend({
|
|||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
} catch(e) {};
|
} catch(e) {};
|
||||||
|
|
||||||
let update_status = null,
|
let update_status = null,
|
||||||
user_entries = null,
|
user_entries = null,
|
||||||
rules = null,
|
sink = null,
|
||||||
dnsmasq = null,
|
sink_local = null,
|
||||||
dnsmasqBypass = null;
|
dnsmasq = null,
|
||||||
|
dnsmasqUserInstances = null;
|
||||||
|
|
||||||
if(data) {
|
if(data) {
|
||||||
if(data.status === 'enabled') {
|
if(data.status === 'enabled') {
|
||||||
@@ -285,39 +350,87 @@ return view.extend({
|
|||||||
|
|
||||||
let nft_data = this.formatNftJson(data);
|
let nft_data = this.formatNftJson(data);
|
||||||
|
|
||||||
if(nft_data.rules) {
|
if(nft_data.sink) {
|
||||||
let table_rules = E('table', { 'class': 'table' }, [
|
let table = E('table', { 'class': 'table' }, [
|
||||||
E('tr', { 'class': 'tr table-titles' }, [
|
E('tr', { 'class': 'tr table-titles' }, [
|
||||||
E('th', { 'class': 'th left', 'style': 'min-width:33%' },
|
E('th', { 'class': 'th left', 'style': 'min-width:33%' },
|
||||||
_('Match-set')),
|
_('Instance')),
|
||||||
|
E('th', { 'class': 'th left' }, _('Protocol')),
|
||||||
E('th', { 'class': 'th left' }, _('Bytes')),
|
E('th', { 'class': 'th left' }, _('Bytes')),
|
||||||
]),
|
]),
|
||||||
]);
|
]);
|
||||||
|
for(let i of nft_data.sink) {
|
||||||
|
let instance = i[0];
|
||||||
|
let proto = (i[1] === undefined) ? _('all') : i[1];
|
||||||
|
let bytes = i[2];
|
||||||
|
|
||||||
for(let [set, bytes] of nft_data.rules) {
|
if(!instance) {
|
||||||
if(!set) {
|
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
table_rules.append(
|
table.append(
|
||||||
E('tr', { 'class': 'tr' }, [
|
E('tr', { 'class': 'tr' }, [
|
||||||
E('td',{
|
|
||||||
'class' : 'td left',
|
|
||||||
'data-title': _('Match-set'),
|
|
||||||
}, set + ((set.length >= 1) ? (
|
|
||||||
' (' + set.replace(/^c/, 'CIDR').replace(/^i/, 'IP').replace(/^d/, 'dnsmasq').replace(/^bi/, 'bypass IP').replace(/^bd/, 'bypass dnsmasq').replace(/^fproxy/, 'full proxy') + ')'
|
|
||||||
) : '')),
|
|
||||||
E('td', {
|
E('td', {
|
||||||
'class' : 'td left',
|
'class' : 'td left',
|
||||||
'id' : 'rules.' + set,
|
'data-title': _('Instance'),
|
||||||
|
}, instance),
|
||||||
|
E('td', {
|
||||||
|
'class' : 'td left',
|
||||||
|
'data-title': _('Protocol'),
|
||||||
|
}, proto),
|
||||||
|
E('td', {
|
||||||
|
'class' : 'td left',
|
||||||
|
'id' : 'sink.' + instance + '.' + (i[1] || 'all'),
|
||||||
'data-title': _('Bytes'),
|
'data-title': _('Bytes'),
|
||||||
}, bytes),
|
}, bytes),
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
rules = E([
|
};
|
||||||
E('h3', {}, _('Nftables rules')),
|
sink = E([
|
||||||
table_rules,
|
E('h3', {}, _('Transit traffic')),
|
||||||
|
table,
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
if(nft_data.sink_local) {
|
||||||
|
let table = E('table', { 'class': 'table' }, [
|
||||||
|
E('tr', { 'class': 'tr table-titles' }, [
|
||||||
|
E('th', { 'class': 'th left', 'style': 'min-width:33%' },
|
||||||
|
_('Instance')),
|
||||||
|
E('th', { 'class': 'th left' }, _('Protocol')),
|
||||||
|
E('th', { 'class': 'th left' }, _('Bytes')),
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
for(let i of nft_data.sink_local) {
|
||||||
|
let instance = i[0];
|
||||||
|
let proto = (i[1] === undefined) ? _('all') : i[1];
|
||||||
|
let bytes = i[2];
|
||||||
|
|
||||||
|
if(!instance) {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
table.append(
|
||||||
|
E('tr', { 'class': 'tr' }, [
|
||||||
|
E('td', {
|
||||||
|
'class' : 'td left',
|
||||||
|
'data-title': _('Instance'),
|
||||||
|
}, instance),
|
||||||
|
E('td', {
|
||||||
|
'class' : 'td left',
|
||||||
|
'data-title': _('Protocol'),
|
||||||
|
}, proto),
|
||||||
|
E('td', {
|
||||||
|
'class' : 'td left',
|
||||||
|
'id' : 'sink_local.' + instance + '.' + (i[1] || 'all'),
|
||||||
|
'data-title': _('Bytes'),
|
||||||
|
}, bytes),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
sink_local = E([
|
||||||
|
E('h3', {}, _('Local traffic')),
|
||||||
|
table,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -325,24 +438,28 @@ return view.extend({
|
|||||||
let rdTableWrapper = E('div', {
|
let rdTableWrapper = E('div', {
|
||||||
'id' : 'rdTableWrapper',
|
'id' : 'rdTableWrapper',
|
||||||
'style': 'width:100%'
|
'style': 'width:100%'
|
||||||
}, this.makeDnsmasqTable(nft_data.dnsmasq));
|
}, this.makeDnsmasqTable(nft_data.dnsmasq, _('Dnsmasq')));
|
||||||
|
|
||||||
dnsmasq = E([
|
dnsmasq = E([
|
||||||
E('h3', {}, _('Dnsmasq')),
|
|
||||||
rdTableWrapper,
|
rdTableWrapper,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(nft_data.dnsmasq_bypass) {
|
if(nft_data.dnsmasq_user_instances) {
|
||||||
let rdbTableWrapper = E('div', {
|
let rdsTableWrapper = E('div', {
|
||||||
'id' : 'rdbTableWrapper',
|
'id' : 'rdsTableWrapper',
|
||||||
'style': 'width:100%'
|
'style': 'width:100%'
|
||||||
}, this.makeDnsmasqTable(nft_data.dnsmasq_bypass));
|
});
|
||||||
|
|
||||||
dnsmasqBypass = E([
|
for(let i of nft_data.dnsmasq_user_instances) {
|
||||||
E('h3', {}, _('Dnsmasq bypass')),
|
rdsTableWrapper.append(this.makeDnsmasqTable(i[1], _('Dnsmasq') + ' ' + i[0]));
|
||||||
rdbTableWrapper,
|
};
|
||||||
]);
|
|
||||||
|
if(nft_data.dnsmasq_user_instances.length > 0) {
|
||||||
|
dnsmasqUserInstances = E([
|
||||||
|
rdsTableWrapper,
|
||||||
|
]);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
poll.add(L.bind(this.pollInfo, this), this.pollInterval);
|
poll.add(L.bind(this.pollInfo, this), this.pollInterval);
|
||||||
@@ -360,7 +477,7 @@ return view.extend({
|
|||||||
E('div', { 'class': 'cbi-section-node' }, update_status)
|
E('div', { 'class': 'cbi-section-node' }, update_status)
|
||||||
),
|
),
|
||||||
E('div', { 'class': 'cbi-section fade-in' },
|
E('div', { 'class': 'cbi-section fade-in' },
|
||||||
E('div', { 'class': 'cbi-section-node' }, rules)
|
E('div', { 'class': 'cbi-section-node' }, sink)
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -373,16 +490,24 @@ return view.extend({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dnsmasqBypass) {
|
if(sink_local) {
|
||||||
layout.splice(5, 0,
|
layout.splice(5, 0,
|
||||||
E('div', { 'class': 'cbi-section fade-in' },
|
E('div', { 'class': 'cbi-section fade-in' },
|
||||||
E('div', { 'class': 'cbi-section-node' }, dnsmasqBypass)
|
E('div', { 'class': 'cbi-section-node' }, sink_local)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if(dnsmasqUserInstances) {
|
||||||
|
layout.splice(6, 0,
|
||||||
|
E('div', { 'class': 'cbi-section fade-in' },
|
||||||
|
E('div', { 'class': 'cbi-section-node' }, dnsmasqUserInstances)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if(dnsmasq) {
|
if(dnsmasq) {
|
||||||
layout.splice(6, 0,
|
layout.splice(7, 0,
|
||||||
E('div', { 'class': 'cbi-section fade-in' },
|
E('div', { 'class': 'cbi-section fade-in' },
|
||||||
E('div', { 'class': 'cbi-section-node' }, dnsmasq)
|
E('div', { 'class': 'cbi-section-node' }, dnsmasq)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
'require baseclass';
|
'require baseclass';
|
||||||
'require fs';
|
'require fs';
|
||||||
|
'require ui';
|
||||||
'require view.ruantiblock.log-widget as widget';
|
'require view.ruantiblock.log-widget as widget';
|
||||||
|
|
||||||
return baseclass.extend({
|
return baseclass.extend({
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
'require baseclass';
|
||||||
'require fs';
|
'require fs';
|
||||||
'require poll';
|
'require poll';
|
||||||
'require uci';
|
'require uci';
|
||||||
@@ -15,7 +16,121 @@ const btn_style_warning = 'btn cbi-button-negative important'
|
|||||||
return view.extend({
|
return view.extend({
|
||||||
statusTokenValue: null,
|
statusTokenValue: null,
|
||||||
|
|
||||||
disableButtons: function(bool, btn, elems=[]) {
|
dialogDestroy: baseclass.extend({
|
||||||
|
__init__(context) {
|
||||||
|
this.context = context;
|
||||||
|
},
|
||||||
|
|
||||||
|
currentDnsmasqCfgDir: null,
|
||||||
|
|
||||||
|
dnsmasqCfgDirsSelect: null,
|
||||||
|
|
||||||
|
cancelButton : E('button', {
|
||||||
|
'id' : 'btn_cancel',
|
||||||
|
'class': btn_style_neutral,
|
||||||
|
'click': ui.hideModal,
|
||||||
|
}, _('Cancel')),
|
||||||
|
|
||||||
|
load() {
|
||||||
|
return L.resolveDefault(fs.list(tools.dnsmasqCfgDirsRoot), null);
|
||||||
|
},
|
||||||
|
|
||||||
|
render(data) {
|
||||||
|
let section = uci.get(tools.appName, 'config');
|
||||||
|
this.currentDnsmasqCfgDir = section.dnsmasq_cfg_dir;
|
||||||
|
let available_cfg_dirs = [];
|
||||||
|
|
||||||
|
let dnsmasq_cfg_dirs_arr = data;
|
||||||
|
if(dnsmasq_cfg_dirs_arr) {
|
||||||
|
dnsmasq_cfg_dirs_arr.forEach(e => {
|
||||||
|
let fname = e.name;
|
||||||
|
if(fname.startsWith('dnsmasq')) {
|
||||||
|
available_cfg_dirs.push([ fname, tools.dnsmasqCfgDirsRoot + '/' + fname ]);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.dnsmasqCfgDirsSelect = E('select', {
|
||||||
|
'id' : 'dnsmasq_cfg_dirs_list',
|
||||||
|
'class': "cbi-input-select",
|
||||||
|
}),
|
||||||
|
|
||||||
|
available_cfg_dirs.forEach(e => {
|
||||||
|
this.dnsmasqCfgDirsSelect.append(
|
||||||
|
E('option', { 'value': e[1] }, e[0]));
|
||||||
|
});
|
||||||
|
this.dnsmasqCfgDirsSelect.value = this.currentDnsmasqCfgDir;
|
||||||
|
|
||||||
|
ui.showModal(this.title, [
|
||||||
|
E('h4', _('The service will be disabled and all blacklist data will be deleted. Continue?')),
|
||||||
|
E('div', { 'class': 'cbi-section' }, [
|
||||||
|
E('div', { 'class': 'cbi-value' }, [
|
||||||
|
E('label', { 'class': 'cbi-value-title' },
|
||||||
|
_('Dnsmasq config directory')),
|
||||||
|
E('div', { 'class': 'cbi-value-field' }, [
|
||||||
|
this.dnsmasqCfgDirsSelect,
|
||||||
|
E('div', { 'class': 'cbi-value-description' },
|
||||||
|
_('Change dnsmasq config directory')),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
E('div', { 'class': 'right' }, [
|
||||||
|
this.cancelButton,
|
||||||
|
' ',
|
||||||
|
E('button', {
|
||||||
|
'id' : 'btn_apply',
|
||||||
|
'class': btn_style_warning,
|
||||||
|
'click': ui.createHandlerFn(this, this.handleApply),
|
||||||
|
}, _('Shutdown')),
|
||||||
|
]),
|
||||||
|
], 'cbi-modal');
|
||||||
|
},
|
||||||
|
|
||||||
|
handleApply(ev) {
|
||||||
|
this.cancelButton.disabled = true;
|
||||||
|
return this.context.appAction('destroy').then(() => {
|
||||||
|
if(this.dnsmasqCfgDirsSelect.value !== this.currentDnsmasqCfgDir) {
|
||||||
|
uci.set(tools.appName, 'config', 'dnsmasq_cfg_dir',
|
||||||
|
this.dnsmasqCfgDirsSelect.value);
|
||||||
|
uci.save();
|
||||||
|
uci.apply();
|
||||||
|
};
|
||||||
|
}).finally(() => {
|
||||||
|
this.cancelButton.disabled = false;
|
||||||
|
ui.hideModal();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
error(e) {
|
||||||
|
ui.showModal(this.title, [
|
||||||
|
E('div', { 'class': 'cbi-section' },
|
||||||
|
E('p', {}, _('An error occurred')
|
||||||
|
+ ': %s'.format(e.message))
|
||||||
|
),
|
||||||
|
E('div', { 'class': 'right' },
|
||||||
|
E('button', {
|
||||||
|
'class': btn_style_neutral,
|
||||||
|
'click': ui.hideModal,
|
||||||
|
}, _('Dismiss'))
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
|
show() {
|
||||||
|
ui.showModal(null,
|
||||||
|
E('p', { 'class': 'spinning' }, _('Loading'))
|
||||||
|
);
|
||||||
|
this.load().then(content => {
|
||||||
|
ui.hideModal();
|
||||||
|
return this.render(content);
|
||||||
|
}).catch(e => {
|
||||||
|
ui.hideModal();
|
||||||
|
return this.error(e);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
disableButtons(bool, btn, elems=[]) {
|
||||||
let btn_start = elems[1] || document.getElementById("btn_start");
|
let btn_start = elems[1] || document.getElementById("btn_start");
|
||||||
let btn_destroy = elems[4] || document.getElementById("btn_destroy");
|
let btn_destroy = elems[4] || document.getElementById("btn_destroy");
|
||||||
let btn_enable = elems[2] || document.getElementById("btn_enable");
|
let btn_enable = elems[2] || document.getElementById("btn_enable");
|
||||||
@@ -31,7 +146,7 @@ return view.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getAppStatus: function() {
|
getAppStatus() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
fs.exec(tools.execPath, [ 'raw-status' ]),
|
fs.exec(tools.execPath, [ 'raw-status' ]),
|
||||||
fs.exec(tools.execPath, [ 'vpn-route-status' ]),
|
fs.exec(tools.execPath, [ 'vpn-route-status' ]),
|
||||||
@@ -46,7 +161,7 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setAppStatus: function(status_array, elems=[], force_app_code) {
|
setAppStatus(status_array, elems=[], force_app_code) {
|
||||||
let section = uci.get(tools.appName, 'config');
|
let section = uci.get(tools.appName, 'config');
|
||||||
if(!status_array || typeof(section) !== 'object') {
|
if(!status_array || typeof(section) !== 'object') {
|
||||||
(elems[0] || document.getElementById("status")).innerHTML = tools.makeStatusString(1);
|
(elems[0] || document.getElementById("status")).innerHTML = tools.makeStatusString(1);
|
||||||
@@ -59,8 +174,7 @@ return view.extend({
|
|||||||
let app_status_code = (force_app_code) ? force_app_code : status_array[0].code;
|
let app_status_code = (force_app_code) ? force_app_code : status_array[0].code;
|
||||||
let vpn_route_status_code = status_array[1].code;
|
let vpn_route_status_code = status_array[1].code;
|
||||||
let enabled_flag = status_array[2];
|
let enabled_flag = status_array[2];
|
||||||
let proxy_local_clients = section.proxy_local_clients;
|
let dnsmasq_cfg_dir = section.dnsmasq_cfg_dir;
|
||||||
let proxy_mode = section.proxy_mode;
|
|
||||||
let bllist_preset = section.bllist_preset;
|
let bllist_preset = section.bllist_preset;
|
||||||
let bllist_module = section.bllist_module;
|
let bllist_module = section.bllist_module;
|
||||||
|
|
||||||
@@ -122,7 +236,6 @@ return view.extend({
|
|||||||
|
|
||||||
(elems[0] || document.getElementById("status")).innerHTML = tools.makeStatusString(
|
(elems[0] || document.getElementById("status")).innerHTML = tools.makeStatusString(
|
||||||
app_status_code,
|
app_status_code,
|
||||||
proxy_mode,
|
|
||||||
bllist_preset,
|
bllist_preset,
|
||||||
bllist_module,
|
bllist_module,
|
||||||
vpn_route_status_code);
|
vpn_route_status_code);
|
||||||
@@ -132,7 +245,7 @@ return view.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
serviceAction: function(action, button) {
|
serviceAction(action, button) {
|
||||||
if(button) {
|
if(button) {
|
||||||
let elem = document.getElementById(button);
|
let elem = document.getElementById(button);
|
||||||
this.disableButtons(true, elem);
|
this.disableButtons(true, elem);
|
||||||
@@ -149,7 +262,7 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
appAction: function(action, button) {
|
appAction(action, button) {
|
||||||
if(button) {
|
if(button) {
|
||||||
let elem = document.getElementById(button);
|
let elem = document.getElementById(button);
|
||||||
this.disableButtons(true, elem);
|
this.disableButtons(true, elem);
|
||||||
@@ -167,13 +280,12 @@ return view.extend({
|
|||||||
return this.getAppStatus().then(
|
return this.getAppStatus().then(
|
||||||
(status_array) => {
|
(status_array) => {
|
||||||
this.setAppStatus(status_array);
|
this.setAppStatus(status_array);
|
||||||
ui.hideModal();
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
statusPoll: function() {
|
statusPoll() {
|
||||||
return fs.read(tools.tokenFile).then(v => {
|
return fs.read(tools.tokenFile).then(v => {
|
||||||
v = tools.normalizeValue(v);
|
v = tools.normalizeValue(v);
|
||||||
if(v != this.statusTokenValue) {
|
if(v != this.statusTokenValue) {
|
||||||
@@ -187,48 +299,21 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
dialogDestroy: function(ev) {
|
load() {
|
||||||
ev.target.blur();
|
|
||||||
let cancel_button = E('button', {
|
|
||||||
'class': btn_style_neutral,
|
|
||||||
'click': ui.hideModal,
|
|
||||||
}, _('Cancel'));
|
|
||||||
|
|
||||||
let shutdown_btn = E('button', {
|
|
||||||
'class': btn_style_warning,
|
|
||||||
}, _('Shutdown'));
|
|
||||||
shutdown_btn.onclick = ui.createHandlerFn(this, () => {
|
|
||||||
cancel_button.disabled = true;
|
|
||||||
return this.appAction('destroy');
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.showModal(_('Shutdown'), [
|
|
||||||
E('div', { 'class': 'cbi-section' }, [
|
|
||||||
E('p', _('The service will be disabled and all blacklist data will be deleted. Continue?')),
|
|
||||||
]),
|
|
||||||
E('div', { 'class': 'right' }, [
|
|
||||||
shutdown_btn,
|
|
||||||
' ',
|
|
||||||
cancel_button,
|
|
||||||
])
|
|
||||||
]);
|
|
||||||
},
|
|
||||||
|
|
||||||
load: function() {
|
|
||||||
return this.getAppStatus();
|
return this.getAppStatus();
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(status_array) {
|
render(status_array) {
|
||||||
if(!status_array) {
|
if(!status_array) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let section = uci.get(tools.appName, 'config');
|
let section = uci.get(tools.appName, 'config');
|
||||||
let proxy_local_clients = (typeof(section) === 'object') ?
|
|
||||||
section.proxy_local_clients : null;
|
|
||||||
this.statusTokenValue = (Array.isArray(status_array)) ?
|
this.statusTokenValue = (Array.isArray(status_array)) ?
|
||||||
tools.normalizeValue(status_array[4]) : null;
|
tools.normalizeValue(status_array[4]) : null;
|
||||||
|
|
||||||
|
let dialog_destroy = new this.dialogDestroy(this);
|
||||||
|
|
||||||
let status_string = E('div', {
|
let status_string = E('div', {
|
||||||
'id' : 'status',
|
'id' : 'status',
|
||||||
'name' : 'status',
|
'name' : 'status',
|
||||||
@@ -281,7 +366,7 @@ return view.extend({
|
|||||||
'name' : 'btn_destroy',
|
'name' : 'btn_destroy',
|
||||||
'class': btn_style_negative,
|
'class': btn_style_negative,
|
||||||
}, _('Shutdown'));
|
}, _('Shutdown'));
|
||||||
btn_destroy.onclick = L.bind(this.dialogDestroy, this);
|
btn_destroy.onclick = () => dialog_destroy.show();
|
||||||
|
|
||||||
layout_append(btn_destroy, _('Shutdown'),
|
layout_append(btn_destroy, _('Shutdown'),
|
||||||
_('Complete service shutdown, as well as deleting nftsets and blacklist data'));
|
_('Complete service shutdown, as well as deleting nftsets and blacklist data'));
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
'require view.ruantiblock.tools as tools';
|
'require view.ruantiblock.tools as tools';
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
parsers : {},
|
parsers : {},
|
||||||
|
|
||||||
appStatusCode: null,
|
appStatusCode : null,
|
||||||
|
|
||||||
depends : function(elem, key, array, empty=true) {
|
depends(elem, key, array, empty=true) {
|
||||||
if(empty && array.length === 0) {
|
if(empty && array.length === 0) {
|
||||||
elem.depends(key, '_dummy');
|
elem.depends(key, '_dummy');
|
||||||
} else {
|
} else {
|
||||||
@@ -20,20 +20,82 @@ return view.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
validateIpPort: function(section, value) {
|
validateIpPort(section, value) {
|
||||||
return (/^$|^([0-9]{1,3}\.){3}[0-9]{1,3}(#[\d]{2,5})?$/.test(value)) ? true : _('Expecting:')
|
return (/^$|^([0-9]{1,3}\.){3}[0-9]{1,3}(#[\d]{2,5})?$/.test(value)) ? true : _('Expecting:')
|
||||||
+ ` ${_('One of the following:')}\n - ${_('valid IP address')}\n - ${_('valid address#port')}\n`;
|
+ ` ${_('One of the following:')}\n - ${_('valid IP address')}\n - ${_('valid address#port')}\n`;
|
||||||
},
|
},
|
||||||
|
|
||||||
validateUrl: function(section, value) {
|
validateUrl(section, value) {
|
||||||
return (/^$|^https?:\/\/[\w.-]+(:[0-9]{2,5})?[\w\/~.&?+=-]*$/.test(value)) ? true : _('Expecting:')
|
return (/^$|^https?:\/\/[\w.-]+(:[0-9]{2,5})?[\w\/~.&?+=-]*$/.test(value)) ? true : _('Expecting:')
|
||||||
+ ` ${_('valid URL')}\n`;
|
+ ` ${_('valid URL')}\n`;
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function() {
|
CBIBlockFileEdit: form.Value.extend({
|
||||||
|
__name__ : 'CBI.BlockFileEdit',
|
||||||
|
|
||||||
|
__init__(map, section, ctx, id, file, title, description, callback) {
|
||||||
|
this.map = map;
|
||||||
|
this.section = section;
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.id = id,
|
||||||
|
this.optional = true;
|
||||||
|
this.rmempty = true;
|
||||||
|
this.file = file;
|
||||||
|
this.title = title;
|
||||||
|
this.description = description;
|
||||||
|
this.callback = callback;
|
||||||
|
this.content = '';
|
||||||
|
},
|
||||||
|
|
||||||
|
cfgvalue(section_id, option) {
|
||||||
|
return this.content;
|
||||||
|
},
|
||||||
|
|
||||||
|
formvalue(section_id) {
|
||||||
|
let value = this.content;
|
||||||
|
let textarea = document.getElementById('widget.file_edit.content.' + this.id);
|
||||||
|
if(textarea) {
|
||||||
|
value = textarea.value.trim().replace(/\r\n/g, '\n') + '\n';
|
||||||
|
};
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
|
||||||
|
write(section_id, formvalue) {
|
||||||
|
return fs.write(this.file, formvalue).then(rc => {
|
||||||
|
ui.addNotification(null, E('p', _('Contents have been saved.')),
|
||||||
|
'info');
|
||||||
|
if(this.callback) {
|
||||||
|
return this.callback(rc);
|
||||||
|
};
|
||||||
|
}).catch(e => {
|
||||||
|
ui.addNotification(null, E('p', _('Unable to save the contents')
|
||||||
|
+ ': %s'.format(e.message)));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
return L.resolveDefault(fs.read(this.file), '').then(c => {
|
||||||
|
this.content = c;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
renderWidget(section_id, option_index, cfgvalue) {
|
||||||
|
return E('textarea', {
|
||||||
|
'id' : 'widget.file_edit.content.' + this.id,
|
||||||
|
'class' : 'cbi-input-textarea',
|
||||||
|
'style' : 'width:100% !important;resize:vertical !important',
|
||||||
|
'rows' : 10,
|
||||||
|
'wrap' : 'off',
|
||||||
|
'spellcheck': 'false',
|
||||||
|
}, cfgvalue);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
load() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
L.resolveDefault(fs.exec(tools.execPath, [ 'raw-status' ]), 1),
|
L.resolveDefault(fs.exec(tools.execPath, [ 'raw-status' ]), 1),
|
||||||
L.resolveDefault(fs.list(tools.parsersDir), null),
|
L.resolveDefault(fs.list(tools.parsersDir), null),
|
||||||
|
L.resolveDefault(fs.list(tools.dnsmasqCfgDirsRoot), null),
|
||||||
uci.load(tools.appName),
|
uci.load(tools.appName),
|
||||||
]).catch(e => {
|
]).catch(e => {
|
||||||
ui.addNotification(null, E('p', _('Unable to read the contents')
|
ui.addNotification(null, E('p', _('Unable to read the contents')
|
||||||
@@ -43,14 +105,14 @@ return view.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(data) {
|
render(data) {
|
||||||
if(!data) {
|
if(!data) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
this.appStatusCode = data[0].code;
|
this.appStatusCode = data[0].code;
|
||||||
let p_dir_arr = data[1];
|
let p_dir_arr = data[1];
|
||||||
let curent_module = uci.get(tools.appName, 'config', 'bllist_module');
|
let curent_module = uci.get(tools.appName, 'config', 'bllist_module');
|
||||||
let curent_preset = uci.get(tools.appName, 'config', 'bllist_preset');
|
let curent_preset = uci.get(tools.appName, 'config', 'bllist_preset');
|
||||||
|
|
||||||
if(p_dir_arr) {
|
if(p_dir_arr) {
|
||||||
p_dir_arr.forEach(e => {
|
p_dir_arr.forEach(e => {
|
||||||
@@ -129,7 +191,7 @@ return view.extend({
|
|||||||
'<br /><code>#comment<br />domain.net<br />anotherdomain.com</code>'
|
'<br /><code>#comment<br />domain.net<br />anotherdomain.com</code>'
|
||||||
);
|
);
|
||||||
|
|
||||||
let m, s, o;
|
let m, s, o, ss;
|
||||||
|
|
||||||
m = new form.Map(tools.appName, _('Ruantiblock') + ' - ' + _('Settings'));
|
m = new form.Map(tools.appName, _('Ruantiblock') + ' - ' + _('Settings'));
|
||||||
|
|
||||||
@@ -140,39 +202,32 @@ return view.extend({
|
|||||||
|
|
||||||
/* Main settings tab */
|
/* Main settings tab */
|
||||||
|
|
||||||
s.tab('main_settings', _('Main settings'));
|
s.tab('main_tab', _('Main settings'));
|
||||||
|
|
||||||
// PROXY_MODE
|
|
||||||
o = s.taboption('main_settings', form.ListValue, 'proxy_mode',
|
|
||||||
_('Proxy mode'));
|
|
||||||
o.value('1', 'Tor');
|
|
||||||
o.value('2', 'VPN');
|
|
||||||
o.value('3', _('Transparent proxy'));
|
|
||||||
|
|
||||||
// PROXY_LOCAL_CLIENTS
|
|
||||||
let proxy_local_clients = s.taboption('main_settings', form.Flag, 'proxy_local_clients',
|
|
||||||
_('Apply proxy rules to router application traffic'));
|
|
||||||
proxy_local_clients.rmempty = false;
|
|
||||||
|
|
||||||
// ENABLE_LOGGING
|
// ENABLE_LOGGING
|
||||||
o = s.taboption('main_settings', form.Flag, 'enable_logging',
|
o = s.taboption('main_tab', form.Flag, 'enable_logging',
|
||||||
_('Logging events'));
|
_('Logging events'));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
||||||
// update_at_startup
|
// update_at_startup
|
||||||
o = s.taboption('main_settings', form.Flag, 'update_at_startup',
|
o = s.taboption('main_tab', form.Flag, 'update_at_startup',
|
||||||
_('Update at startup'));
|
_('Update at startup'));
|
||||||
o.description = _('Update blacklist after system startup');
|
o.description = _('Update blacklist after system startup');
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
||||||
|
// PROXY_LOCAL_CLIENTS
|
||||||
|
o = s.taboption('main_tab', form.Flag, 'proxy_local_clients',
|
||||||
|
_('Apply proxy rules to router application traffic'));
|
||||||
|
o.rmempty = false;
|
||||||
|
|
||||||
// NFTSET_CLEAR_SETS
|
// NFTSET_CLEAR_SETS
|
||||||
o = s.taboption('main_settings', form.Flag, 'nftset_clear_sets',
|
o = s.taboption('main_tab', form.Flag, 'nftset_clear_sets',
|
||||||
_('Clean up nftsets before updating blacklist'));
|
_('Clean up nftsets before updating blacklist'));
|
||||||
o.description = _('Reduces RAM consumption during update');
|
o.description = _('Reduces RAM consumption during update');
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
||||||
// ALLOWED_HOSTS_MODE
|
// ALLOWED_HOSTS_MODE
|
||||||
o = s.taboption('main_settings', form.ListValue, 'allowed_hosts_mode',
|
o = s.taboption('main_tab', form.ListValue, 'allowed_hosts_mode',
|
||||||
_('Host filter'));
|
_('Host filter'));
|
||||||
o.value('0', _('Disabled'));
|
o.value('0', _('Disabled'));
|
||||||
o.value('1', _('Only listed hosts'));
|
o.value('1', _('Only listed hosts'));
|
||||||
@@ -180,40 +235,29 @@ return view.extend({
|
|||||||
o.description = _('Restriction of hosts that are allowed to bypass blocking');
|
o.description = _('Restriction of hosts that are allowed to bypass blocking');
|
||||||
|
|
||||||
// ALLOWED_HOSTS_LIST
|
// ALLOWED_HOSTS_LIST
|
||||||
o = s.taboption('main_settings', form.DynamicList, 'allowed_hosts_list',
|
o = s.taboption('main_tab', form.DynamicList, 'allowed_hosts_list',
|
||||||
_('IP addresses for host filter'));
|
_('IP addresses for host filter'));
|
||||||
o.datatype = 'ip4addr';
|
o.datatype = 'ip4addr';
|
||||||
|
|
||||||
// ENABLE_FPROXY
|
|
||||||
o = s.taboption('main_settings', form.Flag, 'enable_fproxy',
|
|
||||||
_('Enable full proxy mode'));
|
|
||||||
o.description = _('All traffic of the specified hosts passes through the proxy, without a blacklist');
|
|
||||||
o.rmempty = false;
|
|
||||||
|
|
||||||
// FPROXY_LIST
|
|
||||||
o = s.taboption('main_settings', form.DynamicList, 'fproxy_list',
|
|
||||||
_('IP addresses for full proxy mode'));
|
|
||||||
o.datatype = 'ip4addr';
|
|
||||||
|
|
||||||
|
|
||||||
/* Tor tab */
|
/* Tor tab */
|
||||||
|
|
||||||
s.tab('tor_settings', _('Tor mode'));
|
s.tab('tor_tab', _('Tor mode'));
|
||||||
|
|
||||||
// TOR_TRANS_PORT
|
// TOR_TRANS_PORT
|
||||||
o = s.taboption('tor_settings', form.Value, 'tor_trans_port',
|
o = s.taboption('tor_tab', form.Value, 'tor_trans_port',
|
||||||
_('Transparent proxy port'));
|
_('Transparent proxy port'));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.datatype = 'port';
|
o.datatype = 'port';
|
||||||
|
|
||||||
// ONION_DNS_ADDR
|
// ONION_DNS_ADDR
|
||||||
o = s.taboption('tor_settings', form.Value, 'onion_dns_addr',
|
o = s.taboption('tor_tab', form.Value, 'onion_dns_addr',
|
||||||
_("Optional DNS resolver for '.onion' zone"), '<code>ipaddress#port</code>');
|
_("Optional DNS resolver for '.onion' zone"), '<code>ipaddress#port</code>');
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.validate = this.validateIpPort;
|
o.validate = this.validateIpPort;
|
||||||
|
|
||||||
// Torrc edit dialog
|
// Torrc edit dialog
|
||||||
o = s.taboption('tor_settings', form.Button, '_torrc_btn',
|
o = s.taboption('tor_tab', form.Button, '_torrc_btn',
|
||||||
_('Tor configuration file'));
|
_('Tor configuration file'));
|
||||||
o.onclick = () => torrc_edit.show();
|
o.onclick = () => torrc_edit.show();
|
||||||
o.inputtitle = _('Edit');
|
o.inputtitle = _('Edit');
|
||||||
@@ -222,10 +266,10 @@ return view.extend({
|
|||||||
|
|
||||||
/* VPN tab */
|
/* VPN tab */
|
||||||
|
|
||||||
s.tab('vpn_settings', _('VPN mode'));
|
s.tab('vpn_tab', _('VPN mode'));
|
||||||
|
|
||||||
// IF_VPN
|
// IF_VPN
|
||||||
o = s.taboption('vpn_settings', widgets.DeviceSelect, 'if_vpn',
|
o = s.taboption('vpn_tab', widgets.DeviceSelect, 'if_vpn',
|
||||||
_('VPN interface'));
|
_('VPN interface'));
|
||||||
o.multiple = false;
|
o.multiple = false;
|
||||||
o.noaliases = true;
|
o.noaliases = true;
|
||||||
@@ -233,13 +277,13 @@ return view.extend({
|
|||||||
o.default = 'tun0';
|
o.default = 'tun0';
|
||||||
|
|
||||||
// VPN_GW_IP
|
// VPN_GW_IP
|
||||||
o = s.taboption('vpn_settings', form.Value, 'vpn_gw_ip',
|
o = s.taboption('vpn_tab', form.Value, 'vpn_gw_ip',
|
||||||
_('VPN gateway IP address'),
|
_('VPN gateway IP address'),
|
||||||
_('If not specified, the VPN interface address is used (or peer address for PPP protocols)'));
|
_('If not specified, the VPN interface address is used (or peer address for PPP protocols)'));
|
||||||
o.datatype = 'ip4addr(1)';
|
o.datatype = 'ip4addr(1)';
|
||||||
|
|
||||||
// VPN_ROUTE_CHECK
|
// VPN_ROUTE_CHECK
|
||||||
o = s.taboption('vpn_settings', form.ListValue, 'vpn_route_check',
|
o = s.taboption('vpn_tab', form.ListValue, 'vpn_route_check',
|
||||||
_('Type of adding a VPN rule to the routing table'));
|
_('Type of adding a VPN rule to the routing table'));
|
||||||
o.value('0', 'hotplug.d');
|
o.value('0', 'hotplug.d');
|
||||||
o.value('1', 'ruab_route_check');
|
o.value('1', 'ruab_route_check');
|
||||||
@@ -248,32 +292,46 @@ return view.extend({
|
|||||||
_('ruab_route_check - script that regularly checks an entry in the routing table.');
|
_('ruab_route_check - script that regularly checks an entry in the routing table.');
|
||||||
|
|
||||||
|
|
||||||
/* Proxy tab */
|
/* Tproxy tab */
|
||||||
|
|
||||||
s.tab('proxy_settings', _('Transparent proxy mode'));
|
s.tab('tproxy_tab', _('Transparent proxy mode'));
|
||||||
|
|
||||||
|
// T_PROXY_TYPE
|
||||||
|
o = s.taboption('tproxy_tab', form.ListValue, 't_proxy_type',
|
||||||
|
_('Proxy type'));
|
||||||
|
o.value('0', _('redirect'));
|
||||||
|
o.value('1', _('tproxy'));
|
||||||
|
o.description = _('Statement in nftables rules');
|
||||||
|
|
||||||
// T_PROXY_PORT_TCP
|
// T_PROXY_PORT_TCP
|
||||||
o = s.taboption('proxy_settings', form.Value, 't_proxy_port_tcp',
|
o = s.taboption('tproxy_tab', form.Value, 't_proxy_port_tcp',
|
||||||
_('Transparent proxy TCP port'));
|
_('Transparent proxy TCP port'));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.datatype = 'port';
|
o.datatype = 'port';
|
||||||
|
|
||||||
// T_PROXY_ALLOW_UDP
|
// T_PROXY_ALLOW_UDP
|
||||||
o = s.taboption('proxy_settings', form.Flag, 't_proxy_allow_udp',
|
o = s.taboption('tproxy_tab', form.Flag, 't_proxy_allow_udp',
|
||||||
_('Send UDP traffic to transparent proxy'));
|
_('Send UDP traffic to transparent proxy'));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
|
||||||
// T_PROXY_PORT_UDP
|
// T_PROXY_PORT_UDP
|
||||||
o = s.taboption('proxy_settings', form.Value, 't_proxy_port_udp',
|
o = s.taboption('tproxy_tab', form.Value, 't_proxy_port_udp',
|
||||||
_('Transparent proxy UDP port'));
|
_('Transparent proxy UDP port'));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.datatype = 'port';
|
o.datatype = 'port';
|
||||||
|
|
||||||
|
|
||||||
/* Blacklist module tab */
|
/* Blacklist tab */
|
||||||
|
|
||||||
s.tab('blacklist_tab', _('Blacklist settings'));
|
s.tab('blacklist_tab', _('Blacklist settings'));
|
||||||
|
|
||||||
|
// PROXY_MODE
|
||||||
|
o = s.taboption('blacklist_tab', form.ListValue, 'proxy_mode',
|
||||||
|
_('Proxy mode'));
|
||||||
|
o.value('1', 'Tor');
|
||||||
|
o.value('2', 'VPN');
|
||||||
|
o.value('3', _('Transparent proxy'));
|
||||||
|
|
||||||
// BLLIST_PRESET
|
// BLLIST_PRESET
|
||||||
let bllist_preset = s.taboption('blacklist_tab', form.ListValue,
|
let bllist_preset = s.taboption('blacklist_tab', form.ListValue,
|
||||||
'bllist_preset', _('Blacklist update mode'));
|
'bllist_preset', _('Blacklist update mode'));
|
||||||
@@ -312,29 +370,16 @@ return view.extend({
|
|||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.default = 0;
|
o.default = 0;
|
||||||
|
|
||||||
// ADD_USER_ENTRIES
|
// ENABLE_FPROXY
|
||||||
o = s.taboption('blacklist_tab', form.Flag, 'add_user_entries',
|
o = s.taboption('blacklist_tab', form.Flag, 'enable_fproxy',
|
||||||
_('Enable user entries'), _('Add user entries to the blacklist when updating'));
|
_('Enable full proxy mode'));
|
||||||
|
o.description = _('All traffic of the specified hosts passes through the proxy, without a blacklist');
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
o.default = 0;
|
|
||||||
o.depends({ bllist_preset: '', '!reverse': true });
|
|
||||||
|
|
||||||
// USER_ENTRIES edit dialog
|
// FPROXY_LIST
|
||||||
o = s.taboption('blacklist_tab', form.Button, '_user_entries_btn',
|
o = s.taboption('blacklist_tab', form.DynamicList, 'fproxy_list',
|
||||||
_('User entries'));
|
_('IP addresses for full proxy mode'));
|
||||||
o.onclick = () => user_entries_edit.show();
|
o.datatype = 'ip4addr';
|
||||||
o.inputtitle = _('Edit');
|
|
||||||
o.inputstyle = 'edit btn';
|
|
||||||
|
|
||||||
// USER_ENTRIES_REMOTE
|
|
||||||
o = s.taboption('blacklist_tab', form.DynamicList, 'user_entries_remote',
|
|
||||||
_('URLs of remote user entries file'));
|
|
||||||
o.validate = this.validateUrl;
|
|
||||||
|
|
||||||
// USER_ENTRIES_DNS
|
|
||||||
o = s.taboption('blacklist_tab', form.Value, 'user_entries_dns',
|
|
||||||
_("DNS server that is used for the user's FQDN entries"), '<code>ipaddress[#port]</code>');
|
|
||||||
o.validate = this.validateIpPort;
|
|
||||||
|
|
||||||
// BYPASS_MODE
|
// BYPASS_MODE
|
||||||
o = s.taboption('blacklist_tab', form.Flag, 'bypass_mode',
|
o = s.taboption('blacklist_tab', form.Flag, 'bypass_mode',
|
||||||
@@ -354,6 +399,7 @@ return view.extend({
|
|||||||
_('DNS server that is used for the FQDN entries of exclusion list'), '<code>ipaddress[#port]</code>');
|
_('DNS server that is used for the FQDN entries of exclusion list'), '<code>ipaddress[#port]</code>');
|
||||||
o.validate = this.validateIpPort;
|
o.validate = this.validateIpPort;
|
||||||
|
|
||||||
|
|
||||||
if(availableParsers) {
|
if(availableParsers) {
|
||||||
bllist_preset.description += '<br /> ( * - ' + _('requires installed blacklist module') + ' )';
|
bllist_preset.description += '<br /> ( * - ' + _('requires installed blacklist module') + ' )';
|
||||||
|
|
||||||
@@ -398,10 +444,9 @@ return view.extend({
|
|||||||
// BLLIST_GR_EXCLUDED_SLD_FILE edit dialog
|
// BLLIST_GR_EXCLUDED_SLD_FILE edit dialog
|
||||||
o = s.taboption('parser_settings_tab', form.Button, '_gr_excluded_sld_btn',
|
o = s.taboption('parser_settings_tab', form.Button, '_gr_excluded_sld_btn',
|
||||||
_('2nd level domains that are excluded from optimization'));
|
_('2nd level domains that are excluded from optimization'));
|
||||||
o.onclick = () => gr_excluded_sld_edit.show();
|
o.onclick = () => gr_excluded_sld_edit.show();
|
||||||
o.inputtitle = _('Edit');
|
o.inputtitle = _('Edit');
|
||||||
o.inputstyle = 'edit btn';
|
o.inputstyle = 'edit btn';
|
||||||
//o.description = _('e.g:') + ' <code>livejournal.com</code>';
|
|
||||||
|
|
||||||
// BLLIST_ENABLE_IDN
|
// BLLIST_ENABLE_IDN
|
||||||
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_enable_idn',
|
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_enable_idn',
|
||||||
@@ -447,10 +492,9 @@ return view.extend({
|
|||||||
// BLLIST_GR_EXCLUDED_NETS_FILE edit dialog
|
// BLLIST_GR_EXCLUDED_NETS_FILE edit dialog
|
||||||
o = s.taboption('parser_settings_tab', form.Button, '_gr_excluded_nets_btn',
|
o = s.taboption('parser_settings_tab', form.Button, '_gr_excluded_nets_btn',
|
||||||
_('IP subnet patterns (/24) that are excluded from optimization'));
|
_('IP subnet patterns (/24) that are excluded from optimization'));
|
||||||
o.onclick = () => gr_excluded_nets_edit.show();
|
o.onclick = () => gr_excluded_nets_edit.show();
|
||||||
o.inputtitle = _('Edit');
|
o.inputtitle = _('Edit');
|
||||||
o.inputstyle = 'edit btn';
|
o.inputstyle = 'edit btn';
|
||||||
//o.description = _('e.g:') + ' <code>192.168.1.</code>';
|
|
||||||
|
|
||||||
// BLLIST_SUMMARIZE_IP
|
// BLLIST_SUMMARIZE_IP
|
||||||
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_summarize_ip',
|
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_summarize_ip',
|
||||||
@@ -461,7 +505,180 @@ return view.extend({
|
|||||||
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_summarize_cidr',
|
o = s.taboption('parser_settings_tab', form.Flag, 'bllist_summarize_cidr',
|
||||||
_("Summarize '/24' networks"));
|
_("Summarize '/24' networks"));
|
||||||
o.rmempty = false;
|
o.rmempty = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* User entries tab */
|
||||||
|
|
||||||
|
s.tab('user_entries_tab', _('User entries'));
|
||||||
|
|
||||||
|
o = s.taboption('user_entries_tab', form.SectionValue, 'user_instance', form.GridSection,
|
||||||
|
'user_instance');
|
||||||
|
ss = o.subsection;
|
||||||
|
ss.addremove = false;
|
||||||
|
ss.sortable = false;
|
||||||
|
ss.nodescriptions = true;
|
||||||
|
ss.modaltitle = `${_('User entries')} - %s`;
|
||||||
|
ss.max_cols = 2;
|
||||||
|
|
||||||
|
|
||||||
|
/* User entries main settings tab */
|
||||||
|
|
||||||
|
ss.tab('u_main_tab', _('Main settings'));
|
||||||
|
|
||||||
|
// U_ENABLED
|
||||||
|
o = ss.taboption('u_main_tab', form.Flag, 'u_enabled',
|
||||||
|
_('Enabled'),
|
||||||
|
);
|
||||||
|
o.rmempty = false;
|
||||||
|
o.default = '1';
|
||||||
|
o.editable = true;
|
||||||
|
o.modalonly = false;
|
||||||
|
|
||||||
|
// description
|
||||||
|
o = ss.taboption('u_main_tab', form.Value, 'u_description',
|
||||||
|
_("Description"));
|
||||||
|
o.datatype = 'maxlength(100)';
|
||||||
|
o.modalonly = null;
|
||||||
|
|
||||||
|
// U_PROXY_MODE
|
||||||
|
o = ss.taboption('u_main_tab', form.ListValue, 'u_proxy_mode',
|
||||||
|
_('Proxy mode'));
|
||||||
|
o.value('1', 'Tor');
|
||||||
|
o.value('2', 'VPN');
|
||||||
|
o.value('3', _('Transparent proxy'));
|
||||||
|
o.default = '2';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_SKIP_MARKED_PACKETS
|
||||||
|
o = ss.taboption('u_main_tab', form.Flag, 'u_skip_marked_packets',
|
||||||
|
_('Lowest priority'));
|
||||||
|
o.description = _('This proxy will receive traffic last, even after the main blacklist');
|
||||||
|
o.rmempty = false;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_ENABLE_FPROXY
|
||||||
|
o = ss.taboption('u_main_tab', form.Flag, 'u_enable_fproxy',
|
||||||
|
_('Enable full proxy mode'));
|
||||||
|
o.description = _('All traffic of the specified hosts passes through the proxy, without a blacklist');
|
||||||
|
o.rmempty = false;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_FPROXY_LIST
|
||||||
|
o = ss.taboption('u_main_tab', form.DynamicList, 'u_fproxy_list',
|
||||||
|
_('IP addresses for full proxy mode'));
|
||||||
|
o.datatype = 'ip4addr';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
|
||||||
|
/* User entries tor tab */
|
||||||
|
|
||||||
|
ss.tab('u_tor_tab', _('Tor mode'));
|
||||||
|
|
||||||
|
// U_TOR_TRANS_PORT
|
||||||
|
o = ss.taboption('u_tor_tab', form.Value, 'u_tor_trans_port',
|
||||||
|
_('Transparent proxy port'));
|
||||||
|
o.rmempty = false;
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_ONION_DNS_ADDR
|
||||||
|
o = ss.taboption('u_tor_tab', form.Value, 'u_onion_dns_addr',
|
||||||
|
_("Optional DNS resolver for '.onion' zone"), '<code>ipaddress#port</code>');
|
||||||
|
o.rmempty = false;
|
||||||
|
o.validate = this.validateIpPort;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
/* User entries VPN tab */
|
||||||
|
|
||||||
|
ss.tab('u_vpn_tab', _('VPN mode'));
|
||||||
|
|
||||||
|
// U_IF_VPN
|
||||||
|
o = ss.taboption('u_vpn_tab', widgets.DeviceSelect, 'u_if_vpn',
|
||||||
|
_('VPN interface'));
|
||||||
|
o.multiple = false;
|
||||||
|
o.noaliases = true;
|
||||||
|
o.rmempty = false;
|
||||||
|
o.default = 'tun0';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_VPN_GW_IP
|
||||||
|
o = ss.taboption('u_vpn_tab', form.Value, 'u_vpn_gw_ip',
|
||||||
|
_('VPN gateway IP address'),
|
||||||
|
_('If not specified, the VPN interface address is used (or peer address for PPP protocols)'));
|
||||||
|
o.datatype = 'ip4addr(1)';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
|
||||||
|
/* User entries tproxy tab */
|
||||||
|
|
||||||
|
ss.tab('u_tproxy_tab', _('Transparent proxy mode'));
|
||||||
|
|
||||||
|
// U_T_PROXY_TYPE
|
||||||
|
o = ss.taboption('u_tproxy_tab', form.ListValue, 'u_t_proxy_type',
|
||||||
|
_('Proxy type'));
|
||||||
|
o.value('0', _('redirect'));
|
||||||
|
o.value('1', _('tproxy'));
|
||||||
|
o.description = _('Statement in nftables rules');
|
||||||
|
|
||||||
|
// U_T_PROXY_PORT_TCP
|
||||||
|
o = ss.taboption('u_tproxy_tab', form.Value, 'u_t_proxy_port_tcp',
|
||||||
|
_('Transparent proxy TCP port'));
|
||||||
|
o.rmempty = false;
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_T_PROXY_ALLOW_UDP
|
||||||
|
o = ss.taboption('u_tproxy_tab', form.Flag, 'u_t_proxy_allow_udp',
|
||||||
|
_('Send UDP traffic to transparent proxy'));
|
||||||
|
o.rmempty = false;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_T_PROXY_PORT_UDP
|
||||||
|
o = ss.taboption('u_tproxy_tab', form.Value, 'u_t_proxy_port_udp',
|
||||||
|
_('Transparent proxy UDP port'));
|
||||||
|
o.rmempty = false;
|
||||||
|
o.datatype = 'port';
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
|
||||||
|
/* User entries items tab */
|
||||||
|
|
||||||
|
ss.tab('u_entries_tab', _('Entries'));
|
||||||
|
|
||||||
|
ss.addModalOptions = (s, section_id, ev) => {
|
||||||
|
|
||||||
|
// user entries edit dialog
|
||||||
|
o = s.taboption('u_entries_tab', this.CBIBlockFileEdit, this,
|
||||||
|
'user-entries',
|
||||||
|
tools.userListsDir + '/' + s.section,
|
||||||
|
_('Edit entries'),
|
||||||
|
_('One entry (IP, CIDR or FQDN) per line. In the FQDN records, you can specify the DNS server for resolving this domain (separated by a space). You can also comment on lines (<code>#</code> is the first character of a line).<br />Examples:') +
|
||||||
|
'<br /><code>#comment<br />domain.net<br />sub.domain.com 8.8.8.8<br />sub.domain.com 8.8.8.8#53<br />74.125.131.19<br />74.125.0.0/16</code>'
|
||||||
|
);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
console.log(tools.userListsDir + '/' + s.section);
|
||||||
|
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_ENTRIES_REMOTE
|
||||||
|
o = s.taboption('u_entries_tab', form.DynamicList, 'u_entries_remote',
|
||||||
|
_('URLs of remote user entries file'));
|
||||||
|
o.validate = this.validateUrl;
|
||||||
|
o.modalonly = true;
|
||||||
|
|
||||||
|
// U_ENABLE_ENTRIES_REMOTE_PROXY
|
||||||
|
o = s.taboption('u_entries_tab', form.Flag, 'u_enable_entries_remote_proxy',
|
||||||
|
_('Downloading files via proxy'), _('Turn on if files are blocked'));
|
||||||
|
o.rmempty = false;
|
||||||
|
o.default = 0;
|
||||||
|
|
||||||
|
// U_ENTRIES_DNS
|
||||||
|
o = s.taboption('u_entries_tab', form.Value, 'u_entries_dns',
|
||||||
|
_("DNS server that is used for the user's FQDN entries"), '<code>ipaddress[#port]</code>');
|
||||||
|
o.validate = this.validateIpPort;
|
||||||
|
o.modalonly = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
let map_promise = m.render();
|
let map_promise = m.render();
|
||||||
@@ -469,12 +686,28 @@ return view.extend({
|
|||||||
return map_promise;
|
return map_promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSaveApply: function(ev, mode) {
|
handleSave(ev, restart) {
|
||||||
return this.handleSave(ev).then(() => {
|
let tasks = [];
|
||||||
|
document.getElementById('maincontent')
|
||||||
|
.querySelectorAll('.cbi-map').forEach((map, i, a) => {
|
||||||
|
let res = DOM.callClassMethod(map, 'save');
|
||||||
|
if(restart && i == a.length - 1 && this.appStatusCode != 1 && this.appStatusCode != 2) {
|
||||||
|
res.then(() => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
fs.exec_direct(tools.execPath, [ 'restart' ]).then(
|
||||||
|
() => console.log(tools.execPath + ' restarted...')
|
||||||
|
);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
tasks.push(res);
|
||||||
|
});
|
||||||
|
return Promise.all(tasks);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSaveApply(ev, mode) {
|
||||||
|
return this.handleSave(ev, true).then(() => {
|
||||||
ui.changes.apply(mode == '0');
|
ui.changes.apply(mode == '0');
|
||||||
if(this.appStatusCode != 1 && this.appStatusCode != 2) {
|
|
||||||
window.setTimeout(() => fs.exec(tools.execPath, [ 'restart' ]), 3000);
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ return baseclass.extend({
|
|||||||
execPath : '/usr/bin/ruantiblock',
|
execPath : '/usr/bin/ruantiblock',
|
||||||
tokenFile : '/var/run/ruantiblock.token',
|
tokenFile : '/var/run/ruantiblock.token',
|
||||||
parsersDir : '/usr/libexec/ruantiblock',
|
parsersDir : '/usr/libexec/ruantiblock',
|
||||||
|
dnsmasqCfgDirsRoot: '/tmp',
|
||||||
torrcFile : '/etc/tor/torrc',
|
torrcFile : '/etc/tor/torrc',
|
||||||
userEntriesFile : '/etc/ruantiblock/user_entries',
|
userEntriesFile : '/etc/ruantiblock/user_entries',
|
||||||
|
userListsDir : '/etc/ruantiblock/user_lists',
|
||||||
bypassEntriesFile : '/etc/ruantiblock/bypass_entries',
|
bypassEntriesFile : '/etc/ruantiblock/bypass_entries',
|
||||||
fqdnFilterFile : '/etc/ruantiblock/fqdn_filter',
|
fqdnFilterFile : '/etc/ruantiblock/fqdn_filter',
|
||||||
ipFilterFile : '/etc/ruantiblock/ip_filter',
|
ipFilterFile : '/etc/ruantiblock/ip_filter',
|
||||||
@@ -76,7 +78,7 @@ return baseclass.extend({
|
|||||||
expect: { result: false }
|
expect: { result: false }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getInitStatus: function(name) {
|
getInitStatus(name) {
|
||||||
return this.callInitStatus(name).then(res => {
|
return this.callInitStatus(name).then(res => {
|
||||||
if(res) {
|
if(res) {
|
||||||
return res[name].enabled;
|
return res[name].enabled;
|
||||||
@@ -89,7 +91,7 @@ return baseclass.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleServiceAction: function(name, action) {
|
handleServiceAction(name, action) {
|
||||||
return this.callInitAction(name, action).then(success => {
|
return this.callInitAction(name, action).then(success => {
|
||||||
if(!success) {
|
if(!success) {
|
||||||
throw _('Command failed');
|
throw _('Command failed');
|
||||||
@@ -101,13 +103,12 @@ return baseclass.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
normalizeValue: function(v) {
|
normalizeValue(v) {
|
||||||
return (v && typeof(v) === 'string') ? v.trim().replace(/\r?\n/g, '') : v;
|
return (v && typeof(v) === 'string') ? v.trim().replace(/\r?\n/g, '') : v;
|
||||||
},
|
},
|
||||||
|
|
||||||
makeStatusString: function(
|
makeStatusString: function(
|
||||||
app_status_code,
|
app_status_code,
|
||||||
proxy_mode,
|
|
||||||
bllist_preset,
|
bllist_preset,
|
||||||
bllist_module,
|
bllist_module,
|
||||||
vpn_route_status_code) {
|
vpn_route_status_code) {
|
||||||
@@ -152,14 +153,6 @@ return baseclass.extend({
|
|||||||
%s %s
|
%s %s
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="tr">
|
|
||||||
<td class="td left">
|
|
||||||
${_('Proxy mode')}:
|
|
||||||
</td>
|
|
||||||
<td class="td left">
|
|
||||||
%s
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="tr">
|
<tr class="tr">
|
||||||
<td class="td left">
|
<td class="td left">
|
||||||
${_('Blacklist update mode')}:
|
${_('Blacklist update mode')}:
|
||||||
@@ -172,10 +165,9 @@ return baseclass.extend({
|
|||||||
`.format(
|
`.format(
|
||||||
spinning,
|
spinning,
|
||||||
app_status_label,
|
app_status_label,
|
||||||
(app_status_code != 2 && proxy_mode == 2 && vpn_route_status_code != 0)
|
(app_status_code != 2 && vpn_route_status_code != 0)
|
||||||
? '<span class="label-status error">'
|
? '<span class="label-status error">'
|
||||||
+ _('VPN routing error! Need restart') + '</span>' : '',
|
+ _('VPN routing error! Need restart') + '</span>' : '',
|
||||||
(proxy_mode == 3) ? _('Transparent proxy') : (proxy_mode == 2) ? 'VPN' : 'Tor',
|
|
||||||
(!bllist_preset || bllist_preset === '') ? _('user entries only') :
|
(!bllist_preset || bllist_preset === '') ? _('user entries only') :
|
||||||
(this.blacklistPresets[bllist_preset]) ?
|
(this.blacklistPresets[bllist_preset]) ?
|
||||||
`<span style="cursor:help; border-bottom:1px dotted" data-tooltip="${this.blacklistPresets[bllist_preset][2]}">
|
`<span style="cursor:help; border-bottom:1px dotted" data-tooltip="${this.blacklistPresets[bllist_preset][2]}">
|
||||||
@@ -185,7 +177,7 @@ return baseclass.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
fileEditDialog: baseclass.extend({
|
fileEditDialog: baseclass.extend({
|
||||||
__init__: function(file, title, description, callback, file_exists=false) {
|
__init__(file, title, description, callback, file_exists=false) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
@@ -193,11 +185,11 @@ return baseclass.extend({
|
|||||||
this.file_exists = file_exists;
|
this.file_exists = file_exists;
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function() {
|
load() {
|
||||||
return L.resolveDefault(fs.read(this.file), '');
|
return L.resolveDefault(fs.read(this.file), '');
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function(content) {
|
render(content) {
|
||||||
ui.showModal(this.title, [
|
ui.showModal(this.title, [
|
||||||
E('div', { 'class': 'cbi-section' }, [
|
E('div', { 'class': 'cbi-section' }, [
|
||||||
E('div', { 'class': 'cbi-section-descr' }, this.description),
|
E('div', { 'class': 'cbi-section-descr' }, this.description),
|
||||||
@@ -230,7 +222,7 @@ return baseclass.extend({
|
|||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSave: function(ev) {
|
handleSave(ev) {
|
||||||
let textarea = document.getElementById('widget.modal_content');
|
let textarea = document.getElementById('widget.modal_content');
|
||||||
let value = textarea.value.trim().replace(/\r\n/g, '\n') + '\n';
|
let value = textarea.value.trim().replace(/\r\n/g, '\n') + '\n';
|
||||||
|
|
||||||
@@ -249,7 +241,7 @@ return baseclass.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
error: function(e) {
|
error(e) {
|
||||||
if(!this.file_exists && e instanceof Error && e.name === 'NotFoundError') {
|
if(!this.file_exists && e instanceof Error && e.name === 'NotFoundError') {
|
||||||
return this.render();
|
return this.render();
|
||||||
} else {
|
} else {
|
||||||
@@ -268,7 +260,7 @@ return baseclass.extend({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
show: function() {
|
show() {
|
||||||
ui.showModal(null,
|
ui.showModal(null,
|
||||||
E('p', { 'class': 'spinning' }, _('Loading'))
|
E('p', { 'class': 'spinning' }, _('Loading'))
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -70,6 +70,9 @@ msgstr "Байты"
|
|||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Отмена"
|
msgstr "Отмена"
|
||||||
|
|
||||||
|
msgid "Change dnsmasq config directory"
|
||||||
|
msgstr "Изменить директорию конфигов dnsmasq"
|
||||||
|
|
||||||
msgid "Changes have been saved."
|
msgid "Changes have been saved."
|
||||||
msgstr "Изменения сохранены."
|
msgstr "Изменения сохранены."
|
||||||
|
|
||||||
@@ -110,12 +113,18 @@ msgstr "День"
|
|||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr "Отладка"
|
msgstr "Отладка"
|
||||||
|
|
||||||
|
msgid "Description"
|
||||||
|
msgstr "Описание"
|
||||||
|
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr "Отключено"
|
msgstr "Отключено"
|
||||||
|
|
||||||
msgid "Dismiss"
|
msgid "Dismiss"
|
||||||
msgstr "Закрыть"
|
msgstr "Закрыть"
|
||||||
|
|
||||||
|
msgid "Dnsmasq config directory"
|
||||||
|
msgstr "Директория конфигов dnsmasq"
|
||||||
|
|
||||||
msgid "Download error"
|
msgid "Download error"
|
||||||
msgstr "Ошибка загрузки"
|
msgstr "Ошибка загрузки"
|
||||||
|
|
||||||
@@ -125,9 +134,15 @@ msgstr "Скачать журнал"
|
|||||||
msgid "Downloading a blacklist via proxy"
|
msgid "Downloading a blacklist via proxy"
|
||||||
msgstr "Скачивать блэклист через прокси"
|
msgstr "Скачивать блэклист через прокси"
|
||||||
|
|
||||||
|
msgid "Downloading files via proxy"
|
||||||
|
msgstr "Скачивать файлы через прокси"
|
||||||
|
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr "Изменить"
|
msgstr "Изменить"
|
||||||
|
|
||||||
|
msgid "Edit entries"
|
||||||
|
msgstr "Изменить записи"
|
||||||
|
|
||||||
msgid "Emergency"
|
msgid "Emergency"
|
||||||
msgstr "Чрезвычайная ситуация"
|
msgstr "Чрезвычайная ситуация"
|
||||||
|
|
||||||
@@ -233,15 +248,15 @@ msgstr "Шаблоны IP подсетей (/24) не подлежащих оп
|
|||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr "Информация"
|
msgstr "Информация"
|
||||||
|
|
||||||
|
msgid "Instance"
|
||||||
|
msgstr "Экземпляр"
|
||||||
|
|
||||||
msgid "Interval"
|
msgid "Interval"
|
||||||
msgstr "Интервал"
|
msgstr "Интервал"
|
||||||
|
|
||||||
msgid "Invalid regular expression"
|
msgid "Invalid regular expression"
|
||||||
msgstr "Неправильное регулярное выражение"
|
msgstr "Неправильное регулярное выражение"
|
||||||
|
|
||||||
msgid "Nftables rules"
|
|
||||||
msgstr "Правила nftables"
|
|
||||||
|
|
||||||
msgid "Last blacklist update"
|
msgid "Last blacklist update"
|
||||||
msgstr "Последнее обновление блэклиста"
|
msgstr "Последнее обновление блэклиста"
|
||||||
|
|
||||||
@@ -257,6 +272,9 @@ msgstr "Список хостов, которые исключаются из о
|
|||||||
msgid "Loading"
|
msgid "Loading"
|
||||||
msgstr "Загрузка"
|
msgstr "Загрузка"
|
||||||
|
|
||||||
|
msgid "Local traffic"
|
||||||
|
msgstr "Локальный трафик"
|
||||||
|
|
||||||
msgid "Log"
|
msgid "Log"
|
||||||
msgstr "Лог"
|
msgstr "Лог"
|
||||||
|
|
||||||
@@ -269,6 +287,9 @@ msgstr "Уровни логирования"
|
|||||||
msgid "Logread not found"
|
msgid "Logread not found"
|
||||||
msgstr "Logread не найден"
|
msgstr "Logread не найден"
|
||||||
|
|
||||||
|
msgid "Lowest priority"
|
||||||
|
msgstr "Самый низкий приоритет"
|
||||||
|
|
||||||
msgid "Main settings"
|
msgid "Main settings"
|
||||||
msgstr "Основные настройки"
|
msgstr "Основные настройки"
|
||||||
|
|
||||||
@@ -373,9 +394,15 @@ msgstr "Отбор IP адресов из блэклиста по шаблона
|
|||||||
msgid "Pick domains from blacklist by FQDN filter patterns"
|
msgid "Pick domains from blacklist by FQDN filter patterns"
|
||||||
msgstr "Отбор доменов из блэклиста по шаблонам фильтра FQDN"
|
msgstr "Отбор доменов из блэклиста по шаблонам фильтра FQDN"
|
||||||
|
|
||||||
|
msgid "Protocol"
|
||||||
|
msgstr "Протокол"
|
||||||
|
|
||||||
msgid "Proxy mode"
|
msgid "Proxy mode"
|
||||||
msgstr "Режим прокси"
|
msgstr "Режим прокси"
|
||||||
|
|
||||||
|
msgid "Proxy type"
|
||||||
|
msgstr "Тип прокси"
|
||||||
|
|
||||||
msgid "Reduces RAM consumption during update"
|
msgid "Reduces RAM consumption during update"
|
||||||
msgstr "Уменьшает потребление оперативной памяти при обновлении"
|
msgstr "Уменьшает потребление оперативной памяти при обновлении"
|
||||||
|
|
||||||
@@ -418,8 +445,11 @@ msgstr "Настройки"
|
|||||||
msgid "Shutdown"
|
msgid "Shutdown"
|
||||||
msgstr "Выключение"
|
msgstr "Выключение"
|
||||||
|
|
||||||
msgid "Size in memory"
|
msgid "Skip marked packets"
|
||||||
msgstr "Размер в памяти"
|
msgstr "Пропускать помеченные пакеты"
|
||||||
|
|
||||||
|
msgid "Skip packets that have already been marked in previous rules"
|
||||||
|
msgstr "Пропускать пакеты, которые уже были помечены в предыдущих правилах"
|
||||||
|
|
||||||
msgid "Sorting entries"
|
msgid "Sorting entries"
|
||||||
msgstr "Сортировка записей"
|
msgstr "Сортировка записей"
|
||||||
@@ -430,6 +460,9 @@ msgstr "Запускается"
|
|||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Статистика"
|
msgstr "Статистика"
|
||||||
|
|
||||||
|
msgid "Statement in nftables rules"
|
||||||
|
msgstr "Действие в правилах nftables"
|
||||||
|
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Статус"
|
msgstr "Статус"
|
||||||
|
|
||||||
@@ -469,6 +502,9 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Служба будет выключена и все данные блэклиста будут удалены. Продолжить?"
|
"Служба будет выключена и все данные блэклиста будут удалены. Продолжить?"
|
||||||
|
|
||||||
|
msgid "This proxy will receive traffic last, even after the main blacklist"
|
||||||
|
msgstr "В этот прокси трафик будет попадать в последнюю очередь, даже после основного блэклиста"
|
||||||
|
|
||||||
msgid "Time"
|
msgid "Time"
|
||||||
msgstr "Время"
|
msgstr "Время"
|
||||||
|
|
||||||
@@ -487,6 +523,9 @@ msgstr "Конфигурационный файл Tor"
|
|||||||
msgid "Tor mode"
|
msgid "Tor mode"
|
||||||
msgstr "Режим Tor"
|
msgstr "Режим Tor"
|
||||||
|
|
||||||
|
msgid "Transit traffic"
|
||||||
|
msgstr "Транзитный трафик"
|
||||||
|
|
||||||
msgid "Transparent proxy"
|
msgid "Transparent proxy"
|
||||||
msgstr "Прозрачный прокси"
|
msgstr "Прозрачный прокси"
|
||||||
|
|
||||||
@@ -505,6 +544,9 @@ msgstr "UDP порт прозрачного прокси"
|
|||||||
msgid "Turn on if blacklist source is blocked"
|
msgid "Turn on if blacklist source is blocked"
|
||||||
msgstr "Включите, если источник блэклиста заблокирован"
|
msgstr "Включите, если источник блэклиста заблокирован"
|
||||||
|
|
||||||
|
msgid "Turn on if files are blocked"
|
||||||
|
msgstr "Включите, если файлы заблокированы"
|
||||||
|
|
||||||
msgid "Type a search pattern..."
|
msgid "Type a search pattern..."
|
||||||
msgstr "Введите шаблон для поиска"
|
msgstr "Введите шаблон для поиска"
|
||||||
|
|
||||||
@@ -568,6 +610,9 @@ msgstr "Ошибка маршрутизации VPN! Необходим пере
|
|||||||
msgid "Warning"
|
msgid "Warning"
|
||||||
msgstr "Внимание"
|
msgstr "Внимание"
|
||||||
|
|
||||||
|
msgid "all"
|
||||||
|
msgstr "все"
|
||||||
|
|
||||||
msgid "ascending"
|
msgid "ascending"
|
||||||
msgstr "по возрастанию"
|
msgstr "по возрастанию"
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ msgstr ""
|
|||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Change dnsmasq config directory"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Changes have been saved."
|
msgid "Changes have been saved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -95,12 +98,18 @@ msgstr ""
|
|||||||
msgid "Debug"
|
msgid "Debug"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Description"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Disabled"
|
msgid "Disabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Dismiss"
|
msgid "Dismiss"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Dnsmasq config directory"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Download error"
|
msgid "Download error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -110,9 +119,15 @@ msgstr ""
|
|||||||
msgid "Downloading a blacklist via proxy"
|
msgid "Downloading a blacklist via proxy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Downloading files via proxy"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Edit entries"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Emergency"
|
msgid "Emergency"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
msgid "Enable"
|
msgid "Enable"
|
||||||
@@ -214,15 +229,15 @@ msgstr ""
|
|||||||
msgid "Info"
|
msgid "Info"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Instance"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Interval"
|
msgid "Interval"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Invalid regular expression"
|
msgid "Invalid regular expression"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Nftables rules"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Last blacklist update"
|
msgid "Last blacklist update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -238,6 +253,9 @@ msgstr ""
|
|||||||
msgid "Loading"
|
msgid "Loading"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Local traffic"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Log"
|
msgid "Log"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -250,6 +268,9 @@ msgstr ""
|
|||||||
msgid "Logread not found"
|
msgid "Logread not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Lowest priority"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Main settings"
|
msgid "Main settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -342,9 +363,15 @@ msgstr ""
|
|||||||
msgid "Pick domains from blacklist by FQDN filter patterns"
|
msgid "Pick domains from blacklist by FQDN filter patterns"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Protocol"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Proxy mode"
|
msgid "Proxy mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Proxy type"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Reduces RAM consumption during update"
|
msgid "Reduces RAM consumption during update"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -386,9 +413,6 @@ msgstr ""
|
|||||||
msgid "Shutdown"
|
msgid "Shutdown"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Size in memory"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Sorting entries"
|
msgid "Sorting entries"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -397,6 +421,10 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Statement in nftables rules"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -429,6 +457,9 @@ msgid ""
|
|||||||
"Continue?"
|
"Continue?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "This proxy will receive traffic last, even after the main blacklist"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Time"
|
msgid "Time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -447,6 +478,9 @@ msgstr ""
|
|||||||
msgid "Tor mode"
|
msgid "Tor mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Transit traffic"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Transparent proxy"
|
msgid "Transparent proxy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -465,6 +499,9 @@ msgstr ""
|
|||||||
msgid "Turn on if blacklist source is blocked"
|
msgid "Turn on if blacklist source is blocked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Turn on if files are blocked"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Type a search pattern..."
|
msgid "Type a search pattern..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -509,6 +546,7 @@ msgid "URLs of remote user entries file"
|
|||||||
|
|
||||||
msgid "Use optional DNS resolver"
|
msgid "Use optional DNS resolver"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "User entries"
|
msgid "User entries"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -527,6 +565,9 @@ msgstr ""
|
|||||||
msgid "Warning"
|
msgid "Warning"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "all"
|
||||||
|
msgstr "все"
|
||||||
|
|
||||||
msgid "ascending"
|
msgid "ascending"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"/usr/libexec/ruantiblock": [ "list" ],
|
"/usr/libexec/ruantiblock": [ "list" ],
|
||||||
"/etc/ruantiblock/fqdn_filter": [ "read" ],
|
"/etc/ruantiblock/fqdn_filter": [ "read" ],
|
||||||
"/etc/ruantiblock/ip_filter": [ "read" ],
|
"/etc/ruantiblock/ip_filter": [ "read" ],
|
||||||
"/etc/ruantiblock/user_entries": [ "read" ],
|
"/etc/ruantiblock/user_lists/*": [ "read" ],
|
||||||
"/etc/ruantiblock/bypass_entries": [ "read" ],
|
"/etc/ruantiblock/bypass_entries": [ "read" ],
|
||||||
"/etc/ruantiblock/gr_excluded_nets": [ "read" ],
|
"/etc/ruantiblock/gr_excluded_nets": [ "read" ],
|
||||||
"/etc/ruantiblock/gr_excluded_sld": [ "read" ],
|
"/etc/ruantiblock/gr_excluded_sld": [ "read" ],
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
"/etc/crontabs/root": [ "read" ],
|
"/etc/crontabs/root": [ "read" ],
|
||||||
"/usr/bin/ruantiblock*": [ "exec" ],
|
"/usr/bin/ruantiblock*": [ "exec" ],
|
||||||
"/sbin/logread -e ruantiblock:": [ "exec" ],
|
"/sbin/logread -e ruantiblock:": [ "exec" ],
|
||||||
"/usr/sbin/logread -e ruantiblock:": [ "exec" ]
|
"/usr/sbin/logread -e ruantiblock:": [ "exec" ],
|
||||||
|
"/tmp": [ "list" ]
|
||||||
},
|
},
|
||||||
"uci": [ "network", "ruantiblock" ],
|
"uci": [ "network", "ruantiblock" ],
|
||||||
"ubus": {
|
"ubus": {
|
||||||
@@ -27,7 +28,7 @@
|
|||||||
"file": {
|
"file": {
|
||||||
"/etc/ruantiblock/fqdn_filter": [ "write" ],
|
"/etc/ruantiblock/fqdn_filter": [ "write" ],
|
||||||
"/etc/ruantiblock/ip_filter": [ "write" ],
|
"/etc/ruantiblock/ip_filter": [ "write" ],
|
||||||
"/etc/ruantiblock/user_entries": [ "write" ],
|
"/etc/ruantiblock/user_lists/*": [ "write" ],
|
||||||
"/etc/ruantiblock/bypass_entries": [ "write" ],
|
"/etc/ruantiblock/bypass_entries": [ "write" ],
|
||||||
"/etc/ruantiblock/gr_excluded_nets": [ "write" ],
|
"/etc/ruantiblock/gr_excluded_nets": [ "write" ],
|
||||||
"/etc/ruantiblock/gr_excluded_sld": [ "write" ],
|
"/etc/ruantiblock/gr_excluded_sld": [ "write" ],
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=ruantiblock-mod-lua
|
PKG_NAME:=ruantiblock-mod-lua
|
||||||
PKG_VERSION:=1.6.0
|
PKG_VERSION:=2.0.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,8 @@ local Config = Class(nil, {
|
|||||||
["NFTSET_CIDR"] = true,
|
["NFTSET_CIDR"] = true,
|
||||||
["NFTSET_IP"] = true,
|
["NFTSET_IP"] = true,
|
||||||
["NFTSET_DNSMASQ"] = true,
|
["NFTSET_DNSMASQ"] = true,
|
||||||
["NFTSET_CIDR_CFG"] = true,
|
["NFTSET_CIDR_STRING_MAIN"] = true,
|
||||||
["NFTSET_IP_CFG"] = true,
|
["NFTSET_IP_STRING_MAIN"] = true,
|
||||||
["NFTSET_DNSMASQ"] = true,
|
|
||||||
["DNSMASQ_DATA_FILE"] = true,
|
["DNSMASQ_DATA_FILE"] = true,
|
||||||
["IP_DATA_FILE"] = true,
|
["IP_DATA_FILE"] = true,
|
||||||
["UPDATE_STATUS_FILE"] = true,
|
["UPDATE_STATUS_FILE"] = true,
|
||||||
@@ -788,7 +787,7 @@ function WriteConfigFiles:write_ipset_config(ip_table, cidr_table)
|
|||||||
file_handler:write(string.format("flush set %s %s\n", self.NFT_TABLE, v))
|
file_handler:write(string.format("flush set %s %s\n", self.NFT_TABLE, v))
|
||||||
end
|
end
|
||||||
file_handler:write(
|
file_handler:write(
|
||||||
string.format("table %s {\n%s", self.NFT_TABLE, self.NFTSET_CIDR_CFG)
|
string.format("table %s {\n%s", self.NFT_TABLE, self.NFTSET_CIDR_STRING_MAIN)
|
||||||
)
|
)
|
||||||
local c = 0
|
local c = 0
|
||||||
if next(cidr_table) then
|
if next(cidr_table) then
|
||||||
@@ -801,7 +800,7 @@ function WriteConfigFiles:write_ipset_config(ip_table, cidr_table)
|
|||||||
end
|
end
|
||||||
self.cidr_count = c
|
self.cidr_count = c
|
||||||
file_handler:write(
|
file_handler:write(
|
||||||
string.format("}\n%s", self.NFTSET_IP_CFG)
|
string.format("}\n%s", self.NFTSET_IP_STRING_MAIN)
|
||||||
)
|
)
|
||||||
local i = 0
|
local i = 0
|
||||||
if next(ip_table) then
|
if next(ip_table) then
|
||||||
@@ -1076,6 +1075,7 @@ if parser_classes then
|
|||||||
for _, i in ipairs(parser_instances) do
|
for _, i in ipairs(parser_instances) do
|
||||||
ret_list[i:run()] = true
|
ret_list[i:run()] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local return_sum = 0
|
local return_sum = 0
|
||||||
for i, _ in pairs(ret_list) do
|
for i, _ in pairs(ret_list) do
|
||||||
return_sum = return_sum + i
|
return_sum = return_sum + i
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=ruantiblock-mod-py
|
PKG_NAME:=ruantiblock-mod-py
|
||||||
PKG_VERSION:=1.6.0
|
PKG_VERSION:=2.0.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
||||||
|
|
||||||
|
|||||||
@@ -42,9 +42,8 @@ class Config:
|
|||||||
"NFTSET_CIDR",
|
"NFTSET_CIDR",
|
||||||
"NFTSET_IP",
|
"NFTSET_IP",
|
||||||
"NFTSET_DNSMASQ",
|
"NFTSET_DNSMASQ",
|
||||||
"NFTSET_CIDR_CFG",
|
"NFTSET_CIDR_STRING_MAIN",
|
||||||
"NFTSET_IP_CFG",
|
"NFTSET_IP_STRING_MAIN",
|
||||||
"NFTSET_DNSMASQ",
|
|
||||||
"DNSMASQ_DATA_FILE",
|
"DNSMASQ_DATA_FILE",
|
||||||
"IP_DATA_FILE",
|
"IP_DATA_FILE",
|
||||||
"UPDATE_STATUS_FILE",
|
"UPDATE_STATUS_FILE",
|
||||||
@@ -459,6 +458,7 @@ class Summarize:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _group_nets(cls, cidr_list, raw_list=None):
|
def _group_nets(cls, cidr_list, raw_list=None):
|
||||||
|
|
||||||
def remove_items(start, end):
|
def remove_items(start, end):
|
||||||
for ip in range(int(start), int(end) + 1, 256):
|
for ip in range(int(start), int(end) + 1, 256):
|
||||||
raw_list.remove(str(IPv4Address(ip)) + "/24")
|
raw_list.remove(str(IPv4Address(ip)) + "/24")
|
||||||
@@ -570,7 +570,7 @@ class WriteConfigFiles(Config):
|
|||||||
for i in (self.NFTSET_CIDR, self.NFTSET_IP):
|
for i in (self.NFTSET_CIDR, self.NFTSET_IP):
|
||||||
file_handler.write("flush set {} {}\n".format(self.NFT_TABLE, i))
|
file_handler.write("flush set {} {}\n".format(self.NFT_TABLE, i))
|
||||||
file_handler.write(
|
file_handler.write(
|
||||||
"table {} {{\n{}".format(self.NFT_TABLE, self.NFTSET_CIDR_CFG)
|
"table {} {{\n{}".format(self.NFT_TABLE, self.NFTSET_CIDR_STRING_MAIN)
|
||||||
)
|
)
|
||||||
if len(cidr_set) > 0:
|
if len(cidr_set) > 0:
|
||||||
file_handler.write("elements={")
|
file_handler.write("elements={")
|
||||||
@@ -578,7 +578,7 @@ class WriteConfigFiles(Config):
|
|||||||
file_handler.write(f"{i},")
|
file_handler.write(f"{i},")
|
||||||
file_handler.write("};")
|
file_handler.write("};")
|
||||||
file_handler.write(
|
file_handler.write(
|
||||||
"}}\n{}".format(self.NFTSET_IP_CFG)
|
"}}\n{}".format(self.NFTSET_IP_STRING_MAIN)
|
||||||
)
|
)
|
||||||
if len(ip_dict) > 0:
|
if len(ip_dict) > 0:
|
||||||
file_handler.write("elements={")
|
file_handler.write("elements={")
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=ruantiblock
|
PKG_NAME:=ruantiblock
|
||||||
PKG_VERSION:=1.6.0
|
PKG_VERSION:=2.0.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ define Package/$(PKG_NAME)
|
|||||||
TITLE:=Ruantiblock
|
TITLE:=Ruantiblock
|
||||||
URL:=https://github.com/gSpotx2f/ruantiblock_openwrt
|
URL:=https://github.com/gSpotx2f/ruantiblock_openwrt
|
||||||
PKGARCH:=all
|
PKGARCH:=all
|
||||||
DEPENDS:=+dnsmasq-full
|
DEPENDS:=+dnsmasq-full +kmod-nft-tproxy
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/$(PKG_NAME)/description
|
define Package/$(PKG_NAME)/description
|
||||||
@@ -28,10 +28,14 @@ define Package/$(PKG_NAME)/conffiles
|
|||||||
/etc/ruantiblock/ruantiblock.conf
|
/etc/ruantiblock/ruantiblock.conf
|
||||||
/etc/ruantiblock/fqdn_filter
|
/etc/ruantiblock/fqdn_filter
|
||||||
/etc/ruantiblock/ip_filter
|
/etc/ruantiblock/ip_filter
|
||||||
/etc/ruantiblock/user_entries
|
|
||||||
/etc/ruantiblock/bypass_entries
|
/etc/ruantiblock/bypass_entries
|
||||||
/etc/ruantiblock/gr_excluded_nets
|
/etc/ruantiblock/gr_excluded_nets
|
||||||
/etc/ruantiblock/gr_excluded_sld
|
/etc/ruantiblock/gr_excluded_sld
|
||||||
|
/etc/ruantiblock/user_lists/list1
|
||||||
|
/etc/ruantiblock/user_lists/list2
|
||||||
|
/etc/ruantiblock/user_lists/list3
|
||||||
|
/etc/ruantiblock/user_lists/list4
|
||||||
|
/etc/ruantiblock/user_lists/list5
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Build/Configure
|
define Build/Configure
|
||||||
@@ -51,15 +55,22 @@ define Package/$(PKG_NAME)/install
|
|||||||
$(INSTALL_CONF) ./files/etc/ruantiblock/ruantiblock.conf $(1)/etc/ruantiblock/ruantiblock.conf
|
$(INSTALL_CONF) ./files/etc/ruantiblock/ruantiblock.conf $(1)/etc/ruantiblock/ruantiblock.conf
|
||||||
$(INSTALL_DATA) ./files/etc/ruantiblock/fqdn_filter $(1)/etc/ruantiblock/fqdn_filter
|
$(INSTALL_DATA) ./files/etc/ruantiblock/fqdn_filter $(1)/etc/ruantiblock/fqdn_filter
|
||||||
$(INSTALL_DATA) ./files/etc/ruantiblock/ip_filter $(1)/etc/ruantiblock/ip_filter
|
$(INSTALL_DATA) ./files/etc/ruantiblock/ip_filter $(1)/etc/ruantiblock/ip_filter
|
||||||
$(INSTALL_DATA) ./files/etc/ruantiblock/user_entries $(1)/etc/ruantiblock/user_entries
|
|
||||||
$(INSTALL_DATA) ./files/etc/ruantiblock/bypass_entries $(1)/etc/ruantiblock/bypass_entries
|
$(INSTALL_DATA) ./files/etc/ruantiblock/bypass_entries $(1)/etc/ruantiblock/bypass_entries
|
||||||
$(INSTALL_DATA) ./files/etc/ruantiblock/gr_excluded_nets $(1)/etc/ruantiblock/gr_excluded_nets
|
$(INSTALL_DATA) ./files/etc/ruantiblock/gr_excluded_nets $(1)/etc/ruantiblock/gr_excluded_nets
|
||||||
$(INSTALL_DATA) ./files/etc/ruantiblock/gr_excluded_sld $(1)/etc/ruantiblock/gr_excluded_sld
|
$(INSTALL_DATA) ./files/etc/ruantiblock/gr_excluded_sld $(1)/etc/ruantiblock/gr_excluded_sld
|
||||||
|
$(INSTALL_DIR) $(1)/etc/ruantiblock/user_lists
|
||||||
|
$(INSTALL_DATA) ./files/etc/ruantiblock/user_lists/list1 $(1)/etc/ruantiblock/user_lists/list1
|
||||||
|
$(INSTALL_DATA) ./files/etc/ruantiblock/user_lists/list2 $(1)/etc/ruantiblock/user_lists/list2
|
||||||
|
$(INSTALL_DATA) ./files/etc/ruantiblock/user_lists/list3 $(1)/etc/ruantiblock/user_lists/list3
|
||||||
|
$(INSTALL_DATA) ./files/etc/ruantiblock/user_lists/list4 $(1)/etc/ruantiblock/user_lists/list4
|
||||||
|
$(INSTALL_DATA) ./files/etc/ruantiblock/user_lists/list5 $(1)/etc/ruantiblock/user_lists/list5
|
||||||
$(INSTALL_DIR) $(1)/usr/share/ruantiblock
|
$(INSTALL_DIR) $(1)/usr/share/ruantiblock
|
||||||
|
$(INSTALL_DATA) ./files/usr/share/ruantiblock/blacklist_sources $(1)/usr/share/ruantiblock/blacklist_sources
|
||||||
$(INSTALL_DATA) ./files/usr/share/ruantiblock/config_script $(1)/usr/share/ruantiblock/config_script
|
$(INSTALL_DATA) ./files/usr/share/ruantiblock/config_script $(1)/usr/share/ruantiblock/config_script
|
||||||
|
$(INSTALL_DATA) ./files/usr/share/ruantiblock/config_script_user_instances $(1)/usr/share/ruantiblock/config_script_user_instances
|
||||||
$(INSTALL_DATA) ./files/usr/share/ruantiblock/info_output $(1)/usr/share/ruantiblock/info_output
|
$(INSTALL_DATA) ./files/usr/share/ruantiblock/info_output $(1)/usr/share/ruantiblock/info_output
|
||||||
$(INSTALL_DATA) ./files/usr/share/ruantiblock/nft_functions $(1)/usr/share/ruantiblock/nft_functions
|
$(INSTALL_DATA) ./files/usr/share/ruantiblock/nft_functions $(1)/usr/share/ruantiblock/nft_functions
|
||||||
$(INSTALL_DATA) ./files/usr/share/ruantiblock/blacklist_sources $(1)/usr/share/ruantiblock/blacklist_sources
|
$(INSTALL_DATA) ./files/usr/share/ruantiblock/user_instances_common $(1)/usr/share/ruantiblock/user_instances_common
|
||||||
$(INSTALL_DIR) $(1)/usr/libexec/ruantiblock
|
$(INSTALL_DIR) $(1)/usr/libexec/ruantiblock
|
||||||
$(INSTALL_BIN) ./files/usr/libexec/ruantiblock/ruab_route_check $(1)/usr/libexec/ruantiblock/ruab_route_check
|
$(INSTALL_BIN) ./files/usr/libexec/ruantiblock/ruab_route_check $(1)/usr/libexec/ruantiblock/ruab_route_check
|
||||||
$(INSTALL_DIR) $(1)/usr/bin
|
$(INSTALL_DIR) $(1)/usr/bin
|
||||||
@@ -82,14 +93,16 @@ define Package/$(PKG_NAME)/prerm
|
|||||||
FILE_INIT_SCRIPT="/etc/init.d/ruantiblock"
|
FILE_INIT_SCRIPT="/etc/init.d/ruantiblock"
|
||||||
FILE_MAIN_SCRIPT="/usr/bin/ruantiblock"
|
FILE_MAIN_SCRIPT="/usr/bin/ruantiblock"
|
||||||
CRONTAB_FILE="/etc/crontabs/root"
|
CRONTAB_FILE="/etc/crontabs/root"
|
||||||
DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq"
|
DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq*.d/00-ruantiblock_bypass.dnsmasq"
|
||||||
|
DNSMASQ_DATA_FILE_USER_INSTANCES="/tmp/dnsmasq*.d/01-ruantiblock_user_instances.dnsmasq"
|
||||||
|
DNSMASQ_DATA_FILE="/tmp/dnsmasq*.d/02-ruantiblock.dnsmasq"
|
||||||
|
DNSMASQ_DATA_FILE_BYPASS_TMP="${DNSMASQ_DATA_FILE_BYPASS}.tmp"
|
||||||
|
DNSMASQ_DATA_FILE_USER_INSTANCES_TMP="${DNSMASQ_DATA_FILE_USER_INSTANCES}.tmp"
|
||||||
DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
|
DNSMASQ_DATA_FILE_TMP="${DNSMASQ_DATA_FILE}.tmp"
|
||||||
DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq"
|
|
||||||
|
|
||||||
rm -f $$DNSMASQ_DATA_FILE $$DNSMASQ_DATA_FILE_TMP $$DNSMASQ_DATA_FILE_BYPASS
|
|
||||||
test -e "$$FILE_MAIN_SCRIPT" && $$FILE_MAIN_SCRIPT destroy
|
test -e "$$FILE_MAIN_SCRIPT" && $$FILE_MAIN_SCRIPT destroy
|
||||||
|
|
||||||
test -e "$$FILE_INIT_SCRIPT" && $$FILE_INIT_SCRIPT disable
|
test -e "$$FILE_INIT_SCRIPT" && $$FILE_INIT_SCRIPT disable
|
||||||
|
rm -f $$DNSMASQ_DATA_FILE $$DNSMASQ_DATA_FILE_TMP $$DNSMASQ_DATA_FILE_BYPASS $$DNSMASQ_DATA_FILE_BYPASS_TMP $$DNSMASQ_DATA_FILE_USER_INSTANCES $$DNSMASQ_DATA_FILE_USER_INSTANCES_TMP
|
||||||
|
|
||||||
awk -v FILE_MAIN_SCRIPT="$$FILE_MAIN_SCRIPT" '$$0 !~ FILE_MAIN_SCRIPT {
|
awk -v FILE_MAIN_SCRIPT="$$FILE_MAIN_SCRIPT" '$$0 !~ FILE_MAIN_SCRIPT {
|
||||||
print $$0;
|
print $$0;
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ config main 'config'
|
|||||||
option vpn_route_check '0'
|
option vpn_route_check '0'
|
||||||
option tor_trans_port '9040'
|
option tor_trans_port '9040'
|
||||||
option onion_dns_addr '127.0.0.1#9053'
|
option onion_dns_addr '127.0.0.1#9053'
|
||||||
|
option t_proxy_type '0'
|
||||||
option t_proxy_port_tcp '1100'
|
option t_proxy_port_tcp '1100'
|
||||||
option t_proxy_port_udp '1100'
|
option t_proxy_port_udp '1100'
|
||||||
option t_proxy_allow_udp '0'
|
option t_proxy_allow_udp '0'
|
||||||
option bypass_mode '0'
|
option bypass_mode '0'
|
||||||
option enable_bllist_proxy '0'
|
option enable_bllist_proxy '0'
|
||||||
option enable_tmp_downloads '0'
|
option enable_tmp_downloads '0'
|
||||||
option add_user_entries '0'
|
|
||||||
option bllist_min_entries '3000'
|
option bllist_min_entries '3000'
|
||||||
option bllist_ip_limit '0'
|
option bllist_ip_limit '0'
|
||||||
option bllist_summarize_ip '1'
|
option bllist_summarize_ip '1'
|
||||||
@@ -30,3 +30,78 @@ config main 'config'
|
|||||||
option bllist_enable_idn '0'
|
option bllist_enable_idn '0'
|
||||||
option bllist_alt_nslookup '0'
|
option bllist_alt_nslookup '0'
|
||||||
option bllist_alt_dns_addr '8.8.8.8'
|
option bllist_alt_dns_addr '8.8.8.8'
|
||||||
|
|
||||||
|
config user_instance 'list1'
|
||||||
|
option u_enabled '0'
|
||||||
|
option u_proxy_mode '2'
|
||||||
|
option u_tor_trans_port '9040'
|
||||||
|
option u_onion_dns_addr '127.0.0.1#9053'
|
||||||
|
option u_if_vpn 'tun0'
|
||||||
|
option u_t_proxy_type '0'
|
||||||
|
option u_t_proxy_port_tcp '1100'
|
||||||
|
option u_t_proxy_port_udp '1100'
|
||||||
|
option u_t_proxy_allow_udp '0'
|
||||||
|
option u_enable_entries_remote_proxy '0'
|
||||||
|
option u_entries_dns ''
|
||||||
|
option u_enable_fproxy '0'
|
||||||
|
option u_skip_marked_packets '0'
|
||||||
|
|
||||||
|
config user_instance 'list2'
|
||||||
|
option u_enabled '0'
|
||||||
|
option u_proxy_mode '2'
|
||||||
|
option u_tor_trans_port '9040'
|
||||||
|
option u_onion_dns_addr '127.0.0.1#9053'
|
||||||
|
option u_if_vpn 'tun0'
|
||||||
|
option u_t_proxy_type '0'
|
||||||
|
option u_t_proxy_port_tcp '1100'
|
||||||
|
option u_t_proxy_port_udp '1100'
|
||||||
|
option u_t_proxy_allow_udp '0'
|
||||||
|
option u_enable_entries_remote_proxy '0'
|
||||||
|
option u_entries_dns ''
|
||||||
|
option u_enable_fproxy '0'
|
||||||
|
option u_skip_marked_packets '0'
|
||||||
|
|
||||||
|
config user_instance 'list3'
|
||||||
|
option u_enabled '0'
|
||||||
|
option u_proxy_mode '2'
|
||||||
|
option u_tor_trans_port '9040'
|
||||||
|
option u_onion_dns_addr '127.0.0.1#9053'
|
||||||
|
option u_if_vpn 'tun0'
|
||||||
|
option u_t_proxy_type '0'
|
||||||
|
option u_t_proxy_port_tcp '1100'
|
||||||
|
option u_t_proxy_port_udp '1100'
|
||||||
|
option u_t_proxy_allow_udp '0'
|
||||||
|
option u_enable_entries_remote_proxy '0'
|
||||||
|
option u_entries_dns ''
|
||||||
|
option u_enable_fproxy '0'
|
||||||
|
option u_skip_marked_packets '0'
|
||||||
|
|
||||||
|
config user_instance 'list4'
|
||||||
|
option u_enabled '0'
|
||||||
|
option u_proxy_mode '2'
|
||||||
|
option u_tor_trans_port '9040'
|
||||||
|
option u_onion_dns_addr '127.0.0.1#9053'
|
||||||
|
option u_if_vpn 'tun0'
|
||||||
|
option u_t_proxy_type '0'
|
||||||
|
option u_t_proxy_port_tcp '1100'
|
||||||
|
option u_t_proxy_port_udp '1100'
|
||||||
|
option u_t_proxy_allow_udp '0'
|
||||||
|
option u_enable_entries_remote_proxy '0'
|
||||||
|
option u_entries_dns ''
|
||||||
|
option u_enable_fproxy '0'
|
||||||
|
option u_skip_marked_packets '0'
|
||||||
|
|
||||||
|
config user_instance 'list5'
|
||||||
|
option u_enabled '0'
|
||||||
|
option u_proxy_mode '2'
|
||||||
|
option u_tor_trans_port '9040'
|
||||||
|
option u_onion_dns_addr '127.0.0.1#9053'
|
||||||
|
option u_if_vpn 'tun0'
|
||||||
|
option u_t_proxy_type '0'
|
||||||
|
option u_t_proxy_port_tcp '1100'
|
||||||
|
option u_t_proxy_port_udp '1100'
|
||||||
|
option u_t_proxy_allow_udp '0'
|
||||||
|
option u_enable_entries_remote_proxy '0'
|
||||||
|
option u_entries_dns ''
|
||||||
|
option u_enable_fproxy '0'
|
||||||
|
option u_skip_marked_packets '0'
|
||||||
|
|||||||
@@ -1,20 +1,64 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
UCI_CMD=`which uci`
|
if [ "$ACTION" = "ifup" ]; then
|
||||||
if [ $? -ne 0 ]; then
|
NAME="ruantiblock"
|
||||||
echo " Error! UCI doesn't exists" >&2
|
RUAB_CMD="/usr/bin/ruantiblock"
|
||||||
exit 1
|
CONFIG_FILE="/etc/ruantiblock/ruantiblock.conf"
|
||||||
fi
|
USER_INSTANCES_COMMON="/usr/share/ruantiblock/user_instances_common"
|
||||||
RUAB_CMD="/usr/bin/ruantiblock"
|
CONFIG_SCRIPT_USER_INSTANCES="/usr/share/ruantiblock/config_script_user_instances"
|
||||||
PROXY_MODE=`$UCI_CMD get ruantiblock.config.proxy_mode`
|
USER_INSTANCES_DIR="/etc/ruantiblock/user_instances"
|
||||||
IF_VPN=`$UCI_CMD get ruantiblock.config.if_vpn`
|
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 U_SKIP_MARKED_PACKETS"
|
||||||
VPN_ROUTE_CHECK=`$UCI_CMD get ruantiblock.config.vpn_route_check`
|
USER_INSTANCES_MAX=10
|
||||||
|
DEBUG=0
|
||||||
|
IF_VPN_CURRENT=""
|
||||||
|
|
||||||
[ "$VPN_ROUTE_CHECK" != "0" ] && exit 0
|
ruab_route_status=`$RUAB_CMD raw-status`
|
||||||
|
[ $ruab_route_status -eq 1 -o $ruab_route_status -eq 2 ] && exit 0
|
||||||
|
|
||||||
if [ "$ACTION" = "ifup" ] && [ "$PROXY_MODE" = "2" ] && [ "$DEVICE" = "$IF_VPN" ]; then
|
UCI_CMD=`which uci`
|
||||||
if [ `$RUAB_CMD raw-status` -ne 2 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
sleep 5
|
echo " Error! UCI doesn't exists" >&2
|
||||||
$RUAB_CMD reload
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
[ -f "$CONFIG_FILE" ] && . "$CONFIG_FILE"
|
||||||
|
|
||||||
|
VPN_ROUTE_CHECK=`$UCI_CMD get ruantiblock.config.vpn_route_check`
|
||||||
|
[ "$VPN_ROUTE_CHECK" != "0" ] && exit 0
|
||||||
|
|
||||||
|
PROXY_MODE=`$UCI_CMD get ruantiblock.config.proxy_mode`
|
||||||
|
if [ "$PROXY_MODE" = "2" ]; then
|
||||||
|
IF_VPN_CURRENT=`$UCI_CMD get ruantiblock.config.if_vpn`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DEVICE" != "$IF_VPN_CURRENT" ]; then
|
||||||
|
|
||||||
|
. "$USER_INSTANCES_COMMON"
|
||||||
|
|
||||||
|
for inst in `GetUserInstances 2`
|
||||||
|
do
|
||||||
|
IncludeUserInstanceVars "$inst"
|
||||||
|
if [ "$DEVICE" = "$U_IF_VPN" ]; then
|
||||||
|
IF_VPN_CURRENT="$U_IF_VPN"
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " ruantiblock-vpn-iface-script: U_NAME=${U_NAME} U_IF_VPN=${U_IF_VPN}" >&2
|
||||||
|
logger -p "user.debug" -t "ruantiblock-hotplug-script" "U_NAME=${U_NAME} U_IF_VPN=${U_IF_VPN}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
ClearUserInstanceVars
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$DEVICE" = "$IF_VPN_CURRENT" ]; then
|
||||||
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " ruantiblock-vpn-iface-script: IF_VPN_CURRENT=${IF_VPN_CURRENT} ACTION=\"${ACTION}\" DEVICE=${DEVICE} INTERFACE=${INTERFACE}" >&2
|
||||||
|
logger -p "user.debug" -t "ruantiblock-hotplug-script" "IF_VPN_CURRENT=${IF_VPN_CURRENT} ACTION=\"${ACTION}\" DEVICE=${DEVICE} INTERFACE=${INTERFACE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
$RUAB_CMD reload
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,14 +5,40 @@ STOP=01
|
|||||||
|
|
||||||
APP_NAME="ruantiblock"
|
APP_NAME="ruantiblock"
|
||||||
APP_EXEC="/usr/bin/${APP_NAME}"
|
APP_EXEC="/usr/bin/${APP_NAME}"
|
||||||
|
DNSMASQ_VAR_DIR="/tmp"
|
||||||
|
|
||||||
config_load $APP_NAME
|
config_load $APP_NAME
|
||||||
|
|
||||||
|
get_dnsmasq_cfg_dir() {
|
||||||
|
local _first_instance
|
||||||
|
if [ -d "${DNSMASQ_VAR_DIR}/dnsmasq.d" ]; then
|
||||||
|
printf "${DNSMASQ_VAR_DIR}/dnsmasq.d"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_first_instance=`ls -1 "$DNSMASQ_VAR_DIR" | grep -e "^dnsmasq" | head -n 1`
|
||||||
|
if [ -n "$_first_instance" ]; then
|
||||||
|
printf "${DNSMASQ_VAR_DIR}/${_first_instance}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
local update_at_startup
|
local _update_at_startup _dnsmasq_cfg_dir
|
||||||
config_get update_at_startup config update_at_startup
|
config_get _update_at_startup config update_at_startup
|
||||||
|
config_get _dnsmasq_cfg_dir config dnsmasq_cfg_dir ""
|
||||||
|
if [ -z "$_dnsmasq_cfg_dir" ]; then
|
||||||
|
_dnsmasq_cfg_dir=`get_dnsmasq_cfg_dir`
|
||||||
|
if [ $? -eq 0 -a -n "$_dnsmasq_cfg_dir" ]; then
|
||||||
|
uci set "${APP_NAME}.config.dnsmasq_cfg_dir"="$_dnsmasq_cfg_dir"
|
||||||
|
uci commit ruantiblock
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
$APP_EXEC start
|
$APP_EXEC start
|
||||||
if [ $? -eq 0 -a "$update_at_startup" = "1" ]; then
|
if [ $? -eq 0 -a "$_update_at_startup" = "1" ]; then
|
||||||
$APP_EXEC update
|
$APP_EXEC update
|
||||||
else
|
else
|
||||||
/etc/init.d/dnsmasq restart
|
/etc/init.d/dnsmasq restart
|
||||||
|
|||||||
@@ -82,4 +82,3 @@ birds
|
|||||||
forex
|
forex
|
||||||
kraken
|
kraken
|
||||||
zerkalo
|
zerkalo
|
||||||
#lord
|
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
DATA_DIR="/tmp/ruantiblock"
|
DATA_DIR="/tmp/ruantiblock"
|
||||||
### Директория модулей
|
### Директория модулей
|
||||||
MODULES_DIR="/usr/libexec/ruantiblock"
|
MODULES_DIR="/usr/libexec/ruantiblock"
|
||||||
### Дополнительный конфиг dnsmasq с FQDN записями блэклиста
|
### Директория PID-файлов и файлов статуса
|
||||||
DNSMASQ_DATA_FILE="/tmp/dnsmasq.d/02-ruantiblock.dnsmasq"
|
RUN_FILES_DIR="/tmp/run"
|
||||||
DNSMASQ_DATA_FILE_BYPASS="/tmp/dnsmasq.d/01-ruantiblock_bypass.dnsmasq"
|
### Директория доп. конфигов dnsmasq
|
||||||
|
DNSMASQ_CFG_DIR="/tmp/dnsmasq.d"
|
||||||
### Команда для перезапуска dnsmasq
|
### Команда для перезапуска dnsmasq
|
||||||
DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart"
|
DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart"
|
||||||
### Директория для html-страницы статуса (не используется в OpenWrt)
|
### Директория для html-страницы статуса (не используется в OpenWrt)
|
||||||
@@ -31,26 +32,26 @@ ONION_DNS_ADDR="127.0.0.1#9053"
|
|||||||
IF_VPN="tun0"
|
IF_VPN="tun0"
|
||||||
### IP адрес шлюза для VPN конфигурации. Если не задан, используется адрес VPN интерфейса (или адрес пира для протоколов PPP)
|
### IP адрес шлюза для VPN конфигурации. Если не задан, используется адрес VPN интерфейса (или адрес пира для протоколов PPP)
|
||||||
VPN_GW_IP=""
|
VPN_GW_IP=""
|
||||||
### Метка для отбора пакетов в VPN туннель
|
|
||||||
VPN_PKTS_MARK=8
|
|
||||||
### Таблица маршрутизации для отправки пакетов в VPN туннель
|
|
||||||
VPN_ROUTE_TABLE_ID=99
|
|
||||||
### Приоритет правила отбора пакетов при маршрутизации в VPN-интерфейс
|
|
||||||
VPN_RULE_PRIO=1000
|
|
||||||
### Способ добавления в таблицу маршрутизации правила для отправки пакетов в VPN туннель (0 - hotplug.d, 1 - скрипт ruab_route_check)
|
### Способ добавления в таблицу маршрутизации правила для отправки пакетов в VPN туннель (0 - hotplug.d, 1 - скрипт ruab_route_check)
|
||||||
VPN_ROUTE_CHECK=0
|
VPN_ROUTE_CHECK=0
|
||||||
|
### Тип прозрачного прокси (0 - redirect, 1 - tproxy)
|
||||||
|
T_PROXY_TYPE=0
|
||||||
### TCP порт прокси в режиме прозрачного прокси
|
### TCP порт прокси в режиме прозрачного прокси
|
||||||
T_PROXY_PORT_TCP=1100
|
T_PROXY_PORT_TCP=1100
|
||||||
### UDP порт прокси в режиме прозрачного прокси
|
### UDP порт прокси в режиме прозрачного прокси
|
||||||
T_PROXY_PORT_UDP=1100
|
T_PROXY_PORT_UDP=1100
|
||||||
### Отправлять в прозрачный прокси UDP-трафик (0 - выкл, 1 - вкл)
|
### Отправлять в прозрачный прокси UDP-трафик (0 - выкл, 1 - вкл)
|
||||||
T_PROXY_ALLOW_UDP=0
|
T_PROXY_ALLOW_UDP=0
|
||||||
|
### Начальное значение метки для отбора пакетов в фильтрах
|
||||||
|
PKTS_MARK_START=8
|
||||||
### Запись событий в syslog (0 - выкл, 1 - вкл)
|
### Запись событий в syslog (0 - выкл, 1 - вкл)
|
||||||
ENABLE_LOGGING=1
|
ENABLE_LOGGING=1
|
||||||
|
### Вывод дополнительных сообщений в лог (0 - выкл, 1, 2)
|
||||||
|
DEBUG=0
|
||||||
### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt)
|
### Html-страница с инфо о текущем статусе (0 - выкл, 1 - вкл) (не используется в OpenWrt)
|
||||||
ENABLE_HTML_INFO=0
|
ENABLE_HTML_INFO=0
|
||||||
### Максимальное кол-во элементов списка nftables
|
### Максимальное кол-во элементов списка nftables
|
||||||
#NFTSET_MAXELEM_CIDR=65535
|
NFTSET_MAXELEM_CIDR=65535
|
||||||
NFTSET_MAXELEM_IP=1000000
|
NFTSET_MAXELEM_IP=1000000
|
||||||
NFTSET_MAXELEM_DNSMASQ=65535
|
NFTSET_MAXELEM_DNSMASQ=65535
|
||||||
NFTSET_MAXELEM_BYPASS_IP=65535
|
NFTSET_MAXELEM_BYPASS_IP=65535
|
||||||
@@ -63,29 +64,14 @@ NFTSET_POLICY_DNSMASQ="performance"
|
|||||||
NFTSET_DNSMASQ_TIMEOUT="150m"
|
NFTSET_DNSMASQ_TIMEOUT="150m"
|
||||||
### Динамическое обновление таймаута записей в сете $NFTSET_DNSMASQ (0 - выкл, 1 - вкл)
|
### Динамическое обновление таймаута записей в сете $NFTSET_DNSMASQ (0 - выкл, 1 - вкл)
|
||||||
NFTSET_DNSMASQ_TIMEOUT_UPDATE=1
|
NFTSET_DNSMASQ_TIMEOUT_UPDATE=1
|
||||||
### Приоритет правила отбора пакетов nftables для конфигупации Tor или прозрачного прокси
|
|
||||||
NFT_PRIO_NAT="dstnat - 10"
|
|
||||||
### Приоритет правила отбора пакетов nftables для трафика локальных клиентов в конфигупации Tor или прозрачного прокси
|
|
||||||
NFT_PRIO_NAT_LOCAL="filter - 10"
|
|
||||||
### Приоритет правила отбора пакетов nftables для VPN-конфигурации
|
|
||||||
NFT_PRIO_ROUTE="mangle + 10"
|
|
||||||
### Приоритет правила отбора пакетов nftables для трафика локальных клиентов в VPN-конфигурации
|
|
||||||
NFT_PRIO_ROUTE_LOCAL="mangle + 10"
|
|
||||||
### Добавление в список блокировок пользовательских записей из файла $USER_ENTRIES_FILE (0 - выкл, 1 - вкл)
|
|
||||||
### В $CONFIG_DIR можно создать текстовый файл user_entries с записями IP, CIDR или FQDN (одна на строку). Эти записи будут добавлены в список блокировок
|
|
||||||
### В записях FQDN можно задать DNS-сервер для разрешения данного домена, через пробел (прим.: domain.com 8.8.8.8)
|
|
||||||
### Можно комментировать строки (#)
|
|
||||||
ADD_USER_ENTRIES=0
|
|
||||||
### DNS-сервер для пользовательских записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет
|
|
||||||
USER_ENTRIES_DNS=""
|
|
||||||
### Файл пользовательских записей
|
|
||||||
USER_ENTRIES_FILE="/etc/ruantiblock/user_entries"
|
|
||||||
### URL удаленных файлов записей пользователя, через пробел (прим.: http://server.lan/files/user_entries_1 http://server.lan/files/user_entries_2)
|
|
||||||
USER_ENTRIES_REMOTE=""
|
|
||||||
### Кол-во попыток скачивания удаленного файла записей пользователя (в случае неудачи)
|
### Кол-во попыток скачивания удаленного файла записей пользователя (в случае неудачи)
|
||||||
USER_ENTRIES_REMOTE_DOWNLOAD_ATTEMPTS=3
|
USER_ENTRIES_REMOTE_DOWNLOAD_ATTEMPTS=3
|
||||||
### Таймаут между попытками скачивания
|
### Таймаут между попытками скачивания
|
||||||
USER_ENTRIES_REMOTE_DOWNLOAD_TIMEOUT=60
|
USER_ENTRIES_REMOTE_DOWNLOAD_TIMEOUT=60
|
||||||
|
### Кол-во экземпляров записей пользователя (не более 50!)
|
||||||
|
USER_INSTANCES_MAX=5
|
||||||
|
### Пропускать мимо фильтра пакеты уже помеченные в записях пользователя (0 - выкл, 1 - вкл)
|
||||||
|
SKIP_MARKED_PACKETS=0
|
||||||
### Режим списка записей, исключаемых из обхода блокировок (0 - выкл, 1 - вкл)
|
### Режим списка записей, исключаемых из обхода блокировок (0 - выкл, 1 - вкл)
|
||||||
BYPASS_MODE=0
|
BYPASS_MODE=0
|
||||||
### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет
|
### DNS-сервер для исключаемых записей (пустая строка - без DNS-сервера). Можно с портом: 8.8.8.8#53. Если в записи указан свой DNS-сервер - он имеет приоритет
|
||||||
@@ -143,7 +129,7 @@ BLLIST_SD_LIMIT=16
|
|||||||
BLLIST_GR_EXCLUDED_SLD_FILE="/etc/ruantiblock/gr_excluded_sld"
|
BLLIST_GR_EXCLUDED_SLD_FILE="/etc/ruantiblock/gr_excluded_sld"
|
||||||
### Файл с масками SLD не подлежащими группировке при оптимизации (одна запись на строку)
|
### Файл с масками SLD не подлежащими группировке при оптимизации (одна запись на строку)
|
||||||
BLLIST_GR_EXCLUDED_SLD_MASKS_FILE="/etc/ruantiblock/gr_excluded_sld_mask"
|
BLLIST_GR_EXCLUDED_SLD_MASKS_FILE="/etc/ruantiblock/gr_excluded_sld_mask"
|
||||||
### Фильтрация записей блэклиста по шаблонам из файла ENTRIES_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - выкл, 1 - вкл)
|
### Фильтрация записей блэклиста по шаблонам из файла BLLIST_FQDN_FILTER_FILE. Записи (FQDN) попадающие под шаблоны исключаются из кофига dnsmasq (0 - выкл, 1 - вкл)
|
||||||
BLLIST_FQDN_FILTER=0
|
BLLIST_FQDN_FILTER=0
|
||||||
### Тип фильтра FQDN (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
|
### Тип фильтра FQDN (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами)
|
||||||
BLLIST_FQDN_FILTER_TYPE=0
|
BLLIST_FQDN_FILTER_TYPE=0
|
||||||
|
|||||||
@@ -1,17 +1,69 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
PID_FILE="/var/run/`basename $0`.pid"
|
PID_FILE="/var/run/`basename $0`.pid"
|
||||||
|
APP_EXEC="/usr/bin/ruantiblock"
|
||||||
|
|
||||||
VpnRouteStatus() {
|
. "$USER_INSTANCES_COMMON"
|
||||||
[ -n "`$IP_CMD route show table $VPN_ROUTE_TABLE_ID 2> /dev/null`" ] && return 0
|
|
||||||
|
VPN_IFACES_STATUS=1
|
||||||
|
|
||||||
|
CheckIfaceStatus() {
|
||||||
|
local _iface="$1" _ret_val=0
|
||||||
|
if [ -z "`$IP_CMD link show dev $_iface up 2> /dev/null`" ]; then
|
||||||
|
_ret_val=1
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " ruab_route_check.GetVpnRouteStatus: ${_iface} disabled" >&2
|
||||||
|
logger -p "user.debug" -t "ruantiblock" "ruab_route_check.GetVpnRouteStatus: iface ${_iface} disabled"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
return $_ret_val
|
||||||
|
}
|
||||||
|
|
||||||
|
VpnRouteInstanceStatus() {
|
||||||
|
local _vpn_route_table_id=$1
|
||||||
|
[ -n "`$IP_CMD route show table $_vpn_route_table_id 2> /dev/null`" ] && return 0
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GetVpnRouteStatus() {
|
||||||
|
local _inst _i=1 _ret_val=0
|
||||||
|
for _inst in $USER_INSTANCES_VPN_FNAMES
|
||||||
|
do
|
||||||
|
IncludeUserInstanceVars "$_inst"
|
||||||
|
if ! CheckIfaceStatus $U_IF_VPN; then
|
||||||
|
VPN_IFACES_STATUS=0
|
||||||
|
fi
|
||||||
|
if ! VpnRouteInstanceStatus $(($VPN_ROUTE_TABLE_ID_START + $_i)); then
|
||||||
|
_ret_val=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_i=$(($_i + 1))
|
||||||
|
ClearUserInstanceVars
|
||||||
|
done
|
||||||
|
if [ $_ret_val -eq 0 -a "$PROXY_MODE" = "2" ]; then
|
||||||
|
if ! CheckIfaceStatus $IF_VPN; then
|
||||||
|
VPN_IFACES_STATUS=0
|
||||||
|
fi
|
||||||
|
if ! VpnRouteInstanceStatus $VPN_ROUTE_TABLE_ID_START; then
|
||||||
|
_ret_val=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return $_ret_val
|
||||||
|
}
|
||||||
|
|
||||||
Main() {
|
Main() {
|
||||||
while [ -e "$PID_FILE" ]
|
while [ -e "$PID_FILE" ]
|
||||||
do
|
do
|
||||||
if ! VpnRouteStatus; then
|
VPN_IFACES_STATUS=1
|
||||||
if $IP_CMD link show $IF_VPN &> /dev/null; then
|
if ! GetVpnRouteStatus; then
|
||||||
|
if [ "$VPN_IFACES_STATUS" = "1" ]; then
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " ruab_route_check.Main: ${APP_EXEC} reload" >&2
|
||||||
|
logger -p "user.debug" -t "ruantiblock" "ruab_route_check.Main: ${APP_EXEC} reload"
|
||||||
|
fi
|
||||||
$APP_EXEC reload
|
$APP_EXEC reload
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ export RBL_DPI_URL="https://reestr.rublacklist.net/api/v3/dpi/"
|
|||||||
export RBL_ENCODING=""
|
export RBL_ENCODING=""
|
||||||
## zapret-info
|
## zapret-info
|
||||||
export ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
|
export ZI_ALL_URL="https://raw.githubusercontent.com/zapret-info/z-i/master/dump.csv"
|
||||||
#export ZI_ALL_URL="https://app.assembla.com/spaces/z-i/git/source/master/dump.csv?_format=raw"
|
|
||||||
export ZI_ENCODING="CP1251"
|
export ZI_ENCODING="CP1251"
|
||||||
## antifilter
|
## antifilter
|
||||||
export AF_IP_URL="https://antifilter.download/list/allyouneed.lst"
|
export AF_IP_URL="https://antifilter.download/list/allyouneed.lst"
|
||||||
@@ -52,7 +51,6 @@ case "$BLLIST_PRESET" in
|
|||||||
export BLLIST_SOURCE="ruantiblock"
|
export BLLIST_SOURCE="ruantiblock"
|
||||||
export BLLIST_MODE="ip"
|
export BLLIST_MODE="ip"
|
||||||
BLLIST_MODULE="DownloadNativeBlacklist"
|
BLLIST_MODULE="DownloadNativeBlacklist"
|
||||||
# github
|
|
||||||
DL_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/ip/ruantiblock.ip"
|
DL_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/ip/ruantiblock.ip"
|
||||||
DL_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/ip/ruantiblock.dnsmasq"
|
DL_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/ip/ruantiblock.dnsmasq"
|
||||||
DL_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/ip/update_status"
|
DL_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/ip/update_status"
|
||||||
@@ -61,7 +59,6 @@ case "$BLLIST_PRESET" in
|
|||||||
export BLLIST_SOURCE="ruantiblock"
|
export BLLIST_SOURCE="ruantiblock"
|
||||||
export BLLIST_MODE="fqdn"
|
export BLLIST_MODE="fqdn"
|
||||||
BLLIST_MODULE="DownloadNativeBlacklist"
|
BLLIST_MODULE="DownloadNativeBlacklist"
|
||||||
# github
|
|
||||||
DL_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/fqdn/ruantiblock.ip"
|
DL_IPSET_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/fqdn/ruantiblock.ip"
|
||||||
DL_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/fqdn/ruantiblock.dnsmasq"
|
DL_DMASK_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/fqdn/ruantiblock.dnsmasq"
|
||||||
DL_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/fqdn/update_status"
|
DL_STAT_URL="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_blacklist/master/blacklist-1.1/fqdn/update_status"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
UCI_SECTION="ruantiblock.config"
|
UCI_SECTION="ruantiblock.config"
|
||||||
UCI_VARS="proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_mode bypass_entries_dns enable_fproxy fproxy_list enable_bllist_proxy if_vpn vpn_gw_ip vpn_route_check tor_trans_port onion_dns_addr t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp add_user_entries user_entries_dns user_entries_remote enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup enable_tmp_downloads"
|
UCI_VARS="dnsmasq_cfg_dir proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_mode bypass_entries_dns enable_fproxy fproxy_list enable_bllist_proxy if_vpn vpn_gw_ip vpn_route_check tor_trans_port onion_dns_addr t_proxy_type t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup enable_tmp_downloads"
|
||||||
UCI_CMD=`which uci`
|
UCI_CMD=`which uci`
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo " Error! UCI doesn't exists" >&2
|
echo " Error! UCI doesn't exists" >&2
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
UCI_VARS="u_enabled 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_entries_dns u_entries_remote u_enable_entries_remote_proxy u_enable_fproxy u_fproxy_list u_skip_marked_packets"
|
||||||
|
UCI_CMD=`which uci`
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo " Error! UCI doesn't exists" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
AWK_CMD="awk"
|
||||||
|
|
||||||
|
ListUserInstances() {
|
||||||
|
$UCI_CMD export "$NAME" | $AWK_CMD -v TYPE="user_instance" '
|
||||||
|
BEGIN {
|
||||||
|
instances="";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if($0 ~ "config "TYPE) {
|
||||||
|
gsub(/["\047]/, "", $3);
|
||||||
|
instances=instances (length(instances) > 0 ? "\n" : "") $3;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
print instances;
|
||||||
|
}'
|
||||||
|
}
|
||||||
|
|
||||||
|
IncludeUserInstanceVars() {
|
||||||
|
local _inst="$1"
|
||||||
|
local _uci_section="${NAME}.${_inst}"
|
||||||
|
U_NAME="$_inst"
|
||||||
|
eval `$UCI_CMD show "$_uci_section" | $AWK_CMD -F "=" -v UCI_VARS="$UCI_VARS" '
|
||||||
|
BEGIN {
|
||||||
|
split(UCI_VARS, split_array, " ");
|
||||||
|
for(i in split_array)
|
||||||
|
vars_array[split_array[i]]="";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
sub(/^.*[.]/, "", $1);
|
||||||
|
gsub(/["\047]/, "", $2);
|
||||||
|
if($1 in vars_array) {
|
||||||
|
print toupper($1) "=\"" $2 "\"";
|
||||||
|
delete vars_array[$1];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if(length(vars_array) > 0) {
|
||||||
|
for(i in vars_array)
|
||||||
|
print toupper(i) "=\"""\"";
|
||||||
|
};
|
||||||
|
}'`
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 2 ]; then
|
||||||
|
echo " user_instances_config_script.IncludeUserInstanceVars: _inst=${_inst} U_NAME=${U_NAME} U_PROXY_MODE=${U_PROXY_MODE}" >&2
|
||||||
|
MakeLogRecord "debug" "user_instances_config_script.IncludeUserInstanceVars: _inst=${_inst} U_NAME=${U_NAME} U_PROXY_MODE=${U_PROXY_MODE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Info() {
|
Info() {
|
||||||
local _update_status _user_entries_status
|
local _update_status _user_entries_status _inst
|
||||||
if [ -f "$UPDATE_STATUS_FILE" ]; then
|
if [ -f "$UPDATE_STATUS_FILE" ]; then
|
||||||
_update_status=`$AWK_CMD '{
|
_update_status=`$AWK_CMD '{
|
||||||
if(NF < 4) {
|
if(NF < 4) {
|
||||||
@@ -33,29 +33,30 @@ Info() {
|
|||||||
else
|
else
|
||||||
_user_entries_status="[]"
|
_user_entries_status="[]"
|
||||||
fi
|
fi
|
||||||
NftListBllistChainJson 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" -v USER_ENTRIES_STATUS="$_user_entries_status" '
|
NftListSinkChainJson 2> /dev/null | $AWK_CMD -v UPDATE_STATUS="$_update_status" -v USER_ENTRIES_STATUS="$_user_entries_status" '
|
||||||
BEGIN {
|
|
||||||
rules_str = "";
|
|
||||||
}
|
|
||||||
{
|
|
||||||
rules_str = rules_str $0;
|
|
||||||
}
|
|
||||||
END {
|
END {
|
||||||
if(NR == 0) {
|
if(NR == 0) {
|
||||||
printf "{\"status\": \"disabled\"}";
|
printf "{\"status\": \"disabled\"}";
|
||||||
exit 1;
|
exit 1;
|
||||||
} else {
|
} else {
|
||||||
printf "{\"status\":\"enabled\",\"last_blacklist_update\":%s,\"user_entries\":%s,\"rules\":%s", UPDATE_STATUS, USER_ENTRIES_STATUS, rules_str;
|
printf "{\"status\": \"enabled\",\"last_blacklist_update\": %s,\"user_entries\" :%s,\"sink\": %s", UPDATE_STATUS, USER_ENTRIES_STATUS, $0;
|
||||||
exit 0;
|
exit 0;
|
||||||
};
|
};
|
||||||
}'
|
}'
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
|
if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
|
||||||
|
printf ",\"sink_local\":"
|
||||||
|
NftListSinkLocalChainJson 2> /dev/null
|
||||||
|
fi
|
||||||
printf ",\"dnsmasq\":"
|
printf ",\"dnsmasq\":"
|
||||||
$NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ" 2> /dev/null
|
$NFT_CMD -j list set $NFT_TABLE "$NFTSET_DNSMASQ" 2> /dev/null
|
||||||
if [ "$BYPASS_MODE" = "1" ]; then
|
printf ",\"dnsmasq_user_instances\":["
|
||||||
printf ",\"dnsmasq_bypass\":"
|
for _inst in $USER_INSTANCES_ALL
|
||||||
$NFT_CMD -j list set $NFT_TABLE "$NFTSET_BYPASS_FQDN" 2> /dev/null
|
do
|
||||||
fi
|
$NFT_CMD -j list set $NFT_TABLE "${NFTSET_DNSMASQ}-${_inst}" 2> /dev/null
|
||||||
|
printf ","
|
||||||
|
done
|
||||||
|
printf "{\"dummy\": {}}]"
|
||||||
printf "}"
|
printf "}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,35 +2,26 @@ NFT_ALLOWED_HOSTS_CHAIN="allowed_hosts"
|
|||||||
NFT_BLLIST_CHAIN="blacklist"
|
NFT_BLLIST_CHAIN="blacklist"
|
||||||
NFT_FPROXY_FILTER="fproxy_filter"
|
NFT_FPROXY_FILTER="fproxy_filter"
|
||||||
NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN="dnsmasq_timeout_update"
|
NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN="dnsmasq_timeout_update"
|
||||||
NFT_ACTION_CHAIN="action"
|
NFT_MARK_CHAIN="mark_chain"
|
||||||
NFT_LOCAL_CLIENTS_CHAIN="local_clients"
|
NFT_LOCAL_CLIENTS_CHAIN="local_clients"
|
||||||
|
NFT_SINK_CHAIN="sink"
|
||||||
if [ "$PROXY_MODE" = "2" ]; then
|
NFT_SINK_LOCAL_CHAIN="sink_local"
|
||||||
MAIN_CHAIN_TYPE="type filter hook prerouting priority ${NFT_PRIO_ROUTE}; policy accept;"
|
NFT_ACTION_FILTER_CHAIN="action_filter"
|
||||||
LOCAL_CLIENTS_CHAIN_TYPE="type route hook output priority ${NFT_PRIO_ROUTE_LOCAL}; policy accept;"
|
NFT_ACTION_NAT_CHAIN="action_nat"
|
||||||
else
|
NFT_ACTION_NAT_LOCAL_CHAIN="action_nat_local"
|
||||||
MAIN_CHAIN_TYPE="type nat hook prerouting priority ${NFT_PRIO_NAT}; policy accept;"
|
|
||||||
LOCAL_CLIENTS_CHAIN_TYPE="type nat hook output priority ${NFT_PRIO_NAT_LOCAL}; policy accept;"
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$ALLOWED_HOSTS_MODE" in
|
case "$ALLOWED_HOSTS_MODE" in
|
||||||
"1")
|
"1")
|
||||||
NFT_ALLOWED_HOSTS_EXPR="ip saddr @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}"
|
NFT_ALLOWED_HOSTS_PATTERN="ip saddr @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}%s"
|
||||||
;;
|
;;
|
||||||
"2")
|
"2")
|
||||||
NFT_ALLOWED_HOSTS_EXPR="ip saddr != @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}"
|
NFT_ALLOWED_HOSTS_PATTERN="ip saddr != @${NFTSET_ALLOWED_HOSTS} jump ${NFT_BLLIST_CHAIN}%s"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
NFT_ALLOWED_HOSTS_EXPR="jump ${NFT_BLLIST_CHAIN}"
|
NFT_ALLOWED_HOSTS_PATTERN="jump ${NFT_BLLIST_CHAIN}%s"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [ "$NFTSET_DNSMASQ_TIMEOUT_UPDATE" = "1" ]; then
|
|
||||||
NFT_DNSMASQ_RULE_TARGET="$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN"
|
|
||||||
else
|
|
||||||
NFT_DNSMASQ_RULE_TARGET="$NFT_ACTION_CHAIN"
|
|
||||||
fi
|
|
||||||
|
|
||||||
NftCmdWrapper() {
|
NftCmdWrapper() {
|
||||||
local _i=0 _attempts=10 _return_code=1
|
local _i=0 _attempts=10 _return_code=1
|
||||||
while [ $_i -lt $_attempts ]
|
while [ $_i -lt $_attempts ]
|
||||||
@@ -44,105 +35,247 @@ NftCmdWrapper() {
|
|||||||
return $_return_code
|
return $_return_code
|
||||||
}
|
}
|
||||||
|
|
||||||
NftVpnRouteDelete() {
|
NftRouteDelete() {
|
||||||
$IP_CMD route flush table $VPN_ROUTE_TABLE_ID
|
local _route_table_id=$1
|
||||||
$IP_CMD rule del table $VPN_ROUTE_TABLE_ID
|
$IP_CMD route flush table $_route_table_id
|
||||||
|
$IP_CMD rule del table $_route_table_id
|
||||||
}
|
}
|
||||||
|
|
||||||
NftVpnRouteAdd() {
|
NftRouteAdd() {
|
||||||
local _vpn_ip
|
local _vpn_ip _type="$1" _route_table_id=$2 _pkts_mark=$3 _if_vpn="$4" _vpn_gw_ip="$5"
|
||||||
if [ -n "$VPN_GW_IP" ]; then
|
if [ "$_type" = "lo" ]; then
|
||||||
_vpn_ip="$VPN_GW_IP"
|
echo 0 > /proc/sys/net/ipv4/conf/lo/rp_filter
|
||||||
|
$IP_CMD rule add fwmark $_pkts_mark table $_route_table_id priority $LO_RULE_PRIO
|
||||||
|
$IP_CMD route add local default dev lo table $_route_table_id
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " nft_functions.NftRouteAdd: ${IP_CMD} rule add fwmark ${_pkts_mark} table ${_route_table_id} priority ${LO_RULE_PRIO}" >&2
|
||||||
|
MakeLogRecord "debug" "nft_functions.NftRouteAdd: ${IP_CMD} rule add fwmark ${_pkts_mark} table ${_route_table_id} priority ${LO_RULE_PRIO}"
|
||||||
|
echo " nft_functions.NftRouteAdd: ${IP_CMD} route add local default dev lo table ${_route_table_id}" >&2
|
||||||
|
MakeLogRecord "debug" "nft_functions.NftRouteAdd: ${IP_CMD} route add local default dev lo table ${_route_table_id}"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_vpn_ip=`$IP_CMD addr list dev $IF_VPN 2> /dev/null | $AWK_CMD '/inet/{f=($3 == "peer") ? 4 : 2; sub("/[0-9]{1,2}$", "", $f); print $f; exit}'`
|
if [ -n "$_vpn_gw_ip" ]; then
|
||||||
fi
|
_vpn_ip="$_vpn_gw_ip"
|
||||||
if [ -n "$_vpn_ip" ]; then
|
else
|
||||||
echo 0 > /proc/sys/net/ipv4/conf/$IF_VPN/rp_filter
|
_vpn_ip=`$IP_CMD addr list dev $_if_vpn 2> /dev/null | $AWK_CMD '/inet/{f=($3 == "peer") ? 4 : 2; sub("/[0-9]{1,2}$", "", $f); print $f; exit}'`
|
||||||
NftVpnRouteDelete 2> /dev/null
|
fi
|
||||||
$IP_CMD rule add fwmark $VPN_PKTS_MARK table $VPN_ROUTE_TABLE_ID priority $VPN_RULE_PRIO
|
if [ -n "$_vpn_ip" -a "$_type" = "vpn" ]; then
|
||||||
$IP_CMD route add default via $_vpn_ip table $VPN_ROUTE_TABLE_ID
|
echo 0 > /proc/sys/net/ipv4/conf/$_if_vpn/rp_filter
|
||||||
|
NftRouteDelete $_route_table_id 2> /dev/null
|
||||||
|
$IP_CMD rule add fwmark $_pkts_mark table $_route_table_id priority $VPN_RULE_PRIO
|
||||||
|
$IP_CMD route add default via $_vpn_ip table $_route_table_id
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo " Error! An error occurred while adding the route. Routing table id=${_route_table_id}, VPN gateway IP=${_vpn_ip}" >&2
|
||||||
|
MakeLogRecord "err" "Error! An error occurred while adding the route. Routing table id=${_route_table_id}, VPN gateway IP=${_vpn_ip}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " nft_functions.NftRouteAdd: ${IP_CMD} rule add fwmark ${_pkts_mark} table ${_route_table_id} priority ${VPN_RULE_PRIO}" >&2
|
||||||
|
MakeLogRecord "debug" "nft_functions.NftRouteAdd: ${IP_CMD} rule add fwmark ${_pkts_mark} table ${_route_table_id} priority ${VPN_RULE_PRIO}"
|
||||||
|
echo " nft_functions.NftRouteAdd: ${IP_CMD} route add default via ${_vpn_ip} table ${_route_table_id}" >&2
|
||||||
|
MakeLogRecord "debug" "nft_functions.NftRouteAdd: ${IP_CMD} route add default via ${_vpn_ip} table ${_route_table_id}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
NftVpnRouteStatus() {
|
NftRouteStatus() {
|
||||||
[ -n "`$IP_CMD route show table $VPN_ROUTE_TABLE_ID 2> /dev/null`" ] && return 0
|
local _route_table_id=$1
|
||||||
|
[ -n "`$IP_CMD route show table $_route_table_id 2> /dev/null`" ] && return 0
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
NftMainAdd() {
|
NftAddSinkChains() {
|
||||||
local _set
|
local _chain_prio_sink=$1
|
||||||
$NFT_CMD add chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" { $LOCAL_CLIENTS_CHAIN_TYPE }
|
$NFT_CMD add chain $NFT_TABLE "${NFT_SINK_CHAIN}" { type filter hook prerouting priority ${_chain_prio_sink}\; policy accept\; }
|
||||||
$NFT_CMD add chain $NFT_TABLE "$NFT_ACTION_CHAIN"
|
$NFT_CMD add chain $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}" { type route hook output priority ${_chain_prio_sink}\; policy accept\; }
|
||||||
$NFT_CMD add chain $NFT_TABLE "$NFT_FPROXY_FILTER"
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_CHAIN}" meta iif lo return
|
||||||
$NFT_CMD add chain $NFT_TABLE "$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN"
|
}
|
||||||
$NFT_CMD add chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
|
|
||||||
$NFT_CMD add chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" { $MAIN_CHAIN_TYPE }
|
NftDeleteSinkChains() {
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE $NFT_FPROXY_FILTER ip daddr "@${NFTSET_FPROXY_PRIVATE}" return
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_SINK_CHAIN}"
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_FPROXY_FILTER" jump "$NFT_ACTION_CHAIN"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}"
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN" ct state new set update ip daddr "@${NFTSET_DNSMASQ}"
|
}
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN" jump "$NFT_ACTION_CHAIN"
|
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" $NFT_ALLOWED_HOSTS_EXPR
|
NftAddActionChains() {
|
||||||
if [ "$PROXY_MODE" = "2" ]; then
|
local _chain_prio_action=$1
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" mark set $VPN_PKTS_MARK
|
$NFT_CMD add chain $NFT_TABLE "${NFT_ACTION_FILTER_CHAIN}" { type filter hook prerouting priority ${_chain_prio_action}\; policy accept\; }
|
||||||
elif [ "$PROXY_MODE" = "3" ]; then
|
$NFT_CMD add chain $NFT_TABLE "${NFT_ACTION_NAT_CHAIN}" { type nat hook prerouting priority ${_chain_prio_action}\; policy accept\; }
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" tcp dport { 0-65535 } redirect to $T_PROXY_PORT_TCP
|
$NFT_CMD add chain $NFT_TABLE "${NFT_ACTION_NAT_LOCAL_CHAIN}" { type nat hook output priority ${_chain_prio_action}\; policy accept\; }
|
||||||
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
|
NftDeleteActionChains() {
|
||||||
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_ACTION_FILTER_CHAIN}"
|
||||||
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_ACTION_NAT_CHAIN}"
|
||||||
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_ACTION_NAT_LOCAL_CHAIN}"
|
||||||
|
}
|
||||||
|
|
||||||
|
NftInstanceAdd() {
|
||||||
|
local _i _inst _first_chain_type _t_proxy_statement _chain_action_type _set
|
||||||
|
|
||||||
|
for _i in "_name" "_pkts_mark" "_chain_prio_first" "_chain_prio_local" "_proxy_mode" "_tor_trans_port" "_route_table_id" "_if_vpn" "_t_proxy_type" "_t_proxy_port_tcp" "_t_proxy_port_udp" "_t_proxy_allow_udp" "_enable_bllist_proxy" "_enable_fproxy" "_skip_marked_packets" "_vpn_gw_ip"
|
||||||
|
do
|
||||||
|
eval "local $_i=$1"
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
_inst="$_name"
|
||||||
|
if [ "$_name" = " " ]; then
|
||||||
|
_name=""
|
||||||
else
|
else
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ACTION_CHAIN" tcp dport { 0-65535 } redirect to $TOR_TRANS_PORT
|
_name="-${_name}"
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${NFTSET_ONION}" counter goto "$NFT_ACTION_CHAIN"
|
|
||||||
fi
|
fi
|
||||||
if [ "$ENABLE_FPROXY" = "1" ]; then
|
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip saddr "@${NFTSET_FPROXY}" counter goto "$NFT_FPROXY_FILTER"
|
if [ $DEBUG -ge 1 ]; then
|
||||||
|
echo " nft_functions.NftInstanceAdd.args: _name=${_name} _pkts_mark=${_pkts_mark} _chain_prio_first=${_chain_prio_first} _chain_prio_local=${_chain_prio_local} _proxy_mode=${_proxy_mode} _tor_trans_port=${_tor_trans_port} _route_table_id=${_route_table_id} _if_vpn=${_if_vpn} _t_proxy_type=${_t_proxy_type} _t_proxy_port_tcp=${_t_proxy_port_tcp} _t_proxy_port_udp=${_t_proxy_port_udp} _t_proxy_allow_udp=${_t_proxy_allow_udp} _enable_bllist_proxy=${_enable_bllist_proxy} _enable_fproxy=${_enable_fproxy} _skip_marked_packets=${_skip_marked_packets} _vpn_gw_ip=${_vpn_gw_ip}" >&2
|
||||||
|
MakeLogRecord "debug" "nft_functions.NftInstanceAdd.args: _name=${_name} _pkts_mark=${_pkts_mark} _chain_prio_first=${_chain_prio_first} _chain_prio_local=${_chain_prio_local} _proxy_mode=${_proxy_mode} _tor_trans_port=${_tor_trans_port} _route_table_id=${_route_table_id} _if_vpn=${_if_vpn} _t_proxy_type=${_t_proxy_type} _t_proxy_port_tcp=${_t_proxy_port_tcp} _t_proxy_port_udp=${_t_proxy_port_udp} _t_proxy_allow_udp=${_t_proxy_allow_udp} _enable_bllist_proxy=${_enable_bllist_proxy} _enable_fproxy=${_enable_fproxy} _skip_marked_packets=${_skip_marked_packets} _vpn_gw_ip=${_vpn_gw_ip}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$NFTSET_DNSMASQ_TIMEOUT_UPDATE" = "1" ]; then
|
||||||
|
_nft_dnsmasq_rule_target="${NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN}${_name}"
|
||||||
|
else
|
||||||
|
_nft_dnsmasq_rule_target="${NFT_MARK_CHAIN}${_name}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$NFT_CMD add chain $NFT_TABLE "${NFT_LOCAL_CLIENTS_CHAIN}${_name}" { type route hook output priority ${_chain_prio_local}\; policy accept\; }
|
||||||
|
$NFT_CMD add chain $NFT_TABLE "${NFT_MARK_CHAIN}${_name}"
|
||||||
|
$NFT_CMD add chain $NFT_TABLE "${NFT_FPROXY_FILTER}${_name}"
|
||||||
|
$NFT_CMD add chain $NFT_TABLE "${NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN}${_name}"
|
||||||
|
$NFT_CMD add chain $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}"
|
||||||
|
$NFT_CMD add chain $NFT_TABLE "${NFT_ALLOWED_HOSTS_CHAIN}${_name}" { type filter hook prerouting priority ${_chain_prio_first}\; policy accept\; }
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_FPROXY_FILTER}${_name}" ip daddr "@${NFTSET_FPROXY_PRIVATE}" return
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_FPROXY_FILTER}${_name}" jump "${NFT_MARK_CHAIN}${_name}"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN}${_name}" ct state new set update ip daddr "@${NFTSET_DNSMASQ}${_name}"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN}${_name}" jump "${NFT_MARK_CHAIN}${_name}"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ALLOWED_HOSTS_CHAIN}${_name}" "`printf "$NFT_ALLOWED_HOSTS_PATTERN" "$_name"`"
|
||||||
|
|
||||||
|
if [ "$_proxy_mode" = "2" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_CHAIN}" meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}" meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
elif [ "$_proxy_mode" = "3" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_CHAIN}" meta l4proto tcp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}" meta l4proto tcp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
if [ "$_t_proxy_type" = "1" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_FILTER_CHAIN}" meta l4proto tcp meta mark $_pkts_mark tproxy to ":${_t_proxy_port_tcp}" comment \""$_inst"\"
|
||||||
|
if [ "$_t_proxy_allow_udp" = "1" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_FILTER_CHAIN}" meta l4proto udp meta mark $_pkts_mark tproxy to ":${_t_proxy_port_udp}" comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_CHAIN}" meta l4proto udp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}" meta l4proto udp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_NAT_CHAIN}" meta l4proto tcp meta mark $_pkts_mark redirect to ":${_t_proxy_port_tcp}" comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_NAT_LOCAL_CHAIN}" meta l4proto tcp meta mark $_pkts_mark redirect to ":${_t_proxy_port_tcp}" comment \""$_inst"\"
|
||||||
|
if [ "$_t_proxy_allow_udp" = "1" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_NAT_CHAIN}" meta l4proto udp meta mark $_pkts_mark redirect to ":${_t_proxy_port_udp}" comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_NAT_LOCAL_CHAIN}" meta l4proto udp meta mark $_pkts_mark redirect to ":${_t_proxy_port_udp}" comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_CHAIN}" meta l4proto udp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}" meta l4proto udp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
elif [ "$_proxy_mode" != "2" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_NAT_CHAIN}" meta l4proto tcp meta mark $_pkts_mark redirect to ":${_tor_trans_port}" comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_ACTION_NAT_LOCAL_CHAIN}" meta l4proto tcp meta mark $_pkts_mark redirect to ":${_tor_trans_port}" comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_CHAIN}" meta l4proto tcp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_SINK_LOCAL_CHAIN}" meta l4proto tcp meta mark $_pkts_mark counter comment \""$_inst"\"
|
||||||
|
fi
|
||||||
|
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_MARK_CHAIN}${_name}" mark set $_pkts_mark
|
||||||
|
if [ "$_proxy_mode" != "2" -a "$_proxy_mode" != "3" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}" ip daddr "@${NFTSET_ONION}${_name}" counter goto "${NFT_MARK_CHAIN}${_name}"
|
||||||
|
fi
|
||||||
|
if [ "$_skip_marked_packets" = "1" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}" meta mark "@${NFTSET_MARK_SET}" return
|
||||||
|
fi
|
||||||
|
if [ "$_enable_fproxy" = "1" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}" ip saddr "@${NFTSET_FPROXY}${_name}" goto "${NFT_FPROXY_FILTER}${_name}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$BYPASS_MODE" = "1" ]; then
|
if [ "$BYPASS_MODE" = "1" ]; then
|
||||||
for _set in "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"
|
for _set in "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"
|
||||||
do
|
do
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${_set}" counter accept
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}" ip daddr "@${_set}" accept
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
for _set in "$NFTSET_CIDR" "$NFTSET_IP"
|
|
||||||
|
for _set in "${NFTSET_CIDR}${_name}" "${NFTSET_IP}${_name}"
|
||||||
do
|
do
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${_set}" counter goto "$NFT_ACTION_CHAIN"
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}" ip daddr "@${_set}" counter goto "${NFT_MARK_CHAIN}${_name}"
|
||||||
done
|
done
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" ip daddr "@${NFTSET_DNSMASQ}" counter goto "$NFT_DNSMASQ_RULE_TARGET"
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}" ip daddr "@${NFTSET_DNSMASQ}${_name}" counter goto "$_nft_dnsmasq_rule_target"
|
||||||
if [ "$PROXY_MODE" = "2" ]; then
|
|
||||||
NftVpnRouteAdd
|
if [ "$_proxy_mode" = "2" ]; then
|
||||||
|
NftRouteAdd vpn $_route_table_id $_pkts_mark "$_if_vpn" "$_vpn_gw_ip"
|
||||||
|
elif [ "$_proxy_mode" = "3" -a "$_t_proxy_type" = "1" ]; then
|
||||||
|
NftRouteAdd lo $_route_table_id $_pkts_mark
|
||||||
fi
|
fi
|
||||||
if [ "$ENABLE_BLLIST_PROXY" = "1" ]; then
|
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" ip daddr "@${NFTSET_BLLIST_PROXY}" counter goto "$NFT_ACTION_CHAIN"
|
if [ "$_enable_bllist_proxy" = "1" ]; then
|
||||||
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_LOCAL_CLIENTS_CHAIN}${_name}" ip daddr "@${NFTSET_BLLIST_PROXY}${_name}" counter goto "${NFT_MARK_CHAIN}${_name}"
|
||||||
fi
|
fi
|
||||||
if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
|
if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
|
||||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN" jump "$NFT_BLLIST_CHAIN"
|
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "${NFT_LOCAL_CLIENTS_CHAIN}${_name}" jump "${NFT_BLLIST_CHAIN}${_name}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
NftMainDelete() {
|
NftInstanceDelete() {
|
||||||
$NFT_CMD flush chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN"
|
local _name="$1"
|
||||||
$NFT_CMD delete chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN"
|
if [ -z "$_name" -o "$_name" = " " ]; then
|
||||||
$NFT_CMD flush chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN"
|
_name=""
|
||||||
$NFT_CMD delete chain $NFT_TABLE "$NFT_LOCAL_CLIENTS_CHAIN"
|
else
|
||||||
$NFT_CMD flush chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
|
_name="-${_name}"
|
||||||
$NFT_CMD delete chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
|
fi
|
||||||
$NFT_CMD flush chain $NFT_TABLE "$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_ALLOWED_HOSTS_CHAIN}${_name}"
|
||||||
$NFT_CMD delete chain $NFT_TABLE "$NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_LOCAL_CLIENTS_CHAIN}${_name}"
|
||||||
$NFT_CMD flush chain $NFT_TABLE "$NFT_FPROXY_FILTER"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}"
|
||||||
$NFT_CMD delete chain $NFT_TABLE "$NFT_FPROXY_FILTER"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_DNSMASQ_TIMEOUT_UPDATE_CHAIN}${_name}"
|
||||||
$NFT_CMD flush chain $NFT_TABLE "$NFT_ACTION_CHAIN"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_FPROXY_FILTER}${_name}"
|
||||||
$NFT_CMD delete chain $NFT_TABLE "$NFT_ACTION_CHAIN"
|
$NFT_CMD delete chain $NFT_TABLE "${NFT_MARK_CHAIN}${_name}"
|
||||||
NftVpnRouteDelete 2> /dev/null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NftListBllistChain() {
|
NftListBllistChain() {
|
||||||
$NFT_CMD -t list chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
|
local _name="$1"
|
||||||
|
if [ -z "$_name" -o "$_name" = " " ]; then
|
||||||
|
_name=""
|
||||||
|
else
|
||||||
|
_name="-${_name}"
|
||||||
|
fi
|
||||||
|
$NFT_CMD -t list chain $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
NftListBllistChainJson() {
|
NftListBllistChainJson() {
|
||||||
$NFT_CMD -t -j list chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
|
local _name="$1"
|
||||||
|
if [ -z "$_name" -o "$_name" = " " ]; then
|
||||||
|
_name=""
|
||||||
|
else
|
||||||
|
_name="-${_name}"
|
||||||
|
fi
|
||||||
|
$NFT_CMD -t -j list chain $NFT_TABLE "${NFT_BLLIST_CHAIN}${_name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
NftReturnStatus() {
|
NftListSinkChain() {
|
||||||
$NFT_CMD -c add rule $NFT_TABLE "$NFT_BLLIST_CHAIN" continue &> /dev/null
|
$NFT_CMD -t list chain $NFT_TABLE "$NFT_SINK_CHAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
NftListSinkChainJson() {
|
||||||
|
$NFT_CMD -t -j list chain $NFT_TABLE "$NFT_SINK_CHAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
NftListSinkLocalChain() {
|
||||||
|
$NFT_CMD -t list chain $NFT_TABLE "$NFT_SINK_LOCAL_CHAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
NftListSinkLocalChainJson() {
|
||||||
|
$NFT_CMD -t -j list chain $NFT_TABLE "$NFT_SINK_LOCAL_CHAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
NftReturnInstanceStatus() {
|
||||||
|
local _name="$1"
|
||||||
|
if [ -z "$_name" -o "$_name" = " " ]; then
|
||||||
|
_name=""
|
||||||
|
else
|
||||||
|
_name="-${_name}"
|
||||||
|
fi
|
||||||
|
$NFT_CMD -c add rule $NFT_TABLE "${NFT_ALLOWED_HOSTS_CHAIN}${_name}" continue &> /dev/null
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
if [ $USER_INSTANCES_MAX -gt 50 ]; then
|
||||||
|
USER_INSTANCES_MAX=50
|
||||||
|
fi
|
||||||
|
|
||||||
|
IncludeUserInstanceVars() {
|
||||||
|
local _inst="$1"
|
||||||
|
. "${USER_INSTANCES_DIR}/${_inst}"
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 2 ]; then
|
||||||
|
echo " user_instances_common.IncludeUserInstanceVars: _inst=${_inst} U_NAME=${U_NAME} U_PROXY_MODE=${U_PROXY_MODE}" >&2
|
||||||
|
MakeLogRecord "debug" "user_instances_common.IncludeUserInstanceVars: _inst=${_inst} U_NAME=${U_NAME} U_PROXY_MODE=${U_PROXY_MODE}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearUserInstanceVars() {
|
||||||
|
unset $USER_INSTANCE_VARS
|
||||||
|
}
|
||||||
|
|
||||||
|
ListUserInstances() {
|
||||||
|
ls -1 "$USER_INSTANCES_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
|
[ -f "$CONFIG_SCRIPT_USER_INSTANCES" ] && . "$CONFIG_SCRIPT_USER_INSTANCES"
|
||||||
|
|
||||||
|
GetUserInstances() {
|
||||||
|
local _type="$1" _fnames="$2" _i=0 _inst _instances=""
|
||||||
|
for _inst in `ListUserInstances`
|
||||||
|
do
|
||||||
|
IncludeUserInstanceVars "$_inst"
|
||||||
|
if [ $_i -lt $USER_INSTANCES_MAX -a -n "$U_NAME" -a "$U_ENABLED" != "0" ]; then
|
||||||
|
if [ "$_type" = "0" -o "$U_PROXY_MODE" = "$_type" ]; then
|
||||||
|
if [ "$_fnames" = "fnames" ]; then
|
||||||
|
_instances="${_instances}${_inst} "
|
||||||
|
else
|
||||||
|
_instances="${_instances}${U_NAME} "
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
_i=$(($_i + 1))
|
||||||
|
fi
|
||||||
|
ClearUserInstanceVars
|
||||||
|
done
|
||||||
|
printf "$_instances"
|
||||||
|
}
|
||||||
|
|
||||||
|
SetUserInstancesItems() {
|
||||||
|
local _i=0 _inst _instances_all="" _instances_all_fnames="" _instances_vpn="" _instances_vpn_fnames="" _instances_cfg="" _instances_cfg_fnames=""
|
||||||
|
for _inst in `ListUserInstances`
|
||||||
|
do
|
||||||
|
IncludeUserInstanceVars "$_inst"
|
||||||
|
if [ $_i -lt $USER_INSTANCES_MAX -a -n "$U_NAME" -a "$U_ENABLED" != "0" ]; then
|
||||||
|
_instances_all="${_instances_all}${U_NAME} "
|
||||||
|
_instances_all_fnames="${_instances_all_fnames}${_inst} "
|
||||||
|
if [ "$U_PROXY_MODE" = "2" ]; then
|
||||||
|
_instances_vpn="${_instances_vpn}${U_NAME} "
|
||||||
|
_instances_vpn_fnames="${_instances_vpn_fnames}${_inst} "
|
||||||
|
fi
|
||||||
|
_i=$(($_i + 1))
|
||||||
|
fi
|
||||||
|
_instances_cfg="${_instances_cfg}${U_NAME} "
|
||||||
|
_instances_cfg_fnames="${_instances_cfg_fnames}${_inst} "
|
||||||
|
ClearUserInstanceVars
|
||||||
|
done
|
||||||
|
USER_INSTANCES_ALL="$_instances_all"
|
||||||
|
USER_INSTANCES_ALL_FNAMES="$_instances_all_fnames"
|
||||||
|
USER_INSTANCES_VPN="$_instances_vpn"
|
||||||
|
USER_INSTANCES_VPN_FNAMES="$_instances_vpn_fnames"
|
||||||
|
USER_INSTANCES_CFG="$_instances_cfg"
|
||||||
|
USER_INSTANCES_CFG_FNAMES="$_instances_cfg_fnames"
|
||||||
|
|
||||||
|
if [ $DEBUG -ge 2 ]; then
|
||||||
|
echo " user_instances_common.SetUserInstancesItems: USER_INSTANCES_ALL=\"${USER_INSTANCES_ALL}\"; USER_INSTANCES_ALL_FNAMES=\"${USER_INSTANCES_ALL_FNAMES}\"; USER_INSTANCES_VPN=\"${USER_INSTANCES_VPN}\"; USER_INSTANCES_VPN_FNAMES=\"${USER_INSTANCES_VPN_FNAMES}\"" >&2
|
||||||
|
MakeLogRecord "debug" "user_instances_common.SetUserInstancesItems: USER_INSTANCES_ALL=\"${USER_INSTANCES_ALL}\"; USER_INSTANCES_ALL_FNAMES=\"${USER_INSTANCES_ALL_FNAMES}\"; USER_INSTANCES_VPN=\"${USER_INSTANCES_VPN}\"; USER_INSTANCES_VPN_FNAMES=\"${USER_INSTANCES_VPN_FNAMES}\""
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 187 KiB |