diff --git a/package/secubox/luci-app-network-tweaks/Makefile b/package/secubox/luci-app-network-tweaks/Makefile index 8923aa98..8725d940 100644 --- a/package/secubox/luci-app-network-tweaks/Makefile +++ b/package/secubox/luci-app-network-tweaks/Makefile @@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-network-tweaks PKG_VERSION:=1.0.0 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_ARCH:=all PKG_LICENSE:=Apache-2.0 PKG_MAINTAINER:=CyberMind -LUCI_TITLE:=Network Tweaks - Auto Proxy DNS & Hosts -LUCI_DESCRIPTION:=Automatically generates DNS and hosts entries from enabled vhosts for seamless local domain resolution +LUCI_TITLE:=Network Tweaks Dashboard +LUCI_DESCRIPTION:=Unified network services dashboard with DNS/hosts sync, CDN cache control, and WPAD auto-proxy configuration LUCI_DEPENDS:=+luci-base +rpcd +luci-app-vhost-manager +dnsmasq LUCI_PKGARCH:=all diff --git a/package/secubox/luci-app-network-tweaks/htdocs/luci-static/resources/view/network-tweaks/overview.js b/package/secubox/luci-app-network-tweaks/htdocs/luci-static/resources/view/network-tweaks/overview.js index 7fa19006..91e69fc8 100644 --- a/package/secubox/luci-app-network-tweaks/htdocs/luci-static/resources/view/network-tweaks/overview.js +++ b/package/secubox/luci-app-network-tweaks/htdocs/luci-static/resources/view/network-tweaks/overview.js @@ -36,6 +36,32 @@ var callGetCumulativeImpact = rpc.declare({ expect: { } }); +var callCdnCacheStatus = rpc.declare({ + object: 'luci.cdn-cache', + method: 'status', + expect: { } +}); + +var callCdnCacheSetEnabled = rpc.declare({ + object: 'luci.cdn-cache', + method: 'set_enabled', + params: ['enabled'], + expect: { } +}); + +var callGetWpadStatus = rpc.declare({ + object: 'luci.network-tweaks', + method: 'getWpadStatus', + expect: { } +}); + +var callSetWpadEnabled = rpc.declare({ + object: 'luci.network-tweaks', + method: 'setWpadEnabled', + params: ['enabled'], + expect: { } +}); + var callSetComponentEnabled = rpc.declare({ object: 'luci.network-tweaks', method: 'setComponentEnabled', @@ -43,7 +69,14 @@ var callSetComponentEnabled = rpc.declare({ expect: { } }); +var callGetProxyStatus = rpc.declare({ + object: 'luci.network-tweaks', + method: 'getProxyStatus', + expect: { } +}); + return view.extend({ + proxyStatusData: {}, componentsData: [], cumulativeData: {}, networkModeData: {}, @@ -60,7 +93,8 @@ return view.extend({ return Promise.all([ callNetworkTweaksStatus(), callGetNetworkComponents(), - callGetCumulativeImpact() + callGetCumulativeImpact(), + callGetProxyStatus() ]); }, @@ -68,10 +102,12 @@ return view.extend({ var status = data[0] || {}; var componentsResponse = data[1] || {}; var cumulativeResponse = data[2] || {}; + var proxyStatus = data[3] || {}; this.componentsData = componentsResponse.components || []; this.cumulativeData = cumulativeResponse || {}; this.networkModeData = componentsResponse.network_mode || {}; + this.proxyStatusData = proxyStatus || {}; var m, s, o; @@ -129,6 +165,7 @@ return view.extend({ return E('div', { 'class': 'network-tweaks-dashboard' }, [ this.renderCumulativeImpact(), this.renderNetworkModeStatus(), + this.renderProxySettings(), this.renderComponentsGrid(), this.renderSyncSection() ]); @@ -198,6 +235,137 @@ return view.extend({ ]); }, + renderProxySettings: function() { + var proxy = this.proxyStatusData; + var cdnCache = proxy.cdn_cache || {}; + var wpad = proxy.wpad || {}; + + var cdnStatusClass = cdnCache.running ? 'status-running' : 'status-stopped'; + var cdnStatusText = cdnCache.running ? _('Running') : _('Stopped'); + var cdnListeningText = cdnCache.listening ? + _('Listening on port ') + (cdnCache.port || 3128) : + _('Not listening'); + + var wpadStatusClass = wpad.enabled ? 'status-running' : 'status-stopped'; + var wpadStatusText = wpad.enabled ? _('Enabled') : _('Disabled'); + + return E('div', { 'class': 'proxy-settings-section' }, [ + E('h3', {}, _('Proxy & Caching')), + E('div', { 'class': 'proxy-grid', 'style': 'display: grid; grid-template-columns: 1fr 1fr; gap: 1rem;' }, [ + // CDN Cache Card + E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [ + E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [ + E('span', { 'style': 'font-size: 1.5em;' }, '\ud83d\udce6'), + E('span', { 'style': 'font-weight: bold;' }, _('CDN Cache')) + ]), + E('span', { + 'class': 'status-badge ' + cdnStatusClass, + 'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' + + (cdnCache.running ? 'background: #22c55e;' : 'background: #ef4444;') + }, cdnStatusText) + ]), + E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [ + E('div', {}, cdnListeningText), + E('div', {}, cdnCache.installed ? _('nginx proxy installed') : _('Not installed')) + ]), + E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [ + E('button', { + 'class': 'btn cbi-button', + 'click': L.bind(this.handleCdnCacheToggle, this), + 'disabled': !cdnCache.installed + }, cdnCache.enabled ? _('Disable') : _('Enable')), + E('button', { + 'class': 'btn cbi-button', + 'click': L.bind(this.handleCdnCacheRestart, this), + 'disabled': !cdnCache.installed + }, _('Restart')) + ]) + ]), + // WPAD Card + E('div', { 'class': 'proxy-card', 'style': 'background: #16213e; border-radius: 8px; padding: 1rem; border: 1px solid #333;' }, [ + E('div', { 'class': 'proxy-header', 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;' }, [ + E('div', { 'style': 'display: flex; align-items: center; gap: 0.5rem;' }, [ + E('span', { 'style': 'font-size: 1.5em;' }, '\ud83c\udf10'), + E('span', { 'style': 'font-weight: bold;' }, _('WPAD Auto-Proxy')) + ]), + E('span', { + 'class': 'status-badge ' + wpadStatusClass, + 'style': 'padding: 0.25rem 0.5rem; border-radius: 4px; font-size: 0.8em; ' + + (wpad.enabled ? 'background: #22c55e;' : 'background: #ef4444;') + }, wpadStatusText) + ]), + E('div', { 'class': 'proxy-info', 'style': 'font-size: 0.9em; color: #888; margin-bottom: 0.75rem;' }, [ + E('div', {}, wpad.dhcp_configured ? _('DHCP Option 252 configured') : _('DHCP not configured')), + E('div', {}, wpad.url ? wpad.url : _('No PAC URL set')) + ]), + E('div', { 'class': 'proxy-actions', 'style': 'display: flex; gap: 0.5rem;' }, [ + E('button', { + 'class': 'btn cbi-button', + 'click': L.bind(this.handleWpadToggle, this) + }, wpad.enabled ? _('Disable') : _('Enable')) + ]) + ]) + ]) + ]); + }, + + handleCdnCacheToggle: function(ev) { + var currentEnabled = this.proxyStatusData.cdn_cache?.enabled || false; + var newEnabled = !currentEnabled; + + ui.showModal(_('Updating...'), [ + E('p', { 'class': 'spinning' }, _('Please wait...')) + ]); + + return callCdnCacheSetEnabled(newEnabled ? 1 : 0).then(L.bind(function() { + ui.hideModal(); + this.refreshData(); + }, this)).catch(function(err) { + ui.hideModal(); + ui.addNotification(null, E('p', _('Error: ') + err.message), 'error'); + }); + }, + + handleCdnCacheRestart: function(ev) { + ui.showModal(_('Restarting...'), [ + E('p', { 'class': 'spinning' }, _('Please wait...')) + ]); + + return rpc.declare({ + object: 'luci.cdn-cache', + method: 'restart', + expect: { } + })().then(L.bind(function() { + ui.hideModal(); + ui.addNotification(null, E('p', _('CDN Cache restarted')), 'info'); + this.refreshData(); + }, this)).catch(function(err) { + ui.hideModal(); + ui.addNotification(null, E('p', _('Error: ') + err.message), 'error'); + }); + }, + + handleWpadToggle: function(ev) { + var currentEnabled = this.proxyStatusData.wpad?.enabled || false; + var newEnabled = !currentEnabled; + + ui.showModal(_('Updating...'), [ + E('p', { 'class': 'spinning' }, _('Please wait...')) + ]); + + return callSetWpadEnabled(newEnabled ? 1 : 0).then(L.bind(function(result) { + ui.hideModal(); + if (result.success) { + ui.addNotification(null, E('p', result.message || _('WPAD updated')), 'info'); + } + this.refreshData(); + }, this)).catch(function(err) { + ui.hideModal(); + ui.addNotification(null, E('p', _('Error: ') + err.message), 'error'); + }); + }, + renderComponentsGrid: function() { var components = this.componentsData; @@ -362,14 +530,17 @@ return view.extend({ refreshData: function() { return Promise.all([ callGetNetworkComponents(), - callGetCumulativeImpact() + callGetCumulativeImpact(), + callGetProxyStatus() ]).then(L.bind(function(data) { var componentsResponse = data[0] || {}; var cumulativeResponse = data[1] || {}; + var proxyStatus = data[2] || {}; this.componentsData = componentsResponse.components || []; this.cumulativeData = cumulativeResponse || {}; this.networkModeData = componentsResponse.network_mode || {}; + this.proxyStatusData = proxyStatus || {}; this.updateDisplay(); }, this)); @@ -383,6 +554,7 @@ return view.extend({ dom.content(dashboard, [ this.renderCumulativeImpact(), this.renderNetworkModeStatus(), + this.renderProxySettings(), this.renderComponentsGrid(), this.renderSyncSection() ]); diff --git a/package/secubox/luci-app-network-tweaks/root/usr/libexec/rpcd/luci.network-tweaks b/package/secubox/luci-app-network-tweaks/root/usr/libexec/rpcd/luci.network-tweaks index 71027353..c03ecd93 100755 --- a/package/secubox/luci-app-network-tweaks/root/usr/libexec/rpcd/luci.network-tweaks +++ b/package/secubox/luci-app-network-tweaks/root/usr/libexec/rpcd/luci.network-tweaks @@ -284,6 +284,13 @@ case "$1" in json_add_string "app_id" "string" json_add_string "enabled" "boolean" json_close_object + json_add_object "getWpadStatus" + json_close_object + json_add_object "setWpadEnabled" + json_add_string "enabled" "boolean" + json_close_object + json_add_object "getProxyStatus" + json_close_object json_dump ;; @@ -465,6 +472,166 @@ case "$1" in json_dump ;; + getWpadStatus) + # Get WPAD/PAC file status + json_init + json_add_boolean "success" 1 + + # Check if WPAD file exists + wpad_enabled=0 + wpad_file="" + if [ -f /www/wpad.dat ]; then + wpad_enabled=1 + wpad_file="/www/wpad.dat" + fi + + # Check DHCP option 252 configuration + dhcp_wpad_enabled=0 + config_load dhcp + check_dhcp_option() { + local value + config_get value "$1" "252" + [ -n "$value" ] && dhcp_wpad_enabled=1 + } + config_foreach check_dhcp_option dhcp + + # Check dnsmasq wpad entry + dns_wpad_enabled=0 + if grep -q "wpad" /etc/hosts 2>/dev/null || \ + grep -q "wpad" /tmp/hosts.vhosts 2>/dev/null; then + dns_wpad_enabled=1 + fi + + json_add_object "wpad" + json_add_boolean "enabled" "$wpad_enabled" + json_add_string "file" "$wpad_file" + json_add_boolean "dhcp_configured" "$dhcp_wpad_enabled" + json_add_boolean "dns_configured" "$dns_wpad_enabled" + json_close_object + + json_dump + ;; + + setWpadEnabled) + # Enable/disable WPAD + read input + json_load "$input" + + json_get_var enabled enabled + + if [ "$enabled" = "1" ] || [ "$enabled" = "true" ]; then + # Get LAN IP + lan_ip=$(uci get network.lan.ipaddr 2>/dev/null | cut -d'/' -f1) + [ -z "$lan_ip" ] && lan_ip="192.168.255.1" + + # Create WPAD/PAC file + cat > /www/wpad.dat << EOF +function FindProxyForURL(url, host) { + // Direct access for local network + if (isInNet(host, "192.168.0.0", "255.255.0.0") || + isInNet(host, "10.0.0.0", "255.0.0.0") || + isInNet(host, "172.16.0.0", "255.240.0.0") || + shExpMatch(host, "*.local") || + shExpMatch(host, "*.lan")) { + return "DIRECT"; + } + // Use CDN Cache proxy for everything else + return "PROXY ${lan_ip}:3128; DIRECT"; +} +EOF + chmod 644 /www/wpad.dat + + # Add DHCP option 252 for WPAD discovery + uci set dhcp.lan.dhcp_option_force="252,http://${lan_ip}/wpad.dat" + uci commit dhcp + + # Add wpad DNS entry + if ! grep -q "wpad" /etc/hosts 2>/dev/null; then + echo "${lan_ip} wpad wpad.lan" >> /etc/hosts + fi + + # Restart dnsmasq + /etc/init.d/dnsmasq reload >/dev/null 2>&1 + + json_init + json_add_boolean "success" 1 + json_add_string "message" "WPAD enabled" + else + # Remove WPAD file + rm -f /www/wpad.dat + + # Remove DHCP option + uci delete dhcp.lan.dhcp_option_force 2>/dev/null + uci commit dhcp + + # Remove wpad DNS entry + sed -i '/wpad/d' /etc/hosts 2>/dev/null + + # Restart dnsmasq + /etc/init.d/dnsmasq reload >/dev/null 2>&1 + + json_init + json_add_boolean "success" 1 + json_add_string "message" "WPAD disabled" + fi + + json_dump + ;; + + getProxyStatus) + # Get comprehensive proxy status (CDN Cache + WPAD) + json_init + json_add_boolean "success" 1 + + # CDN Cache status + cdn_running=0 + cdn_enabled=0 + cdn_port=3128 + + if [ -x /etc/init.d/cdn-cache ]; then + /etc/init.d/cdn-cache running >/dev/null 2>&1 && cdn_running=1 + cdn_enabled=$(uci get cdn-cache.main.enabled 2>/dev/null) + [ -z "$cdn_enabled" ] && cdn_enabled=0 + cdn_port=$(uci get cdn-cache.main.listen_port 2>/dev/null) + [ -z "$cdn_port" ] && cdn_port=3128 + fi + + # Check if port is actually listening + cdn_listening=0 + if netstat -tln 2>/dev/null | grep -q ":${cdn_port}"; then + cdn_listening=1 + fi + + json_add_object "cdn_cache" + json_add_boolean "installed" "$([ -x /etc/init.d/cdn-cache ] && echo 1 || echo 0)" + json_add_boolean "enabled" "$cdn_enabled" + json_add_boolean "running" "$cdn_running" + json_add_boolean "listening" "$cdn_listening" + json_add_int "port" "$cdn_port" + json_close_object + + # WPAD status + wpad_enabled=0 + [ -f /www/wpad.dat ] && wpad_enabled=1 + + dhcp_wpad=0 + wpad_url="" + config_load dhcp + wpad_opt=$(uci get dhcp.lan.dhcp_option_force 2>/dev/null) + if echo "$wpad_opt" | grep -q "252"; then + dhcp_wpad=1 + wpad_url=$(echo "$wpad_opt" | sed 's/252,//') + fi + + json_add_object "wpad" + json_add_boolean "enabled" "$wpad_enabled" + json_add_boolean "dhcp_configured" "$dhcp_wpad" + json_add_string "url" "$wpad_url" + json_close_object + + json_dump + ;; + *) json_init json_add_boolean "success" 0 diff --git a/package/secubox/luci-app-network-tweaks/root/usr/share/luci/menu.d/luci-app-network-tweaks.json b/package/secubox/luci-app-network-tweaks/root/usr/share/luci/menu.d/luci-app-network-tweaks.json index 722d4d1e..eb568d44 100644 --- a/package/secubox/luci-app-network-tweaks/root/usr/share/luci/menu.d/luci-app-network-tweaks.json +++ b/package/secubox/luci-app-network-tweaks/root/usr/share/luci/menu.d/luci-app-network-tweaks.json @@ -1,7 +1,7 @@ { - "admin/secubox/network/tweaks": { + "admin/services/network-tweaks": { "title": "Network Tweaks", - "order": 50, + "order": 80, "action": { "type": "view", "path": "network-tweaks/overview" diff --git a/package/secubox/luci-app-network-tweaks/root/usr/share/rpcd/acl.d/luci-app-network-tweaks.json b/package/secubox/luci-app-network-tweaks/root/usr/share/rpcd/acl.d/luci-app-network-tweaks.json index 8615245b..679eec7c 100644 --- a/package/secubox/luci-app-network-tweaks/root/usr/share/rpcd/acl.d/luci-app-network-tweaks.json +++ b/package/secubox/luci-app-network-tweaks/root/usr/share/rpcd/acl.d/luci-app-network-tweaks.json @@ -3,15 +3,17 @@ "description": "Grant access to Network Tweaks", "read": { "ubus": { - "luci.network-tweaks": ["getStatus", "getConfig", "getNetworkComponents", "getCumulativeImpact"] + "luci.network-tweaks": ["getStatus", "getConfig", "getNetworkComponents", "getCumulativeImpact", "getWpadStatus", "getProxyStatus"], + "luci.cdn-cache": ["status", "stats"] }, - "uci": ["network_tweaks", "vhosts"] + "uci": ["network_tweaks", "vhosts", "cdn-cache", "dhcp"] }, "write": { "ubus": { - "luci.network-tweaks": ["syncNow", "setConfig", "setComponentEnabled"] + "luci.network-tweaks": ["syncNow", "setConfig", "setComponentEnabled", "setWpadEnabled"], + "luci.cdn-cache": ["set_enabled", "restart"] }, - "uci": ["network_tweaks"] + "uci": ["network_tweaks", "dhcp"] } } } diff --git a/package/secubox/luci-app-secubox-security-threats/Makefile b/package/secubox/luci-app-secubox-security-threats/Makefile index 3a210d31..61174859 100644 --- a/package/secubox/luci-app-secubox-security-threats/Makefile +++ b/package/secubox/luci-app-secubox-security-threats/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-secubox-security-threats PKG_VERSION:=1.0.0 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_ARCH:=all PKG_LICENSE:=Apache-2.0 PKG_MAINTAINER:=CyberMind diff --git a/package/secubox/luci-app-secubox-security-threats/root/usr/libexec/rpcd/luci.secubox-security-threats b/package/secubox/luci-app-secubox-security-threats/root/usr/libexec/rpcd/luci.secubox-security-threats index 2103d9a9..da43af72 100755 --- a/package/secubox/luci-app-secubox-security-threats/root/usr/libexec/rpcd/luci.secubox-security-threats +++ b/package/secubox/luci-app-secubox-security-threats/root/usr/libexec/rpcd/luci.secubox-security-threats @@ -321,7 +321,12 @@ get_security_stats() { # HAProxy connections (if running in LXC) if lxc-info -n haproxy -s 2>/dev/null | grep -q "RUNNING"; then - haproxy_conns=$(lxc-attach -n haproxy -- sh -c 'echo "show stat" | socat stdio /var/run/haproxy/admin.sock 2>/dev/null | tail -n+2 | awk -F, "{sum+=\$8} END {print sum}"' 2>/dev/null || echo 0) + # Try multiple socket paths (chroot-relative and absolute) + haproxy_conns=$(lxc-attach -n haproxy -- sh -c ' + for sock in /stats /run/haproxy.sock /var/lib/haproxy/stats /var/run/haproxy/admin.sock; do + [ -S "$sock" ] && echo "show stat" | socat stdio "$sock" 2>/dev/null && break + done | tail -n+2 | awk -F, "{sum+=\$5} END {print sum+0}" + ' 2>/dev/null || echo 0) fi haproxy_conns=$(echo "$haproxy_conns" | tr -d '\n') haproxy_conns=${haproxy_conns:-0} diff --git a/package/secubox/luci-app-tor-shield/Makefile b/package/secubox/luci-app-tor-shield/Makefile index 2abea598..18fb72bd 100644 --- a/package/secubox/luci-app-tor-shield/Makefile +++ b/package/secubox/luci-app-tor-shield/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-tor-shield PKG_VERSION:=1.0.0 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_ARCH:=all PKG_LICENSE:=MIT diff --git a/package/secubox/luci-app-tor-shield/root/usr/share/rpcd/acl.d/luci-app-tor-shield.json b/package/secubox/luci-app-tor-shield/root/usr/share/rpcd/acl.d/luci-app-tor-shield.json index 40965fd2..89f0378b 100644 --- a/package/secubox/luci-app-tor-shield/root/usr/share/rpcd/acl.d/luci-app-tor-shield.json +++ b/package/secubox/luci-app-tor-shield/root/usr/share/rpcd/acl.d/luci-app-tor-shield.json @@ -11,7 +11,9 @@ "bandwidth", "presets", "bridges", - "settings" + "settings", + "excluded_destinations", + "refresh_ips" ], "system": [ "info", "board" ], "file": [ "read", "stat", "exec" ] @@ -35,7 +37,10 @@ "add_hidden_service", "remove_hidden_service", "set_bridges", - "save_settings" + "save_settings", + "add_excluded_destination", + "remove_excluded_destination", + "apply_exclusions" ] }, "uci": [ "tor-shield" ],