crowdswc full

This commit is contained in:
CyberMind-FR 2025-12-23 20:38:36 +01:00
parent ff20666817
commit eb72e12a72
9 changed files with 1013 additions and 56 deletions

View File

@ -4,7 +4,9 @@
"Bash(done)", "Bash(done)",
"Bash(ls:*)", "Bash(ls:*)",
"Bash(find:*)", "Bash(find:*)",
"Bash(xargs:*)" "Bash(xargs:*)",
"Bash(mkdir:*)",
"Bash(shellcheck:*)"
] ]
} }
} }

5
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"recommendations": [
"anthropic.claude-code"
]
}

View File

@ -1,22 +1,75 @@
# SecuBox - Security Suite for OpenWrt # SecuBox Central Hub
Unified security dashboard providing central management for: Central management dashboard for the SecuBox security and network management suite for OpenWrt.
- **CrowdSec** - Collaborative intrusion prevention ## Features
### Dashboard Overview
- Real-time system health monitoring (CPU, Memory, Disk, Network)
- Visual gauges with color-coded status indicators
- Module status grid with quick access links
- Aggregated alerts from all modules
- Quick action buttons for common tasks
### System Health Monitoring
- **CPU**: Load average and percentage with multi-core support
- **Memory**: RAM usage with total/used/available metrics
- **Disk**: Root filesystem usage and available space
- **Network**: Real-time RX/TX bandwidth statistics
### Quick Actions
- Restart RPCD service
- Restart uHTTPd web server
- Clear system cache
- Create configuration backup
- Restart network services
- Restart firewall
### Module Management
Auto-detection and status monitoring for all SecuBox modules:
**Security & Monitoring**
- **CrowdSec** - Collaborative threat intelligence
- **Netdata** - Real-time system monitoring - **Netdata** - Real-time system monitoring
- **Netifyd** - Deep packet inspection and traffic analysis - **Netifyd** - Deep packet inspection
- **WireGuard** - Modern VPN - **Client Guardian** - Network access control and captive portal
- **Network Modes** - Simplified network configuration - **Auth Guardian** - Advanced authentication system
- **Client Guardian** - Access control and captive portal
- **System Hub** - System control center **Network Management**
- **CDN Cache** - Bandwidth optimization proxy - **WireGuard** - Modern VPN with QR codes
- **Traffic Shaper** - QoS, priorities, and quotas - **Network Modes** - Network topology configuration
- **Bandwidth Manager** - QoS and bandwidth quotas
- **Media Flow** - Media traffic detection and optimization
- **Traffic Shaper** - Advanced traffic shaping
**System & Performance**
- **System Hub** - Unified control center
- **CDN Cache** - Local caching proxy
- **Virtual Host Manager** - Virtual host configuration
## RPCD API Methods
The hub provides a comprehensive RPC API via ubus:
- `status` - Get hub status and basic system info
- `modules` - List all SecuBox modules with status
- `modules_by_category` - Filter modules by category
- `module_info` - Get detailed info for a specific module
- `get_system_health` - Detailed system health metrics
- `get_alerts` - Aggregated alerts from all modules
- `get_dashboard_data` - All dashboard data in one call
- `quick_action` - Execute quick actions
- `start_module` / `stop_module` / `restart_module` - Module control
- `health` - System health checks
- `diagnostics` - Generate diagnostics bundle
## Installation ## Installation
```bash ```bash
opkg update opkg update
opkg install luci-app-secubox opkg install luci-app-secubox
/etc/init.d/rpcd restart
/etc/init.d/uhttpd restart
``` ```
## Building ## Building
@ -27,6 +80,33 @@ git clone https://github.com/youruser/luci-app-secubox.git package/luci-app-secu
make package/luci-app-secubox/compile V=s make package/luci-app-secubox/compile V=s
``` ```
## Configuration
Edit `/etc/config/secubox` to customize module definitions and settings.
## File Structure
```
luci-app-secubox/
├── Makefile
├── README.md
├── htdocs/luci-static/resources/
│ ├── view/secubox/
│ │ ├── dashboard.js # Main dashboard view
│ │ ├── modules.js # Modules management view
│ │ └── settings.js # Settings view
│ └── secubox/
│ ├── api.js # RPC API client
│ └── secubox.css # Dashboard styles
└── root/
├── etc/config/secubox # UCI configuration
└── usr/
├── libexec/rpcd/secubox # RPCD backend
└── share/
├── luci/menu.d/luci-app-secubox.json
└── rpcd/acl.d/luci-app-secubox.json
```
## License ## License
MIT License - CyberMind Security Apache-2.0 - Copyright (C) 2025 CyberMind.fr

