Merge Mainline

This commit is contained in:
CN_SZTL 2020-07-23 17:42:33 +08:00
commit 75f51faaab
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
50 changed files with 1046 additions and 199 deletions

View File

@ -55,7 +55,8 @@ luci-theme-argon-mod source: [Leo-Jo-My/luci-theme-argon-mod](https://github.com
node-request source: [jerrykuku/node-request](https://github.com/jerrykuku/node-request).<br/>
luci-app-jd-dailybonus source: [jerrykuku/luci-app-jd-dailybonus](https://github.com/jerrykuku/luci-app-jd-dailybonus).<br/>
luci-app-oled source: [NateLol/luci-app-oled](https://github.com/NateLol/luci-app-oled).<br/>
luci-theme-edge source: [garypang13/luci-theme-edge](https://github.com//garypang13/luci-theme-edge).
luci-theme-edge source: [garypang13/luci-theme-edge](https://github.com//garypang13/luci-theme-edge).<br/>
luci-app-beardropper source: [NateLol/natelol](https://github.com/NateLol/natelol).
## License
### Depend on their own License.

View File

@ -0,0 +1,22 @@
#
# Copyright (C) 2020 Nate Ding
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
LUCI_Title:=LuCI Support for BearDropper
LUCI_PKGARCH=all
PKG_VERSION:=1.1
PKG_RELEASE:=20200522
PKG_MAINTANINER:=Nate Ding <natelol@github.com>
PKG_LICENSE:=GLPv3
PKG_LICENSE_FILES:=LICENSE
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,19 @@
module("luci.controller.beardropper", package.seeall)
function index()
if not nixio.fs.access("/etc/config/beardropper") then
return
end
entry({"admin", "services", "beardropper"}, alias("admin", "services", "beardropper", "setting"),_("BearDropper"), 20).dependent = true
entry({"admin", "services", "beardropper", "status"}, call("act_status"))
entry({"admin", "services", "beardropper", "setting"}, cbi("beardropper/setting"), _("Setting"), 30).leaf= true
entry({"admin", "services", "beardropper", "log"}, form("beardropper/log"),_("Log"), 40).leaf= true
--entry:
end
function act_status()
local e={}
e.running = luci.sys.call("pgrep -f /usr/sbin/beardropper >/dev/null")==0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -0,0 +1,17 @@
f = SimpleForm("logview")
f.reset = false
f.submit = false
t = f:field(TextValue, "conf")
t.rmempty = true
t.rows = 20
function t.cfgvalue()
local logs = luci.util.execi("logread | grep authpriv | grep beardropper")
local s = ""
for line in logs do
s = line .. "\n" .. s
end
return s
end
t.readonly="readonly"
return f

View File

@ -0,0 +1,54 @@
m = Map("beardropper", translate("BearDropper"),
translate("luci-app-beardropper, the LuCI app built with the elegant firewall rule generation on-the-fly script bearDropper. <br /> <br /> Should you have any questions, please refer to the repo: ")..[[<a href="https://github.com/NateLol/luci-app-bearDropper" target="_blank">luci-app-beardropper</a>]]
)
m:chain("luci")
m:section(SimpleSection).template="beardropper/status"
s = m:section(TypedSection, "beardropper", translate(""))
s.anonymous = true
s.addremove = false
-- TABS
s:tab("options", translate("Options"))
s:tab("blocked", translate("Blocked IP"))
o = s:taboption("options", Flag, "enabled",translate("Enabled"))
o.default = 0
-- OPTIONS
o = s:taboption("options", ListValue, "defaultMode", translate("Running Mode"))
o.default = "follow"
o:value("follow", translate("Follow"))
o:value("entire", translate("Entire"))
o:value("today", translate("Today"))
o:value("wipe", translate("Wipe"))
o = s:taboption("options", Value, "attemptCount", translate("Attempt Tolerance"), translate("failure attempts from a given IP required to trigger a ban"))
o = s:taboption("options", Value, "attemptPeriod", translate("Attempt Cycle"), translate("time period during which attemptCount must be exceeded in order to trigger a ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"))
o = s:taboption("options", Value, "banLength", translate("Ban Period"), translate("how long a ban exist once the attempt threshold is exceeded"))
o = s:taboption("options", ListValue, "logLevel", translate("Log Level"))
o.default = "1"
o:value("0", translate("Silent"))
o:value("1", translate("Default"))
o:value("2", translate("Verbose"))
o:value("3", translate("Debug"))
o = s:taboption("blocked", Value, "blocked", translate("Blocked IP List"))
o.template="cbi/tvalue"
o.rows=40
o.wrap="off"
o.readonly="true"
function o.cfgvalue(e, e)
return luci.sys.exec("cat /tmp/beardropper.bddb | awk /'=1/'| awk -F '=' '{print $1}' | awk '{print substr($0,6)}' | awk 'gsub(/_/,\":\",$0)'")
end
return m

View File

@ -0,0 +1,22 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[beardropper]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('beardropper_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>BearDropper <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>BearDropper <%:NOT RUNNING%></font></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="beardropper_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>

View File

@ -0,0 +1,115 @@
bearDropper#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
msgid "Attempt Cycle"
msgstr "尝试登录时间段"
msgid "Setting"
msgstr "设置"
msgid "Log"
msgstr "日志"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
msgid "Attempt Tolerance"
msgstr "最大尝试登录次数"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
msgid "Ban Period"
msgstr "封禁IP时长"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/controller/bearDropper.lua:7
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:7
msgid "BearDropper"
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:20
msgid "Blocked IP"
msgstr "屏蔽列表"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:52
msgid "Blocked IP List"
msgstr "已屏蔽IP列表"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:20
msgid "Collecting data..."
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:45
msgid "Debug"
msgstr "调试"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:43
msgid "Default"
msgstr "默认"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:22
msgid "Enabled"
msgstr "启用"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:29
msgid "Entire"
msgstr "已有记录"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:28
msgid "Follow"
msgstr "后台监控"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:40
msgid "Log Level"
msgstr "日志等级"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:10
msgid "NOT RUNNING"
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:19
msgid "Options"
msgstr "选项"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:7
msgid "RUNNING"
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:26
msgid "Running Mode"
msgstr "运行模式"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:42
msgid "Silent"
msgstr "安静"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:30
msgid "Today"
msgstr "仅今日"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:44
msgid "Verbose"
msgstr "详细"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:31
msgid "Wipe"
msgstr "清除所有"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
msgid "failure attempts from a given IP required to trigger a ban"
msgstr "尝试登录超过设定值次数的IP将被封禁"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
msgid "how long a ban exist once the attempt threshold is exceeded"
msgstr "IP将被封禁设定的时间"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:8
msgid ""
"luci-app-beardropper, the LuCI app built with the elegant firewall rule "
"generation on-the-fly script bearDropper. <br /> <br /> Should you have any "
"questions, please refer to the repo:"
msgstr ""
"luci-app-beardropper, 是一款能够在开启公网访问之后对潜在的ssh attack进行防御"
"的脚本. <br /> <br /> 如果你在使用中有任何问题,请到项目中提问: "
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
msgid ""
"time period during which attemptCount must be exceeded in order to trigger a "
"ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"
msgstr ""
"在设定的时间段内连续尝试失败 <br> 格式1w2d3h4m5s代表1周2天3小时4分5秒"

View File

@ -0,0 +1,115 @@
bearDropper#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
msgid "Attempt Cycle"
msgstr "嘗試登錄時間段"
msgid "Setting"
msgstr "設置"
msgid "Log"
msgstr "日誌"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
msgid "Attempt Tolerance"
msgstr "最大嘗試登錄次數"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
msgid "Ban Period"
msgstr "封禁IP時長"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/controller/bearDropper.lua:7
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:7
msgid "BearDropper"
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:20
msgid "Blocked IP"
msgstr "屏蔽列表"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:52
msgid "Blocked IP List"
msgstr "已屏蔽IP列表"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:20
msgid "Collecting data..."
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:45
msgid "Debug"
msgstr "調試"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:43
msgid "Default"
msgstr "默認"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:22
msgid "Enabled"
msgstr "啟用"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:29
msgid "Entire"
msgstr "已有記錄"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:28
msgid "Follow"
msgstr "後臺監控"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:40
msgid "Log Level"
msgstr "日誌等級"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:10
msgid "NOT RUNNING"
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:19
msgid "Options"
msgstr "選項"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:7
msgid "RUNNING"
msgstr ""
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:26
msgid "Running Mode"
msgstr "運行模式"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:42
msgid "Silent"
msgstr "安靜"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:30
msgid "Today"
msgstr "僅今日"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:44
msgid "Verbose"
msgstr "詳細"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:31
msgid "Wipe"
msgstr "清除所有"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
msgid "failure attempts from a given IP required to trigger a ban"
msgstr "嘗試登錄超過設定值次數的IP將被封禁"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
msgid "how long a ban exist once the attempt threshold is exceeded"
msgstr "IP將被封禁設定的時間"
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:8
msgid ""
"luci-app-beardropper, the LuCI app built with the elegant firewall rule "
"generation on-the-fly script bearDropper. <br /> <br /> Should you have any "
"questions, please refer to the repo:"
msgstr ""
"luci-app-beardropper, 是壹款能夠在開啟公網訪問之後對潛在的ssh attack進行防禦"
"的腳本. <br /> <br /> 如果妳在使用中有任何問題,請到項目中提問: "
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
msgid ""
"time period during which attemptCount must be exceeded in order to trigger a "
"ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"
msgstr ""
"在設定的時間段內連續嘗試失敗 <br> 格式1w2d3h4m5s代表1周2天3小時4分5秒"

View File

@ -0,0 +1,18 @@
config beardropper
option attemptCount '5'
option attemptPeriod '12h'
option banLength '1w'
option logFacility 'authpriv.notice'
option fileStateType 'bddb'
option fileStateTempPrefix '/tmp/beardropper'
option fileStatePersistPrefix '/etc/beardropper'
list firewallHookChain 'input_wan_rule:1'
list firewallHookChain 'forwarding_wan_rule:1'
option firewallTarget 'DROP'
list logRegex 's/[`$"\'\'']//g'
list logRegex '/has invalid shell, rejected$/d'
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p'
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p'
option defaultMode 'follow'
option enabled '1'
option logLevel '2'

View File

@ -0,0 +1,46 @@
#!/bin/sh /etc/rc.common
START=98
PROG=/usr/sbin/beardropper
SERVICE_DAEMONIZE=1
SERVICE_WRITE_PID=1
getKids() {
egrep "^PPid: *$1$" /proc/[0-9]*/s*s 2>/dev/null | cut -f3 -d/ | xargs echo
}
start() {
service_start ${PROG} -m follow
echo "beardropper started!"
}
stop() {
#PID=`cat /var/run/bearDropper.pid`
#kill `getKids $PID`
kill -9 `pgrep -f /usr/sbin/beardropper`
sleep 1
service_stop ${PROG}
echo "beardropper exit...."
}
restart() {
enabled=$(uci get beardropper.@beardropper[0].enabled)
pgrep -f ${PROG} >/dev/null
if [ $? -eq 0 ];then #running
if [ $enabled -eq 1 ]; then
stop
sleep 1
echo "beardropper is restarting..."
start
else
stop
fi
else
if [ $enabled -eq 1 ]; then
start
else
exit 0
fi
fi
}

View File

@ -0,0 +1,12 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@beardropper[-1]
add ucitrack beardropper
set ucitrack.@beardropper[-1].init=beardropper
commit ucitrack
EOF
touch /tmp/beardropper.bddb
rm -rf /tmp/luci-*
exit 0

View File

@ -0,0 +1,517 @@
#!/bin/ash
#
# beardropper - dropbear log parsing ban agent for OpenWRT (Chaos Calmer rewrite of dropBrute.sh)
# http://github.com/robzr/bearDropper -- Rob Zwissler 11/2015
#
# - lightweight, no dependencies, busybox ash + native OpenWRT commands
# - uses uci for configuration, overrideable via command line arguments
# - runs continuously in background (via init script) or periodically (via cron)
# - uses BIND time shorthand, ex: 1w5d3h1m8s is 1 week, 5 days, 3 hours, 1 minute, 8 seconds
# - Whitelist IP or CIDR entries (TBD) in uci config file
# - Records state file to tmpfs and intelligently syncs to persistent storage (can disable)
# - Persistent sync routines are optimized to avoid excessive writes (persistentStateWritePeriod)
# - Every run occurs in one of the following modes. If not specified, interval mode (24 hours) is
# the default when not specified (the init script specifies follow mode via command line)
#
# "follow" mode follows syslog to process entries as they happen; generally launched via init
# script. Responds the fastest, runs the most efficiently, but is always in memory.
# "interval" mode only processes entries going back the specified interval; requires
# more processing than today mode, but responds more accurately. Use with cron.
# "today" mode looks at log entries from the day it is being run, simple and lightweight,
# generally run from cron periodically (same simplistic behavior as dropBrute.sh)
# "entire" mode runs through entire contents of the syslog ring buffer
# "wipe" mode tears down the firewall rules and removes the state files
# Load UCI config variable, or use default if not set
# Args: $1 = variable name (also uci option name), $2 = default_value
uciSection='beardropper.@[0]'
uciLoadVar () {
local getUci
getUci=`uci -q get ${uciSection}."$1"` || getUci="$2"
eval $1=\'$getUci\';
}
uciLoad() {
local tFile=`mktemp` delim="
"
[ "$1" = -d ] && { delim="$2"; shift 2; }
uci -q -d"$delim" get "$uciSection.$1" 2>/dev/null >$tFile
if [ $? = 0 ] ; then
sed -e s/^\'// -e s/\'$// <$tFile
else
while [ -n "$2" ]; do echo $2; shift; done
fi
rm -f $tFile
}
# Common config variables - edit these in /etc/config/beardropper
# or they can be overridden at runtime with command line options
#
uciLoadVar defaultMode entire
uciLoadVar enabled 0
uciLoadVar attemptCount 10
uciLoadVar attemptPeriod 12h
uciLoadVar banLength 1w
uciLoadVar logLevel 1
uciLoadVar logFacility authpriv.notice
uciLoadVar persistentStateWritePeriod -1
uciLoadVar fileStateType bddb
uciLoadVar fileStateTempPrefix /tmp/beardropper
uciLoadVar fileStatePersistPrefix /etc/beardropper
firewallHookChains="`uciLoad -d \ firewallHookChain input_wan_rule:1 forwarding_wan_rule:1`"
uciLoadVar firewallTarget DROP
# Not commonly changed, but changeable via uci or cmdline (primarily
# to enable multiple parallel runs with different parameters)
uciLoadVar firewallChain beardropper
# Advanced variables, changeable via uci only (no cmdline), it is
# unlikely that these will need to be changed, but just in case...
#
uciLoadVar syslogTag "beardropper[$$]"
# how often to attempt to expire bans when in follow mode
uciLoadVar followModeCheckInterval 30m
uciLoadVar cmdLogread 'logread' # for tuning, ex: "logread -l250"
uciLoadVar cmdLogreadEba 'logread' # for "Exit before auth:" backscanning
uciLoadVar formatLogDate '%b %e %H:%M:%S %Y' # used to convert syslog dates
uciLoadVar formatTodayLogDateRegex '^%a %b %e ..:..:.. %Y' # filter for today mode
# Begin functions
#
# Clear bddb entries from environment
bddbClear () {
local bddbVar
for bddbVar in `set | egrep '^bddb_[0-9_]*=' | cut -f1 -d= | xargs echo -n` ; do eval unset $bddbVar ; done
bddbStateChange=1
}
# Returns count of unique IP entries in environment
bddbCount () { set | egrep '^bddb_[0-9_]*=' | wc -l ; }
# Loads existing bddb file into environment
# Arg: $1 = file, $2 = type (bddb/bddbz), $3 =
bddbLoad () {
local loadFile="$1.$2" fileType="$2"
if [ "$fileType" = bddb -a -f "$loadFile" ] ; then
. "$loadFile"
elif [ "$fileType" = bddbz -a -f "$loadFile" ] ; then
local tmpFile="`mktemp`"
zcat $loadFile > "$tmpFile"
. "$tmpFile"
rm -f "$tmpFile"
fi
bddbStateChange=0
}
# Saves environment bddb entries to file, Arg: $1 = file to save in
bddbSave () {
local saveFile="$1.$2" fileType="$2"
if [ "$fileType" = bddb ] ; then
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g > "$saveFile"
elif [ "$fileType" = bddbz ] ; then
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g | gzip -c > "$saveFile"
fi
bddbStateChange=0
}
# Set bddb record status=1, update ban time flag with newest
# Args: $1=IP Address $2=timeFlag
bddbEnableStatus () {
local record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
local newestTime=`bddbGetTimes $1 | sed 's/.* //' | xargs echo $2 | tr \ '\n' | sort -n | tail -1 `
eval $record="1,$newestTime"
bddbStateChange=1
}
# Args: $1=IP Address
bddbGetStatus () {
bddbGetRecord $1 | cut -d, -f1
}
# Args: $1=IP Address
bddbGetTimes () {
bddbGetRecord $1 | cut -d, -f2-
}
# Args: $1 = IP address, $2 [$3 ...] = timestamp (seconds since epoch)
bddbAddRecord () {
local ip="`echo "$1" | tr . _`" ; shift
local newEpochList="$@" status="`eval echo \\\$bddb_$ip | cut -f1 -d,`"
local oldEpochList="`eval echo \\\$bddb_$ip | cut -f2- -d, | tr , \ `"
local epochList=`echo $oldEpochList $newEpochList | xargs -n 1 echo | sort -un | xargs echo -n | tr \ ,`
[ -z "$status" ] && status=0
eval "bddb_$ip"\=\"$status,$epochList\"
bddbStateChange=1
}
# Args: $1 = IP address
bddbRemoveRecord () {
local ip="`echo "$1" | tr . _`"
eval unset bddb_$ip
bddbStateChange=1
}
# Returns all IPs (not CIDR) present in records
bddbGetAllIPs () {
local ipRaw record
set | egrep '^bddb_[0-9_]*=' | tr \' \ | while read record ; do
ipRaw=`echo $record | cut -f1 -d= | sed 's/^bddb_//'`
if [ `echo $ipRaw | tr _ \ | wc -w` -eq 4 ] ; then
echo $ipRaw | tr _ .
fi
done
}
# retrieve single IP record, Args: $1=IP
bddbGetRecord () {
local record
record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
eval echo \$$record
}
isValidBindTime () { echo "$1" | egrep -q '^[0-9]+$|^([0-9]+[wdhms]?)+$' ; }
# expands Bind time syntax into seconds (ex: 3w6d23h59m59s), Arg: $1=time string
expandBindTime () {
isValidBindTime "$1" || { logLine 0 "Error: Invalid time specified ($1)" >&2 ; exit 254 ; }
echo $((`echo "$1" | sed -e 's/w+*/*7d+/g' -e 's/d+*/*24h+/g' -e 's/h+*/*60m+/g' -e 's/m+*/*60+/g' \
-e s/s//g -e s/+\$//`))
}
# Args: $1 = loglevel, $2 = info to log
logLine () {
[ $1 -gt $logLevel ] && return
shift
if [ "$logFacility" = "stdout" ] ; then echo "$@"
elif [ "$logFacility" = "stderr" ] ; then echo "$@" >&2
else logger -t "$syslogTag" -p "$logFacility" "$@"
fi
}
# extra validation, fails safe. Args: $1=log line
getLogTime () {
local logDateString=`echo "$1" | sed -n \
's/^[A-Z][a-z]* \([A-Z][a-z]* *[0-9][0-9]* *[0-9][0-9]*:[0-9][0-9]:[0-9][0-9] [0-9][0-9]*\) .*$/\1/p'`
date -d"$logDateString" -D"$formatLogDate" +%s || logLine 1 \
"Error: logDateString($logDateString) malformed line ($1)"
}
# extra validation, fails safe. Args: $1=log line
getLogIP () {
local logLine="$1"
local ebaPID=`echo "$logLine" | sed -n 's/^.*authpriv.info \(dropbear\[[0-9]*\]:\) Exit before auth:.*/\1/p'`
[ -n "$ebaPID" ] && logLine=`$cmdLogreadEba | fgrep "${ebaPID} Child connection from "`
echo "$logLine" | sed -n 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'
}
# Args: $1=IP
unBanIP () {
if iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
logLine 1 "Removing ban rule for IP $ip from iptables"
iptables -D $firewallChain -s $ip -j "$firewallTarget"
else
logLine 3 "unBanIP() Ban rule for $ip not present in iptables"
fi
}
# Args: $1=IP
banIP () {
local ip="$1" x chain position
if ! iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
logLine 1 "Creating iptables chain $firewallChain"
iptables -N $firewallChain
fi
for x in $firewallHookChains ; do
chain="${x%:*}" ; position="${x#*:}"
if [ $position -ge 0 ] && ! iptables -C $chain -j $firewallChain 2>/dev/null ; then
logLine 1 "Inserting hook into iptables chain $chain"
if [ $position = 0 ] ; then
iptables -A $chain -j $firewallChain
else
iptables -I $chain $position -j $firewallChain
fi ; fi
done
if ! iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
logLine 1 "Inserting ban rule for IP $ip into iptables chain $firewallChain"
iptables -A $firewallChain -s $ip -j "$firewallTarget"
else
logLine 3 "banIP() rule for $ip already present in iptables chain"
fi
}
wipeFirewall () {
local x chain position
for x in $firewallHookChains ; do
chain="${x%:*}" ; position="${x#*:}"
if [ $position -ge 0 ] ; then
if iptables -C $chain -j $firewallChain 2>/dev/null ; then
logLine 1 "Removing hook from iptables chain $chain"
iptables -D $chain -j $firewallChain
fi ; fi
done
if iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
logLine 1 "Flushing and removing iptables chain $firewallChain"
iptables -F $firewallChain 2>/dev/null
iptables -X $firewallChain 2>/dev/null
fi
}
# review state file for expired records - we could add the bantime to
# the rule via --comment but I can't think of a reason why that would
# be necessary unless there is a bug in the expiration logic. The
# state db should be more resiliant than the firewall in practice.
#
bddbCheckStatusAll () {
local now=`date +%s`
bddbGetAllIPs | while read ip ; do
if [ `bddbGetStatus $ip` -eq 1 ] ; then
logLine 3 "bddbCheckStatusAll($ip) testing banLength:$banLength + bddbGetTimes:`bddbGetTimes $ip` vs. now:$now"
if [ $((banLength + `bddbGetTimes $ip`)) -lt $now ] ; then
logLine 1 "Ban expired for $ip, removing from iptables"
unBanIP $ip
bddbRemoveRecord $ip
else
logLine 3 "bddbCheckStatusAll($ip) not expired yet"
banIP $ip
fi
elif [ `bddbGetStatus $ip` -eq 0 ] ; then
local times=`bddbGetTimes $ip | tr , \ `
local timeCount=`echo $times | wc -w`
local lastTime=`echo $times | cut -d\ -f$timeCount`
if [ $((lastTime + attemptPeriod)) -lt $now ] ; then
bddbRemoveRecord $ip
fi ; fi
saveState
done
loadState
}
# Only used when status is already 0 and possibly going to 1, Args: $1=IP
bddbEvaluateRecord () {
local ip=$1 firstTime lastTime
local times=`bddbGetRecord $1 | cut -d, -f2- | tr , \ `
local timeCount=`echo $times | wc -w`
local didBan=0
# 1: not enough attempts => do nothing and exit
# 2: attempts exceed threshold in time period => ban
# 3: attempts exceed threshold but time period is too long => trim oldest time, recalculate
while [ $timeCount -ge $attemptCount ] ; do
firstTime=`echo $times | cut -d\ -f1`
lastTime=`echo $times | cut -d\ -f$timeCount`
timeDiff=$((lastTime - firstTime))
logLine 3 "bddbEvaluateRecord($ip) count=$timeCount timeDiff=$timeDiff/$attemptPeriod"
if [ $timeDiff -le $attemptPeriod ] ; then
bddbEnableStatus $ip $lastTime
logLine 2 "bddbEvaluateRecord($ip) exceeded ban threshold, adding to iptables"
banIP $ip
didBan=1
fi
times=`echo $times | cut -d\ -f2-`
timeCount=`echo $times | wc -w`
done
[ $didBan = 0 ] && logLine 2 "bddbEvaluateRecord($ip) does not exceed threshhold, skipping"
}
# Reads filtered log line and evaluates for action Args: $1=log line
processLogLine () {
local time=`getLogTime "$1"`
local ip=`getLogIP "$1"`
local status="`bddbGetStatus $ip`"
if [ "$status" = -1 ] ; then
logLine 2 "processLogLine($ip,$time) IP is whitelisted"
elif [ "$status" = 1 ] ; then
if [ "`bddbGetTimes $ip`" -ge $time ] ; then
logLine 2 "processLogLine($ip,$time) already banned, ban timestamp already equal or newer"
else
logLine 2 "processLogLine($ip,$time) already banned, updating ban timestamp"
bddbEnableStatus $ip $time
fi
banIP $ip
elif [ -n "$ip" -a -n "$time" ] ; then
bddbAddRecord $ip $time
logLine 2 "processLogLine($ip,$time) Added record, comparing"
bddbEvaluateRecord $ip
else
logLine 1 "processLogLine($ip,$time) malformed line ($1)"
fi
}
# Args, $1=-f to force a persistent write (unless lastPersistentStateWrite=-1)
saveState () {
local forcePersistent=0
[ "$1" = "-f" ] && forcePersistent=1
if [ $bddbStateChange -gt 0 ] ; then
logLine 3 "saveState() saving to temp state file"
bddbSave "$fileStateTempPrefix" "$fileStateType"
logLine 3 "saveState() now=`date +%s` lPSW=$lastPersistentStateWrite pSWP=$persistentStateWritePeriod fP=$forcePersistent"
fi
if [ $persistentStateWritePeriod -gt 1 ] || [ $persistentStateWritePeriod -eq 0 -a $forcePersistent -eq 1 ] ; then
if [ $((`date +%s` - lastPersistentStateWrite)) -ge $persistentStateWritePeriod ] || [ $forcePersistent -eq 1 ] ; then
if [ ! -f "$fileStatePersist" ] || ! cmp -s "$fileStateTemp" "$fileStatePersist" ; then
logLine 2 "saveState() writing to persistent state file"
bddbSave "$fileStatePersistPrefix" "$fileStateType"
lastPersistentStateWrite="`date +%s`"
fi ; fi ; fi
}
loadState () {
bddbClear
bddbLoad "$fileStatePersistPrefix" "$fileStateType"
bddbLoad "$fileStateTempPrefix" "$fileStateType"
logLine 2 "loadState() loaded `bddbCount` entries"
}
printUsage () {
cat <<-_EOF_
Usage: beardropper [-m mode] [-a #] [-b #] [-c ...] [-C ...] [-f ...] [-l #] [-j ...] [-p #] [-P #] [-s ...]
Running Modes (-m) (def: $defaultMode)
follow constantly monitors log
entire processes entire log contents
today processes log entries from same day only
# interval mode, specify time string or seconds
wipe wipe state files, unhook and remove firewall chain
Options
-a # attempt count before banning (def: $attemptCount)
-b # ban length once attempts hit threshold (def: $banLength)
-c ... firewall chain to record bans (def: $firewallChain)
-C ... firewall chains/positions to hook into (def: $firewallHookChains)
-f ... log facility (syslog facility or stdout/stderr) (def: $logFacility)
-j ... firewall target (def: $firewallTarget)
-l # log level - 0=off, 1=standard, 2=verbose (def: $logLevel)
-p # attempt period which attempt counts must happen in (def: $attemptPeriod)
-P # persistent state file write period (def: $persistentStateWritePeriod)
-s ... persistent state file prefix (def: $fileStatePersistPrefix)
-t ... temporary state file prefix (def: $fileStateTempPrefix)
All time strings can be specified in seconds, or using BIND style
time strings, ex: 1w2d3h5m30s is 1 week, 2 days, 3 hours, etc...
_EOF_
}
# Begin main logic
#
unset logMode
while getopts a:b:c:C:f:hj:l:m:p:P:s:t: arg ; do
case "$arg" in
a) attemptCount="$OPTARG" ;;
b) banLength="$OPTARG" ;;
c) firewallChain="$OPTARG" ;;
C) firewallHookChains="$OPTARG" ;;
f) logFacility="$OPTARG" ;;
j) firewallTarget="$OPTARG" ;;
l) logLevel="$OPTARG" ;;
m) logMode="$OPTARG" ;;
p) attemptPeriod="$OPTARG" ;;
P) persistentStateWritePeriod="$OPTARG" ;;
s) fileStatePersistPrefix="$OPTARG" ;;
s) fileStatePersistPrefix="$OPTARG" ;;
*) printUsage
exit 254
esac
shift `expr $OPTIND - 1`
done
[ -z $logMode ] && logMode="$defaultMode"
fileStateTemp="$fileStateTempPrefix.$fileStateType"
fileStatePersist="$fileStatePersistPrefix.$fileStateType"
attemptPeriod=`expandBindTime $attemptPeriod`
banLength=`expandBindTime $banLength`
[ $persistentStateWritePeriod != -1 ] && persistentStateWritePeriod=`expandBindTime $persistentStateWritePeriod`
followModeCheckInterval=`expandBindTime $followModeCheckInterval`
exitStatus=0
# Here we convert the logRegex list into a sed -f file
fileRegex="/tmp/beardropper.$$.regex"
uciLoad logRegex 's/[`$"'\\\'']//g' '/has invalid shell, rejected$/d' \
'/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p' \
'/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p' > "$fileRegex"
lastPersistentStateWrite="`date +%s`"
loadState
bddbCheckStatusAll
# main event loops
if [ "$logMode" = follow ] ; then
logLine 1 "Running in follow mode"
readsSinceSave=0 lastCheckAll=0 worstCaseReads=1 tmpFile="/tmp/beardropper.$$.1"
# Verify if these do any good - try saving to a temp. Scope may make saveState useless.
trap "rm -f "$tmpFile" "$fileRegex" ; exit " SIGINT
[ $persistentStateWritePeriod -gt 1 ] && worstCaseReads=$((persistentStateWritePeriod / followModeCheckInterval))
firstRun=1
$cmdLogread -f | while read -t $followModeCheckInterval line || true ; do
if [ $firstRun -eq 1 ] ; then
trap "saveState -f" SIGHUP
trap "saveState -f; exit" SIGINT
firstRun=0
fi
sed -nEf "$fileRegex" > "$tmpFile" <<-_EOF_
$line
_EOF_
line="`cat $tmpFile`"
[ -n "$line" ] && processLogLine "$line"
logLine 3 "ReadComp:$readsSinceSave/$worstCaseReads"
if [ $((++readsSinceSave)) -ge $worstCaseReads ] ; then
now="`date +%s`"
if [ $((now - lastCheckAll)) -ge $followModeCheckInterval ] ; then
bddbCheckStatusAll
lastCheckAll="$now"
saveState
readsSinceSave=0
fi
fi
done
elif [ "$logMode" = entire ] ; then
logLine 1 "Running in entire mode"
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
processLogLine "$line"
saveState
done
loadState
bddbCheckStatusAll
saveState -f
elif [ "$logMode" = today ] ; then
logLine 1 "Running in today mode"
# merge the egrep into sed with -e /^$formatTodayLogDateRegex/!d
$cmdLogread | egrep "`date +\'$formatTodayLogDateRegex\'`" | sed -nEf "$fileRegex" | while read line ; do
processLogLine "$line"
saveState
done
loadState
bddbCheckStatusAll
saveState -f
elif isValidBindTime "$logMode" ; then
logInterval=`expandBindTime $logMode`
logLine 1 "Running in interval mode (reviewing $logInterval seconds of log entries)..."
timeStart=$((`date +%s` - logInterval))
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
timeWhen=`getLogTime "$line"`
[ $timeWhen -ge $timeStart ] && processLogLine "$line"
saveState
done
loadState
bddbCheckStatusAll
saveState -f
elif [ "$logMode" = wipe ] ; then
logLine 2 "Wiping state files, unhooking and removing iptables chains"
wipeFirewall
if [ -f "$fileStateTemp" ] ; then
logLine 1 "Removing non-persistent statefile ($fileStateTemp)"
rm -f "$fileStateTemp"
fi
if [ -f "$fileStatePersist" ] ; then
logLine 1 "Removing persistent statefile ($fileStatePersist)"
rm -f "$fileStatePersist"
fi
else
logLine 0 "Error: invalid log mode ($logMode)"
exitStatus=254
fi
rm -f "$fileRegex"
exit $exitStatus

