update 2026-05-10 09:48:30

This commit is contained in:
action committed 2026-05-10 09:48:30 +08:00
1 parent 95ac96413e
commit 0b362674f1
6244 files changed
+2992248

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-daed
PKG_VERSION:=1.4
PKG_RELEASE:=1
LUCI_TITLE:=LuCI Support for DAED
LUCI_DEPENDS:=+daed +zoneinfo-asia +luci-compat
LUCI_PKGARCH:=all
define Package/$(PKG_NAME)/conffiles
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
+34
View File
@@ -0,0 +1,34 @@
local sys = require "luci.sys"
local http = require "luci.http"
module("luci.controller.daed", package.seeall)
function index()
if not nixio.fs.access("/etc/config/daed") then
return
end
entry({"admin", "services", "daed"}, alias("admin", "services", "daed", "setting"),_("DAED"), 58).dependent = true
entry({"admin", "services", "daed", "setting"}, cbi("daed/basic"), _("Base Setting"), 1).leaf=true
entry({"admin", "services", "daed", "daed"}, template("daed/daed"), _("Dashboard"), 2).leaf = true
entry({"admin", "services", "daed", "log"}, cbi("daed/log"), _("Logs"), 3).leaf = true
entry({"admin", "services", "daed_status"}, call("act_status"))
entry({"admin", "services", "daed", "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", "daed", "clear_log"}, call("clear_log")).leaf = true
end
function act_status()
local sys = require "luci.sys"
local e = { }
e.running = sys.call("pidof daed >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
function get_log()
http.write(sys.exec("cat /var/log/daed/daed.log"))
end
function clear_log()
sys.call("true > /var/log/daed/daed.log")
end
@@ -0,0 +1,35 @@
local m, s ,o
m = Map("daed")
m.title = translate("DAED")
m.description = translate("DAE is a Linux high-performance transparent proxy solution based on eBPF, And DAED is a modern dashboard for dae.")
m:section(SimpleSection).template = "daed/daed_status"
s = m:section(TypedSection, "daed", translate("Global Settings"))
s.addremove = false
s.anonymous = true
o = s:option(Flag,"enabled",translate("Enable"))
o.default = 0
o = s:option(Value, "log_maxbackups", translate("Logfile retention count"))
o.default = 1
o = s:option(Value, "log_maxsize", translate("Logfile Max Size (MB)"))
o.default = 5
o = s:option(Value, "listen_addr",translate("Set the DAED listen address"))
o.default = '0.0.0.0:2023'
o = s:option(Value, "dashboard_port", translate("Dashboard Access Port"))
o.placeholder = translate("Leave empty to use listen port")
o.datatype = "range(1,65535)"
o.description = translate("For reverse proxy scenarios, leave empty to use the port from listen address")
m.apply_on_parse = true
m.on_after_apply = function(self,map)
luci.sys.exec("/etc/init.d/daed restart")
end
return m
@@ -0,0 +1,5 @@
m = Map("daed")
m:append(Template("daed/daed_log"))
return m
+56
View File
@@ -0,0 +1,56 @@
<%+header%>
<%
local running = luci.sys.exec("pgrep -x /usr/bin/daed")
%>
<% if tonumber(running) ~= nil then %>
<div class="cbi-map">
<iframe id="daed" class="daed-iframe"></iframe>
</div>
<style>
.daed-iframe {
width: 100%;
height: 100vh;
min-height: 780px;
border: none;
border-radius: .375rem;
box-shadow: rgba(0, 0, 0, 0.75) 0px 0px 15px -5px;
display: block;
}
</style>
<script type="text/javascript">
var listenAddr = "<%=luci.model.uci.cursor():get_first("daed", "daed", "listen_addr") or ''%>";
var dashboardPort = "<%=luci.model.uci.cursor():get_first("daed", "daed", "dashboard_port") or ''%>";
var port = "";
if (dashboardPort && dashboardPort.trim() !== "") {
port = dashboardPort.trim();
} else {
var portRegex = /:(\d+)/;
var match = listenAddr.match(portRegex);
if (match && match[1]) {
port = match[1];
}
}
if (port) {
var protocol = window.location.protocol;
var hostname = window.location.hostname;
var url = protocol + "//" + hostname;
if (!((protocol === "http:" && port === "80") || (protocol === "https:" && port === "443"))) {
url += ":" + port;
}
document.getElementById("daed").src = url;
}
</script>
<% else %>
<style>.notrunning{text-align: center;} h1{font-size: 25px; color: #333; margin-bottom: 16px;} p{font-size: 18px; color: #666; margin-bottom: 24px;}</style>
<div class="notrunning">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAYAAAA9zQYyAAAAAXNSR0IArs4c6QAAIABJREFUeF7sfQd0VcX2/p5Tbu/pjdC7lNBBgqh0EFBEfCj4QEBUUKRIUZGiKHYRVEBQUB+KgkgH6V0UkBYgQEgC6cnt99xT57/m3HtjQEoo+vT9/mctykpOmTPzzZ5vf3vPPgj+Bgfea64LilwbAFcHoKqAAomAlFgAFAWAbABgAgx6ANAAAvpv0OT/S02QAUAAAA4AfBjAhQBKAUORQkEeBZADgM8DRZ9Bbb2n/tsdg/7qBuA91hqApbsVBbVGCDdHAI0BgAUMAJHWkP8DAEbkRzjyn7+6qf/nnxcakop/q6MCODxQKDI04fECBCIA/AYY/QIU3g+I2Y3auc/9lR35lwAa7zTeBwA9AUFXwFC3HLih/vkdyH/lm/8fetZf1sV/eJD6g1OAYQMArEHp/i1/drf/aYDGu00NQMGDAMGjAJDy/7H7Zw/lte9PYIUxJVNIof5y81EB5BggFwH8BxBagu72nfgzeuSOAxrvNnYCQM9gjHtHGnzHH3IHe+Lq1iu0rP6d233TXaC+UojE/VePCD2h0CoAPBfd7d98J9tzx94O7zClA4UnAeCu//VOq0QPRfqVnIpIL7BY/Y8KcCFMDitxn3LKVOGGfwPYVKbl/71zfufcpA0bQEGzUAffzjvRoNsGNN5mjgYNngUyflJt0G3f8U68ViXuQTBLmqsDAAMC7MeizAFLsyAjA6JVf/5aR/mAhIHPht5bvZ8U9gtu4B6Uu1oE/Wq/XYPp/mUEuBJ9dqdPqej8I7QQRDQJdfSW3M5jbgt+eLfxXxjD+wAQ80/CMkGeggAoCwKQsDD3K9n39jKRLnNhq14Hga+n6qR776Us2BXq8XKsRcBFmCj5wwCAniIEVQafgjCNMNIjGpPJQPz9iEpzlVmOaQCkAQAaAZAVQazgHxNhktxfAQAyQf5P+M4qJypGCJ5Hd/u/vlVQ3zKg8S7jB4Bh9HWty6226k+8ToUoAZoeIPss9vWcxEvHzytWlW+Qn2MMGg3lD2zWUZQB9DgIgAhwiRUm4CP/EuwpgMGFhTV7peCXmxW047CsNRuQNP5frDDsccYGAUxhPvysiCUiQ0buZaIIWDFfirkyL+YT4pAJLIgGhCh19kggg4AxMAiBAjT2KoBUXvQ/fESMRejfD1F7/3O38rY33UsqxaCVrwBB51t54H//mhBXBhuCme+LRS8v5GMAKEQRi0iMIrGKCPMHPtEFWran7cRCYgQKX6RwhaXAHjwtBQ5mALvvOA6evCAbS72YRRhoDBQQ9GEE8jMPsq6PZmjt4FYoLIVYGMYYkBYBmJHy00bZ++ZXIvo5Q9F4/CBViUdwdyNKrJdK2ci0OpOjuA9kKELtJAQLJmkMcVUpI3aG1d+bHrH/fo/fXAvCyMawCWRq4M1SkJvqnnBQZCVguOufTu0wS/gzJXUeEfRtPiDZCKKJS6gCGjB/bIlOaNiBNh36Sfa8/qWkrN8vs4Eg1gJWI5WUClIyMbACDMPIOp3O7/f5LWooAmHxp/d0/vs60TYoC5tnYtnNSB79iuCas0K0AgYm5I2GKA1W/wqDP+yKkCvtJuTJWamjjNGUCam8/p/e8zeGd7mxRnAMIabvzQRnKg1oAmasSOsBoFalL7px2/+cM64XXIw4gwwArkpBxhbZ02AQpwNMaSgKAw7hTx73KOs8kikzPx2UjSENJKx4hQ28ikUV1SEOQwQSTCCOAWQFQ91Uypnxo94EHGZVHhyF4L2PhdIX5og2wIiOrAgReq0+t4L3H7Lq5KYKdG9DO9fO19nAqyCQbuBE/jk9+pffVQV1CNmZQDHdKgvqSmFTpRmsspVY5r/8zSr1wMsJmHoJoRAR8EY4LAEjsa9GBECDnH9W8U1ZKMLnayULIanE7EYwpYSRTTgETfy+8rB8GMXlYP69gZEfha28cO4bvVC9DmXCMgauFALGLhwZJKKh/P6gMKcvf7Cqf5OpEaZAMoDBAH7fPj0Ag4zIGX6pEJO/OVWpolx2s9dWahzu7EnlzUVwDETq3srQj8oBeqdhIyDU+W/dB2EOrI6zAYUUBPJ2hELwGLBAHEEEYAAoPK34/j1TkNb/LBtIwhMV8gfDOQqhblRwyAdUgRXp2UqMl/pIgjmM8VtPa13jnmPsIAO8NVdyTpjH2wiBV+9biXup76LeC8njB9Ku2c+yRrBROvApQJzV0Fwo55yXgbt8rCr+mvxf7afQElbBClayNf/F0zBsQun+LjdqwQ0BLe8yfkARNUM98++bKCRKgFk7RsDQOP+sEli9RwxmZGOok0KjRzvRBks80pTkKtyC1bL40nxRgwEbQlSB/LkKvEIk+XIeUAHy5Qb7yh4ut6wYGtdkPEdWaQllgXsG8tzOI5JJRXPEut5odMK/x0ooJcioR9zkQUxw8lOsAfRICy4MWLyM+YQmsgygOqOR+FBkZTIhkq8Y+r0Xh865SSNfySbf8dPC8/KG6sd1AU10ZsDwlTrcRDcl1q6ypuWOv9J1bqgDKMrHvq83yaUHzyj2rzfLLGCsC8MR67VITIlB+MxFlajqyDBSIbcuJOFVWMX/8JQKPJnwWdXIETWNmOEIwNVeDDt44d/L6q+xcHGlXkqqRmmt7QJ+rx8sKq+5hU5ULXXYZDeoitxzXtDiezrQJmCAQRwh7iFNHPsVHjHAgggUlsKEXwuATBSc/EVy/+cnmbGaEH5hAKOjWGBUfv+3XnorjEhohRl4PZ36moBWeTOjnCRBE/V9acBgwAj8iDj25ccNTfyfDWwy0GTAEEgxXeTiUqcShUHUqACjQpMwNF7hv8mPw/z6uk0LA51waSK5RRzACoYbI0C8yWyQvV4/iTeqedqXwxXB3LFs6dMDWLOmLUeLItDUlfy5sv0TsfxKSCsn8mBabcr75lMsdU9TWsfEIbRhneQbPlvQNqpBB9e8w5pI6IZMa0SDOPktwTtrqUgolg4Ay9OGaJ2vjGOjVRXm72ikrt0vxSBR9a/Fp68N6D2mBaCEw9lmBN+ukvPKXBzz1AhDLJRRQGb/30HrV2FKOKkdwQefiO4xcwQzQhQxoiHnqoIJrviy1x7D3yGpEO8ujGCaosR+/R5y7dm3T66ammoe9ewo5d777g38evjX4NHfjpoyz5yRtFpdjFarKVy8+At7WVkpscWaCQNAfOZhnS/1Id6EEWJVA32LR0WaQxYIFdiAsUFHcbWTKXTkrEIDKBoERm/pRi1lr84bwQdCj2cEz7q9EtksEV5GsPTtdK334d6MHTwkbPoP4R0Rqkajhaidb9jVuvGq3RtKNFJ2hGO3AHYM85dA3og5NVzznz6W+uQIgxEVE54W4Z+3MUqVGNzIinjlv5FL1Z8TG6kAb7+fE11eMKlW+GZW9wg/UVSQREJ8Sp/efYo7drxH7tq1G65du7bu4sVcISk5JQ6FIinlCe8oFOwmcUDCYJTcnJyi0c+N5SnfEYu37Bz90yFsQTQJBF6TfVeiJ648JUJ9wiNN/AGsAKU1+6Wdehabfaj9I4Jv7zHZTiY26RNClXq0ZVxrFugsauBHruBY3kILbvWS22I5Kp1DHa6W0HR1QO8yEr25q9pN5AyLDB8v4t1i/Q1Z8z953z60+froMeONRigO5Rr8FZZaXfUJSImLFSDxjCsSPMlLxlHw0ceCa9T7ghVdIcNdv+NDaMYK4chql4ht2rTmP/zww9LmzZvTADgprIqGtBSCWAIcdRkIrQOqgwkARYWFrtKyMqhXr54WAGvK3EJJvfqNtMV5Z2yRnR4h/n77x9XmK6FIMVHmvF/nA/XYdL9h5xGFSJIhMBPwIsS5NmhlSzxlwu7/3iqrZiTeHtXZgNr7u/1xil/xEzWfWYFNFfNpsBXDoi8CJRej5pWNHzNSGxVXl5316GnT8+ONFihGgMWwc3X7Y3Rla8q3+xCGKvEg7z9Fudo3UBxAq5Hm8kOFFNl1GATO2CkoBzhsKnf8KtEuAlDAIE6YMMHbu/cDfNu27aIA1BSi8B5GEkUst91/uCNFUSBJoux0uf2yJGoMeoNgsVoIj1UUBfObNm7093qgFytJsp2cG5kGlWhapU+JAJxlEM+LWCJshCCYCCthKRFG9WOdH76msUNJiGrclqWsdMsqnBjWChUFKRQiq9yttSBMNTtfmU/9B1OBd5t+AKz0/l3UxAAmBNu2+vnZWx72rl/7LZtX4OLv7tADD2u7Vz9pksECLhqwoNzxzFG10WQRDy/mGIMy+gNN/quDxfioOEwDSf6JgDrkAQNEI5jxtlT2ykLeEZLkrtfrv1vmmLjY4JdLvyzt1Ol+HWAURTq6PLYS/s/Vuj7yMwLSclkz/EhFkRVJkgRASMnJyS6JjYlDL058EX/yyadVyP0pdcm58wdxYjGmAFHlu/9CqgwCzrNer5jjkPG66bF3vkmX3xEBOD3AW4yYpWlE3QqHV/udQqtQO1+fije/bLjVbVMYH//DvNUDXMzyy+3GVsk/eSrLaNRTdgzAVanZ3t+3/m7mwzf1VhygEQTCS9itTbo/vDRRyQSJErWMQtTTkI6ggKKyVyPRYBECkg0XWbqIc2hEwDtxwN6dg6AAhtDqfm0yTWiGIyqqdM+evYE6dWqnqHQi4gxeY2ArcvkI7Yg8gVxLxkiSxCDDskwoZwPA4/H4LRaLZt/+/ZeGDhliycjIcIQmwR0+Ig2psKSHJEQFxg7QON9+NWydb2+5v41Gh3cDRdp5q1iJtJ9CDStu57oM0PIu45sIYMIfjBqBk8TLTQYrgS9X5/AN6yZFE0CT8xq37husKv8gr/pM6wCFpcAblrhu65VDfFmRkJJdoiurFsdFq7cjL2EBOHcKBwdMZbyTByl0n27YgfzhBGdyCpHqoikYO5V3vfuNaFMzMq8ka+UOoKore9auXevp3r17PAEfSRIioeo/LLine truncated
<h1><font color="color:red"><%:DAED is not running%></font></h1>
<p><%:Please start the DAED service first and try again%></p>
</div>
<% end -%>
<%+footer%>
@@ -0,0 +1,33 @@
<script type="text/javascript">
//<![CDATA[
function clear_log(btn) {
XHR.get('<%=url([[admin]], [[services]], [[daed]], [[clear_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = "";
log_textarea.scrollTop = log_textarea.scrollHeight;
}
location.reload();
}
);
}
var scrolled = false;
XHR.poll(2, '<%=url([[admin]], [[services]], [[daed]], [[get_log]])%>', null,
function(x, data) {
if(x && x.status == 200) {
var log_textarea = document.getElementById('log_textarea');
log_textarea.innerHTML = x.responseText;
if (!scrolled) {
log_textarea.scrollTop = log_textarea.scrollHeight;
scrolled = true;
}
}
}
);
//]]>
</script>
<fieldset class="cbi-section" id="_log_fieldset">
<input class="cbi-button cbi-input-remove" type="button" onclick="clear_log()" value="<%:Clear logs%>" style="margin-left: 10px; margin-top: 10px;">
<textarea id="log_textarea" class="cbi-input-textarea" style="width: calc(100% - 20px); height: 645px; margin: 10px;" data-update="change" rows="5" wrap="off" readonly="readonly"></textarea>
</fieldset>
@@ -0,0 +1,24 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[daed_status]])%>', null,
function(x, data) {
var tb = document.getElementById('daed_status');
if (data && tb)
{
if (data.running)
{
tb.innerHTML = '<em><b style=\"color:green\"><%:DAED%> <%:RUNNING%></b></em>';
}
else
{
tb.innerHTML = '<em><b style=\"color:red\"><%:DAED%> <%:NOT RUNNING%></b></em>';
}
}
}
);
//]]></script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="daed_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
+68
View File
@@ -0,0 +1,68 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "DAED"
msgstr "DAED"
msgid "DAE is a Linux high-performance transparent proxy solution based on eBPF, And DAED is a modern dashboard for dae."
msgstr "DAE是一个基于eBPF的Linux高性能透明代理解决方案,而DAED是DAE的管理面板。"
msgid "Base Setting"
msgstr "基本设置"
msgid "Dashboard"
msgstr "仪表板"
msgid "Logs"
msgstr "日志"
msgid "Clear logs"
msgstr "清空日志"
msgid "RUNNING"
msgstr "运行中"
msgid "NOT RUNNING"
msgstr "未运行"
msgid "Collecting data..."
msgstr "收集数据..."
msgid "Logfile retention count"
msgstr "日志文件保留数量"
msgid "Logfile Max Size (MB)"
msgstr "日志文件大小(MB)"
msgid "Set the DAED listen address"
msgstr "设置监听地址"
msgid "Dashboard Access Port"
msgstr "仪表板访问端口"
msgid "Leave empty to use listen port"
msgstr "留空则使用监听端口"
msgid "For reverse proxy scenarios, leave empty to use the port from listen address"
msgstr "用于反向代理场景,留空则使用监听地址的端口"
msgid "DAED is not running"
msgstr "DAED 未运行"
msgid "Please start the DAED service first and try again"
msgstr "请先启动 DAED 服务后重试"
msgid "Enable Auto Subscribe Update"
msgstr "启用订阅自动更新"
msgid "Update Cycle"
msgstr "更新周期"
msgid "Update Time (Every Day)"
msgstr "更新时间(每天)"
msgid "Username"
msgstr "用户名"
msgid "Password"
msgstr "密码"
+22
View File
@@ -0,0 +1,22 @@
#!/bin/sh
[ "${ACTION}" = "ifup" ] || exit 0
DEVICE=$(logread | grep "link is up" | tail -n 1 | awk -F "'" '{print $2}')
DEVICE_TYPE=$(ip link show dev "$DEVICE")
case "$DEVICE_TYPE" in
*"link/ether"*)
(
LOCK_FILE="/tmp/lock/daed_hotplug_lock"
if [ -f "$LOCK_FILE" ]; then
exit 1
else
echo $$ > "$LOCK_FILE" 2>/dev/null
trap 'rm -f "$LOCK_FILE"' EXIT
sleep 60
/etc/init.d/daed restart 2>&1
fi
) &
;;
esac
+70
View File
@@ -0,0 +1,70 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2023 Tianling Shen <cnsztl@immortalwrt.org>
USE_PROCD=0
START=98
CONF="daed"
PROG="/usr/bin/daed"
LOG="/var/log/daed/daed.log"
CRON_FILE="/etc/crontabs/root"
RANDOM_SEED=$RANDOM
RANDOM_NUM=$((RANDOM_SEED % 10 + 1))
setcron() {
touch $CRON_FILE
sed -i '/daed_sub.sh/d' $CRON_FILE 2>/dev/null
[ "$(uci -q get daed.config.subscribe_auto_update)" -eq 1 ] && echo "${RANDOM_NUM} $(uci -q get daed.config.subscribe_update_day_time) * * $(uci -q get daed.config.subscribe_update_week_time) /etc/daed/daed_sub.sh >/dev/null 2>&1" >>$CRON_FILE
crontab $CRON_FILE
}
delcron() {
sed -i '/daed_sub.sh/d' $CRON_FILE 2>/dev/null
crontab $CRON_FILE
}
setlocaluse() {
uci set dhcp.@dnsmasq[0].localuse="1"
uci commit dhcp
/etc/init.d/dnsmasq restart
}
dellocaluse() {
uci set dhcp.@dnsmasq[0].localuse="0"
uci commit dhcp
/etc/init.d/dnsmasq restart
. /lib/functions/network.sh
network_find_wan LOGICAL_WAN || exit 1
dns_list=$(ubus call network.interface.$LOGICAL_WAN status | jsonfilter -e '@["dns-server"]' | sed 's/[]["]//g' | sed 's/,/\n/g' | grep -oE '\b([0-9]{1,3}\.){3}[0-9]{1,3}\b')
[ -z "$dns_list" ] && dns_list="119.29.29.29 180.76.76.76 223.5.5.5"
grep -v '^nameserver ' /etc/resolv.conf > /tmp/resolv.conf.new.daed 2>/dev/null
for dns in $dns_list; do
echo "nameserver $dns" >> /tmp/resolv.conf.new.daed
done
cat /tmp/resolv.conf.new.daed > /etc/resolv.conf
rm -f /tmp/resolv.conf.new.daed
}
start_service() {
[ -f "/etc/init.d/daed" ] && grep -q "DAE_LOCATION_ASSET" "/etc/init.d/daed" || sed -i '/run/i\ procd_set_param env DAE_LOCATION_ASSET="/usr/share/v2ray"' "/etc/init.d/daed"
config_load "$CONF"
local enabled
config_get_bool enabled "config" "enabled" "0"
if [ "$enabled" -eq 0 ]; then
#delcron
setlocaluse
return 1
fi
#setcron
dellocaluse
}
stop_service() {
#delcron
setlocaluse
}
service_triggers() {
procd_add_reload_trigger "$CONF"
}
@@ -0,0 +1,11 @@
{
"luci-app-daed": {
"description": "Grant UCI access for luci-app-daed",
"read": {
"uci": [ "daed" ]
},
"write": {
"uci": [ "daed" ]
}
}
}