View File

@ -64,6 +64,31 @@ var callDiagnostics = rpc.declare({
expect: { } expect: { }
}); });
var callSystemHealth = rpc.declare({
object: 'luci.secubox',
method: 'get_system_health',
expect: { }
});
var callAlerts = rpc.declare({
object: 'luci.secubox',
method: 'get_alerts',
expect: { alerts: [] }
});
var callQuickAction = rpc.declare({
object: 'luci.secubox',
method: 'quick_action',
params: ['action'],
expect: { }
});
var callDashboardData = rpc.declare({
object: 'luci.secubox',
method: 'get_dashboard_data',
expect: { }
});
function formatUptime(seconds) { function formatUptime(seconds) {
if (!seconds) return '0s'; if (!seconds) return '0s';
var d = Math.floor(seconds / 86400); var d = Math.floor(seconds / 86400);
@ -74,6 +99,14 @@ function formatUptime(seconds) {
return m + 'm'; return m + 'm';
} }
function formatBytes(bytes) {
if (!bytes) return '0 B';
var k = 1024;
var sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
var i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];
}
return baseclass.extend({ return baseclass.extend({
getStatus: callStatus, getStatus: callStatus,
getModules: callModules, getModules: callModules,
@ -84,5 +117,10 @@ return baseclass.extend({
restartModule: callRestartModule, restartModule: callRestartModule,
getHealth: callHealth, getHealth: callHealth,
getDiagnostics: callDiagnostics, getDiagnostics: callDiagnostics,
formatUptime: formatUptime getSystemHealth: callSystemHealth,
getAlerts: callAlerts,
quickAction: callQuickAction,
getDashboardData: callDashboardData,
formatUptime: formatUptime,
formatBytes: formatBytes
}); });

View File

@ -30,3 +30,262 @@
.sb-color-client-guardian { --module-color: #ef4444; } .sb-color-client-guardian { --module-color: #ef4444; }
.sb-color-system-hub { --module-color: #6366f1; } .sb-color-system-hub { --module-color: #6366f1; }
.sb-color-cdn-cache { --module-color: #06b6d4; } .sb-color-cdn-cache { --module-color: #06b6d4; }
/* System Health Section */
.secubox-health-section {
margin: 20px 0;
padding: 20px;
background: var(--sb-bg-card);
border-radius: 8px;
border: 1px solid var(--sb-border);
}
.secubox-health-section h3 {
margin: 0 0 16px 0;
color: var(--sb-text);
font-size: 18px;
font-weight: 600;
}
.secubox-health-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.secubox-gauge {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
background: rgba(15, 23, 42, 0.5);
border-radius: 8px;
}
.secubox-gauge-label {
font-size: 14px;
font-weight: 600;
color: var(--sb-text);
margin-bottom: 8px;
}
.secubox-gauge-chart {
margin: 8px 0;
}
.secubox-gauge-details {
font-size: 12px;
color: var(--sb-text-muted);
text-align: center;
margin-top: 8px;
}
/* Quick Actions Section */
.secubox-quick-actions {
margin: 20px 0;
padding: 20px;
background: var(--sb-bg-card);
border-radius: 8px;
border: 1px solid var(--sb-border);
}
.secubox-quick-actions h3 {
margin: 0 0 16px 0;
color: var(--sb-text);
font-size: 18px;
font-weight: 600;
}
.secubox-actions-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
}
.secubox-quick-actions .cbi-button-action {
padding: 12px 16px;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Alerts Section */
.secubox-alerts-section {
margin: 20px 0;
padding: 20px;
background: var(--sb-bg-card);
border-radius: 8px;
border: 1px solid var(--sb-border);
}
.secubox-alerts-section h3 {
margin: 0 0 16px 0;
color: var(--sb-text);
font-size: 18px;
font-weight: 600;
}
.secubox-alerts-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.secubox-alert {
padding: 12px 16px;
border-radius: 6px;
border-left: 4px solid;
font-size: 14px;
}
.secubox-alert-warning {
background: rgba(245, 158, 11, 0.1);
border-left-color: var(--sb-warning);
color: #fbbf24;
}
.secubox-alert-error {
background: rgba(239, 68, 68, 0.1);
border-left-color: var(--sb-danger);
color: #fca5a5;
}
.secubox-alert-info {
background: rgba(59, 130, 246, 0.1);
border-left-color: var(--sb-primary);
color: #93c5fd;
}
/* Modules Section */
.secubox-modules-section {
margin: 20px 0;
}
.secubox-modules-section h3 {
margin: 0 0 16px 0;
color: var(--sb-text);
font-size: 18px;
font-weight: 600;
}
.secubox-modules-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.secubox-module-card {
background: var(--sb-bg-card);
border: 1px solid var(--sb-border);
border-radius: 8px;
padding: 16px;
transition: all 0.2s ease;
display: flex;
flex-direction: column;
}
.secubox-module-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
border-color: var(--sb-primary);
}
.secubox-module-card[data-status="running"] {
border-left: 4px solid var(--sb-success);
}
.secubox-module-card[data-status="stopped"] {
border-left: 4px solid var(--sb-danger);
}
.secubox-module-card[data-status="not-installed"] {
opacity: 0.6;
}
.secubox-module-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
}
.secubox-module-icon {
width: 48px;
height: 48px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
}
.secubox-module-status {
font-size: 20px;
font-weight: bold;
}
.secubox-module-body {
flex: 1;
margin-bottom: 12px;
}
.secubox-module-name {
font-size: 16px;
font-weight: 600;
color: var(--sb-text);
margin-bottom: 4px;
}
.secubox-module-description {
font-size: 13px;
color: var(--sb-text-muted);
margin-bottom: 8px;
line-height: 1.4;
}
.secubox-module-category {
display: inline-block;
padding: 4px 8px;
background: rgba(59, 130, 246, 0.2);
color: var(--sb-primary);
border-radius: 4px;
font-size: 11px;
text-transform: uppercase;
font-weight: 600;
letter-spacing: 0.5px;
}
.secubox-module-footer {
padding-top: 12px;
border-top: 1px solid var(--sb-border);
}
.secubox-module-footer .cbi-button-link {
width: 100%;
text-align: center;
padding: 8px;
}
.secubox-not-installed {
display: block;
text-align: center;
color: var(--sb-text-muted);
font-size: 13px;
font-style: italic;
}
/* Responsive Design */
@media (max-width: 768px) {
.secubox-health-grid {
grid-template-columns: repeat(2, 1fr);
}
.secubox-actions-grid {
grid-template-columns: 1fr;
}
.secubox-modules-grid {
grid-template-columns: 1fr;
}
}

View File

@ -1,38 +1,216 @@
'use strict'; 'use strict';
'require view'; 'require view';
'require rpc'; 'require ui';
'require secubox/api as API';
'require dom';
var callStatus = rpc.declare({object:'luci.secubox',method:'status',expect:{}}); // Load CSS
var callModules = rpc.declare({object:'luci.secubox',method:'modules',expect:{modules:[]}}); document.head.appendChild(E('link', {
'rel': 'stylesheet',
'type': 'text/css',
'href': L.resource('secubox/secubox.css')
}));
return view.extend({ return view.extend({
load: function() { return Promise.all([callStatus(), callModules()]); }, load: function() {
render: function(data) { return Promise.all([
var status = data[0] || {}, modules = data[1].modules || []; API.getDashboardData(),
var cats = {security:[], monitoring:[], network:[], system:[]}; API.getSystemHealth(),
modules.forEach(function(m) { if(cats[m.category]) cats[m.category].push(m); }); API.getAlerts()
]);
return E('div', {class:'cbi-map'}, [ },
E('h2', {}, '🛡️ SecuBox Dashboard'),
E('div', {style:'display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin:20px 0'}, [ render: function(data) {
E('div', {style:'background:#1e293b;padding:16px;border-radius:8px;text-align:center'}, [ var dashboard = data[0] || {};
E('div', {style:'font-size:24px;font-weight:bold;color:#22d3ee'}, status.modules_total || 0), var health = data[1] || {};
E('div', {style:'color:#94a3b8'}, 'Total Modules') var alertsData = data[2] || {};
]),
E('div', {style:'background:#1e293b;padding:16px;border-radius:8px;text-align:center'}, [ var status = dashboard.status || {};
E('div', {style:'font-size:24px;font-weight:bold;color:#3b82f6'}, status.modules_installed || 0), var modules = dashboard.modules || [];
E('div', {style:'color:#94a3b8'}, 'Installed') var counts = dashboard.counts || {};
]), var alerts = alertsData.alerts || [];
E('div', {style:'background:#1e293b;padding:16px;border-radius:8px;text-align:center'}, [
E('div', {style:'font-size:24px;font-weight:bold;color:#22c55e'}, status.modules_running || 0), var container = E('div', { 'class': 'cbi-map' });
E('div', {style:'color:#94a3b8'}, 'Running')
]), // Header
E('div', {style:'background:#1e293b;padding:16px;border-radius:8px;text-align:center'}, [ container.appendChild(E('h2', {}, 'SecuBox Central Hub'));
E('div', {style:'font-size:24px;font-weight:bold;color:#f59e0b'}, (status.memory_percent || 0) + '%'), container.appendChild(E('p', {},
E('div', {style:'color:#94a3b8'}, 'Memory') 'Hostname: ' + (status.hostname || 'Unknown') + ' | ' +
]) 'Uptime: ' + API.formatUptime(status.uptime) + ' | ' +
]), 'Load: ' + (status.load || '0.00')
E('p', {}, 'Hostname: ' + (status.hostname || 'unknown') + ' | Load: ' + (status.load || '0')) ));
]);
} // System Health Section
container.appendChild(this.renderSystemHealth(health));
// Quick Actions Section
container.appendChild(this.renderQuickActions());
// Alerts Section
if (alerts.length > 0) {
container.appendChild(this.renderAlerts(alerts));
}
// Modules Grid
container.appendChild(this.renderModulesGrid(modules));
return container;
},
renderSystemHealth: function(health) {
var cpu = health.cpu || {};
var memory = health.memory || {};
var disk = health.disk || {};
var network = health.network || {};
var section = E('div', { 'class': 'secubox-health-section' }, [
E('h3', {}, 'System Health'),
E('div', { 'class': 'secubox-health-grid' }, [
this.renderGauge('CPU', cpu.percent || 0, '%', cpu.load_1min),
this.renderGauge('Memory', memory.percent || 0, '%',
API.formatBytes(memory.used_kb * 1024) + ' / ' + API.formatBytes(memory.total_kb * 1024)),
this.renderGauge('Disk', disk.percent || 0, '%',
API.formatBytes(disk.used_kb * 1024) + ' / ' + API.formatBytes(disk.total_kb * 1024)),
this.renderGauge('Network', 0, '',
'RX: ' + API.formatBytes(network.rx_bytes) + ' | TX: ' + API.formatBytes(network.tx_bytes))
])
]);
return section;
},
renderGauge: function(label, percent, unit, details) {
var color = percent < 70 ? '#22c55e' : percent < 85 ? '#f59e0b' : '#ef4444';
return E('div', { 'class': 'secubox-gauge' }, [
E('div', { 'class': 'secubox-gauge-label' }, label),
E('div', { 'class': 'secubox-gauge-chart' }, [
E('svg', { 'width': '120', 'height': '120', 'viewBox': '0 0 120 120' }, [
E('circle', {
'cx': '60', 'cy': '60', 'r': '54',
'fill': 'none', 'stroke': '#1e293b', 'stroke-width': '12'
}),
E('circle', {
'cx': '60', 'cy': '60', 'r': '54',
'fill': 'none', 'stroke': color, 'stroke-width': '12',
'stroke-dasharray': (339.292 * percent / 100) + ' 339.292',
'stroke-linecap': 'round',
'transform': 'rotate(-90 60 60)'
}),
E('text', {
'x': '60', 'y': '65', 'text-anchor': 'middle',
'font-size': '24', 'font-weight': 'bold', 'fill': color
}, percent + unit)
])
]),
E('div', { 'class': 'secubox-gauge-details' }, details || '')
]);
},
renderQuickActions: function() {
var self = this;
var actions = [
{ name: 'restart_rpcd', label: 'Restart RPCD', icon: '🔄' },
{ name: 'restart_uhttpd', label: 'Restart uHTTPd', icon: '🌐' },
{ name: 'clear_cache', label: 'Clear Cache', icon: '🧹' },
{ name: 'backup_config', label: 'Backup Config', icon: '💾' },
{ name: 'restart_network', label: 'Restart Network', icon: '📡' },
{ name: 'restart_firewall', label: 'Restart Firewall', icon: '🛡️' }
];
var buttons = actions.map(function(action) {
return E('button', {
'class': 'cbi-button cbi-button-action',
'click': function() {
self.executeQuickAction(action.name, action.label);
}
}, action.icon + ' ' + action.label);
});
return E('div', { 'class': 'secubox-quick-actions' }, [
E('h3', {}, 'Quick Actions'),
E('div', { 'class': 'secubox-actions-grid' }, buttons)
]);
},
executeQuickAction: function(action, label) {
ui.showModal(_('Quick Action'), [
E('p', { 'class': 'spinning' }, _('Executing: ') + label + '...')
]);
API.quickAction(action).then(function(result) {
ui.hideModal();
if (result && result.success) {
ui.addNotification(null, E('p', result.message || 'Action completed'), 'info');
} else {
ui.addNotification(null, E('p', result.message || 'Action failed'), 'error');
}
}).catch(function(err) {
ui.hideModal();
ui.addNotification(null, E('p', 'Error: ' + err.message), 'error');
});
},
renderAlerts: function(alerts) {
var alertItems = alerts.map(function(alert) {
var severityClass = 'secubox-alert-' + (alert.severity || 'info');
return E('div', { 'class': 'secubox-alert ' + severityClass }, [
E('strong', {}, alert.module + ': '),
E('span', {}, alert.message)
]);
});
return E('div', { 'class': 'secubox-alerts-section' }, [
E('h3', {}, 'Recent Alerts (' + alerts.length + ')'),
E('div', { 'class': 'secubox-alerts-list' }, alertItems)
]);
},
renderModulesGrid: function(modules) {
var moduleCards = modules.map(function(module) {
var statusClass = module.installed ? (module.running ? 'running' : 'stopped') : 'not-installed';
var statusIcon = module.installed ? (module.running ? '✓' : '✗') : '○';
var statusColor = module.installed ? (module.running ? '#22c55e' : '#ef4444') : '#64748b';
return E('div', {
'class': 'secubox-module-card',
'data-status': statusClass
}, [
E('div', { 'class': 'secubox-module-header' }, [
E('div', {
'class': 'secubox-module-icon',
'style': 'background-color: ' + (module.color || '#64748b')
}, module.icon || '📦'),
E('div', {
'class': 'secubox-module-status',
'style': 'color: ' + statusColor
}, statusIcon)
]),
E('div', { 'class': 'secubox-module-body' }, [
E('div', { 'class': 'secubox-module-name' }, module.name || module.id),
E('div', { 'class': 'secubox-module-description' }, module.description || ''),
E('div', { 'class': 'secubox-module-category' }, module.category || 'other')
]),
E('div', { 'class': 'secubox-module-footer' }, [
module.installed ? E('a', {
'href': '#',
'class': 'cbi-button cbi-button-link',
'click': function(ev) {
ev.preventDefault();
window.location.hash = '#admin/secubox/' + module.id;
}
}, 'Open Dashboard') : E('span', { 'class': 'secubox-not-installed' }, 'Not Installed')
])
]);
});
return E('div', { 'class': 'secubox-modules-section' }, [
E('h3', {}, 'Installed Modules'),
E('div', { 'class': 'secubox-modules-grid' }, moduleCards)
]);
},
handleSaveApply: null,
handleSave: null,
handleReset: null
}); });

View File

@ -95,3 +95,58 @@ config module 'cdn_cache'
option config 'cdn-cache' option config 'cdn-cache'
option installed '0' option installed '0'
option enabled '0' option enabled '0'
config module 'bandwidth_manager'
option name 'Bandwidth Manager'
option description 'QoS and bandwidth quotas'
option category 'network'
option icon 'activity'
option color '#3b82f6'
option package 'luci-app-bandwidth-manager'
option config 'bandwidth_manager'
option installed '0'
option enabled '0'
config module 'auth_guardian'
option name 'Auth Guardian'
option description 'Advanced authentication system'
option category 'security'
option icon 'key'
option color '#f59e0b'
option package 'luci-app-auth-guardian'
option config 'auth_guardian'
option installed '0'
option enabled '0'
config module 'media_flow'
option name 'Media Flow'
option description 'Media traffic detection and optimization'
option category 'network'
option icon 'play-circle'
option color '#ec4899'
option package 'luci-app-media-flow'
option config 'media_flow'
option installed '0'
option enabled '0'
config module 'vhost_manager'
option name 'Virtual Host Manager'
option description 'Virtual host configuration'
option category 'system'
option icon 'server'
option color '#8b5cf6'
option package 'luci-app-vhost-manager'
option config 'vhost_manager'
option installed '0'
option enabled '0'
config module 'traffic_shaper'
option name 'Traffic Shaper'
option description 'Advanced traffic shaping'
option category 'network'
option icon 'trending-up'
option color '#10b981'
option package 'luci-app-traffic-shaper'
option config 'traffic_shaper'
option installed '0'
option enabled '0'

View File

@ -7,8 +7,23 @@
. /lib/functions.sh . /lib/functions.sh
. /usr/share/libubox/jshn.sh . /usr/share/libubox/jshn.sh
# Module registry # Module registry - auto-detected from /usr/libexec/rpcd/
MODULES="crowdsec netdata netifyd wireguard network_modes client_guardian system_hub cdn_cache" detect_modules() {
local modules=""
local scripts="crowdsec-dashboard netdata-dashboard netifyd-dashboard wireguard-dashboard network-modes client-guardian system-hub bandwidth-manager auth-guardian media-flow vhost-manager cdn-cache traffic-shaper"
for script in $scripts; do
if [ -x "/usr/libexec/rpcd/$script" ]; then
# Convert script name to module ID (remove -dashboard suffix)
local module_id=$(echo "$script" | sed 's/-dashboard$//')
modules="$modules $module_id"
fi
done
echo "$modules"
}
MODULES=$(detect_modules)
# Check if a module is installed # Check if a module is installed
check_module_installed() { check_module_installed() {
@ -338,7 +353,7 @@ get_health() {
# Generate diagnostics bundle # Generate diagnostics bundle
get_diagnostics() { get_diagnostics() {
json_init json_init
# System info # System info
json_add_object "system" json_add_object "system"
json_add_string "hostname" "$(uci -q get system.@system[0].hostname)" json_add_string "hostname" "$(uci -q get system.@system[0].hostname)"
@ -347,13 +362,13 @@ get_diagnostics() {
json_add_string "kernel" "$(uname -r)" json_add_string "kernel" "$(uname -r)"
json_add_int "uptime" "$(cat /proc/uptime | cut -d. -f1)" json_add_int "uptime" "$(cat /proc/uptime | cut -d. -f1)"
json_close_object json_close_object
# Modules status # Modules status
json_add_array "modules" json_add_array "modules"
for module in $MODULES; do for module in $MODULES; do
local is_installed=$(check_module_installed "$module") local is_installed=$(check_module_installed "$module")
local is_running=$(check_module_running "$module") local is_running=$(check_module_running "$module")
json_add_object "" json_add_object ""
json_add_string "id" "$module" json_add_string "id" "$module"
json_add_boolean "installed" "$is_installed" json_add_boolean "installed" "$is_installed"
@ -361,13 +376,13 @@ get_diagnostics() {
json_close_object json_close_object
done done
json_close_array json_close_array
# Network interfaces # Network interfaces
json_add_array "interfaces" json_add_array "interfaces"
for iface in $(ls /sys/class/net/); do for iface in $(ls /sys/class/net/); do
local mac=$(cat /sys/class/net/$iface/address 2>/dev/null) local mac=$(cat /sys/class/net/$iface/address 2>/dev/null)
local state=$(cat /sys/class/net/$iface/operstate 2>/dev/null) local state=$(cat /sys/class/net/$iface/operstate 2>/dev/null)
json_add_object "" json_add_object ""
json_add_string "name" "$iface" json_add_string "name" "$iface"
json_add_string "mac" "$mac" json_add_string "mac" "$mac"
@ -375,9 +390,287 @@ get_diagnostics() {
json_close_object json_close_object
done done
json_close_array json_close_array
json_add_int "generated" "$(date +%s)" json_add_int "generated" "$(date +%s)"
json_dump
}
# Get system health metrics
get_system_health() {
json_init
# CPU usage (based on load average)
local load=$(cat /proc/loadavg | cut -d' ' -f1)
local cpu_cores=$(grep -c processor /proc/cpuinfo)
local cpu_pct=$(awk "BEGIN {printf \"%.0f\", ($load / $cpu_cores) * 100}")
# Memory
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
local mem_avail=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
local mem_used=$((mem_total - mem_avail))
local mem_pct=$((mem_used * 100 / mem_total))
# Disk usage (root filesystem)
local disk_info=$(df / | tail -1)
local disk_total=$(echo "$disk_info" | awk '{print $2}')
local disk_used=$(echo "$disk_info" | awk '{print $3}')
local disk_pct=$(echo "$disk_info" | awk '{print $5}' | tr -d '%')
# Network stats (sum all interfaces)
local net_rx=0
local net_tx=0
for iface in $(ls /sys/class/net/ | grep -v lo); do
if [ -f "/sys/class/net/$iface/statistics/rx_bytes" ]; then
local rx=$(cat /sys/class/net/$iface/statistics/rx_bytes 2>/dev/null || echo 0)
local tx=$(cat /sys/class/net/$iface/statistics/tx_bytes 2>/dev/null || echo 0)
net_rx=$((net_rx + rx))
net_tx=$((net_tx + tx))
fi
done
# Uptime
local uptime=$(cat /proc/uptime | cut -d. -f1)
# Load averages
local load_1min=$(cat /proc/loadavg | cut -d' ' -f1)
local load_5min=$(cat /proc/loadavg | cut -d' ' -f2)
local load_15min=$(cat /proc/loadavg | cut -d' ' -f3)
json_add_object "cpu"
json_add_int "percent" "$cpu_pct"
json_add_int "cores" "$cpu_cores"
json_add_string "load_1min" "$load_1min"
json_add_string "load_5min" "$load_5min"
json_add_string "load_15min" "$load_15min"
json_close_object
json_add_object "memory"
json_add_int "percent" "$mem_pct"
json_add_int "total_kb" "$mem_total"
json_add_int "used_kb" "$mem_used"
json_add_int "available_kb" "$mem_avail"
json_close_object
json_add_object "disk"
json_add_int "percent" "$disk_pct"
json_add_int "total_kb" "$disk_total"
json_add_int "used_kb" "$disk_used"
json_close_object
json_add_object "network"
json_add_int "rx_bytes" "$net_rx"
json_add_int "tx_bytes" "$net_tx"
json_close_object
json_add_int "uptime" "$uptime"
json_add_int "timestamp" "$(date +%s)"
json_dump
}
# Get aggregated alerts from all modules
get_alerts() {
json_init
json_add_array "alerts"
# Check each installed module for alerts via ubus
for module in $MODULES; do
local is_installed=$(check_module_installed "$module")
if [ "$is_installed" = "1" ]; then
# Try to call module's status method to get alerts
local module_script=$(echo "$module" | sed 's/_/-/g')
if [ -x "/usr/libexec/rpcd/${module_script}" ] || [ -x "/usr/libexec/rpcd/${module_script}-dashboard" ]; then
# Call via ubus if available
local alerts=$(ubus call "luci.${module_script//-/_}" status 2>/dev/null | jsonfilter -e '@.alerts[@]' 2>/dev/null)
if [ -n "$alerts" ]; then
# Module has alerts, add them
json_add_object ""
json_add_string "module" "$module"
json_add_string "message" "$alerts"
json_add_string "severity" "warning"
json_add_int "timestamp" "$(date +%s)"
json_close_object
fi
fi
# Check if module service is not running
local is_running=$(check_module_running "$module")
if [ "$is_running" != "1" ]; then
config_load secubox
local name
config_get name "$module" name "$module"
json_add_object ""
json_add_string "module" "$module"
json_add_string "message" "$name service is not running"
json_add_string "severity" "warning"
json_add_int "timestamp" "$(date +%s)"
json_close_object
fi
fi
done
json_close_array
json_add_int "count" "$(ubus call luci.secubox get_alerts 2>/dev/null | jsonfilter -e '@.alerts[*]' | wc -l || echo 0)"
json_add_int "timestamp" "$(date +%s)"
json_dump
}
# Execute quick actions
quick_action() {
local action="$1"
json_init
case "$action" in
restart_rpcd)
/etc/init.d/rpcd restart >/dev/null 2>&1
json_add_boolean "success" 1
json_add_string "message" "RPCD service restarted"
;;
restart_uhttpd)
/etc/init.d/uhttpd restart >/dev/null 2>&1
json_add_boolean "success" 1
json_add_string "message" "uHTTPd service restarted"
;;
clear_cache)
sync
echo 3 > /proc/sys/vm/drop_caches 2>/dev/null
json_add_boolean "success" 1
json_add_string "message" "System cache cleared"
;;
backup_config)
local backup_file="/tmp/backup-$(date +%Y%m%d-%H%M%S).tar.gz"
sysupgrade -b "$backup_file" >/dev/null 2>&1
if [ -f "$backup_file" ]; then
json_add_boolean "success" 1
json_add_string "message" "Configuration backup created"
json_add_string "file" "$backup_file"
else
json_add_boolean "success" 0
json_add_string "message" "Backup failed"
fi
;;
restart_network)
/etc/init.d/network restart >/dev/null 2>&1
json_add_boolean "success" 1
json_add_string "message" "Network services restarted"
;;
restart_firewall)
/etc/init.d/firewall restart >/dev/null 2>&1
json_add_boolean "success" 1
json_add_string "message" "Firewall restarted"
;;
*)
json_add_boolean "success" 0
json_add_string "message" "Unknown action: $action"
;;
esac
json_add_int "timestamp" "$(date +%s)"
json_dump
}
# Get all dashboard data in one call
get_dashboard_data() {
json_init
# Get status info
local uptime=$(cat /proc/uptime | cut -d. -f1)
local load=$(cat /proc/loadavg | cut -d' ' -f1-3)
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
local mem_free=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
local mem_used=$((mem_total - mem_free))
local mem_pct=$((mem_used * 100 / mem_total))
json_add_object "status"
json_add_string "version" "1.0.0"
json_add_string "hostname" "$(uci -q get system.@system[0].hostname || echo 'SecuBox')"
json_add_int "uptime" "$uptime"
json_add_string "load" "$load"
json_add_int "memory_total" "$mem_total"
json_add_int "memory_used" "$mem_used"
json_add_int "memory_percent" "$mem_pct"
json_close_object
# Get modules list
json_add_array "modules"
config_load secubox
for module in $MODULES; do
local name desc category icon color
config_get name "$module" name "$module"
config_get desc "$module" description ""
config_get category "$module" category "other"
config_get icon "$module" icon "box"
config_get color "$module" color "#64748b"
local is_installed=$(check_module_installed "$module")
local is_running=$(check_module_running "$module")
json_add_object ""
json_add_string "id" "$module"
json_add_string "name" "$name"
json_add_string "description" "$desc"
json_add_string "category" "$category"
json_add_string "icon" "$icon"
json_add_string "color" "$color"
json_add_boolean "installed" "$is_installed"
json_add_boolean "running" "$is_running"
json_close_object
done
json_close_array
# Count installed and running modules
local total=0 installed=0 running=0
for module in $MODULES; do
total=$((total + 1))
[ "$(check_module_installed "$module")" = "1" ] && installed=$((installed + 1))
[ "$(check_module_running "$module")" = "1" ] && running=$((running + 1))
done
json_add_object "counts"
json_add_int "total" "$total"
json_add_int "installed" "$installed"
json_add_int "running" "$running"
json_close_object
# Get system health
local cpu_cores=$(grep -c processor /proc/cpuinfo)
local load_val=$(cat /proc/loadavg | cut -d' ' -f1)
local cpu_pct=$(awk "BEGIN {printf \"%.0f\", ($load_val / $cpu_cores) * 100}")
local disk_pct=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
json_add_object "health"
json_add_int "cpu_percent" "$cpu_pct"
json_add_int "memory_percent" "$mem_pct"
json_add_int "disk_percent" "$disk_pct"
json_close_object
# Get recent alerts (simplified)
json_add_array "alerts"
for module in $MODULES; do
local is_installed=$(check_module_installed "$module")
local is_running=$(check_module_running "$module")
if [ "$is_installed" = "1" ] && [ "$is_running" != "1" ]; then
config_load secubox
local name
config_get name "$module" name "$module"
json_add_object ""
json_add_string "module" "$module"
json_add_string "message" "$name is not running"
json_add_string "severity" "warning"
json_close_object
fi
done
json_close_array
json_add_int "timestamp" "$(date +%s)"
json_dump json_dump
} }
@ -408,6 +701,15 @@ case "$1" in
json_close_object json_close_object
json_add_object "diagnostics" json_add_object "diagnostics"
json_close_object json_close_object
json_add_object "get_system_health"
json_close_object
json_add_object "get_alerts"
json_close_object
json_add_object "quick_action"
json_add_string "action" "string"
json_close_object
json_add_object "get_dashboard_data"
json_close_object
json_dump json_dump
;; ;;
call) call)
@ -454,6 +756,21 @@ case "$1" in
diagnostics) diagnostics)
get_diagnostics get_diagnostics
;; ;;
get_system_health)
get_system_health
;;
get_alerts)
get_alerts
;;
quick_action)
read -r input
json_load "$input"
json_get_var action action ""
quick_action "$action"
;;
get_dashboard_data)
get_dashboard_data
;;
*) *)
echo '{"error":"Unknown method"}' echo '{"error":"Unknown method"}'
;; ;;

View File

@ -1,7 +1,30 @@
{ {
"luci-app-secubox": { "luci-app-secubox": {
"description": "SecuBox Dashboard", "description": "SecuBox Dashboard",
"read": {"ubus": {"luci.secubox": ["status", "modules"]}}, "read": {
"write": {} "ubus": {
"luci.secubox": [
"status",
"modules",
"modules_by_category",
"module_info",
"health",
"diagnostics",
"get_system_health",
"get_alerts",
"get_dashboard_data"
]
}
},
"write": {
"ubus": {
"luci.secubox": [
"start_module",
"stop_module",
"restart_module",
"quick_action"
]
}
}
} }
} }