View File

@ -11,7 +11,7 @@ start() {
#crontab daemon
cat /etc/crontabs/root | grep oled > /dev/null
if [ $? -eq 1 ]; then
echo "*/15 * * * * /etc/init.d/oled restart &>/dev/null 2>&1" >> /etc/crontabs/root
echo "*/5 * * * * /etc/init.d/oled restart &>/dev/null 2>&1" >> /etc/crontabs/root
fi
date=$(uci get oled.@oled[0].date)
@ -40,15 +40,13 @@ start() {
ps|grep netspeed|grep -v grep|awk '{print $1}'|xargs kill -9
rm -f /tmp/netspeed
fi
nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" > /dev/null 2>&1 &
nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" 1 > /dev/null 2>&1 &
}
stop() {
kill `pgrep /usr/bin/oled`
sleep 1
kill -2 `pgrep /usr/bin/oled`
ps|grep netspeed|grep -v grep|awk '{print $1}'|xargs kill -9
sleep 1
echo "oled exit..."
}
@ -57,9 +55,36 @@ restart(){
pgrep -f ${PROG} >/dev/null
if [ $? -eq 0 ]; then
if [ $enabled -eq 1 ]; then
stop
sleep 1
start
kill `pgrep /usr/bin/oled`
ps|grep netspeed|grep -v grep|awk '{print $1}'|xargs kill -9
date=$(uci get oled.@oled[0].date)
lanip=$(uci get oled.@oled[0].lanip)
cputemp=$(uci get oled.@oled[0].cputemp)
cpufreq=$(uci get oled.@oled[0].cpufreq)
netspeed=$(uci get oled.@oled[0].netspeed)
time=$(uci get oled.@oled[0].time)
drawline=$(uci get oled.@oled[0].drawline)
drawrect=$(uci get oled.@oled[0].drawrect)
fillrect=$(uci get oled.@oled[0].fillrect)
drawcircle=$(uci get oled.@oled[0].drawcircle)
drawroundrect=$(uci get oled.@oled[0].drawroundrect)
fillroundrect=$(uci get oled.@oled[0].fillroundrect)
drawtriangle=$(uci get oled.@oled[0].drawtriangle)
filltriangle=$(uci get oled.@oled[0].filltriangle)
displaybitmap=$(uci get oled.@oled[0].displaybitmap)
displayinvertnormal=$(uci get oled.@oled[0].displayinvertnormal)
drawbitmapeg=$(uci get oled.@oled[0].drawbitmapeg)
scroll=$(uci get oled.@oled[0].scroll)
text=$(uci get oled.@oled[0].text)
netsource=$(uci get oled.@oled[0].netsource)
if [ ${netspeed} -eq 1 ]; then
nohup /usr/sbin/netspeed ${netsource} >/dev/null 2>&1 &
else
ps|grep netspeed|grep -v grep|awk '{print $1}'|xargs kill -9
rm -f /tmp/netspeed
fi
nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" 0 > /dev/null 2>&1 &
else
stop
fi

View File

@ -60,7 +60,7 @@ int main(int argc, char* argv[])
int scroll=atoi(argv[18]);
char *text=argv[19];
char *eth = argv[20];
int needinit=atoi(argv[21]);
/* Initialize I2C bus and connect to the I2C Device */
@ -77,9 +77,9 @@ int main(int argc, char* argv[])
/* Register the Alarm Handler */
signal(SIGALRM, ALARMhandler);
signal(SIGINT, BreakDeal);
signal(SIGTERM, BreakDeal);
//signal(SIGTERM, BreakDeal);
/* Run SDD1306 Initialization Sequence */
display_Init_seq();
if (needinit==1) {display_Init_seq();}
/* Clear display */
clearDisplay();

View File

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-clash
PKG_VERSION:=v1.7.5.4
PKG_VERSION:=v1.7.5.5
PKG_MAINTAINER:=frainzy1477
include $(INCLUDE_DIR)/package.mk
@ -117,7 +117,6 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/share/clash/yacd
$(INSTALL_DIR) $(1)/etc/clash/clashtun
$(INSTALL_DIR) $(1)/etc/clash/dtun
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_DIR) $(1)/usr/share/clashbackup
$(INSTALL_DIR) $(1)/usr/share/clash/create
$(INSTALL_DIR) $(1)/etc/clash/provider
@ -145,10 +144,10 @@ define Package/$(PKG_NAME)/install
$(INSTALL_BIN) ./root/usr/share/clash/clash.txt $(1)/usr/share/clash
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/index.html $(1)/etc/clash/dashboard
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/main.4563da698059d88c08dc.css $(1)/etc/clash/dashboard
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/main.3f7e8457ba9e97b6d7c9.css $(1)/etc/clash/dashboard
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/img/ffac0fa1d89f15922b4594863b8b32e9.png $(1)/etc/clash/dashboard/img
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/js/1.bundle.4563da698059d88c08dc.min.js $(1)/etc/clash/dashboard/js
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/js/bundle.4563da698059d88c08dc.min.js $(1)/etc/clash/dashboard/js
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/js/1.bundle.3f7e8457ba9e97b6d7c9.min.js $(1)/etc/clash/dashboard/js
$(INSTALL_BIN) ./root/usr/share/clash/dashboard/js/bundle.3f7e8457ba9e97b6d7c9.min.js $(1)/etc/clash/dashboard/js
$(INSTALL_BIN) ./root/usr/share/clash/yacd/* $(1)/usr/share/clash/yacd
$(INSTALL_DATA) ./luasrc/clash.lua $(1)/usr/lib/lua/luci

View File

@ -178,9 +178,6 @@ local function check_core()
return luci.sys.exec("sh /usr/share/clash/check_core_version.sh")
end
local function check_clashr_core()
return luci.sys.exec("sh /usr/share/clash/check_clashr_core_version.sh")
end
local function check_clashtun_core()
return luci.sys.exec("sh /usr/share/clash/check_clashtun_core_version.sh")
@ -198,9 +195,6 @@ local function new_core_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_core_version")
end
local function new_clashr_core_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_clashr_core_version")
end
local function new_clashtun_core_version()
return luci.sys.exec("sed -n 1p /usr/share/clash/new_clashtun_core_version")
@ -233,18 +227,6 @@ local function clash_core()
end
local function clashr_core()
if nixio.fs.access("/usr/bin/clash") then
local core=luci.sys.exec("/usr/bin/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
if core ~= "" then
return luci.sys.exec("/usr/bin/clash -v 2>/dev/null |awk -F ' ' '{print $2}'")
else
return luci.sys.exec("sed -n 1p /usr/share/clash/corer_version")
end
else
return "0"
end
end
local function clashtun_core()
@ -333,11 +315,8 @@ function check_status()
check_version = check_version(),
check_core = check_core(),
current_version = current_version(),
check_clashr_core = check_clashr_core(),
new_version = new_version(),
new_clashr_core_version = new_clashr_core_version(),
clash_core = clash_core(),
clashr_core = clashr_core(),
check_dtun_core = check_dtun_core(),
new_dtun_core = new_dtun_core(),
clashtun_core = clashtun_core(),
@ -361,9 +340,7 @@ function action_status()
new_core_version = new_core_version(),
new_clashtun_core_version =new_clashtun_core_version(),
new_version = new_version(),
new_clashr_core_version = new_clashr_core_version(),
clash_core = clash_core(),
clashr_core = clashr_core(),
dtun_core = dtun_core(),
dash_pass = dash_pass(),
clashtun_core = clashtun_core(),

View File

@ -18,16 +18,13 @@ o.default = "clashcore"
if nixio.fs.access("/etc/clash/clash") then
o:value("1", translate("Clash"))
end
if nixio.fs.access("/usr/bin/clash") then
o:value("2", translate("Clashr"))
end
if nixio.fs.access("/etc/clash/clashtun/clash") then
o:value("3", translate("Clash(cTun)"))
end
if nixio.fs.access("/etc/clash/dtun/clash") then
o:value("4", translate("Clash(dTun)"))
o:value("4", translate("Clash(premium)"))
end
o.description = translate("Select core, clashr support ssr while clash does not.")
o = s:option(ListValue, "g_rules", translate("Game Rules"))
o.default = "0"

View File

@ -43,22 +43,9 @@ local encrypt_methods_ssr = {
"aes-128-ctr",
"aes-192-ctr",
"aes-256-ctr",
"aes-128-ofb",
"aes-192-ofb",
"aes-256-ofb",
"des-cfb",
"bf-cfb",
"cast5-cfb",
"rc4-md5",
"chacha20",
"chacha20-ietf",
"salsa20",
"camellia-128-cfb",
"camellia-192-cfb",
"camellia-256-cfb",
"idea-cfb",
"rc2-cfb",
"seed-cfb",
}
@ -68,6 +55,8 @@ local protocol_ssr = {
"auth_sha1_v4",
"auth_aes128_md5",
"auth_aes128_sha1",
"auth_chain_a",
"auth_chain_b",
}
@ -77,6 +66,8 @@ local obfs_ssr_list = {
"http_simple",
"http_post",
"tls1.2_ticket_auth",
"tls1.2_ticket_fastauth",
"random_head",
}
m = Map(clash, translate("Edit Server"))
@ -201,6 +192,7 @@ o = s:option(ListValue, "udp", translate("udp"))
o:value("true")
o:value("false")
o:depends("type", "ss")
o:depends("type", "ssr")
o:depends("type", "vmess")
o:depends("type", "socks5")
o:depends("type", "trojan")

View File

@ -26,11 +26,9 @@ o.description =''..font_red..bold_on..translate("Manually download, unzip and re
.."<br />"
..translate("Dreamacro clash tun core (dtun) - (https://github.com/Dreamacro/clash/releases/tag/premium)")
.."<br />"
..translate("comzyh clash tun core (ctun) - (https://github.com/comzyh/clash/releases)")
.."<br />"
..translate("Dreamacro clash core - (https://github.com/Dreamacro/clash/releases)")
.."<br />"
..translate("Frainzy1477 clashr core - (https://github.com/frainzy1477/clashrdev/releases)")
..translate("comzyh clash tun core (ctun) - (https://github.com/comzyh/clash/releases)")
.."<br />"
..translate("Frainzy1477 clash core - (https://github.com/frainzy1477/clash_dev/releases)")
@ -42,7 +40,6 @@ um.template = "clash/clash_dvalue"
local dir, fd,dtun,ctun,cssr
dir = "/etc/clash/"
cssr="/usr/bin/"
dtun="/etc/clash/dtun/"
ctun="/etc/clash/clashtun/"
@ -54,8 +51,6 @@ http.setfilehandler(
if fp == "clash" then
if meta and chunk then fd = nixio.open(dir .. meta.file, "w") end
elseif fp == "clashr" then
if meta and chunk then fd = nixio.open(cssr .. meta.file, "w") end
elseif fp == "clashctun" then
if meta and chunk then fd = nixio.open(ctun .. meta.file, "w") end
elseif fp == "clashdtun" then
@ -78,10 +73,6 @@ http.setfilehandler(
SYS.exec("chmod 755 /etc/clash/clash 2>&1 &")
SYS.exec("rm -rf /usr/share/clash/core_version 2>/dev/null && /etc/clash/clash -v | awk -F ' ' '{print $2}' >> /usr/share/clash/core_version 2>/dev/null")
um.value = translate("File saved to") .. ' "/etc/clash/'..meta.file..'"'
elseif fp == "clashr" then
SYS.exec("chmod 755 /usr/bin/clash 2>&1 &")
SYS.exec("rm -rf /usr/share/clash/corer_version 2>/dev/null && /usr/bin/clash -v | awk -F ' ' '{print $2}' >> /usr/share/clash/corer_version 2>/dev/null")
um.value = translate("File saved to") .. ' "/usr/bin/'..meta.file..'"'
elseif fp == "clashctun" then
SYS.exec("chmod 755 /etc/clash/clashtun/clash 2>&1 &")
SYS.exec("rm -rf /usr/share/clash/tun_version 2>/dev/null && /etc/clash/clashtun/clash -v | awk -F ' ' '{print $2}' >> /usr/share/clash/tun_version 2>/dev/null")
@ -116,10 +107,9 @@ s.anonymous = true
o = s:option(ListValue, "dcore", translate("Core Type"))
o.default = "clashcore"
o:value("1", translate("Clash"))
o:value("2", translate("Clashr"))
o:value("3", translate("Clash(ctun)"))
o:value("4", translate("Clash(dtun)"))
o.description = translate("Select core, clashr support ssr while clash does not.")
o:value("4", translate("Clash(premium)"))
local cpu_model=SYS.exec("opkg status libc 2>/dev/null |grep 'Architecture' |awk -F ': ' '{print $2}' 2>/dev/null")

View File

@ -13,14 +13,11 @@
<tr>
<td align="center" width="35%">clash</td> <td align="center" width="35%" id="_core"><%:Collecting data...%></td> <td width="35%" align="center" id="_corebutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">clashr</td> <td align="center" width="35%" id="_corer"><%:Collecting data...%></td> <td width="35%" align="center" id="_corerbutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">clash(ctun)</td> <td align="center" width="35%" id="_coretun"><%:Collecting data...%></td> <td width="35%" align="center" id="_coretunbutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">clash(dtun)</td> <td align="center" width="35%" id="_coredtun"><%:Collecting data...%></td> <td width="35%" align="center" id="_coredtunbutt"><font color="red"><%:Checking...%></font> </td>
<td align="center" width="35%">clash(premium)</td> <td align="center" width="35%" id="_coredtun"><%:Collecting data...%></td> <td width="35%" align="center" id="_coredtunbutt"><font color="red"><%:Checking...%></font> </td>
</tr>
<tr>
<td align="center" width="35%">luci-app-clash</td> <td align="center" width="35%" id="_version"><%:Collecting data...%> </td> <td width="35%" align="center" id="_versionbutt"><font color="red"><%:Checking...%></font> </td>
@ -38,7 +35,6 @@
var version = document.getElementById('_version');
var core = document.getElementById('_core');
var corer = document.getElementById('_corer');
var coretun = document.getElementById('_coretun');
var version_butt = document.getElementById('_versionbutt');
var core_butt = document.getElementById('_corebutt');
@ -55,11 +51,6 @@
}else{
core.innerHTML = status.clash_core ? '<b><font color="green">'+status.clash_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
if(status.clashr_core==0){
corer.innerHTML = status.clashr_core ? '<b><font color="red"><%:Not Installed%></font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}else{
corer.innerHTML = status.clashr_core ? '<b><font color="green">'+status.clashr_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}
if(status.clashtun_core==0){
coretun.innerHTML = status.clashtun_core ? '<b><font color="red"><%:Not Installed%></font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
}else{
@ -83,7 +74,6 @@
if ( x && x.status == 200 ) {
version_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
core_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_core_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
corer_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_clashr_core_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
coretun_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_clashtun_core_version+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';
coredtun_butt.innerHTML = status.current_version ? '<b><font color="green">'+status.new_dtun_core+'</font> </b>' : '<em><b><font color="red"><%:Checking...%></font></b></em>';

View File

@ -1,9 +1,8 @@
<%+cbi/valueheader%>
<select name="file_type" style="width:20%">&nbsp;&nbsp;&nbsp;
<option value="clash" selected="selected"><%:clash%></option>
<option value="clashr"><%:clashr%></option>
<option value="clashctun"><%:clash(ctun)%></option>
<option value="clashdtun"><%:clash(dtun)%></option>
<option value="clashdtun"><%:clash(premium)%></option>
</select>
<input class="cbi-input-file" style="width: 60%" type="file" id="ulfile" name="ulfile" />
<input type="submit" style="width: 100%" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload%>" />

View File

@ -4,7 +4,6 @@ START=99
STOP=15
CLASH="/etc/clash/clash"
CLASHR="/usr/bin/clash"
CLASHT="/etc/clash/clashtun/clash"
CLASHD="/etc/clash/dtun/clash"
CLASH_CONFIG="/etc/clash"
@ -455,22 +454,11 @@ if [ "${core}" -eq 1 ] && [ ! -f /etc/clash/clash ]; then
echo "找不到/etc/clash/clash,请从更新页下载clash内核" >> $REAL_LOG
fi
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
elif [ "${core}" -eq 2 ] && [ ! -f /usr/bin/clash ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - clashr core not found in /usr/bin/clash download and install clashr from update page " >> /usr/share/clash/clash.txt
echo "clashr core not found, download and install clash from update page" >> $REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 找不到/usr/bin/clash,请从更新页下载clashr内核" >> /usr/share/clash/clash.txt
echo "找不到/usr/bin/clash,请从更新页下载clashr内核" >> $REAL_LOG
fi
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
elif [ "${core}" -eq 3 ] && [ ! -f /etc/clash/clashtun/clash ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - clashr Tun core not found in /etc/clash/clashtun/clash " >> /usr/share/clash/clash.txt
echo " $(date "+%Y-%m-%d %H:%M:%S") - clash Tun core not found in /etc/clash/clashtun/clash " >> /usr/share/clash/clash.txt
echo "clash Tun core not found in /etc/clash/clashtun/clash" >> $REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo " $(date "+%Y-%m-%d %H:%M:%S") - 找不到/etc/clash/clashtun/clash, clash Tun内核" >> /usr/share/clash/clash.txt
@ -572,22 +560,6 @@ if [ -f $CONFIG_YAML ] && [ "$(ls -l $CONFIG_YAML|awk '{print int($5)}')" -ne
yml_change >/dev/null 2>&1
checktype=$(grep -c "type: ssr" /etc/clash/config.yaml 2>/dev/null)
if [ "${checktype}" -gt 0 ] && [ "${core}" -ne 2 ]; then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clash Core does not Support Config, use clashr core" >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clash内核不支持你的配置改用Clashr内核" >$REAL_LOG
fi
remove_mark >/dev/null 2>&1
sleep 1
echo "Clash for OpenWRT" >$REAL_LOG
exit 0
fi
if [ ! -f /etc/clash/Country.mmdb ];then
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Cannot find Country.mmdb" >$REAL_LOG
@ -643,15 +615,6 @@ if [ -f $CONFIG_YAML ] && [ "$(ls -l $CONFIG_YAML|awk '{print int($5)}')" -ne
elif [ "${lang}" == "zh_cn" ];then
echo "Clash 计划任务,启动进程守护程序..." >$REAL_LOG
fi
elif [ "$(uci get clash.config.core)" -eq 2 ];then
nohup $CLASHR -d "$CLASH_CONFIG" > /usr/share/clash/clash.txt 2>&1 &
if [ "${lang}" == "en" ] || [ $lang == "auto" ];then
echo "Clashr Core Started Successfully " >$REAL_LOG
elif [ "${lang}" == "zh_cn" ];then
echo "Clashr 计划任务,启动进程守护程序..." >$REAL_LOG
fi
fi
ln -s /usr/share/clash/yacd /www/luci-static/yacd 2>/dev/null

View File

@ -1,12 +0,0 @@
#!/bin/sh
new_clashr_core_version=`curl -sL "https://github.com/frainzy1477/clashrdev/tags"| grep "/frainzy1477/clashrdev/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ "$?" -eq "0" ]; then
rm -rf /usr/share/clash/new_clashr_core_version
if [ $new_clashr_core_version ]; then
echo $new_clashr_core_version > /usr/share/clash/new_clashr_core_version 2>&1 & >/dev/null
elif [ $new_clashr_core_version =="" ]; then
echo 0 > /usr/share/clash/new_clashr_core_version 2>&1 & >/dev/null
fi
fi

View File

@ -60,29 +60,6 @@ CLASHTUN=$(sed -n 1p /usr/share/clash/download_tun_version 2>/dev/null)
fi
fi
if [ $CORETYPE -eq 2 ];then
if [ -f /usr/share/clash/download_corer_version ];then
rm -rf /usr/share/clash/download_corer_version
fi
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - 正在检查最新版本。。" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Checking latest version.." >$LOG_FILE
fi
new_clashr_core_version=`wget -qO- "https://github.com/frainzy1477/clashrdev/tags"| grep "/frainzy1477/clashrdev/releases/"| head -n 1| awk -F "/tag/" '{print $2}'| sed 's/\">//'`
if [ $new_clashr_core_version ]; then
echo $new_clashr_core_version > /usr/share/clash/download_corer_version 2>&1 & >/dev/null
elif [ $new_clashr_core_version =="" ]; then
echo 0 > /usr/share/clash/download_corer_version 2>&1 & >/dev/null
fi
sleep 5
if [ -f /usr/share/clash/download_corer_version ];then
CLASHRVER=$(sed -n 1p /usr/share/clash/download_corer_version 2>/dev/null)
fi
fi
if [ $CORETYPE -eq 1 ];then
if [ -f /usr/share/clash/download_core_version ];then
rm -rf /usr/share/clash/download_core_version
@ -118,8 +95,6 @@ update(){
fi
if [ $CORETYPE -eq 1 ];then
wget --no-check-certificate https://github.com/frainzy1477/clash_dev/releases/download/"$CLASHVER"/clash-"$MODELTYPE".gz -O 2>&1 >1 /tmp/clash.gz
elif [ $CORETYPE -eq 2 ];then
wget --no-check-certificate https://github.com/frainzy1477/clashrdev/releases/download/"$CLASHRVER"/clashr-"$MODELTYPE".gz -O 2>&1 >1 /tmp/clash.gz
elif [ $CORETYPE -eq 3 ];then
wget --no-check-certificate https://github.com/frainzy1477/clashtun/releases/download/"$CLASHTUN"/clash-"$MODELTYPE".gz -O 2>&1 >1 /tmp/clash.gz
elif [ $CORETYPE -eq 4 ];then
@ -155,19 +130,6 @@ update(){
echo " ${LOGTIME} - Clash Core Update Successful" >$LOG_FILE
fi
elif [ $CORETYPE -eq 2 ];then
rm -rf /usr/bin/clash >/dev/null 2>&1
mv /tmp/clash /usr/bin/clash >/dev/null 2>&1
rm -rf /usr/share/clash/corer_version >/dev/null 2>&1
mv /usr/share/clash/download_corer_version /usr/share/clash/corer_version >/dev/null 2>&1
if [ $lang == "zh_cn" ];then
echo " ${LOGTIME} - Clashr内核更新成功" >$LOG_FILE
elif [ $lang == "en" ] || [ $lang == "auto" ];then
echo " ${LOGTIME} - Clashr Core Update Successful" >>$LOG_FILE
fi
elif [ $CORETYPE -eq 3 ];then
rm -rf /etc/clash/clashtun/clash >/dev/null 2>&1
mv /tmp/clash /etc/clash/clashtun/clash >/dev/null 2>&1
@ -207,7 +169,7 @@ update(){
fi
}
if [ $CORETYPE -eq 1 ] || [ $CORETYPE -eq 2 ] || [ $CORETYPE -eq 3 ] || [ $CORETYPE -eq 4 ]; then
if [ $CORETYPE -eq 1 ] || [ $CORETYPE -eq 3 ] || [ $CORETYPE -eq 4 ]; then
update
fi

View File

@ -622,10 +622,15 @@ cat >> "$SERVER_FILE" <<-EOF
cipher: $cipher_ssr
password: "$password"
protocol: "$protocol"
protocolparam: "$protocolparam"
protocol-param: "$protocolparam"
obfs: "$obfs_ssr"
obfsparam: "$obfsparam"
obfs-param: "$obfsparam"
EOF
if [ ! -z "$udp" ]; then
cat >> "$SERVER_FILE" <<-EOF
udp: $udp
EOF
fi
fi

View File

@ -1 +1 @@
<!doctype html><html lang="en" dir="ltr"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel="icon" type="image/x-icon" href="https://cdn.jsdelivr.net/gh/Dreamacro/clash/docs/logo.png"/><title>Clash Dashboard</title><link href="main.4563da698059d88c08dc.css" rel="stylesheet"></head><body><div id="root"></div><script src="js/1.bundle.4563da698059d88c08dc.min.js"></script><script src="js/bundle.4563da698059d88c08dc.min.js"></script></body></html>
<!doctype html><html lang="en" dir="ltr"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel="icon" type="image/x-icon" href="https://cdn.jsdelivr.net/gh/Dreamacro/clash/docs/logo.png"/><title>Clash</title><link href="main.3f7e8457ba9e97b6d7c9.css" rel="stylesheet"></head><body><div id="root"></div><script src="js/1.bundle.3f7e8457ba9e97b6d7c9.min.js"></script><script src="js/bundle.3f7e8457ba9e97b6d7c9.min.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,6 @@
.rule-provider{position:relative;display:flex;flex-direction:column;font-size:16px;padding:20px;color:#546b87}.rule-provider-header{display:flex;align-items:center;justify-content:space-between}.rule-provider-header-part{display:flex;align-items:center}.rule-provider-name{width:120px;margin-right:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rule-provider-behavior{width:80px;margin:0 20px 0 12px;background-color:#2c8af8;color:#fff}.rule-provider-spinner{transform:scale(0.4)}.rule-provider-proxies{list-style:none}.rule-provider-item{box-shadow:0 0 24px 0 rgba(44,138,248,.2)}.rule-provider-item:hover{box-shadow:0 0 24px 0 rgba(84,117,154,.4)}.rule-provider-update{line-height:14px;font-size:14px}.rule-provider-icon{display:block;margin-left:20px;cursor:pointer}.rule-provider-icon.rule-provider-loading::before{color:#909399;cursor:not-allowed;-webkit-animation:spinner 2s infinite linear;animation:spinner 2s infinite linear}@media(max-width: 768px){.rule-provider-header{flex-direction:column;align-items:flex-start}.rule-provider-header-part{margin:6px 0}}
.rules-card{display:flex;flex-direction:column;flex:1;min-height:700px;margin-top:10px;padding:0}.rules-card:focus{outline:none}.rules-card .rules{flex:1 0 auto}.rule-item{line-height:30px;padding:5px 0;height:50px;overflow:hidden;list-style:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-bottom:1px solid rgba(228,234,239,.5)}.rule-item .rule-item-row{padding:5px 0}.rule-item .drag-handler{cursor:row-resize;margin:0 10px;display:flex;justify-content:center}.rule-item .drag-handler>i{font-weight:bold;color:#b7c5d6}.rule-item .rule-type{font-size:14px;color:#54759a}.rule-item .rule-type>i{margin-left:5px;color:#54759a}.rule-item .payload{font-size:14px;color:#54759a;cursor:pointer}.rule-item .rule-proxy{font-size:14px;color:#54759a}.rule-item .delete-btn{opacity:0;transition:all 300ms ease}.rule-item .delete-btn span{font-size:14px;color:#f56c6c;cursor:pointer}.rule-item:last-child{border-bottom:none}.rule-item:hover .delete-btn{opacity:1}.rule-proxy-option{display:flex;align-items:center;overflow:hidden}.rule-proxy-option .label{margin-right:5px;height:20px;line-height:20px;padding:0 8px;font-size:10px;border-radius:10px;color:#fff;background:#b7c5d6}.rule-proxy-option .value{line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.settings-card{margin-top:10px;padding:20px 0}.settings-card .column{font-weight:bold;align-items:center}.settings-card .value-column{justify-content:flex-end}.settings-card .label{font-size:14px;color:#54759a}.settings-card .external-controller{font-size:14px;color:#54759a;display:flex;justify-content:flex-end;font-weight:normal;line-height:17px}.settings-card .external-controller .modify-btn{color:#2c8af8;cursor:pointer}.clash-version{position:relative;margin-top:10px;padding:20px 45px;display:flex}.clash-version .check-icon{width:24px;height:24px;border-radius:50%;background:linear-gradient(135deg, #57befc, #2c8af8);display:flex;justify-content:center;align-items:center}.clash-version .check-icon>i{transform:scale(0.5);color:#fff;font-weight:bold}.clash-version .version-info{margin-left:10px;font-size:14px;line-height:24px;color:#54759a}.clash-version .check-update-btn{position:absolute;right:45px;font-size:14px;line-height:24px;color:#b7c5d6;cursor:pointer;transition:all 150ms ease}.clash-version .check-update-btn:hover{color:#54759a}@media(max-width: 768px){.settings-card .row{flex-direction:column;padding-top:0;padding-bottom:0}.settings-card .row>.column{width:100%;margin:10px 0}}
.sidebar{position:fixed;top:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:160px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.sidebar-logo{margin-top:50px;width:60px;height:60px}.sidebar-menu{display:flex;flex-direction:column;flex:1;margin-top:12px}.sidebar-menu .item{display:block;margin-top:18px}.sidebar-menu .item>a{display:block;width:120px;height:36px;line-height:36px;font-size:14px;border-radius:18px;text-align:center}.sidebar-menu .item>a,.sidebar-menu .item a:active,.sidebar-menu .item a:visited{color:#909399;text-decoration:none}.sidebar-menu .item>a.active{background:linear-gradient(135deg, #57befc, #2c8af8);color:#fff;box-shadow:0 2px 8px rgba(44,138,248,.5)}.sidebar-version{display:flex;flex-direction:column;align-items:center;padding-bottom:20px}.sidebar-version-label{font-size:14px;color:#2c8af8;text-shadow:0 2px 6px rgba(44,138,248,.4)}.sidebar-version-text{text-align:center;font-size:14px;margin:8px 0;color:#54759a}@media(max-width: 768px){.sidebar{width:100%;height:60px;flex-direction:row;background:#f4f5f6;z-index:10}.sidebar-logo{margin:0 15px;width:36px;height:36px}.sidebar-menu{flex:1;flex-direction:row;justify-content:center;margin-top:0;overflow-x:scroll;padding:10px}.sidebar-menu::-webkit-scrollbar{display:none}.sidebar-menu .item{margin:0 3px}.sidebar-menu .item>a{width:80px;height:32px;line-height:32px}.sidebar-menu .item.no-mobile{display:none}.sidebar-version{display:none}}
.sidebar{position:fixed;top:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:160px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.sidebar-logo{margin-top:50px;width:60px;height:60px}.sidebar-menu{display:flex;flex-direction:column;flex:1;margin-top:12px}.sidebar-menu .item{display:block;margin-top:18px}.sidebar-menu .item>a{display:block;width:120px;height:36px;line-height:36px;font-size:14px;border-radius:18px;text-align:center}.sidebar-menu .item>a,.sidebar-menu .item a:active,.sidebar-menu .item a:visited{color:#909399;text-decoration:none}.sidebar-menu .item>a.active{background:linear-gradient(135deg, #57befc, #2c8af8);color:#fff;box-shadow:0 2px 8px rgba(44,138,248,.5)}.sidebar-version{display:flex;flex-direction:column;align-items:center;padding-bottom:20px}.sidebar-version-label{font-size:14px;color:#2c8af8;text-shadow:0 2px 6px rgba(44,138,248,.4)}.sidebar-version-text{text-align:center;font-size:14px;margin:8px 0;padding:0 10px;color:#54759a}@media(max-width: 768px){.sidebar{width:100%;height:60px;flex-direction:row;background:#f4f5f6;z-index:10}.sidebar-logo{margin:0 15px;width:36px;height:36px}.sidebar-menu{flex:1;flex-direction:row;justify-content:center;margin-top:0;overflow-x:scroll;padding:10px}.sidebar-menu::-webkit-scrollbar{display:none}.sidebar-menu .item{margin:0 3px}.sidebar-menu .item>a{width:80px;height:32px;line-height:32px}.sidebar-menu .item.no-mobile{display:none}.sidebar-version{display:none}}
.connections-card{display:flex;flex-direction:column;flex:1;margin-top:10px;padding:0;overflow:hidden}.connections-card .connections{display:flex;flex-direction:column;width:100%;flex-grow:1;flex-basis:0;overflow:auto}.connections-card .connections-body{flex:1 0 auto}.connections-card .connections-th{position:relative;text-align:center;color:#909399;background:#f3f6f9;height:30px;line-height:30px;font-weight:500;font-size:14px;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.connections-card .connections-resizer{position:absolute;opacity:0;right:-10px;top:8px;bottom:8px;width:20px;transition:opacity .3s ease;z-index:10;font-size:14px;font-weight:300}.connections-card .connections-resizer::before{content:"";display:block;position:absolute;left:10px;transform:translateX(-2px);width:2px;height:100%;background-color:rgba(144,147,153,.6)}.connections-card .connections-header{position:-webkit-sticky;position:sticky;top:0;white-space:nowrap}.connections-card .connections-header:hover .connections-resizer{opacity:1}.connections-card .connetions-item{height:36px}.connections-card .connections-block{display:flex;align-items:center;font-size:14px;line-height:36px;padding:0 10px;color:#54759a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.connections-card .connections-block.center{text-align:center}.connections-card .connections-block.completed{background-color:#e9eef4;color:rgba(84,117,154,.5)}.connections-filter{color:#2c8af8;font-size:14px;line-height:20px;margin-left:15px;text-shadow:0 0 6px rgba(44,138,248,.4);cursor:pointer}.connections-filter.dangerous{color:#f56c6c;text-shadow:0 0 6px rgba(87,190,252,.2)}.connections-filter.total{flex:1;cursor:unset}
.external-controller .row{padding:0}.external-controller .alert{margin:10px 0}.external-controller .title,.external-controller .form{margin:15px 0}.external-controller .title{margin-top:15px;font-size:14px;font-weight:bold}@media(max-width: 768px){.external-controller .row{flex-direction:column;align-items:flex-start}.external-controller .title{margin:5px 0}.external-controller .form{margin:5px 0}.external-controller .column{width:100%}.external-controller .alert{display:none}}

View File

@ -25,7 +25,7 @@ elif [ ! -z "$(grep "^rules:" "$CLASH_CONFIG")" ]; then
fi
sed -i -e "\$a#RULEEND#" $CLASH_CONFIG 2>/dev/null
awk '/#RULESTART#/,/#RULEEND#/{print}' "$CLASH_CONFIG" 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed 's/\t/ /g' 2>/dev/null |grep - |awk -F '- ' '{print "- "$2}' | sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null >$RULE 2>&1
awk '/#RULESTART#/,/#RULEEND#/{print}' "$CLASH_CONFIG" 2>/dev/null |sed "s/\'//g" 2>/dev/null |sed 's/\"//g' 2>/dev/null |sed 's/\t/ /g' 2>/dev/null |grep '^ \{0,\}- '|awk -F '- ' '{print "- "$2}' | sed 's/^ \{0,\}//' 2>/dev/null |sed 's/ \{0,\}$//' 2>/dev/null >$RULE 2>&1
sed -i '/#RULESTART#/,/#RULEEND#/d' "$CLASH_CONFIG" 2>/dev/null
@ -77,10 +77,8 @@ if [ -f $CUSTOM_RULE_FILE ];then
sed -i -e "\$a#CUSTOMRULEEND#" $CUSTOM_RULE_FILE 2>/dev/null
sed -i '/#CUSTOMRULESTART#/,/#CUSTOMRULEEND#/d' "$CLASH_CONFIG" 2>/dev/null
if [ ! -z "$(grep "^ \{0,\}- GEOIP" "$CLASH_CONFIG")" ]; then
sed -i '1,/^ \{0,\}- GEOIP,/{/^ \{0,\}- GEOIP,/s/^ \{0,\}- GEOIP,/#CUSTOMRULESTART#\n&/}' "$CLASH_CONFIG" 2>/dev/null
elif [ ! -z "$(grep "^ \{0,\}- MATCH," "$CLASH_CONFIG")" ]; then
sed -i '1,/^ \{0,\}- MATCH,/{/^ \{0,\}- MATCH,/s/^ \{0,\}- MATCH,/#CUSTOMRULESTART#\n&/}' "$CLASH_CONFIG" 2>/dev/null
if [ ! -z "$(grep "^ \{0,\}rules:" "$CLASH_CONFIG")" ]; then
sed -i '/rules:/a\#CUSTOMRULESTART#' "$CLASH_CONFIG" 2>/dev/null
else
echo "#CUSTOMRULESTART#" >> "$CLASH_CONFIG" 2>/dev/null
fi

View File

@ -1 +1 @@
v1.7.5.4
v1.7.5.5

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
/*! modern-normalize v0.6.0 | MIT License | https://github.com/sindresorhus/modern-normalize */*,:after,:before{box-sizing:border-box}:root{-moz-tab-size:4;tab-size:4}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}hr{height:0}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{padding:0}progress{vertical-align:initial}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}
@font-face{font-family:Roboto Mono;font-style:normal;font-display:swap;font-weight:400;src:local("Roboto Mono Regular "),local("Roboto Mono-Regular"),url(roboto-mono-latin-400.woff2) format("woff2")}@font-face{font-family:Open Sans;font-style:normal;font-display:swap;font-weight:400;src:local("Open Sans Regular "),local("Open Sans-Regular"),url(open-sans-latin-400.woff2) format("woff2")}@font-face{font-family:Open Sans;font-style:normal;font-display:swap;font-weight:700;src:local("Open Sans Bold "),local("Open Sans-Bold"),url(open-sans-latin-700.woff2) format("woff2")}.border-bottom,.border-left,.border-top,.relative{position:relative}.border-top:before{top:0}.border-bottom:after,.border-top:before{position:absolute;content:"";height:1px;width:100%;transform:scaleY(.5) translateZ(0);left:0;right:0;background:#555}.border-bottom:after{bottom:0}.border-left:before{position:absolute;content:"";height:100%;width:1px;transform:scaleX(.5) translateZ(0);top:0;bottom:0;background:#555;left:0}*,:after,:before{box-sizing:border-box}:root{--font-mono:"Roboto Mono",Menlo,monospace;--font-normal:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,"PingFang SC","Microsoft YaHei","微软雅黑",Arial,sans-serif;--color-focus-blue:#1a73e8}body{font-family:Open Sans,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,PingFang SC,Microsoft YaHei,;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-text-size-adjust:100%;-webkit-font-smoothing:antialiased;margin:0;padding:0}body,body.dark{--color-background:#202020;--color-text:#ddd;--color-text-secondary:#ccc;--color-text-highlight:#fff;--color-bg-sidebar:#2d2d30;--color-sb-active-row-bg:#494b4e;--color-input-bg:#2d2d30;--color-input-border:#3f3f3f;--color-toggle-bg:#353535;--color-toggle-selected:#181818;--color-icon:#c7c7c7;--color-separator:#333;--color-btn-bg:#232323;--color-btn-fg:#bebebe;--color-bg-proxy:#303030;--color-row-odd:#282828;--bg-modal:#1f1f20;--bg-near-transparent:hsla(0,0%,100%,0.1);--select-border-color:#040404;--select-bg-hover:url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 7l3 4H1l3-4zM4 17l-3-4h6l-3 4z' fill='%23fff'/%3E%3C/svg%3E")}body.light{--color-background:#fbfbfb;--color-text:#222;--color-text-secondary:#646464;--color-text-highlight:#040404;--color-bg-sidebar:#e7e7e7;--color-sb-active-row-bg:#d0d0d0;--color-input-bg:#fff;--color-input-border:silver;--color-toggle-bg:#fff;--color-toggle-selected:#d7d7d7;--color-icon:#5b5b5b;--color-separator:#ccc;--color-btn-bg:#f4f4f4;--color-btn-fg:#101010;--color-bg-proxy:#e7e7e7;--color-row-odd:#f5f5f5;--bg-modal:#fbfbfb;--bg-near-transparent:rgba(0,0,0,0.1);--select-border-color:#999;--select-bg-hover:url("data:image/svg+xml;charset=utf-8,%3Csvg width='8' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 7l3 4H1l3-4zM4 17l-3-4h6l-3 4z' fill='%23222'/%3E%3C/svg%3E")}.flexCenter{display:flex;align-items:center;justify-content:center}.fabgrp{position:fixed;z-index:3;right:20px;bottom:20px}
._3hz7LVhvUv:focus{outline:none}._3HF-KB9mgO{display:flex;justify-content:center;align-items:center}._3HF-KB9mgO ._3HzgPICn91{color:#2d2d30;opacity:.4;transition:opacity .4s}._3HF-KB9mgO ._3HzgPICn91:hover{opacity:.7}._1wpZuvoD5I{padding:30px 0 10px}.L7jTy-EFJ2{display:flex}.L7jTy-EFJ2 div{flex:1 1 auto}.L7jTy-EFJ2 div:nth-child(2){flex-grow:0;flex-basis:120px;margin-left:10px}._2fehqRU9GV{padding:30px 0 10px;display:flex;justify-content:flex-end;align-items:center}
._2A0HoxnDqc{-webkit-appearance:none;outline:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-flex;align-items:center;justify-content:center;color:var(--color-btn-fg);background:var(--color-btn-bg);border:1px solid #555;border-radius:100px;font-size:.85em;padding:4px 7px}._2A0HoxnDqc:focus{border-color:var(--color-focus-blue)}._2A0HoxnDqc:hover{background:#387cec;border:1px solid #387cec;color:#fff}._2A0HoxnDqc:active{transform:scale(.97)}@media screen and (min-width:30em){._2A0HoxnDqc{font-size:1em;padding:6px 12px}}._2A0HoxnDqc.rBrOhcv1IU{border-color:transparent;background:none}._2A0HoxnDqc.rBrOhcv1IU:focus{border-color:var(--color-focus-blue)}._2A0HoxnDqc.rBrOhcv1IU:hover{color:#fff;background:#387cec;border:1px solid #387cec}.CtvjIaf7QB{margin-right:5px;display:inline-flex;align-items:center;justify-content:center}._2KAqQdptfT{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:inline-flex}
._2A0HoxnDqc{-webkit-appearance:none;outline:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:inline-flex;align-items:center;justify-content:center;color:var(--color-btn-fg);background:var(--color-btn-bg);border:1px solid #555;border-radius:100px;font-size:.85em;padding:4px 7px}._2A0HoxnDqc:focus{border-color:var(--color-focus-blue)}._2A0HoxnDqc:hover{background:#387cec;border:1px solid #387cec;color:#fff}._2A0HoxnDqc:active{transform:scale(.97)}@media screen and (min-width:30em){._2A0HoxnDqc{font-size:1em;padding:6px 12px}}._2A0HoxnDqc.rBrOhcv1IU{border-color:transparent;background:none}._2A0HoxnDqc.rBrOhcv1IU:focus{border-color:var(--color-focus-blue)}._2A0HoxnDqc.rBrOhcv1IU:hover{color:#fff;background:#387cec;border:1px solid #387cec}._2A0HoxnDqc:disabled{opacity:.5}.CtvjIaf7QB{margin-right:5px;display:inline-flex;align-items:center;justify-content:center}._2KAqQdptfT{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:inline-flex}
h2._1p7G03ShKD{margin:0;font-size:1.3em}@media screen and (min-width:30em){h2._1p7G03ShKD{font-size:1.5em}}h2._1p7G03ShKD span:nth-child(2){font-size:12px;color:#777;font-weight:400;margin:0 .3em}body.light{--loading-dot-1-1:rgba(0,0,0,0.1);--loading-dot-1-2:rgba(0,0,0,0.5);--loading-dot-1-3:rgba(0,0,0,0.3);--loading-dot-2-1:rgba(0,0,0,0.3);--loading-dot-2-2:rgba(0,0,0,0.1);--loading-dot-2-3:rgba(0,0,0,0.5);--loading-dot-3-1:rgba(0,0,0,0.5);--loading-dot-3-2:rgba(0,0,0,0.3);--loading-dot-3-3:rgba(0,0,0,0.1)}body.dark{--loading-dot-1-1:hsla(0,0%,100%,0.5);--loading-dot-1-2:hsla(0,0%,100%,0.1);--loading-dot-1-3:hsla(0,0%,100%,0.3);--loading-dot-2-1:hsla(0,0%,100%,0.3);--loading-dot-2-2:hsla(0,0%,100%,0.5);--loading-dot-2-3:hsla(0,0%,100%,0.1);--loading-dot-3-1:hsla(0,0%,100%,0.1);--loading-dot-3-2:hsla(0,0%,100%,0.3);--loading-dot-3-3:hsla(0,0%,100%,0.5)}._1l_b31nvKC,._1l_b31nvKC:after,._1l_b31nvKC:before{display:inline-block;vertical-align:middle;width:6px;height:6px;border-radius:50%;font-size:0}._1l_b31nvKC{position:relative;background-color:var(--loading-dot-2-1);animation:AmeWPxQSDb 1s step-start infinite}._1l_b31nvKC:before{content:"";position:absolute;left:-12px;background-color:var(--loading-dot-1-1);animation:_1C49ms67Ai 1s step-start infinite}._1l_b31nvKC:after{content:"";position:absolute;right:-12px;background-color:var(--loading-dot-3-1);animation:p_etI2Ova8 1s step-start infinite}@keyframes _1C49ms67Ai{0%,to{background-color:var(--loading-dot-1-1)}33%{background-color:var(--loading-dot-1-2)}66%{background-color:var(--loading-dot-1-3)}}@keyframes AmeWPxQSDb{0%,to{background-color:var(--loading-dot-2-1)}33%{background-color:var(--loading-dot-2-2)}66%{background-color:var(--loading-dot-2-3)}}@keyframes p_etI2Ova8{0%,to{background-color:var(--loading-dot-3-1)}33%{background-color:var(--loading-dot-3-2)}66%{background-color:var(--loading-dot-3-3)}}
._1r-KsYFNaj{position:relative;padding:10px 0}._1r-KsYFNaj input{-webkit-appearance:none;background-color:initial;background-image:none;border:none;border-radius:0;border-bottom:1px solid var(--color-input-border);box-sizing:border-box;color:#c1c1c1;display:inline-block;font-size:inherit;height:40px;outline:none;padding:0 8px;transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}._1r-KsYFNaj input:focus{border-color:var(--color-focus-blue)}._1r-KsYFNaj label{position:absolute;left:8px;bottom:22px;transition:transform .15s ease-in-out;transform-origin:0 0}._1r-KsYFNaj input:focus+label,._1r-KsYFNaj label.Hn6h5kxOg7{transform:scale(.75) translateY(-25px)}._1r-KsYFNaj input:focus+label{color:var(--color-focus-blue)}
._2MMSFnbhST{stroke-dasharray:890;stroke-dashoffset:890;animation:apL4DUAKgd 3s ease-in-out infinite normal forwards}@keyframes apL4DUAKgd{0%{stroke-dashoffset:890}to{stroke-dashoffset:0}}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="UTF-8"><link rel="shortcut icon" href="yacd.ico"><link rel="icon" type="image/png" sizes="64x64" href="yacd-64.png"><link rel="icon" type="image/png" sizes="128x128" href="yacd-128.png"><link rel="preload" href="/open-sans-latin-400.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/open-sans-latin-700.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/roboto-mono-latin-400.woff2" as="font" type="font/woff2" crossorigin><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="application-name" content="yacd"><meta name="description" content="Yet Another Clash Dashboard"><meta name="theme-color" content="#202020"><title>yacd - Yet Another Clash Dashboard</title><meta property="og:image" content="https://user-images.githubusercontent.com/1166872/47304841-536f3d80-d65a-11e8-8908-1917127dafc5.png"><meta property="og:site_name" content="yacd"><meta property="og:type" content="object"><meta property="og:title" content="yacd"><meta property="og:url" content="http://yacd.haishan.me"><meta property="og:description" content="Yet Another Clash Dashboard"><script defer="defer" src="runtime.2f322c031bcb67b98af2.js"></script><script defer="defer" src="core-js~app.36c6f0077ac1e602b325.js"></script><script defer="defer" src="react~app.10618449a8e9b56a1845.js"></script><script defer="defer" src="app.09d100e5dacbf4f76606.js"></script><link href="app.b814d6460bc4d015f5f9.css" rel="stylesheet"></head><body><div id="app"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="UTF-8"><link rel="shortcut icon" href="yacd.ico"><link rel="icon" type="image/png" sizes="64x64" href="yacd-64.png"><link rel="icon" type="image/png" sizes="128x128" href="yacd-128.png"><link rel="preload" href="/open-sans-latin-400.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/open-sans-latin-700.woff2" as="font" type="font/woff2" crossorigin><link rel="preload" href="/roboto-mono-latin-400.woff2" as="font" type="font/woff2" crossorigin><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="application-name" content="yacd"><meta name="description" content="Yet Another Clash Dashboard"><meta name="theme-color" content="#202020"><title>yacd - Yet Another Clash Dashboard</title><meta property="og:image" content="https://user-images.githubusercontent.com/1166872/47304841-536f3d80-d65a-11e8-8908-1917127dafc5.png"><meta property="og:site_name" content="yacd"><meta property="og:type" content="object"><meta property="og:title" content="yacd"><meta property="og:url" content="http://yacd.haishan.me"><meta property="og:description" content="Yet Another Clash Dashboard"><script defer="defer" src="runtime.30479c2b09f71505cee3.js"></script><script defer="defer" src="core-js~app.4e0935a458133ffa9ca3.js"></script><script defer="defer" src="react~app.10618449a8e9b56a1845.js"></script><script defer="defer" src="app.2710ac87312332833aa4.js"></script><link href="app.bb773b8bdd4263de9ffd.css" rel="stylesheet"></head><body><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
._2FCzysAb-M{display:grid;grid-template-columns:40px 1fr 46px;height:100%}._1hjXIQMZOU{display:inline-flex;color:var(--color-text-secondary);opacity:.4}._1hjXIQMZOU,._3ulCcX3zrK{align-items:center}._3ulCcX3zrK{display:grid;grid-template-rows:1fr auto auto}._2rDvq4osPH{color:#777}._2RFtzkPbgh{display:grid;place-items:center}._2cUdzkKfZU{display:inline-flex}._2KpM-FkfFa{animation:_36QJoL-63v 3s linear infinite}@keyframes _36QJoL-63v{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}
._1LsRPWba72{-webkit-appearance:none;background-color:var(--color-input-bg);background-image:none;border-radius:20px;border:1px solid var(--color-input-border);box-sizing:border-box;color:#c1c1c1;display:inline-block;font-size:inherit;outline:none;padding:8px 15px;transition:border-color .2s cubic-bezier(.645,.045,.355,1);width:100%}._1LsRPWba72:focus{border:1px solid var(--color-focus-blue)}
._3eSLieOhVX{display:flex;align-items:center;padding:6px 15px}@media screen and (min-width:30em){._3eSLieOhVX{padding:10px 40px}}._2n1pW09UvV{width:40px;padding-right:15px;color:var(--color-text-secondary);opacity:.4}.t1XJIwvW7A{display:flex;align-items:center;font-size:12px;opacity:.8}._1fNf8kj0HA{padding:10px 0;font-family:Roboto Mono,Menlo,monospace;font-size:16px}@media screen and (min-width:30em){._1fNf8kj0HA{font-size:19px}}._3yJmN0tON0{width:110px}
.wlEX90q03S{display:grid;grid-template-columns:1fr minmax(auto,330px);align-items:center;padding-right:15px}@media screen and (min-width:30em){.wlEX90q03S{padding-right:40px}}.MokwzRoj-f{padding:6px 15px}@media screen and (min-width:30em){.MokwzRoj-f{padding:10px 40px}}

View File

@ -1 +0,0 @@
._3eSLieOhVX{display:flex;align-items:center;padding:6px 15px}@media screen and (min-width:30em){._3eSLieOhVX{padding:10px 40px}}._2n1pW09UvV{width:40px;padding-right:15px;color:var(--color-text-secondary);opacity:.4}.t1XJIwvW7A{display:flex;align-items:center;font-size:12px;opacity:.8}._1fNf8kj0HA{padding:10px 0;font-family:Roboto Mono,Menlo,monospace;font-size:16px}@media screen and (min-width:30em){._1fNf8kj0HA{font-size:19px}}._3yJmN0tON0{width:110px}

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{BVyM:function(e,t,a){"use strict";a.r(t);var r=a("ODXe"),n=a("q1tI"),i=a.n(n),c=a("OAQO"),o=a("iR1w"),l=a("Kv4h"),u=a("OADI"),s=a("EwbC"),f=a("DKqX"),p=a("17x9"),d=a.n(p),m=a("xrux"),v=a.n(m),b={_default:"#59caf9",DIRECT:"#f5bc41",REJECT:"#cb3166"};function y(e){var t=e.type,a=e.payload,r=e.proxy,n=e.id,c=function(e){var t=e.proxy,a=b._default;return b[t]&&(a=b[t]),{color:a}}({proxy:r});return i.a.createElement("div",{className:v.a.rule},i.a.createElement("div",{className:v.a.left},n),i.a.createElement("div",null,i.a.createElement("div",{className:v.a.b},a),i.a.createElement("div",{className:v.a.a},i.a.createElement("div",{className:v.a.type},t),i.a.createElement("div",{style:c},r))))}y.propTypes={id:d.a.number,type:d.a.string,payload:d.a.string,proxy:d.a.string};var O=y,E=a("II4a"),h=a("WfPo"),w=Object(h.a)((function(e){return{searchText:Object(s.d)(e),updateSearchText:s.f}}))(E.a),g=a("9cvt"),x=i.a.memo,j=i.a.useEffect,k=i.a.useMemo,C=i.a.useCallback;function N(e,t){return t[e].id}var I=x((function(e){var t=e.index,a=e.style,r=e.data[t];return i.a.createElement("div",{style:a},i.a.createElement(O,r))}),o.b);t.default=Object(h.a)((function(e){return{apiConfig:Object(u.c)(e),rules:Object(s.c)(e)}}))((function(e){var t=e.dispatch,a=e.apiConfig,n=e.rules,u=C((function(){t(Object(s.a)(a))}),[a,t]);j((function(){t(Object(s.b)(a))}),[t,a]);var p=Object(l.a)(),d=Object(r.a)(p,2),m=d[0],v=d[1],b=k((function(){return i.a.createElement(c.a,{width:16})}),[]);return i.a.createElement("div",null,i.a.createElement(f.a,{title:"Rules"}),i.a.createElement(w,null),i.a.createElement("div",{ref:m,style:{paddingBottom:30}},i.a.createElement(o.a,{height:v-30,width:"100%",itemCount:n.length,itemSize:80,itemData:n,itemKey:N},I)),i.a.createElement(g.b,{icon:b,text:"Refresh",onClick:u,position:g.c}))}))},OAQO:function(e,t,a){"use strict";var r=a("q1tI"),n=a.n(r),i=a("17x9"),c=a.n(i);function o(){return(o=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var a=arguments[t];for(var r in a)Object.prototype.hasOwnProperty.call(a,r)&&(e[r]=a[r])}return e}).apply(this,arguments)}function l(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},i=Object.keys(e);for(r=0;r<i.length;r++)a=i[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)a=i[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var u=Object(r.forwardRef)((function(e,t){var a=e.color,r=void 0===a?"currentColor":a,i=e.size,c=void 0===i?24:i,u=l(e,["color","size"]);return n.a.createElement("svg",o({ref:t,xmlns:"http://www.w3.org/2000/svg",width:c,height:c,viewBox:"0 0 24 24",fill:"none",stroke:r,strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},u),n.a.createElement("polyline",{points:"23 4 23 10 17 10"}),n.a.createElement("path",{d:"M20.49 15a9 9 0 1 1-2.12-9.36L23 10"}))}));u.propTypes={color:c.a.string,size:c.a.oneOfType([c.a.string,c.a.number])},u.displayName="RotateCw",t.a=u},xrux:function(e,t,a){e.exports={rule:"_3eSLieOhVX",left:"_2n1pW09UvV",a:"t1XJIwvW7A",b:"_1fNf8kj0HA",type:"_3yJmN0tON0"}}}]);

View File

@ -1 +0,0 @@
!function(e){function t(t){for(var n,o,i=t[0],l=t[1],d=t[2],f=t[3]||[],s=0,h=[];s<i.length;s++)o=i[s],Object.prototype.hasOwnProperty.call(a,o)&&a[o]&&h.push(a[o][0]),a[o]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(p&&p(t),c.push.apply(c,f);h.length;)h.shift()();return u.push.apply(u,d||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,o=1;o<r.length;o++){var d=r[o];0!==a[d]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return 0===u.length&&(c.forEach((function(e){if(void 0===a[e]){a[e]=null;var t=document.createElement("link");l.nc&&t.setAttribute("nonce",l.nc),t.rel="prefetch",t.as="script",t.href=i(e),document.head.appendChild(t)}})),c.length=0),e}var n={},o={5:0},a={5:0},u=[],c=[];function i(e){return l.p+""+({2:"proxies",4:"rules",6:"vendors~chartjs",7:"vendors~proxies"}[e]||e)+"."+{2:"77fef0018a8d1766e6eb",4:"efd650d64b4afda8d49b",6:"e4543f10556636d64b75",7:"34b4cb2526b2e8ed766c",8:"872bd111e9c497e7acca"}[e]+".js"}function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.e=function(e){var t=[];o[e]?t.push(o[e]):0!==o[e]&&{2:1,4:1}[e]&&t.push(o[e]=new Promise((function(t,r){for(var n=({2:"proxies",4:"rules",6:"vendors~chartjs",7:"vendors~proxies"}[e]||e)+"."+{2:"1e31d885e6fe278da534",4:"664f8b737878361937cb",6:"31d6cfe0d16ae931b73c",7:"31d6cfe0d16ae931b73c",8:"31d6cfe0d16ae931b73c"}[e]+".css",a=l.p+n,u=document.getElementsByTagName("link"),c=0;c<u.length;c++){var i=(f=u[c]).getAttribute("data-href")||f.getAttribute("href");if("stylesheet"===f.rel&&(i===n||i===a))return t()}var d=document.getElementsByTagName("style");for(c=0;c<d.length;c++){var f;if((i=(f=d[c]).getAttribute("data-href"))===n||i===a)return t()}var s=document.createElement("link");s.rel="stylesheet",s.type="text/css",s.onload=t,s.onerror=function(t){var n=t&&t.target&&t.target.src||a,u=new Error("Loading CSS chunk "+e+" failed.\n("+n+")");u.code="CSS_CHUNK_LOAD_FAILED",u.request=n,delete o[e],s.parentNode.removeChild(s),r(u)},s.href=a,document.getElementsByTagName("head")[0].appendChild(s)})).then((function(){o[e]=0})));var r=a[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=a[e]=[t,n]}));t.push(r[2]=n);var u,c=document.createElement("script");c.charset="utf-8",c.timeout=120,l.nc&&c.setAttribute("nonce",l.nc),c.src=i(e);var d=new Error;u=function(t){c.onerror=c.onload=null,clearTimeout(f);var r=a[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;d.message="Loading chunk "+e+" failed.\n("+n+": "+o+")",d.name="ChunkLoadError",d.type=n,d.request=o,r[1](d)}a[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:c})}),12e4);c.onerror=c.onload=u,document.head.appendChild(c)}return Promise.all(t)},l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="",l.oe=function(e){throw console.error(e),e};var d=window.webpackJsonp=window.webpackJsonp||[],f=d.push.bind(d);d.push=t,d=d.slice();for(var s=0;s<d.length;s++)t(d[s]);var p=f;r()}([]);

