mirror of
https://github.com/gSpotx2f/ruantiblock_openwrt.git
synced 2026-05-14 22:50:58 +00:00
Minor improvements. luci-app-ruantiblock: updated log.
This commit is contained in:
@@ -10,9 +10,9 @@ LUCI_APP=1
|
||||
HTTPS_DNS_PROXY=1
|
||||
|
||||
OWRT_VERSION="current"
|
||||
RUAB_VERSION="2.1.4-r3"
|
||||
RUAB_MOD_LUA_VERSION="2.1.4-r1"
|
||||
RUAB_LUCI_APP_VERSION="2.1.4-r1"
|
||||
RUAB_VERSION="2.1.5-r1"
|
||||
RUAB_MOD_LUA_VERSION="2.1.5-r1"
|
||||
RUAB_LUCI_APP_VERSION="2.1.5-r1"
|
||||
BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master"
|
||||
PKG_DIR="/tmp"
|
||||
|
||||
@@ -29,7 +29,6 @@ URL_LUCI_APP_PKG="${BASE_URL}/${OWRT_VERSION}/luci-app-ruantiblock_${RUAB_LUCI_A
|
||||
URL_LUCI_APP_RU_PKG="${BASE_URL}/${OWRT_VERSION}/luci-i18n-ruantiblock-ru_${RUAB_LUCI_APP_VERSION}_all.ipk"
|
||||
### tor
|
||||
URL_TORRC="https://raw.githubusercontent.com/gSpotx2f/ruantiblock_openwrt/master/tor/etc/tor/torrc"
|
||||
### ruantiblock-mod-lua
|
||||
URL_LUA_IDN="https://raw.githubusercontent.com/haste/lua-idn/master/idn.lua"
|
||||
|
||||
### Local files
|
||||
@@ -37,7 +36,7 @@ URL_LUA_IDN="https://raw.githubusercontent.com/haste/lua-idn/master/idn.lua"
|
||||
CONFIG_DIR="${PREFIX}/etc/ruantiblock"
|
||||
USER_LISTS_DIR="${CONFIG_DIR}/user_lists"
|
||||
EXEC_DIR="${PREFIX}/usr/bin"
|
||||
BACKUP_DIR="${CONFIG_DIR}/autoinstall.bak.`date +%s`"
|
||||
BACKUP_DIR="${CONFIG_DIR}/autoinstall.bak.$(date +%s)"
|
||||
### packages
|
||||
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"
|
||||
@@ -56,23 +55,21 @@ FILE_INIT_SCRIPT="${PREFIX}/etc/init.d/ruantiblock"
|
||||
FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
|
||||
### tor
|
||||
FILE_TORRC="${PREFIX}/etc/tor/torrc"
|
||||
### ruantiblock-mod-lua
|
||||
#FILE_LUA_IPTOOL="${PREFIX}/usr/lib/lua/iptool.lua"
|
||||
FILE_LUA_IDN="${PREFIX}/usr/lib/lua/idn.lua"
|
||||
|
||||
AWK_CMD="awk"
|
||||
WGET_CMD=`which wget`
|
||||
WGET_CMD="$(which wget)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! wget doesn't exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
WGET_PARAMS="--no-check-certificate -q -O "
|
||||
OPKG_CMD=`which opkg`
|
||||
OPKG_CMD="$(which opkg)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! opkg doesn't exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
UCI_CMD=`which uci`
|
||||
UCI_CMD="$(which uci)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! uci doesn't exists" >&2
|
||||
exit 1
|
||||
@@ -104,7 +101,7 @@ RemoveFile() {
|
||||
DlFile() {
|
||||
local _dir _file
|
||||
if [ -n "$2" ]; then
|
||||
_dir=`dirname "$2"`
|
||||
_dir=$(dirname "$2")
|
||||
MakeDir "$_dir"
|
||||
_file="$2"
|
||||
else
|
||||
@@ -119,19 +116,19 @@ DlFile() {
|
||||
}
|
||||
|
||||
BackupFile() {
|
||||
[ -e "$1" ] && cp -f "$1" "${1}.bak.`date +%s`"
|
||||
[ -e "$1" ] && cp -f "$1" "${1}.bak.$(date +%s)"
|
||||
}
|
||||
|
||||
BackupCurrentConfig() {
|
||||
local _file
|
||||
MakeDir "$BACKUP_DIR"
|
||||
for _file in `ls -1 "$CONFIG_DIR" | grep -v "$(basename $BACKUP_DIR)"`
|
||||
for _file in $(ls -1 "$CONFIG_DIR" | grep -v "$(basename $BACKUP_DIR)")
|
||||
do
|
||||
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}`"
|
||||
[ -e "$_file" ] && cp -af "$_file" "${BACKUP_DIR}/$(basename ${_file})"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -165,7 +162,7 @@ InstallPackages() {
|
||||
local _pkg
|
||||
for _pkg in $@
|
||||
do
|
||||
if [ -z "`$OPKG_CMD list-installed $_pkg`" ]; then
|
||||
if [ -z "$($OPKG_CMD list-installed $_pkg)" ]; then
|
||||
$OPKG_CMD --force-overwrite install $_pkg
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error during installation of the package (${_pkg})" >&2
|
||||
@@ -181,7 +178,6 @@ InstallBaseConfig() {
|
||||
RemoveFile "$FILE_RUAB_PKG" > /dev/null
|
||||
DlFile "$URL_RUAB_PKG" "$FILE_RUAB_PKG" && $OPKG_CMD install "$FILE_RUAB_PKG" > /dev/null
|
||||
_return_code=$?
|
||||
# костыль для остановки сервиса, который запускается автоматически после установки пакета!
|
||||
AppStop
|
||||
return $_return_code
|
||||
}
|
||||
@@ -205,7 +201,7 @@ InstallTPConfig() {
|
||||
}
|
||||
|
||||
TorrcSettings() {
|
||||
local _lan_ip=`$UCI_CMD get network.lan.ipaddr | $AWK_CMD -F "/" '{print $1}'`
|
||||
local _lan_ip=$($UCI_CMD get network.lan.ipaddr | $AWK_CMD -F "/" '{print $1}')
|
||||
if [ -z "$_lan_ip" ]; then
|
||||
_lan_ip="0.0.0.0"
|
||||
fi
|
||||
@@ -223,7 +219,6 @@ InstallTorConfig() {
|
||||
TorrcSettings
|
||||
$UCI_CMD set ruantiblock.config.proxy_mode="1"
|
||||
$UCI_CMD commit ruantiblock
|
||||
# dnsmasq rebind protection
|
||||
$UCI_CMD add_list dhcp.@dnsmasq[0].rebind_domain='onion'
|
||||
$UCI_CMD commit dhcp
|
||||
}
|
||||
@@ -392,7 +387,6 @@ ConfirmProcessing() {
|
||||
|
||||
ConfirmProxyMode
|
||||
ConfirmBlacklist
|
||||
#ConfirmLuaModule
|
||||
ConfirmLuciApp
|
||||
ConfirmHttpsDnsProxy
|
||||
ConfirmProcessing
|
||||
@@ -414,7 +408,7 @@ if [ $? -eq 0 ]; then
|
||||
else
|
||||
PrintBold "Installing Tor configuration..."
|
||||
InstallTorConfig
|
||||
if `/etc/init.d/tor enabled`; then
|
||||
if $(/etc/init.d/tor enabled); then
|
||||
/etc/init.d/tor restart
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -7,7 +7,7 @@ PREFIX=""
|
||||
CONFIG_DIR="${PREFIX}/etc/ruantiblock"
|
||||
USER_LISTS_DIR="${CONFIG_DIR}/user_lists"
|
||||
EXEC_DIR="${PREFIX}/usr/bin"
|
||||
BACKUP_DIR="${CONFIG_DIR}/autoinstall.bak.`date +%s`"
|
||||
BACKUP_DIR="${CONFIG_DIR}/autoinstall.bak.$(date +%s)"
|
||||
HTDOCS_VIEW="${PREFIX}/www/luci-static/resources/view"
|
||||
HTDOCS_RUAB="${HTDOCS_VIEW}/ruantiblock"
|
||||
CRONTAB_FILE="/etc/crontabs/root"
|
||||
@@ -33,7 +33,7 @@ FILE_MAIN_SCRIPT="${EXEC_DIR}/ruantiblock"
|
||||
FILE_TORRC="${PREFIX}/etc/tor/torrc"
|
||||
|
||||
AWK_CMD="awk"
|
||||
OPKG_CMD=`which opkg`
|
||||
OPKG_CMD="$(which opkg)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! opkg doesn't exists" >&2
|
||||
exit 1
|
||||
@@ -61,13 +61,13 @@ RemoveFile() {
|
||||
BackupCurrentConfig() {
|
||||
local _file
|
||||
MakeDir "$BACKUP_DIR"
|
||||
for _file in `ls -1 "$CONFIG_DIR" | grep -v "$(basename $BACKUP_DIR)"`
|
||||
for _file in $(ls -1 "$CONFIG_DIR" | grep -v "$(basename $BACKUP_DIR)")
|
||||
do
|
||||
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}`"
|
||||
[ -e "$_file" ] && cp -af "$_file" "${BACKUP_DIR}/$(basename ${_file})"
|
||||
done
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ RemoveCronTask() {
|
||||
RestoreTorConfig() {
|
||||
[ -e "${FILE_TORRC}.bak" ] && mv -f "${FILE_TORRC}.bak" "$FILE_TORRC"
|
||||
if [ -x "/etc/init.d/tor" ]; then
|
||||
if `/etc/init.d/tor enabled`; then
|
||||
if $(/etc/init.d/tor enabled); then
|
||||
/etc/init.d/tor restart
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#
|
||||
# (с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
# (с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ruantiblock
|
||||
PKG_VERSION:=2.1.4
|
||||
PKG_VERSION:=2.1.5
|
||||
PKG_RELEASE:=1
|
||||
LUCI_TITLE:=LuCI support for ruantiblock
|
||||
LUCI_DEPENDS:=+ruantiblock
|
||||
|
||||
@@ -10,6 +10,7 @@ document.head.append(E('style', {'type': 'text/css'},
|
||||
--app-log-dark-font-color: #2e2e2e;
|
||||
--app-log-light-font-color: #fff;
|
||||
--app-log-debug-font-color: #737373;
|
||||
--app-log-raw-font-color: #737373;
|
||||
--app-log-emerg-color: #a93734;
|
||||
--app-log-alert: #ff7968;
|
||||
--app-log-crit: #fcc3bf;
|
||||
@@ -18,12 +19,14 @@ document.head.append(E('style', {'type': 'text/css'},
|
||||
--app-log-notice: #e3ffec;
|
||||
--app-log-info: rgba(0,0,0,0);
|
||||
--app-log-debug: #ebf6ff;
|
||||
--app-log-raw: #eee;
|
||||
--app-log-entries-count-border: #ccc;
|
||||
}
|
||||
:root[data-darkmode="true"] {
|
||||
--app-log-dark-font-color: #fff;
|
||||
--app-log-light-font-color: #fff;
|
||||
--app-log-debug-font-color: #e7e7e7;
|
||||
--app-log-raw-font-color: #aaa;
|
||||
--app-log-emerg-color: #960909;
|
||||
--app-log-alert: #eb5050;
|
||||
--app-log-crit: #dc7f79;
|
||||
@@ -32,6 +35,7 @@ document.head.append(E('style', {'type': 'text/css'},
|
||||
--app-log-notice: #007627;
|
||||
--app-log-info: rgba(0,0,0,0);
|
||||
--app-log-debug: #5986b1;
|
||||
--app-log-raw: #353535;
|
||||
--app-log-entries-count-border: #555;
|
||||
}
|
||||
#logWrapper {
|
||||
@@ -114,6 +118,16 @@ log-emerg td {
|
||||
.log-debug td {
|
||||
color: var(--app-log-debug-font-color) !important;
|
||||
}
|
||||
.log-raw {
|
||||
background-color: var(--app-log-raw) !important;
|
||||
color: var(--app-log-raw-font-color) !important;
|
||||
}
|
||||
.log-raw .td {
|
||||
color: var(--app-log-raw-font-color) !important;
|
||||
}
|
||||
.log-raw td {
|
||||
color: var(--app-log-raw-font-color) !important;
|
||||
}
|
||||
.log-highlight-item {
|
||||
background-color: #ffef00;
|
||||
color: #2e2e2e;
|
||||
@@ -168,25 +182,32 @@ return baseclass.extend({
|
||||
*
|
||||
* @property {string} viewName
|
||||
*/
|
||||
viewName : null,
|
||||
viewName : null,
|
||||
|
||||
/**
|
||||
* Page title.
|
||||
*
|
||||
* @property {string} title
|
||||
*/
|
||||
title : null,
|
||||
title : null,
|
||||
|
||||
/**
|
||||
* Enable auto refresh log.
|
||||
*
|
||||
* @property {bool} autoRefresh
|
||||
* @property {bool} enableAutoRefresh
|
||||
*/
|
||||
autoRefresh : false,
|
||||
enableAutoRefresh : false,
|
||||
|
||||
pollInterval : L.env.pollinterval,
|
||||
/**
|
||||
* Enable timestamp conversion.
|
||||
*
|
||||
* @property {bool} enableConvertTimestamp
|
||||
*/
|
||||
enableConvertTimestamp: false,
|
||||
|
||||
logFacilities : {
|
||||
pollInterval : L.env.pollinterval,
|
||||
|
||||
logFacilities : {
|
||||
'kern' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'kern')),
|
||||
'user' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'user')),
|
||||
'mail' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'mail')),
|
||||
@@ -211,7 +232,7 @@ return baseclass.extend({
|
||||
'local7' : E('span', { 'class': 'zonebadge log-facility-dropdown-item' }, E('strong', 'local7')),
|
||||
},
|
||||
|
||||
logLevels : {
|
||||
logLevels : {
|
||||
'emerg' : E('span', { 'class': 'zonebadge log-emerg' }, E('strong', 'Emergency')),
|
||||
'alert' : E('span', { 'class': 'zonebadge log-alert' }, E('strong', 'Alert')),
|
||||
'crit' : E('span', { 'class': 'zonebadge log-crit' }, E('strong', 'Critical')),
|
||||
@@ -246,13 +267,15 @@ return baseclass.extend({
|
||||
|
||||
autoRefreshValue : true,
|
||||
|
||||
isAutorefresh : true,
|
||||
autorefreshOn : true,
|
||||
|
||||
isHosts : false,
|
||||
logTimestampFlag : false,
|
||||
|
||||
isFacilities : false,
|
||||
logHostsFlag : false,
|
||||
|
||||
isLevels : false,
|
||||
logFacilitiesFlag : false,
|
||||
|
||||
logLevelsFlag : false,
|
||||
|
||||
logHosts : {},
|
||||
|
||||
@@ -266,7 +289,13 @@ return baseclass.extend({
|
||||
|
||||
totalLogLines : 0,
|
||||
|
||||
lastHash : null,
|
||||
logCols : [ '#', null, null, null, null, _('Message') ],
|
||||
|
||||
convertTimestampValue: false,
|
||||
|
||||
convertTimestampOn : false,
|
||||
|
||||
lastHash : null,
|
||||
|
||||
actionButtons : [],
|
||||
|
||||
@@ -283,6 +312,68 @@ return baseclass.extend({
|
||||
return (/^[0-9]+$/.test(value)) ? value : 0
|
||||
},
|
||||
|
||||
makeLogConvertTimestampSection() {
|
||||
if(!this.enableConvertTimestamp) {
|
||||
return '';
|
||||
};
|
||||
return E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', {
|
||||
'class': 'cbi-value-title',
|
||||
'for' : 'convertTimestamp',
|
||||
}, _('Date')),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('div', { 'class': 'cbi-checkbox' }, [
|
||||
this.convertTimestamp,
|
||||
E('label', {}),
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value-description' },
|
||||
_('Convert timestamps to a human readable date')
|
||||
),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
|
||||
makeLogTimeFilterSection() {
|
||||
return E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', {
|
||||
'class': 'cbi-value-title',
|
||||
'for' : 'timeFilter',
|
||||
}, _('Timestamp filter')),
|
||||
E('div', { 'class': 'cbi-value-field' },
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
this.timeFilter,
|
||||
E('button', {
|
||||
'class': 'cbi-button btn',
|
||||
'click': L.bind(ev => {
|
||||
ev.target.blur();
|
||||
ev.preventDefault();
|
||||
this.timeFilter.value = null;
|
||||
this.timeFilter.focus();
|
||||
}, this),
|
||||
}, '⌫'),
|
||||
])
|
||||
),
|
||||
]);
|
||||
},
|
||||
|
||||
makeLogtimeFilterReSection() {
|
||||
return E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', {
|
||||
'class': 'cbi-value-title',
|
||||
'for' : 'timeFilterRe',
|
||||
}, _('Filter is regexp')),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('div', { 'class': 'cbi-checkbox' }, [
|
||||
this.timeFilterRe,
|
||||
E('label', {}),
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value-description' },
|
||||
_('Apply timestamp filter as regular expression')
|
||||
),
|
||||
]),
|
||||
]);
|
||||
},
|
||||
|
||||
makeLogHostsDropdownItem(host) {
|
||||
return E(
|
||||
'span',
|
||||
@@ -385,23 +476,28 @@ return baseclass.extend({
|
||||
},
|
||||
|
||||
setFilterSettings() {
|
||||
this.tailValue = this.checkZeroValue(this.tailInput.value);
|
||||
this.timeFilterValue = this.timeFilter.value;
|
||||
this.timeFilterReValue = this.timeFilterRe.checked;
|
||||
if(this.isHosts) {
|
||||
this.tailValue = this.checkZeroValue(this.tailInput.value);
|
||||
if(this.logTimestampFlag) {
|
||||
if(this.enableConvertTimestamp) {
|
||||
this.convertTimestampValue = this.convertTimestamp.checked;
|
||||
};
|
||||
this.timeFilterValue = this.timeFilter.value;
|
||||
this.timeFilterReValue = this.timeFilterRe.checked;
|
||||
};
|
||||
if(this.logHostsFlag) {
|
||||
this.hostFilterValue = this.logHostsDropdown.getValue();
|
||||
};
|
||||
if(this.isFacilities) {
|
||||
if(this.logFacilitiesFlag) {
|
||||
this.facilityFilterValue = this.logFacilitiesDropdown.getValue();
|
||||
};
|
||||
if(this.isLevels) {
|
||||
if(this.logLevelsFlag) {
|
||||
this.levelFilterValue = this.logLevelsDropdown.getValue();
|
||||
};
|
||||
this.msgFilterValue = this.msgFilter.value;
|
||||
this.msgFilterReValue = this.msgFilterRe.checked;
|
||||
this.logSortingValue = this.logSorting.value;
|
||||
this.autoRefreshValue = this.autoRefresh.checked;
|
||||
if(this.isAutorefresh) {
|
||||
this.msgFilterValue = this.msgFilter.value;
|
||||
this.msgFilterReValue = this.msgFilterRe.checked;
|
||||
this.logSortingValue = this.logSorting.value;
|
||||
this.autoRefreshValue = this.autoRefresh.checked;
|
||||
if(this.autorefreshOn) {
|
||||
if(this.autoRefreshValue) {
|
||||
poll.add(this.pollFuncWrapper, this.pollInterval);
|
||||
this.refreshBtn.style.visibility = 'hidden';
|
||||
@@ -413,16 +509,21 @@ return baseclass.extend({
|
||||
},
|
||||
|
||||
resetFormValues() {
|
||||
this.tailInput.value = this.tailValue;
|
||||
this.timeFilter.value = this.timeFilterValue;
|
||||
this.timeFilterRe.checked = this.timeFilterReValue;
|
||||
if(this.isHosts) {
|
||||
this.tailInput.value = this.tailValue;
|
||||
if(this.logTimestampFlag) {
|
||||
if(this.enableConvertTimestamp) {
|
||||
this.convertTimestamp.checked = this.convertTimestampValue;
|
||||
};
|
||||
this.timeFilter.value = this.timeFilterValue;
|
||||
this.timeFilterRe.checked = this.timeFilterReValue;
|
||||
};
|
||||
if(this.logHostsFlag) {
|
||||
this.logHostsDropdown.setValue(this.hostFilterValue);
|
||||
};
|
||||
if(this.isFacilities) {
|
||||
if(this.logFacilitiesFlag) {
|
||||
this.logFacilitiesDropdown.setValue(this.facilityFilterValue);
|
||||
};
|
||||
if(this.isLevels) {
|
||||
if(this.logLevelsFlag) {
|
||||
this.logLevelsDropdown.setValue(this.levelFilterValue);
|
||||
};
|
||||
this.msgFilter.value = this.msgFilterValue;
|
||||
@@ -508,7 +609,7 @@ return baseclass.extend({
|
||||
regExp.lastIndex = 0;
|
||||
});
|
||||
} catch(err) {
|
||||
if(err.name === 'SyntaxError') {
|
||||
if(err.name == 'SyntaxError') {
|
||||
ui.addNotification(null,
|
||||
E('p', {}, _('Invalid regular expression') + ': ' + err.message));
|
||||
return entriesArray;
|
||||
@@ -533,7 +634,7 @@ return baseclass.extend({
|
||||
let logHostsKeys = Object.keys(this.logHosts);
|
||||
if(logHostsKeys.length > 0 && this.logHostsDropdown) {
|
||||
this.logHostsDropdown.addChoices(logHostsKeys, this.logHosts);
|
||||
if(this.hostFilterValue.length === 0 || logHostsKeys.length === this.hostFilterValue.length) {
|
||||
if(this.hostFilterValue.length == 0) {
|
||||
return entriesArray;
|
||||
};
|
||||
return entriesArray.filter(e => this.hostFilterValue.includes(e[2]));
|
||||
@@ -544,7 +645,7 @@ return baseclass.extend({
|
||||
setFacilityFilter(entriesArray) {
|
||||
let logFacilitiesKeys = Object.keys(this.logFacilities);
|
||||
if(logFacilitiesKeys.length > 0 && this.logFacilitiesDropdown) {
|
||||
if(this.facilityFilterValue.length === 0 || logFacilitiesKeys.length === this.facilityFilterValue.length) {
|
||||
if(this.facilityFilterValue.length == 0) {
|
||||
return entriesArray;
|
||||
};
|
||||
return entriesArray.filter(e => this.facilityFilterValue.includes(e[3]));
|
||||
@@ -555,7 +656,7 @@ return baseclass.extend({
|
||||
setLevelFilter(entriesArray) {
|
||||
let logLevelsKeys = Object.keys(this.logLevels);
|
||||
if(logLevelsKeys.length > 0 && this.logLevelsDropdown) {
|
||||
if(this.levelFilterValue.length === 0 || logLevelsKeys.length === this.levelFilterValue.length) {
|
||||
if(this.levelFilterValue.length == 0) {
|
||||
return entriesArray;
|
||||
};
|
||||
return entriesArray.filter(e => this.levelFilterValue.includes(e[4]));
|
||||
@@ -630,7 +731,13 @@ return baseclass.extend({
|
||||
if(logSortingLocal) {
|
||||
this.logSortingValue = logSortingLocal;
|
||||
};
|
||||
if(this.isAutorefresh) {
|
||||
if(this.enableConvertTimestamp) {
|
||||
let convertTimestampLocal = localStorage.getItem(`luci-app-${this.viewName}-convertTimestampValue`);
|
||||
if(convertTimestampLocal) {
|
||||
this.convertTimestampValue = Boolean(Number(convertTimestampLocal));
|
||||
};
|
||||
};
|
||||
if(this.enableAutoRefresh) {
|
||||
let autoRefreshLocal = localStorage.getItem(`luci-app-${this.viewName}-autoRefreshValue`);
|
||||
if(autoRefreshLocal) {
|
||||
this.autoRefreshValue = Boolean(Number(autoRefreshLocal));
|
||||
@@ -638,7 +745,7 @@ return baseclass.extend({
|
||||
};
|
||||
},
|
||||
|
||||
saveSettingsToLocalStorage(tailValue, logSortingValue, autoRefreshValue) {
|
||||
saveSettingsToLocalStorage(tailValue, logSortingValue, autoRefreshValue, convertTimestampValue) {
|
||||
tailValue = this.checkZeroValue(tailValue);
|
||||
if(this.tailValue != tailValue) {
|
||||
localStorage.setItem(
|
||||
@@ -648,7 +755,13 @@ return baseclass.extend({
|
||||
localStorage.setItem(
|
||||
`luci-app-${this.viewName}-logSortingValue`, logSortingValue);
|
||||
};
|
||||
if(this.isAutorefresh) {
|
||||
if(this.convertTimestampOn) {
|
||||
if(this.convertTimestampValue != convertTimestampValue) {
|
||||
localStorage.setItem(
|
||||
`luci-app-${this.viewName}-convertTimestampValue`, String(Number(convertTimestampValue)));
|
||||
};
|
||||
};
|
||||
if(this.autorefreshOn) {
|
||||
if(this.autoRefreshValue != autoRefreshValue) {
|
||||
localStorage.setItem(
|
||||
`luci-app-${this.viewName}-autoRefreshValue`, String(Number(autoRefreshValue)));
|
||||
@@ -681,13 +794,23 @@ return baseclass.extend({
|
||||
)
|
||||
);
|
||||
if(logdata && logdata !== '') {
|
||||
if(this.isFacilities && !this.logFacilitiesDropdown) {
|
||||
if(this.enableConvertTimestamp && !this.logConvertTimestampElem) {
|
||||
this.logConvertTimestampElem = this.makeLogConvertTimestampSection();
|
||||
};
|
||||
if(this.logTimestampFlag && !this.logTimeFilterElem) {
|
||||
this.logTimeFilterElem = this.makeLogTimeFilterSection();
|
||||
};
|
||||
if(this.logTimestampFlag && !this.logtimeFilterReElem) {
|
||||
this.logtimeFilterReElem = this.makeLogtimeFilterReSection();
|
||||
};
|
||||
|
||||
if(this.logFacilitiesFlag && !this.logFacilitiesDropdown) {
|
||||
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
|
||||
};
|
||||
if(this.isLevels && !this.logLevelsDropdown) {
|
||||
if(this.logLevelsFlag && !this.logLevelsDropdown) {
|
||||
this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection();
|
||||
};
|
||||
if(this.isHosts && !this.logHostsDropdown) {
|
||||
if(this.logHostsFlag && !this.logHostsDropdown) {
|
||||
this.logHostsDropdownElem = this.makeLogHostsDropdownSection();
|
||||
};
|
||||
};
|
||||
@@ -730,41 +853,9 @@ return baseclass.extend({
|
||||
])
|
||||
),
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', {
|
||||
'class': 'cbi-value-title',
|
||||
'for' : 'timeFilter',
|
||||
}, _('Timestamp filter')),
|
||||
E('div', { 'class': 'cbi-value-field' },
|
||||
E('span', { 'class': 'control-group' }, [
|
||||
this.timeFilter,
|
||||
E('button', {
|
||||
'class': 'cbi-button btn',
|
||||
'click': L.bind(ev => {
|
||||
ev.target.blur();
|
||||
ev.preventDefault();
|
||||
this.timeFilter.value = null;
|
||||
this.timeFilter.focus();
|
||||
}, this),
|
||||
}, '⌫'),
|
||||
])
|
||||
),
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', {
|
||||
'class': 'cbi-value-title',
|
||||
'for' : 'timeFilterRe',
|
||||
}, _('Filter is regexp')),
|
||||
E('div', { 'class': 'cbi-value-field' }, [
|
||||
E('div', { 'class': 'cbi-checkbox' }, [
|
||||
this.timeFilterRe,
|
||||
E('label', {}),
|
||||
]),
|
||||
E('div', { 'class': 'cbi-value-description' },
|
||||
_('Apply timestamp filter as regular expression')
|
||||
),
|
||||
]),
|
||||
]),
|
||||
this.logConvertTimestampElem,
|
||||
this.logTimeFilterElem,
|
||||
this.logtimeFilterReElem,
|
||||
this.logHostsDropdownElem,
|
||||
this.logFacilitiesDropdownElem,
|
||||
this.logLevelsDropdownElem,
|
||||
@@ -810,7 +901,7 @@ return baseclass.extend({
|
||||
}, _('Sorting entries')),
|
||||
E('div', { 'class': 'cbi-value-field' }, this.logSorting),
|
||||
]),
|
||||
((this.isAutorefresh) ?
|
||||
((this.autorefreshOn) ?
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('label', {
|
||||
'class': 'cbi-value-title',
|
||||
@@ -877,6 +968,25 @@ return baseclass.extend({
|
||||
throw new Error('getLogHash must be overridden by a subclass');
|
||||
},
|
||||
|
||||
/**
|
||||
* Converts the timestamp format.
|
||||
* Abstract method, must be overridden by a subclass!
|
||||
*
|
||||
* To completely disable the convert timrstamp option, views extending
|
||||
* this base class should overwrite the `convertTimestampFunc` function
|
||||
* with `null`.
|
||||
*
|
||||
* @instance
|
||||
* @abstract
|
||||
*
|
||||
* @param {string} t
|
||||
* @returns {String}
|
||||
* Returns the converted timestamp string.
|
||||
*/
|
||||
convertTimestampFunc(t) {
|
||||
throw new Error('convertTimestampFunc must be overridden by a subclass');
|
||||
},
|
||||
|
||||
async pollFunc() {
|
||||
await this.getLogHash().then(async hash => {
|
||||
if(this.lastHash !== hash) {
|
||||
@@ -895,7 +1005,8 @@ return baseclass.extend({
|
||||
};
|
||||
};
|
||||
this.saveSettingsToLocalStorage(
|
||||
this.tailInput.value, this.logSorting.value, this.autoRefresh.checked);
|
||||
this.tailInput.value, this.logSorting.value,
|
||||
this.autoRefresh.checked, this.convertTimestamp.checked);
|
||||
this.setFilterSettings();
|
||||
this.fastTailValue = Number(this.tailValue);
|
||||
return this.reloadLog(Number(this.tailValue), true);
|
||||
@@ -911,10 +1022,13 @@ return baseclass.extend({
|
||||
|
||||
load() {
|
||||
this.restoreSettingsFromLocalStorage();
|
||||
if(!this.autoRefresh || typeof(this.getLogHash) != 'function') {
|
||||
this.isAutorefresh = false;
|
||||
if(!this.enableAutoRefresh || typeof(this.getLogHash) != 'function') {
|
||||
this.autorefreshOn = false;
|
||||
this.autoRefreshValue = false;
|
||||
};
|
||||
if(this.enableConvertTimestamp && typeof(this.convertTimestampFunc) == 'function') {
|
||||
this.convertTimestampOn = true;
|
||||
};
|
||||
return this.getLogData(this.tailValue);
|
||||
},
|
||||
|
||||
@@ -939,18 +1053,13 @@ return baseclass.extend({
|
||||
this.tailInput.value = this.tailValue;
|
||||
ui.addValidator(this.tailInput, 'uinteger', true);
|
||||
|
||||
this.logHostsDropdownElem = '';
|
||||
this.logFacilitiesDropdownElem = '';
|
||||
this.logLevelsDropdownElem = '';
|
||||
if(this.isLevels) {
|
||||
this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection();
|
||||
};
|
||||
if(this.isFacilities) {
|
||||
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
|
||||
};
|
||||
if(this.isHosts) {
|
||||
this.logHostsDropdownElem = this.makeLogHostsDropdownSection();
|
||||
};
|
||||
this.convertTimestamp = E('input', {
|
||||
'id' : 'convertTimestamp',
|
||||
'name' : 'convertTimestamp',
|
||||
'type' : 'checkbox',
|
||||
'form' : 'logFilterForm',
|
||||
});
|
||||
this.convertTimestamp.checked = this.convertTimestampValue;
|
||||
|
||||
this.timeFilter = E('input', {
|
||||
'id' : 'timeFilter',
|
||||
@@ -971,6 +1080,28 @@ return baseclass.extend({
|
||||
|
||||
this.setRegexpValidator(this.timeFilter, this.timeFilterRe);
|
||||
|
||||
this.logConvertTimestampElem = '';
|
||||
this.logTimeFilterElem = '';
|
||||
this.logtimeFilterReElem = '';
|
||||
this.logHostsDropdownElem = '';
|
||||
this.logFacilitiesDropdownElem = '';
|
||||
this.logLevelsDropdownElem = '';
|
||||
|
||||
if(this.logTimestampFlag) {
|
||||
this.logConvertTimestampElem = this.makeLogConvertTimestampSection();
|
||||
this.logTimeFilterElem = this.makeLogTimeFilterSection();
|
||||
this.logtimeFilterReElem = this.makeLogtimeFilterReSection();
|
||||
};
|
||||
if(this.logLevelsFlag) {
|
||||
this.logLevelsDropdownElem = this.makeLogLevelsDropdownSection();
|
||||
};
|
||||
if(this.logFacilitiesFlag) {
|
||||
this.logFacilitiesDropdownElem = this.makeLogFacilitiesDropdownSection();
|
||||
};
|
||||
if(this.logHostsFlag) {
|
||||
this.logHostsDropdownElem = this.makeLogHostsDropdownSection();
|
||||
};
|
||||
|
||||
this.msgFilter = E('input', {
|
||||
'id' : 'msgFilter',
|
||||
'name' : 'msgFilter',
|
||||
@@ -1123,7 +1254,7 @@ return baseclass.extend({
|
||||
])
|
||||
);
|
||||
|
||||
if(this.isAutorefresh && this.autoRefreshValue) {
|
||||
if(this.autorefreshOn && this.autoRefreshValue) {
|
||||
poll.add(this.pollFuncWrapper, this.pollInterval);
|
||||
};
|
||||
|
||||
|
||||
+63
-35
@@ -1,17 +1,18 @@
|
||||
'use strict';
|
||||
'require baseclass';
|
||||
'require fs';
|
||||
'require ui';
|
||||
'require view.ruantiblock.log-widget as widget';
|
||||
|
||||
return baseclass.extend({
|
||||
view: widget.view.extend({
|
||||
enableAutoRefresh: true,
|
||||
|
||||
/**
|
||||
* Pattern for picking application-specific entries from the log.
|
||||
*
|
||||
* @property {string} appPattern
|
||||
*/
|
||||
appPattern : '^',
|
||||
appPattern : '^',
|
||||
|
||||
/**
|
||||
* Enable "tail" option for the logread (logread -l).
|
||||
@@ -19,19 +20,19 @@ return baseclass.extend({
|
||||
*
|
||||
* @property {bool} loggerTail
|
||||
*/
|
||||
loggerTail : false,
|
||||
loggerTail : false,
|
||||
|
||||
logdRegexp : new RegExp(/^([^\s]{3}\s+[^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2}\s+\d{4})\s+([a-z0-9]+)\.([a-z]+)\s+(.*)$/),
|
||||
logdRegexp : new RegExp(/^([^\s]{3}\s+[^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2}\s+\d{4})\s+([a-z0-9]+)\.([a-z]+)\s+(.*)$/),
|
||||
|
||||
syslog_ngRegexp: new RegExp(/^([^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2})\s+([^\s]+)\s+(.*)$/),
|
||||
syslog_ngRegexp : new RegExp(/^([^\s]{3}\s+\d{1,2}\s+\d{1,2}:\d{1,2}:\d{1,2})\s+([^\s]+)\s+(.*)$/),
|
||||
|
||||
entryRegexp : null,
|
||||
entryRegexp : null,
|
||||
|
||||
isLoggerChecked: false,
|
||||
loggerChecked : false,
|
||||
|
||||
entriesHandler : null,
|
||||
entriesHandler : null,
|
||||
|
||||
logger : null,
|
||||
logger : null,
|
||||
|
||||
getLogHash() {
|
||||
return this.getLogData(1, true).then(data => {
|
||||
@@ -66,6 +67,18 @@ return baseclass.extend({
|
||||
];
|
||||
},
|
||||
|
||||
// unsupported log handler
|
||||
unsupportedLogHandler(line, lineNum) {
|
||||
return [
|
||||
lineNum, // # (Number)
|
||||
null, // Timestamp (String)
|
||||
null, // Host (String)
|
||||
null, // Facility (String)
|
||||
null, // Level (String)
|
||||
this.htmlEntities(line) || ' ', // Message (String)
|
||||
];
|
||||
},
|
||||
|
||||
checkLogread() {
|
||||
return Promise.all([
|
||||
L.resolveDefault(fs.stat('/sbin/logread'), null),
|
||||
@@ -102,8 +115,7 @@ return baseclass.extend({
|
||||
return [];
|
||||
};
|
||||
|
||||
let unsupportedLog = false;
|
||||
let strings = logdata.trim().split(/\n/);
|
||||
let strings = logdata.trim().split(/\n/);
|
||||
|
||||
if(!this.loggerTail && tail && tail > 0 && strings) {
|
||||
strings = strings.slice(-tail);
|
||||
@@ -111,45 +123,61 @@ return baseclass.extend({
|
||||
|
||||
this.totalLogLines = strings.length;
|
||||
|
||||
let entriesArray = strings.map((e, i) => {
|
||||
if(!this.isLoggerChecked) {
|
||||
let entriesArray = strings.map((e, i) => {
|
||||
if(!this.loggerChecked) {
|
||||
if(this.logdRegexp.test(e)) {
|
||||
this.entryRegexp = this.logdRegexp;
|
||||
this.isFacilities = true;
|
||||
this.isLevels = true;
|
||||
this.logHosts = {};
|
||||
this.entriesHandler = this.logdHandler;
|
||||
this.entryRegexp = this.logdRegexp;
|
||||
this.logTimestampFlag = true;
|
||||
this.logFacilitiesFlag = true;
|
||||
this.logLevelsFlag = true;
|
||||
this.logHostsFlag = false;
|
||||
this.logHosts = {};
|
||||
this.entriesHandler = this.logdHandler;
|
||||
this.logCols = [
|
||||
'#',
|
||||
_('Timestamp'),
|
||||
null,
|
||||
_('Facility'),
|
||||
_('Level'),
|
||||
_('Message'),
|
||||
];
|
||||
this.loggerChecked = true;
|
||||
}
|
||||
else if(this.syslog_ngRegexp.test(e)) {
|
||||
this.entryRegexp = this.syslog_ngRegexp;
|
||||
this.isHosts = true;
|
||||
this.logFacilities = {};
|
||||
this.logLevels = {};
|
||||
this.entriesHandler = this.syslog_ngHandler;
|
||||
this.entryRegexp = this.syslog_ngRegexp;
|
||||
this.logTimestampFlag = true;
|
||||
this.logFacilitiesFlag = false;
|
||||
this.logLevelsFlag = false;
|
||||
this.logHostsFlag = true;
|
||||
this.logFacilities = {};
|
||||
this.logLevels = {};
|
||||
this.entriesHandler = this.syslog_ngHandler;
|
||||
this.logCols = [
|
||||
'#',
|
||||
_('Timestamp'),
|
||||
_('Host'),
|
||||
null,
|
||||
null,
|
||||
_('Message'),
|
||||
];
|
||||
this.loggerChecked = true;
|
||||
} else {
|
||||
unsupportedLog = true;
|
||||
return;
|
||||
return this.unsupportedLogHandler(e, i + 1);
|
||||
};
|
||||
this.isLoggerChecked = true;
|
||||
};
|
||||
|
||||
let strArray = e.match(this.entryRegexp);
|
||||
if(strArray) {
|
||||
return this.entriesHandler(strArray, i + 1);
|
||||
} else {
|
||||
unsupportedLog = true;
|
||||
return;
|
||||
return this.unsupportedLogHandler(e, i + 1);
|
||||
};
|
||||
});
|
||||
|
||||
if(unsupportedLog) {
|
||||
throw new Error(_('Unable to load log data:') + ' ' + _('Unsupported log format'));
|
||||
} else {
|
||||
if(this.logSortingValue === 'desc') {
|
||||
entriesArray.reverse();
|
||||
};
|
||||
return entriesArray;
|
||||
if(this.logSortingValue == 'desc') {
|
||||
entriesArray.reverse();
|
||||
};
|
||||
return entriesArray;
|
||||
},
|
||||
}),
|
||||
});
|
||||
@@ -46,38 +46,50 @@ return baseclass.extend({
|
||||
if(e[4] in this.logLevels) {
|
||||
this.logLevelsStat[e[4]] = this.logLevelsStat[e[4]] + 1;
|
||||
};
|
||||
lines.push(
|
||||
`<tr class="tr log-${e[4] || 'empty'}"><td class="td left log-entry-text-nowrap" data-title="#">${e[0]}</td>` +
|
||||
((e[1]) ? `<td class="td left log-entry-time-cell" data-title="${_('Timestamp')}">${e[1]}</td>` : '') +
|
||||
((e[2]) ? `<td class="td left log-entry-host-cell" data-title="${_('Host')}">${e[2]}</td>` : '') +
|
||||
((e[3]) ? `<td class="td left log-entry-text-nowrap" data-title="${_('Facility')}">${e[3]}</td>` : '') +
|
||||
((e[4]) ? `<td class="td left log-entry-text-nowrap" data-title="${_('Level')}">${e[4]}</td>` : '') +
|
||||
((e[5]) ? `<td class="td left log-entry-message-cell" data-title="${_('Message')}">${e[5]}</td>` : '') +
|
||||
'</tr>'
|
||||
);
|
||||
|
||||
let line = [ `<tr class="tr log-${(e[1]) ? e[4] || 'empty' : (this.entriesHandler) ? 'raw' : 'empty'}">` ];
|
||||
this.logCols.forEach((c, i) => {
|
||||
if(c) {
|
||||
let cellClass = '';
|
||||
switch(i) {
|
||||
case 0:
|
||||
case 3:
|
||||
case 4:
|
||||
cellClass = 'log-entry-text-nowrap';
|
||||
break;
|
||||
case 1:
|
||||
cellClass = 'log-entry-time-cell';
|
||||
break;
|
||||
case 2:
|
||||
cellClass = 'log-entry-host-cell';
|
||||
break;
|
||||
case 5:
|
||||
cellClass = 'log-entry-message-cell';
|
||||
break;
|
||||
};
|
||||
line.push(`<td class="td left ${cellClass}" data-title="${c}">${e[i] || ' '}</td>`);
|
||||
};
|
||||
});
|
||||
line.push('</tr>');
|
||||
lines.push(line.join(''));
|
||||
});
|
||||
lines = lines.join('');
|
||||
logTable.append(
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, '#'),
|
||||
(logdataArray[0][1]) ?
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, _('Timestamp')) : '',
|
||||
(logdataArray[0][2]) ?
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, _('Host')) : '',
|
||||
(logdataArray[0][3]) ?
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, _('Facility')) : '',
|
||||
(logdataArray[0][4]) ?
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, _('Level')) : '',
|
||||
(logdataArray[0][5]) ?
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, _('Message')) : '',
|
||||
])
|
||||
);
|
||||
|
||||
let logTableHeader = E('tr', { 'class': 'tr table-titles' });
|
||||
this.logCols.forEach(e => {
|
||||
if(e) {
|
||||
logTableHeader.append(
|
||||
E('th', { 'class': 'th left log-entry-text-nowrap' }, e)
|
||||
);
|
||||
};
|
||||
});
|
||||
logTable.append(logTableHeader);
|
||||
};
|
||||
|
||||
try {
|
||||
logTable.insertAdjacentHTML('beforeend', lines);
|
||||
} catch(err) {
|
||||
if(err.name === 'SyntaxError') {
|
||||
if(err.name == 'SyntaxError') {
|
||||
ui.addNotification(null,
|
||||
E('p', {}, _('HTML/XML error') + ': ' + err.message), 'error');
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
'use strict';
|
||||
'require view.ruantiblock.log-abstract as abc';
|
||||
'require view.ruantiblock.log-system as abc';
|
||||
'require view.ruantiblock.tools as tools';
|
||||
|
||||
return abc.view.extend({
|
||||
viewName : 'ruantiblock',
|
||||
title : _('Ruantiblock') + ' - ' + _('Log'),
|
||||
autoRefresh: false,
|
||||
appPattern : tools.appName + ':',
|
||||
viewName : 'ruantiblock',
|
||||
title : _('Ruantiblock') + ' - ' + _('Log'),
|
||||
enableAutoRefresh: false,
|
||||
appPattern : tools.appName + ':',
|
||||
});
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#
|
||||
# (с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
# (с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ruantiblock-mod-lua
|
||||
PKG_VERSION:=2.1.4
|
||||
PKG_VERSION:=2.1.5
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
--[[
|
||||
(с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
(с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
|
||||
lua == 5.1
|
||||
--]]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#
|
||||
# (с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
# (с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ruantiblock-mod-py
|
||||
PKG_VERSION:=2.1.4
|
||||
PKG_VERSION:=2.1.5
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
(с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
(с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
|
||||
Python >= 3.6
|
||||
"""
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#
|
||||
# (с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
# (с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ruantiblock
|
||||
PKG_VERSION:=2.1.4
|
||||
PKG_RELEASE:=3
|
||||
PKG_VERSION:=2.1.5
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/ruantiblock_openwrt>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@@ -12,10 +12,10 @@ if [ "$ACTION" = "ifup" ]; then
|
||||
DEBUG=0
|
||||
IF_VPN_CURRENT=""
|
||||
|
||||
ruab_route_status=`$RUAB_CMD raw-status`
|
||||
ruab_route_status=$($RUAB_CMD raw-status)
|
||||
[ $ruab_route_status -eq 1 -o $ruab_route_status -eq 2 ] && exit 0
|
||||
|
||||
UCI_CMD=`which uci`
|
||||
UCI_CMD="$(which uci)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! UCI doesn't exists" >&2
|
||||
exit 1
|
||||
@@ -23,19 +23,19 @@ if [ "$ACTION" = "ifup" ]; then
|
||||
|
||||
[ -f "$CONFIG_FILE" ] && . "$CONFIG_FILE"
|
||||
|
||||
VPN_ROUTE_CHECK=`$UCI_CMD get ruantiblock.config.vpn_route_check`
|
||||
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`
|
||||
PROXY_MODE=$($UCI_CMD get ruantiblock.config.proxy_mode)
|
||||
if [ "$PROXY_MODE" = "2" ]; then
|
||||
IF_VPN_CURRENT=`$UCI_CMD get ruantiblock.config.if_vpn`
|
||||
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`
|
||||
for inst in $(GetUserInstances 2)
|
||||
do
|
||||
IncludeUserInstanceVars "$inst"
|
||||
if [ "$DEVICE" = "$U_IF_VPN" ]; then
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
########################################################################
|
||||
#
|
||||
# Ruantiblock
|
||||
# (с) 2024 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
# (с) 2025 gSpot (https://github.com/gSpotx2f/ruantiblock_openwrt)
|
||||
#
|
||||
########################################################################
|
||||
|
||||
export NAME="ruantiblock"
|
||||
export APP_EXEC="$0"
|
||||
export APP_NAME="`basename $0`"
|
||||
export APP_NAME="$(basename $0)"
|
||||
export LANG="en_US.UTF-8"
|
||||
export LANGUAGE="en"
|
||||
|
||||
@@ -182,6 +182,18 @@ export BLLIST_ALT_NSLOOKUP=0
|
||||
### Альтернативный DNS-сервер
|
||||
export BLLIST_ALT_DNS_ADDR="8.8.8.8"
|
||||
|
||||
########################## Instances defaults ##########################
|
||||
|
||||
INSTANCES_DEF_PROXY_MODE=$PROXY_MODE
|
||||
INSTANCES_DEF_TOR_TRANS_PORT=$TOR_TRANS_PORT
|
||||
INSTANCES_DEF_IF_VPN=$IF_VPN
|
||||
INSTANCES_DEF_T_PROXY_TYPE=$T_PROXY_TYPE
|
||||
INSTANCES_DEF_T_PROXY_PORT_TCP=$T_PROXY_PORT_TCP
|
||||
INSTANCES_DEF_T_PROXY_PORT_UDP=$T_PROXY_PORT_UDP
|
||||
INSTANCES_DEF_T_PROXY_ALLOW_UDP=$T_PROXY_ALLOW_UDP
|
||||
INSTANCES_DEF_ENABLE_BLLIST_PROXY=$ENABLE_BLLIST_PROXY
|
||||
INSTANCES_DEF_ENABLE_FPROXY=$ENABLE_FPROXY
|
||||
|
||||
############################ Configuration #############################
|
||||
|
||||
### External config
|
||||
@@ -207,24 +219,24 @@ export DNSMASQ_DATA_FILE="${DNSMASQ_CONFDIR}/02-${NAME}.dnsmasq"
|
||||
|
||||
### Utilities
|
||||
AWK_CMD="awk"
|
||||
NFT_CMD=`which nft`
|
||||
NFT_CMD="$(which nft)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! Nftables doesn't exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
LOGGER_CMD=`which logger`
|
||||
LOGGER_CMD="$(which logger)"
|
||||
if [ $ENABLE_LOGGING = "1" -a $? -ne 0 ]; then
|
||||
echo " Logger doesn't exists" >&2
|
||||
ENABLE_LOGGING=0
|
||||
fi
|
||||
LOGGER_PARAMS="-t ${APP_NAME}"
|
||||
WGET_CMD=`which wget`
|
||||
WGET_CMD="$(which wget)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! Wget doesn't exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
WGET_PARAMS="--no-check-certificate -q -O"
|
||||
NSLOOKUP_CMD=`which nslookup`
|
||||
NSLOOKUP_CMD="$(which nslookup)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! Nslookup doesn't exists" >&2
|
||||
exit 1
|
||||
@@ -261,8 +273,8 @@ export NFTSET_IP_TYPE="ipv4_addr"
|
||||
export NFTSET_DNSMASQ_TYPE="ipv4_addr"
|
||||
export NFTSET_CIDR_PATTERN="set %s {type ${NFTSET_CIDR_TYPE};size ${NFTSET_MAXELEM_CIDR};policy ${NFTSET_POLICY_CIDR};flags interval;auto-merge;"
|
||||
export NFTSET_IP_PATTERN="set %s {type ${NFTSET_IP_TYPE};size ${NFTSET_MAXELEM_IP};policy ${NFTSET_POLICY_IP};flags dynamic;"
|
||||
export NFTSET_CIDR_STRING_MAIN=`printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}"`
|
||||
export NFTSET_IP_STRING_MAIN=`printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}"`
|
||||
export NFTSET_CIDR_STRING_MAIN=$(printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}")
|
||||
export NFTSET_IP_STRING_MAIN=$(printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}")
|
||||
export NFTSET_BYPASS_IP_STRING="set ${NFTSET_BYPASS_IP} {type ${NFTSET_BYPASS_IP_TYPE};size ${NFTSET_MAXELEM_BYPASS_IP};policy ${NFTSET_POLICY_CIDR};flags interval;auto-merge;"
|
||||
export UPDATE_STATUS_FILE="${DATA_DIR}/update_status"
|
||||
export USER_ENTRIES_STATUS_FILE="${DATA_DIR}/user_entries_status"
|
||||
@@ -402,7 +414,7 @@ DownloadNativeBlacklist() {
|
||||
}
|
||||
|
||||
RestartDnsmasq() {
|
||||
eval `echo "$DNSMASQ_RESTART_CMD"`
|
||||
eval $(echo "$DNSMASQ_RESTART_CMD")
|
||||
}
|
||||
|
||||
FlushNftSets() {
|
||||
@@ -443,14 +455,14 @@ FormatNftSetElemsList() {
|
||||
AddBaseNftSets() {
|
||||
local _allowed_hosts _fproxy_private
|
||||
$NFT_CMD add set $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { type "$NFTSET_ALLOWED_HOSTS_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||||
_allowed_hosts=`FormatNftSetElemsList "$ALLOWED_HOSTS_LIST"`
|
||||
_allowed_hosts=$(FormatNftSetElemsList "$ALLOWED_HOSTS_LIST")
|
||||
if [ -n "$_allowed_hosts" ]; then
|
||||
$NFT_CMD add element $NFT_TABLE "$NFTSET_ALLOWED_HOSTS" { "$_allowed_hosts" }
|
||||
fi
|
||||
$NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_IP" { type "$NFTSET_BYPASS_IP_TYPE"\; size $NFTSET_MAXELEM_BYPASS_IP\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||||
$NFT_CMD add set $NFT_TABLE "$NFTSET_BYPASS_FQDN" { type "$NFTSET_BYPASS_FQDN_TYPE"\; size $NFTSET_MAXELEM_BYPASS_FQDN\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
|
||||
$NFT_CMD add set $NFT_TABLE "$NFTSET_FPROXY_PRIVATE" { type "$NFTSET_FPROXY_PRIVATE_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||||
_fproxy_private=`FormatNftSetElemsList "$FPROXY_PRIVATE_NETS"`
|
||||
_fproxy_private=$(FormatNftSetElemsList "$FPROXY_PRIVATE_NETS")
|
||||
if [ -n "$_fproxy_private" ]; then
|
||||
$NFT_CMD add element $NFT_TABLE "$NFTSET_FPROXY_PRIVATE" { "$_fproxy_private" }
|
||||
fi
|
||||
@@ -468,7 +480,7 @@ MakeInstanceNftSets() {
|
||||
$NFT_CMD add set $NFT_TABLE "${NFTSET_DNSMASQ}${_name}" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
|
||||
$NFT_CMD add set $NFT_TABLE "${NFTSET_ONION}${_name}" { type "$NFTSET_DNSMASQ_TYPE"\; size $NFTSET_MAXELEM_DNSMASQ\; policy "$NFTSET_POLICY_DNSMASQ"\; flags dynamic,timeout\; timeout "$NFTSET_DNSMASQ_TIMEOUT"\; }
|
||||
$NFT_CMD add set $NFT_TABLE "${NFTSET_FPROXY}${_name}" { type "$NFTSET_FPROXY_TYPE"\; policy "$NFTSET_POLICY_CIDR"\; flags interval\; auto-merge\; }
|
||||
_fproxy_hosts=`FormatNftSetElemsList "$_fproxy_list"`
|
||||
_fproxy_hosts=$(FormatNftSetElemsList "$_fproxy_list")
|
||||
if [ -n "$_fproxy_hosts" ]; then
|
||||
$NFT_CMD add element $NFT_TABLE "${NFTSET_FPROXY}${_name}" { "$_fproxy_hosts" }
|
||||
fi
|
||||
@@ -494,7 +506,7 @@ UpdateBllistProxySet() {
|
||||
_name=".${_name}"
|
||||
fi
|
||||
FlushNftSets "${NFTSET_BLLIST_PROXY}${_name}"
|
||||
for _host in `echo "$_urls" | $AWK_CMD '
|
||||
for _host in $(echo "$_urls" | $AWK_CMD '
|
||||
BEGIN {
|
||||
RS = " ";
|
||||
}
|
||||
@@ -511,15 +523,15 @@ UpdateBllistProxySet() {
|
||||
for(i in hosts_arr) {
|
||||
printf i " ";
|
||||
};
|
||||
}'`
|
||||
}')
|
||||
do
|
||||
if printf "$_host" | $AWK_CMD '{exit ($0 ~ /^([0-9]{1,3}.){3}[0-9]{1,3}$/) ? 0 : 1}'; then
|
||||
_ip_string="${_ip_string}${_host} "
|
||||
else
|
||||
_ip_string="${_ip_string}`$NSLOOKUP_CMD $_host 2> /dev/null | $AWK_CMD '/^Address: ([0-9]{1,3}.){3}[0-9]{1,3}$/ {printf $2" "}'`"
|
||||
_ip_string="${_ip_string}$($NSLOOKUP_CMD $_host 2> /dev/null | $AWK_CMD '/^Address: ([0-9]{1,3}.){3}[0-9]{1,3}$/ {printf $2" "}')"
|
||||
fi
|
||||
done
|
||||
_ip_string=`FormatNftSetElemsList "$_ip_string"`
|
||||
_ip_string=$(FormatNftSetElemsList "$_ip_string")
|
||||
|
||||
if [ $DEBUG -ge 1 ]; then
|
||||
echo " ruantiblock.UpdateBllistProxySet()._ip_string=${_ip_string}; _name=${_name}" >&2
|
||||
@@ -570,7 +582,7 @@ AddUserInstancesNftRules() {
|
||||
_route_table_id=$_tproxy_route_table_id
|
||||
fi
|
||||
_pkts_mark=$(($_pkts_mark + 1))
|
||||
NftInstanceAdd "\"$U_NAME\"" $_pkts_mark $U_PROXY_MODE $U_TOR_TRANS_PORT $_route_table_id "\"$U_IF_VPN\"" $U_T_PROXY_TYPE $U_T_PROXY_PORT_TCP $U_T_PROXY_PORT_UDP $U_T_PROXY_ALLOW_UDP $U_ENABLE_ENTRIES_REMOTE_PROXY $U_ENABLE_FPROXY "\"$U_VPN_GW_IP\""
|
||||
NftInstanceAdd "\"$U_NAME\"" $_pkts_mark ${U_PROXY_MODE:=$INSTANCES_DEF_PROXY_MODE} ${U_TOR_TRANS_PORT:=$INSTANCES_DEF_TOR_TRANS_PORT} $_route_table_id "\"${U_IF_VPN:=$INSTANCES_DEF_IF_VPN}\"" ${U_T_PROXY_TYPE:=$INSTANCES_DEF_T_PROXY_TYPE} ${U_T_PROXY_PORT_TCP:=$INSTANCES_DEF_T_PROXY_PORT_TCP} ${U_T_PROXY_PORT_UDP:=$INSTANCES_DEF_T_PROXY_PORT_UDP} ${U_T_PROXY_ALLOW_UDP:=$INSTANCES_DEF_T_PROXY_ALLOW_UDP} ${U_ENABLE_ENTRIES_REMOTE_PROXY:=$INSTANCES_DEF_ENABLE_BLLIST_PROXY} ${U_ENABLE_FPROXY:=$INSTANCES_DEF_ENABLE_FPROXY} "\"$U_VPN_GW_IP\""
|
||||
ClearUserInstanceVars
|
||||
_prio_offset=$(($_prio_offset - 1))
|
||||
done
|
||||
@@ -603,7 +615,7 @@ AddNftRules() {
|
||||
NftAddBaseChains $_chain_prio_first $_chain_prio_local $_chain_prio_fproxy
|
||||
NftAddActionChains $_chain_prio_action
|
||||
AddUserInstancesNftRules
|
||||
NftInstanceAdd "\" \"" $PKTS_MARK_START $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 "\"$VPN_GW_IP\""
|
||||
NftInstanceAdd "\" \"" $PKTS_MARK_START ${PROXY_MODE:=$INSTANCES_DEF_PROXY_MODE} ${TOR_TRANS_PORT:=$INSTANCES_DEF_TOR_TRANS_PORT} $_route_table_id "\"${IF_VPN:=$INSTANCES_DEF_IF_VPN}\"" ${T_PROXY_TYPE:=$INSTANCES_DEF_T_PROXY_TYPE} ${T_PROXY_PORT_TCP:=$INSTANCES_DEF_T_PROXY_PORT_TCP} ${T_PROXY_PORT_UDP:=$INSTANCES_DEF_T_PROXY_PORT_UDP} ${T_PROXY_ALLOW_UDP:=$INSTANCES_DEF_T_PROXY_ALLOW_UDP} ${ENABLE_BLLIST_PROXY:=$INSTANCES_DEF_ENABLE_BLLIST_PROXY} ${ENABLE_FPROXY:=$INSTANCES_DEF_ENABLE_FPROXY} "\"$VPN_GW_IP\""
|
||||
if [ "$PROXY_LOCAL_CLIENTS" = "1" ]; then
|
||||
NftAddLocalClientsRule
|
||||
fi
|
||||
@@ -864,7 +876,7 @@ AddUserEntries() {
|
||||
printf "server=/onion/%s\nnftset=/onion/%s#%s\n" "$U_ONION_DNS_ADDR" "$NFT_TABLE_DNSMASQ" "${NFTSET_ONION}.${U_NAME}" >> "$_dnsmasq_data_file_user_instances"
|
||||
fi
|
||||
if [ -f "$_instance_entries_file" ]; then
|
||||
{ cat "$_instance_entries_file"; printf "\n0\n"; } | ParseUserEntries "`printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}.${U_NAME}"`" "`printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}.${U_NAME}"`" "${NFTSET_DNSMASQ}.${U_NAME}" "$_ip_data_file_user_instances" "$_dnsmasq_data_file_user_instances" "$_user_entries_status_file" "${U_NAME}:local" "$U_ENTRIES_DNS"
|
||||
{ cat "$_instance_entries_file"; printf "\n0\n"; } | ParseUserEntries "$(printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}.${U_NAME}")" "$(printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}.${U_NAME}")" "${NFTSET_DNSMASQ}.${U_NAME}" "$_ip_data_file_user_instances" "$_dnsmasq_data_file_user_instances" "$_user_entries_status_file" "${U_NAME}:local" "$U_ENTRIES_DNS"
|
||||
fi
|
||||
if [ -n "$U_ENTRIES_REMOTE" ]; then
|
||||
for _url in $U_ENTRIES_REMOTE
|
||||
@@ -876,7 +888,7 @@ AddUserEntries() {
|
||||
if [ "$U_ENABLE_ENTRIES_REMOTE_PROXY" = "1" ]; then
|
||||
UpdateBllistProxySet "$U_NAME" "$_url"
|
||||
fi
|
||||
{ Download - "$_url"; printf "\n$?\n"; } | ParseUserEntries "`printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}.${U_NAME}"`" "`printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}.${U_NAME}"`" "${NFTSET_DNSMASQ}.${U_NAME}" "$_ip_data_file_user_instances" "$_dnsmasq_data_file_user_instances" "$_user_entries_status_file" "${U_NAME}:${_url}" "$U_ENTRIES_DNS"
|
||||
{ Download - "$_url"; printf "\n$?\n"; } | ParseUserEntries "$(printf "$NFTSET_IP_PATTERN" "${NFTSET_IP}.${U_NAME}")" "$(printf "$NFTSET_CIDR_PATTERN" "${NFTSET_CIDR}.${U_NAME}")" "${NFTSET_DNSMASQ}.${U_NAME}" "$_ip_data_file_user_instances" "$_dnsmasq_data_file_user_instances" "$_user_entries_status_file" "${U_NAME}:${_url}" "$U_ENTRIES_DNS"
|
||||
if [ $? -eq 0 ]; then
|
||||
_instance_return_code=0
|
||||
break
|
||||
@@ -922,11 +934,11 @@ AddUserEntries() {
|
||||
if [ "$ENABLE_TMP_DOWNLOADS" != "1" ] || [ "$ENABLE_TMP_DOWNLOADS" = "1" -a $_return_code -eq 0 ]; then
|
||||
while read _str
|
||||
do
|
||||
_update_string=`printf "$_str" | $AWK_CMD '{
|
||||
_update_string=$(printf "$_str" | $AWK_CMD '{
|
||||
if(NF == 4) {
|
||||
printf "User entries (%s): CIDR: %s, IP: %s, FQDN: %s", $4, $1, $2, $3;
|
||||
};
|
||||
}'`
|
||||
}')
|
||||
if [ -n "$_update_string" ]; then
|
||||
### STDOUT
|
||||
echo " ${_update_string}"
|
||||
@@ -983,14 +995,14 @@ GetMainInstanceEntries() {
|
||||
FlushNftSets "$NFTSET_BLLIST_PROXY"
|
||||
fi
|
||||
if [ $_return_code -eq 0 ]; then
|
||||
_update_string=`$AWK_CMD '{
|
||||
_update_string=$($AWK_CMD '{
|
||||
printf "Received entries: %s\n", (NF < 3) ? "No data" : "CIDR: "$1", IP: "$2", FQDN: "$3;
|
||||
exit;
|
||||
}' "$UPDATE_STATUS_FILE"`
|
||||
}' "$UPDATE_STATUS_FILE")
|
||||
### STDOUT
|
||||
echo " ${_update_string}"
|
||||
MakeLogRecord "notice" "${_update_string}"
|
||||
printf " `date +%d.%m.%Y-%H:%M`\n" >> "$UPDATE_STATUS_FILE"
|
||||
printf " $(date +%d.%m.%Y-%H:%M)\n" >> "$UPDATE_STATUS_FILE"
|
||||
fi
|
||||
elif [ -z "$BLLIST_PRESET" -a -z "$BLLIST_MODULE" ]; then
|
||||
ClearDataFiles main_instance
|
||||
@@ -1199,20 +1211,20 @@ Reload() {
|
||||
Status() {
|
||||
local _update_status _user_entries_status _vpn_error
|
||||
if [ -f "$UPDATE_STATUS_FILE" ]; then
|
||||
_update_status=`$AWK_CMD '{
|
||||
_update_status=$($AWK_CMD '{
|
||||
update_string=(NF < 4) ? "No data" : $4" (CIDR: "$1" | IP: "$2" | FQDN: "$3")";
|
||||
printf "Last blacklist update: %s", update_string;
|
||||
}' "$UPDATE_STATUS_FILE"`
|
||||
}' "$UPDATE_STATUS_FILE")
|
||||
else
|
||||
_update_status="Last blacklist update: No data"
|
||||
fi
|
||||
|
||||
if [ -f "$USER_ENTRIES_STATUS_FILE" ]; then
|
||||
_user_entries_status=`$AWK_CMD '{
|
||||
_user_entries_status=$($AWK_CMD '{
|
||||
if(NF == 4) {
|
||||
printf " User entries (%s): CIDR: %s | IP: %s | FQDN: %s\n", $4, $1, $2, $3;
|
||||
};
|
||||
}' "$USER_ENTRIES_STATUS_FILE"`
|
||||
}' "$USER_ENTRIES_STATUS_FILE")
|
||||
fi
|
||||
|
||||
if ! GetVpnRouteStatus; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
PID_FILE="/var/run/`basename $0`.pid"
|
||||
PID_FILE="/var/run/$(basename $0).pid"
|
||||
APP_EXEC="/usr/bin/ruantiblock"
|
||||
|
||||
. "$USER_INSTANCES_COMMON"
|
||||
@@ -9,7 +9,7 @@ VPN_IFACES_STATUS=1
|
||||
|
||||
CheckIfaceStatus() {
|
||||
local _iface="$1" _ret_val=0
|
||||
if [ -z "`$IP_CMD link show dev $_iface up 2> /dev/null`" ]; then
|
||||
if [ -z "$($IP_CMD link show dev $_iface up 2> /dev/null)" ]; then
|
||||
_ret_val=1
|
||||
|
||||
if [ $DEBUG -ge 1 ]; then
|
||||
@@ -23,7 +23,7 @@ CheckIfaceStatus() {
|
||||
|
||||
VpnRouteInstanceStatus() {
|
||||
local _vpn_route_table_id=$1
|
||||
[ -n "`$IP_CMD route show table $_vpn_route_table_id 2> /dev/null`" ] && return 0
|
||||
[ -n "$($IP_CMD route show table $_vpn_route_table_id 2> /dev/null)" ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ Start() {
|
||||
}
|
||||
|
||||
Stop() {
|
||||
kill -s SIGKILL `cat "$PID_FILE"` 2> /dev/null
|
||||
kill -s SIGKILL $(cat "$PID_FILE") 2> /dev/null
|
||||
rm -f "$PID_FILE"
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ case "$1" in
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: `basename $0` start|stop"
|
||||
echo "Usage: $(basename $0) start|stop"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
|
||||
UCI_SECTION="ruantiblock.config"
|
||||
UCI_VARS="dnsmasq_confdir 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
|
||||
echo " Error! UCI doesn't exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
AWK_CMD="awk"
|
||||
|
||||
eval `$UCI_CMD show "$UCI_SECTION" | $AWK_CMD -F "=" -v UCI_VARS="$UCI_VARS" '
|
||||
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)
|
||||
@@ -26,7 +27,7 @@ eval `$UCI_CMD show "$UCI_SECTION" | $AWK_CMD -F "=" -v UCI_VARS="$UCI_VARS" '
|
||||
for(i in vars_array)
|
||||
print toupper(i) "=\"""\"";
|
||||
};
|
||||
}'`
|
||||
}')
|
||||
|
||||
. /lib/functions/network.sh
|
||||
network_get_subnet subnet_lan "lan"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
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"
|
||||
UCI_CMD=`which uci`
|
||||
UCI_CMD="$(which uci)"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " Error! UCI doesn't exists" >&2
|
||||
exit 1
|
||||
@@ -26,7 +27,7 @@ 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" '
|
||||
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)
|
||||
@@ -45,7 +46,7 @@ IncludeUserInstanceVars() {
|
||||
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
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
Info() {
|
||||
local _update_status _user_entries_status _inst
|
||||
if [ -f "$UPDATE_STATUS_FILE" ]; then
|
||||
_update_status=`$AWK_CMD '{
|
||||
_update_status=$($AWK_CMD '{
|
||||
if(NF < 4) {
|
||||
printf "{\"status\":false}";
|
||||
} else {
|
||||
printf "{\"status\":true,\"date\":\""$4"\",\"cidr\":\""$1"\",\"ip\":\""$2"\",\"fqdn\":\""$3"\"}";
|
||||
};
|
||||
}' "$UPDATE_STATUS_FILE"`
|
||||
}' "$UPDATE_STATUS_FILE")
|
||||
else
|
||||
_update_status="{\"status\":false}"
|
||||
fi
|
||||
if [ -f "$USER_ENTRIES_STATUS_FILE" ]; then
|
||||
_user_entries_status=`$AWK_CMD '
|
||||
_user_entries_status=$($AWK_CMD '
|
||||
BEGIN {
|
||||
items = 0;
|
||||
printf "[";
|
||||
@@ -29,7 +29,7 @@ Info() {
|
||||
}
|
||||
END {
|
||||
printf "]";
|
||||
}' "$USER_ENTRIES_STATUS_FILE"`
|
||||
}' "$USER_ENTRIES_STATUS_FILE")
|
||||
else
|
||||
_user_entries_status="[]"
|
||||
fi
|
||||
|
||||
@@ -56,7 +56,7 @@ NftRouteAdd() {
|
||||
if [ -n "$_vpn_gw_ip" ]; then
|
||||
_vpn_ip="$_vpn_gw_ip"
|
||||
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}'`
|
||||
_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}')
|
||||
fi
|
||||
if [ -n "$_vpn_ip" -a "$_type" = "vpn" ]; then
|
||||
echo 0 > "/proc/sys/net/ipv4/conf/${_if_vpn}/rp_filter"
|
||||
@@ -80,7 +80,7 @@ NftRouteAdd() {
|
||||
|
||||
NftRouteStatus() {
|
||||
local _route_table_id=$1
|
||||
[ -n "`$IP_CMD route show table "$_route_table_id" 2> /dev/null`" ] && return 0
|
||||
[ -n "$($IP_CMD route show table "$_route_table_id" 2> /dev/null)" ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -90,9 +90,7 @@ NftAddBaseChains() {
|
||||
$NFT_CMD add chain $NFT_TABLE "$NFT_BLLIST_CHAIN"
|
||||
$NFT_CMD add chain $NFT_TABLE "$NFT_FPROXY_CHAIN" { type filter hook prerouting priority ${_chain_prio_fproxy}\; policy accept\; }
|
||||
$NFT_CMD add chain $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" { type filter hook prerouting priority ${_chain_prio_first}\; policy accept\; }
|
||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_FPROXY_CHAIN" meta iif lo return
|
||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_FPROXY_CHAIN" ip daddr "@${NFTSET_FPROXY_PRIVATE}" return
|
||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" meta iif lo return
|
||||
NftCmdWrapper $NFT_CMD add rule $NFT_TABLE "$NFT_ALLOWED_HOSTS_CHAIN" "$NFT_ALLOWED_HOSTS_PATTERN"
|
||||
if [ "$BYPASS_MODE" = "1" ]; then
|
||||
for _set in "$NFTSET_BYPASS_IP" "$NFTSET_BYPASS_FQDN"
|
||||
|
||||
@@ -25,7 +25,7 @@ ListUserInstances() {
|
||||
|
||||
GetUserInstances() {
|
||||
local _type="$1" _fnames="$2" _i=0 _inst _instances=""
|
||||
for _inst in `ListUserInstances`
|
||||
for _inst in $(ListUserInstances)
|
||||
do
|
||||
IncludeUserInstanceVars "$_inst"
|
||||
if [ $_i -lt $USER_INSTANCES_MAX -a -n "$U_NAME" -a "$U_ENABLED" != "0" ]; then
|
||||
@@ -45,7 +45,7 @@ GetUserInstances() {
|
||||
|
||||
SetUserInstancesItems() {
|
||||
local _i=0 _inst _instances_all="" _instances_all_fnames="" _instances_vpn="" _instances_vpn_fnames="" _instances_cfg="" _instances_cfg_fnames=""
|
||||
for _inst in `ListUserInstances`
|
||||
for _inst in $(ListUserInstances)
|
||||
do
|
||||
IncludeUserInstanceVars "$_inst"
|
||||
if [ $_i -lt $USER_INSTANCES_MAX -a -n "$U_NAME" -a "$U_ENABLED" != "0" ]; then
|
||||
|
||||
Reference in New Issue
Block a user