View File

@ -0,0 +1 @@
!function(e){function r(r){for(var n,o,i=r[0],d=r[1],l=r[2],s=r[3]||[],f=0,h=[];f<i.length;f++)o=i[f],Object.prototype.hasOwnProperty.call(a,o)&&a[o]&&h.push(a[o][0]),a[o]=0;for(n in d)Object.prototype.hasOwnProperty.call(d,n)&&(e[n]=d[n]);for(p&&p(r),u.push.apply(u,s);h.length;)h.shift()();return c.push.apply(c,l||[]),t()}function t(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var l=t[o];0!==a[l]&&(n=!1)}n&&(c.splice(r--,1),e=d(d.s=t[0]))}return 0===c.length&&(u.forEach((function(e){if(void 0===a[e]){a[e]=null;var r=document.createElement("link");d.nc&&r.setAttribute("nonce",d.nc),r.rel="prefetch",r.as="script",r.href=i(e),document.head.appendChild(r)}})),u.length=0),e}var n={},o={5:0},a={5:0},c=[],u=[];function i(e){return d.p+""+({2:"proxies",4:"rules",6:"vendors~chartjs",7:"vendors~proxies",8:"vendors~rules"}[e]||e)+"."+{2:"beaddeef3e0db08db953",4:"90faad053acc32c74a88",6:"e4543f10556636d64b75",7:"34b4cb2526b2e8ed766c",8:"b2e93c21da80f9dc4a80",9:"e5ebc45c57147750a8b7"}[e]+".js"}function d(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,d),t.l=!0,t.exports}d.e=function(e){var r=[];o[e]?r.push(o[e]):0!==o[e]&&{2:1,4:1}[e]&&r.push(o[e]=new Promise((function(r,t){for(var n=({2:"proxies",4:"rules",6:"vendors~chartjs",7:"vendors~proxies",8:"vendors~rules"}[e]||e)+"."+{2:"1e31d885e6fe278da534",4:"3ba17dd53c9d8bd8b221",6:"31d6cfe0d16ae931b73c",7:"31d6cfe0d16ae931b73c",8:"31d6cfe0d16ae931b73c",9:"31d6cfe0d16ae931b73c"}[e]+".css",a=d.p+n,c=document.getElementsByTagName("link"),u=0;u<c.length;u++){var i=(s=c[u]).getAttribute("data-href")||s.getAttribute("href");if("stylesheet"===s.rel&&(i===n||i===a))return r()}var l=document.getElementsByTagName("style");for(u=0;u<l.length;u++){var s;if((i=(s=l[u]).getAttribute("data-href"))===n||i===a)return r()}var f=document.createElement("link");f.rel="stylesheet",f.type="text/css",f.onload=r,f.onerror=function(r){var n=r&&r.target&&r.target.src||a,c=new Error("Loading CSS chunk "+e+" failed.\n("+n+")");c.code="CSS_CHUNK_LOAD_FAILED",c.request=n,delete o[e],f.parentNode.removeChild(f),t(c)},f.href=a,document.getElementsByTagName("head")[0].appendChild(f)})).then((function(){o[e]=0})));var t=a[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=a[e]=[r,n]}));r.push(t[2]=n);var c,u=document.createElement("script");u.charset="utf-8",u.timeout=120,d.nc&&u.setAttribute("nonce",d.nc),u.src=i(e);var l=new Error;c=function(r){u.onerror=u.onload=null,clearTimeout(s);var t=a[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),o=r&&r.target&&r.target.src;l.message="Loading chunk "+e+" failed.\n("+n+": "+o+")",l.name="ChunkLoadError",l.type=n,l.request=o,t[1](l)}a[e]=void 0}};var s=setTimeout((function(){c({type:"timeout",target:u})}),12e4);u.onerror=u.onload=c,document.head.appendChild(u)}return Promise.all(r)},d.m=e,d.c=n,d.d=function(e,r,t){d.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},d.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},d.t=function(e,r){if(1&r&&(e=d(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(d.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)d.d(t,n,function(r){return e[r]}.bind(null,n));return t},d.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return d.d(r,"a",r),r},d.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},d.p="",d.oe=function(e){throw console.error(e),e};var l=window.webpackJsonp=window.webpackJsonp||[],s=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var p=s;t()}([]);

File diff suppressed because one or more lines are too long