feat(vhost-manager): Add centralized VHost manager

- Create secubox-app-vhost-manager package for unified vhost orchestration
- Single CLI tool (secubox-vhost) manages HAProxy, DNS, Tor, Mesh, mitmproxy
- Unified UCI config (/etc/config/vhosts) as single source of truth
- Backend adapters for each component (haproxy.sh, dns.sh, tor.sh, mesh.sh, mitmproxy.sh)
- Centralized backend resolution function (backends.sh)
- Import tool for existing HAProxy vhosts
- Validation of backend reachability before creation

Also includes:
- FAQ-TROUBLESHOOTING.md with LXC cgroup v1/v2 fixes
- Fix mitmproxyctl cgroup v1 -> v2 syntax for container compatibility
- HAProxy backend resolution bugfixes

CLI commands:
  secubox-vhost add <domain> <service> <port> [--ssl] [--tor] [--mesh]
  secubox-vhost remove/list/status/enable/disable/set/sync/validate/import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-05 10:16:19 +01:00
parent 0e0749ed08
commit e13b6e4c8c
118 changed files with 2751 additions and 373 deletions

View File

@ -0,0 +1,332 @@
# SecuBox Troubleshooting FAQ
_Last updated: 2026-02-06_
This document collects resolved issues and their solutions for future reference.
---
## LXC Container Issues
### Issue: LXC containers fail to start with "Failed to mount /sys/fs/cgroup"
**Symptoms:**
```
ERROR cgfsng - Failed to create cgroup at_mnt 38()
ERROR conf - Failed to mount "/sys/fs/cgroup"
ERROR conf - Failed to setup remaining automatic mounts
Received container state "ABORTING" instead of "RUNNING"
```
**Root Cause:**
OpenWrt uses cgroup v2 (unified hierarchy), but LXC configs may be using cgroup v1 syntax.
**Solution:**
1. **Fix global LXC defaults** - Create/edit `/usr/share/lxc/config/common.conf`:
```
# Comment out all lxc.cgroup.devices lines (cgroup v1 syntax)
# These cause "Failed to mount /sys/fs/cgroup" on cgroup v2 systems
#lxc.cgroup.devices.deny = a
#lxc.cgroup.devices.allow = c *:* m
# ... (all device lines commented out)
```
2. **Fix per-container config** - Replace cgroup v1 with v2 syntax:
```
# OLD (cgroup v1 - breaks on cgroup v2 systems):
lxc.cgroup.memory.limit_in_bytes = 256M
# NEW (cgroup v2):
lxc.cgroup2.memory.max = 268435456
```
3. **Add cgroup v2 compatibility flags**:
```
lxc.seccomp.profile =
lxc.tty.max = 0
lxc.pty.max = 256
lxc.cap.drop = sys_module mac_admin mac_override sys_time
```
**Reference:** [OpenWrt Forum LXC Guide](https://forum.openwrt.org/t/openwrt-arm64-quick-lxc-howto-guide-lms-in-debian-system-in-lxc-container/99835)
---
### Issue: Alpine-based LXC rootfs incompatible with host cgroups
**Symptoms:**
Container starts but immediately exits, or mounts fail inside container.
**Solution:**
Use Debian-based rootfs instead of Alpine. Copy from a working container:
```bash
# Create new container from working Debian rootfs
cp -a /srv/lxc/domoticz/rootfs /srv/lxc/newcontainer/rootfs
```
---
## Networking Issues
### Issue: Port 80 requests redirected to port 8888
**Symptoms:**
HTTP requests on port 80 go to mitmproxy (8888) instead of HAProxy.
**Root Cause:**
mitmproxy WAN protection mode uses nftables to redirect incoming WAN traffic.
**Solution:**
```bash
# Check if mitmproxy WAN protection is enabled
uci get mitmproxy.wan_protection.enabled
# Disable it
uci set mitmproxy.wan_protection.enabled='0'
uci commit mitmproxy
# Remove nftables rules
nft delete table inet mitmproxy_wan
```
---
### Issue: DNS rebind attack blocking internal IPs
**Symptoms:**
BIND (or other DNS server) returns private IP (192.168.x.x), but clients get SERVFAIL.
**Root Cause:**
dnsmasq has DNS rebind protection that blocks private IPs in DNS responses (security feature against DNS rebinding attacks).
**Solution:**
Whitelist the domain in dnsmasq config:
```
# /etc/dnsmasq.d/yourdomain.conf
rebind-domain-ok=/yourdomain.com/
```
Then restart dnsmasq:
```bash
/etc/init.d/dnsmasq restart
```
---
### Issue: WAN traffic not reaching Docker/LXC containers
**Symptoms:**
External requests on ports 80/443 timeout, but LAN access works.
**Root Cause:**
Firewall forward chain missing rules for WAN to Docker bridge.
**Solution:**
```bash
# Check firewall rules
nft list chain inet fw4 forward_wan
# Add forward rules for HTTP/HTTPS
# Via LuCI: Network > Firewall > Traffic Rules
# Or via UCI:
uci add firewall rule
uci set firewall.@rule[-1].name='Forward-HAProxy-HTTP'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest='docker'
uci set firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].dest_port='80'
uci set firewall.@rule[-1].target='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart
```
---
## HAProxy Issues
### Issue: HAProxy fails with "unable to find required use_backend"
**Symptoms:**
```
[ALERT] config : Proxy 'https-in': unable to find required use_backend: '127.0.0.1:8091'
```
**Root Cause:**
`haproxyctl generate` created invalid backend references using IP:port format instead of backend names.
**Solution:**
1. Check for invalid backends:
```bash
grep -n 'use_backend.*127.0.0.1' /srv/haproxy/config/haproxy.cfg
```
2. Fix by either:
- Manually edit the config to use proper backend names
- Delete the vhost config files and regenerate
- Create missing backend definitions
```
# Example fix - add missing backend definition:
backend localai
mode http
server localai 127.0.0.1:8091 check inter 10s
```
---
## Mitmproxy WAF Issues
### Issue: Mitmproxy container stops after haproxy-enable
**Symptoms:**
`mitmproxyctl haproxy-enable` completes but container is STOPPED.
**Root Cause:**
The enable command restarts services which regenerates the LXC config with cgroup v1 syntax.
**Solution:**
Patch `/usr/sbin/mitmproxyctl` to use cgroup v2 syntax:
```bash
sed -i "s/lxc.cgroup.memory.limit_in_bytes/lxc.cgroup2.memory.max/" /usr/sbin/mitmproxyctl
```
Also add seccomp disable after the cgroup line:
```bash
sed -i "/lxc.cgroup2.memory.max/a lxc.seccomp.profile =" /usr/sbin/mitmproxyctl
```
Then manually fix the container config and restart:
```bash
# Edit /srv/lxc/mitmproxy/config with cgroup v2 syntax
lxc-start -n mitmproxy
```
---
### Issue: Mitmproxy not detecting threats
**Symptoms:**
`/srv/mitmproxy/threats.log` is empty or not being updated.
**Checklist:**
1. Container running: `lxc-info -n mitmproxy`
2. Port 8889 listening: `netstat -tlnp | grep 8889`
3. HAProxy routing through mitmproxy: `grep mitmproxy_inspector /srv/haproxy/config/haproxy.cfg`
4. Routes synced: `cat /srv/mitmproxy/haproxy-routes.json`
**Solution:**
```bash
mitmproxyctl sync-routes
mitmproxyctl haproxy-enable
```
---
## DNS Provider Issues
### Issue: Let's Encrypt DNS-01 fails with CAA timeout
**Symptoms:**
ACME challenge fails because CAA record lookup times out.
**Root Cause:**
Router is authoritative for the domain but dnsmasq cannot serve CAA records.
**Solutions:**
1. **Remove local authority** - Let external DNS (Gandi/Cloudflare) handle everything:
```
# /etc/dnsmasq.d/yourdomain.conf
# Remove: local=/yourdomain.com/
# Keep only: server=/yourdomain.com/127.0.0.1#5353 (for BIND)
# Or forward to external: server=/yourdomain.com/8.8.8.8
```
2. **Use BIND instead of dnsmasq** for authoritative DNS (supports CAA records).
---
## Quick Diagnostic Commands
```bash
# Check all LXC containers
for d in /srv/lxc/*/; do n=$(basename "$d"); lxc-info -n "$n" 2>/dev/null | head -3; done
# Check listening ports
netstat -tlnp | grep -E "80|443|8889|8089"
# Check firewall forward rules
nft list chain inet fw4 forward_wan
# Check DNS resolution
nslookup yourdomain.com 127.0.0.1
# Check mitmproxy status
mitmproxyctl status
# Recent threats
tail -20 /srv/mitmproxy/threats.log
# HAProxy config test
haproxy -c -f /srv/haproxy/config/haproxy.cfg
```
---
### Issue: haproxyctl generate creates invalid backend references
**Symptoms:**
HAProxy config contains `use_backend 127.0.0.1:8091` instead of a named backend.
**Root Cause:**
UCI vhost entries were created with `backend='127.0.0.1:8091'` (IP:port) instead of a named backend like `backend='localai'`.
This happens when:
1. `haproxyctl vhost add` is used with a non-existent backend name
2. Manual UCI edits use IP:port instead of backend name
3. Scripts create vhosts without first creating the backend
**Solution:**
1. Create the backend first:
```bash
haproxyctl backend add localai
haproxyctl server add localai 127.0.0.1:8091
```
2. Then fix the vhost to use the backend name:
```bash
uci set haproxy.<vhost_section>.backend='localai'
uci set haproxy.<vhost_section>.original_backend='localai'
uci commit haproxy
haproxyctl generate
```
3. Add missing backends to haproxy.cfg:
```
backend localai
mode http
server localai 127.0.0.1:8091 check inter 10s
```
**Prevention:**
Always create named backends before adding vhosts that reference them.
---
## Package-Specific Fixes Applied
| Package | Issue | Fix |
|---------|-------|-----|
| `mitmproxyctl` | cgroup v1 syntax | Changed to `lxc.cgroup2.memory.max` |
| `dnsmasq` | DNS rebind blocking | Added `rebind-domain-ok` |
| `haproxy` | Invalid backend names | Manual config repair |
| LXC common.conf | cgroup v1 device rules | Commented out device lines |
---
## References
- [OpenWrt LXC ARM64 Guide](https://forum.openwrt.org/t/openwrt-arm64-quick-lxc-howto-guide-lms-in-debian-system-in-lxc-container/99835)
- [LXC cgroup v2 migration](https://linuxcontainers.org/lxc/manpages/man5/lxc.container.conf.5.html)
- [dnsmasq man page - rebind-domain-ok](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html)

View File

@ -327,3 +327,23 @@ _Last updated: 2026-02-06_
- Service mirroring via reverse proxy chaining
- Gossip-based exposure config sync
- Submastering/multimixslaving architecture
32. **Threat Analyst KISS Dashboard v0.1.0 (2026-02-05)**
- Regenerated `luci-app-threat-analyst` following CrowdSec dashboard KISS template pattern.
- **Architectural changes**:
- `api.js`: Migrated from plain object to `baseclass.extend()` pattern
- `dashboard.css`: External CSS file (loaded dynamically in view)
- `dashboard.js`: View-only JS following CrowdSec pattern with `view.extend()`
- **CVE integration**:
- System Health: New "CVE Alerts" indicator with warning icon (yellow) when CVEs detected
- Threats table: New CVE column with hyperlinks to NVD (`https://nvd.nist.gov/vuln/detail/CVE-XXXX-XXXXX`)
- CVE extraction: `extractCVE()` function in API parses CVE-YYYY-NNNNN patterns from scenarios
- CVE row styling: Red-tinted background for CVE-related threats
- **RPCD updates**:
- Status method now returns `cve_alerts` count from CrowdSec alerts
- Fixed output bug (grep `|| echo 0` causing double output)
- **CSS additions**:
- `.ta-health-icon.warning` for CVE alerts in health section
- `.ta-cve-link` for NVD hyperlinks (red badge style)
- `.ta-cve-row` for highlighted CVE threat rows
- Following LuCI UI Generation Model Template v0.1.0 for future KISS modules.

View File

@ -45,6 +45,15 @@ _Last updated: 2026-02-06_
_None currently active_
### Just Completed
- **Subdomain Generator Tool** — DONE (2026-02-05)
- `secubox-subdomain` CLI for generative subdomain management
- Automates: DNS A record + HAProxy vhost + UCI registration
- Uses wildcard certificate (*.zone) for instant SSL
- Quick-add shortcuts for common services (gitea, grafana, jellyfin, etc.)
- Part of Punk Exposure infrastructure
### Next Up — Couche 1
1. **Guacamole Pre-built Binaries**
@ -89,6 +98,13 @@ _None currently active_
- Created `luci-app-threat-analyst` with AI chatbot dashboard
- RPCD handler with 10 methods for status, chat, rules, approval
- **Threat Analyst KISS Dashboard v0.1.0** — DONE (2026-02-05)
- Regenerated LuCI dashboard following CrowdSec KISS template pattern
- External CSS loading, baseclass.extend() API pattern
- CVE alerts in System Health section
- CVE column in threats table with NVD hyperlinks
- AI Security Assistant chat interface
- **MCP Server Implementation** — DONE (2026-02-06)
- Created `secubox-mcp-server` package with JSON-RPC 2.0 over stdio
- 9 core tools: crowdsec.alerts/decisions, waf.logs, dns.queries, network.flows, system.metrics, wireguard.status, uci.get/set

View File

@ -278,7 +278,8 @@
"Bash(jsonfilter:*)",
"WebFetch(domain:zigbeefordomoticz.github.io)",
"WebFetch(domain:rustdesk.com)",
"WebFetch(domain:deepwiki.com)"
"WebFetch(domain:deepwiki.com)",
"Bash(traceroute:*)"
]
}
}

View File

@ -54,25 +54,35 @@ method_status() {
stats_port=$(get_uci main stats_port 8404)
stats_enabled=$(get_uci main stats_enabled 1)
# Check container status - prefer lxc-info, fallback to pgrep lxc-start
if command -v lxc-info >/dev/null 2>&1; then
container_running=$(lxc-info -n haproxy -s 2>/dev/null | grep -q "RUNNING" && echo "1" || echo "0")
else
# Fallback: check if lxc-start is running for haproxy
container_running=$(pgrep -f "lxc-start.*-n haproxy" >/dev/null 2>&1 && echo "1" || echo "0")
# Check container status - Docker first, then LXC
container_running="0"
haproxy_running="0"
# Check Docker container (secubox-haproxy or haproxy)
if command -v docker >/dev/null 2>&1; then
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qE '^(secubox-haproxy|haproxy)$'; then
container_running="1"
haproxy_running="1"
fi
fi
# Check HAProxy process
if [ "$container_running" = "1" ]; then
# Try lxc-attach first, fallback to direct pgrep
if command -v lxc-attach >/dev/null 2>&1; then
haproxy_running=$(lxc-attach -n haproxy -- pgrep haproxy >/dev/null 2>&1 && echo "1" || echo "0")
else
# Fallback: check if haproxy process exists (it runs in container but visible from host)
haproxy_running=$(pgrep -f "haproxy.*haproxy.cfg" >/dev/null 2>&1 && echo "1" || echo "0")
# If not Docker, check LXC
if [ "$container_running" = "0" ]; then
if command -v lxc-info >/dev/null 2>&1; then
if lxc-info -n haproxy -s 2>/dev/null | grep -q "RUNNING"; then
container_running="1"
# Check HAProxy process inside LXC
haproxy_running=$(lxc-attach -n haproxy -- pgrep haproxy >/dev/null 2>&1 && echo "1" || echo "0")
fi
fi
fi
# Final fallback: check if HAProxy port is listening
if [ "$container_running" = "0" ]; then
if netstat -tln 2>/dev/null | grep -q ":80 "; then
container_running="1"
haproxy_running="1"
fi
else
haproxy_running="0"
fi
json_init

View File

@ -28,6 +28,7 @@ define Package/luci-app-threat-analyst/install
$(INSTALL_DIR) $(1)/www/luci-static/resources/threat-analyst
$(INSTALL_DATA) ./htdocs/luci-static/resources/threat-analyst/api.js $(1)/www/luci-static/resources/threat-analyst/
$(INSTALL_DATA) ./htdocs/luci-static/resources/threat-analyst/dashboard.css $(1)/www/luci-static/resources/threat-analyst/
endef
$(eval $(call BuildPackage,luci-app-threat-analyst))

View File

@ -1,6 +1,19 @@
'use strict';
'require baseclass';
'require rpc';
/**
* Threat Analyst API
* Package: luci-app-threat-analyst
* RPCD object: luci.threat-analyst
* Version: 0.1.0
*
* Generative AI-powered threat filtering for:
* - CrowdSec autoban scenarios
* - mitmproxy filter rules
* - WAF rules
*/
var callStatus = rpc.declare({
object: 'luci.threat-analyst',
method: 'status',
@ -14,13 +27,6 @@ var callGetThreats = rpc.declare({
expect: { }
});
var callGetAlerts = rpc.declare({
object: 'luci.threat-analyst',
method: 'get_alerts',
params: ['limit'],
expect: { }
});
var callGetPending = rpc.declare({
object: 'luci.threat-analyst',
method: 'get_pending',
@ -34,12 +40,6 @@ var callChat = rpc.declare({
expect: { }
});
var callAnalyze = rpc.declare({
object: 'luci.threat-analyst',
method: 'analyze',
expect: { }
});
var callGenerateRules = rpc.declare({
object: 'luci.threat-analyst',
method: 'generate_rules',
@ -67,15 +67,72 @@ var callRunCycle = rpc.declare({
expect: { }
});
return {
status: callStatus,
function formatRelativeTime(dateStr) {
if (!dateStr) return 'N/A';
try {
var date = new Date(dateStr);
var now = new Date();
var seconds = Math.floor((now - date) / 1000);
if (seconds < 60) return seconds + 's ago';
if (seconds < 3600) return Math.floor(seconds / 60) + 'm ago';
if (seconds < 86400) return Math.floor(seconds / 3600) + 'h ago';
return Math.floor(seconds / 86400) + 'd ago';
} catch(e) {
return dateStr;
}
}
function parseScenario(scenario) {
if (!scenario) return 'Unknown';
var parts = scenario.split('/');
var name = parts[parts.length - 1];
return name.split('-').map(function(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
}).join(' ');
}
function getSeverityClass(scenario) {
if (!scenario) return 'medium';
var s = scenario.toLowerCase();
if (s.includes('malware') || s.includes('exploit') || s.includes('cve')) return 'critical';
if (s.includes('bruteforce') || s.includes('scan')) return 'high';
if (s.includes('crawl') || s.includes('http')) return 'low';
return 'medium';
}
function extractCVE(scenario) {
if (!scenario) return null;
// Match CVE patterns: CVE-YYYY-NNNNN
var match = scenario.match(/CVE-\d{4}-\d{4,}/i);
return match ? match[0].toUpperCase() : null;
}
return baseclass.extend({
getStatus: callStatus,
getThreats: callGetThreats,
getAlerts: callGetAlerts,
getPending: callGetPending,
chat: callChat,
analyze: callAnalyze,
generateRules: callGenerateRules,
approveRule: callApproveRule,
rejectRule: callRejectRule,
runCycle: callRunCycle
};
runCycle: callRunCycle,
formatRelativeTime: formatRelativeTime,
parseScenario: parseScenario,
getSeverityClass: getSeverityClass,
extractCVE: extractCVE,
getOverview: function() {
return Promise.all([
callStatus(),
callGetThreats(20),
callGetPending()
]).then(function(results) {
return {
status: results[0] || {},
threats: (results[1] || {}).threats || [],
pending: (results[2] || {}).pending || []
};
});
}
});

View File

@ -0,0 +1,454 @@
/* Threat Analyst Dashboard CSS - v0.1.0 */
/* Following CrowdSec Dashboard KISS pattern */
.ta-view {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
/* Header */
.ta-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid var(--border-color-medium, #ddd);
}
.ta-title {
font-size: 24px;
font-weight: 600;
color: var(--text-color, #333);
}
.ta-status {
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
}
.ta-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #ccc;
}
.ta-dot.online { background: #4caf50; }
.ta-dot.offline { background: #f44336; }
/* Navigation */
.ta-nav {
display: flex;
gap: 4px;
margin-bottom: 20px;
background: var(--background-color-alt, #f5f5f5);
padding: 4px;
border-radius: 8px;
}
.ta-nav a {
padding: 8px 16px;
border-radius: 6px;
text-decoration: none;
color: var(--text-color, #333);
font-size: 14px;
transition: all 0.2s;
}
.ta-nav a:hover {
background: var(--background-color, #fff);
}
.ta-nav a.active {
background: var(--primary-color, #2196f3);
color: white;
}
/* Stats */
.ta-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 16px;
margin-bottom: 20px;
}
.ta-stat {
background: var(--background-color, #fff);
border: 1px solid var(--border-color-low, #eee);
border-radius: 8px;
padding: 16px;
text-align: center;
}
.ta-stat-value {
font-size: 28px;
font-weight: 700;
color: var(--primary-color, #2196f3);
}
.ta-stat-label {
font-size: 12px;
color: var(--text-color-secondary, #666);
margin-top: 4px;
text-transform: uppercase;
}
.ta-stat.success .ta-stat-value { color: #4caf50; }
.ta-stat.warning .ta-stat-value { color: #ff9800; }
.ta-stat.danger .ta-stat-value { color: #f44336; }
/* Grid Layout */
.ta-grid-2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-bottom: 20px;
}
@media (max-width: 900px) {
.ta-grid-2 { grid-template-columns: 1fr; }
}
/* Cards */
.ta-card {
background: var(--background-color, #fff);
border: 1px solid var(--border-color-low, #eee);
border-radius: 8px;
overflow: hidden;
}
.ta-card-header {
padding: 12px 16px;
font-weight: 600;
font-size: 14px;
background: var(--background-color-alt, #f9f9f9);
border-bottom: 1px solid var(--border-color-low, #eee);
}
.ta-card-body {
padding: 16px;
}
/* Tables */
.ta-table {
width: 100%;
border-collapse: collapse;
}
.ta-table th,
.ta-table td {
padding: 10px 12px;
text-align: left;
border-bottom: 1px solid var(--border-color-low, #eee);
}
.ta-table th {
font-size: 11px;
text-transform: uppercase;
color: var(--text-color-secondary, #666);
font-weight: 600;
}
.ta-table tbody tr:hover {
background: var(--background-color-alt, #f9f9f9);
}
/* Badges */
.ta-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 500;
}
.ta-badge.critical { background: #f44336; color: white; }
.ta-badge.high { background: #ff9800; color: white; }
.ta-badge.medium { background: #ffc107; color: #333; }
.ta-badge.low { background: #4caf50; color: white; }
.ta-badge.crowdsec { background: #5c6bc0; color: white; }
.ta-badge.mitmproxy { background: #26a69a; color: white; }
.ta-badge.waf { background: #7e57c2; color: white; }
/* Buttons */
.ta-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
border: none;
border-radius: 6px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: opacity 0.2s;
}
.ta-btn:hover { opacity: 0.9; }
.ta-btn-primary { background: var(--primary-color, #2196f3); color: white; }
.ta-btn-success { background: #4caf50; color: white; }
.ta-btn-warning { background: #ff9800; color: white; }
.ta-btn-danger { background: #f44336; color: white; }
.ta-btn-sm { padding: 4px 10px; font-size: 12px; }
/* Actions Bar */
.ta-actions {
display: flex;
gap: 8px;
margin-top: 16px;
}
/* Pending Rules */
.ta-pending-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.ta-pending-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: var(--background-color-alt, #f9f9f9);
border-radius: 6px;
}
.ta-pending-info {
flex: 1;
}
.ta-pending-type {
font-weight: 600;
margin-bottom: 4px;
}
.ta-pending-date {
font-size: 12px;
color: var(--text-color-secondary, #666);
}
.ta-pending-actions {
display: flex;
gap: 6px;
}
/* Chat */
.ta-chat {
display: flex;
flex-direction: column;
height: 400px;
}
.ta-chat-messages {
flex: 1;
overflow-y: auto;
padding: 12px;
background: var(--background-color-alt, #f5f5f5);
border-radius: 6px;
margin-bottom: 12px;
}
.ta-message {
margin-bottom: 12px;
display: flex;
flex-direction: column;
}
.ta-message.user {
align-items: flex-end;
}
.ta-message-bubble {
max-width: 80%;
padding: 10px 14px;
border-radius: 12px;
font-size: 14px;
line-height: 1.4;
}
.ta-message.user .ta-message-bubble {
background: var(--primary-color, #2196f3);
color: white;
border-bottom-right-radius: 4px;
}
.ta-message.ai .ta-message-bubble {
background: var(--background-color, #fff);
border: 1px solid var(--border-color-low, #eee);
border-bottom-left-radius: 4px;
}
.ta-message-time {
font-size: 10px;
color: var(--text-color-secondary, #999);
margin-top: 4px;
}
.ta-chat-input {
display: flex;
gap: 8px;
}
.ta-chat-input input {
flex: 1;
padding: 12px;
border: 1px solid var(--border-color-medium, #ddd);
border-radius: 6px;
font-size: 14px;
}
.ta-chat-input input:focus {
outline: none;
border-color: var(--primary-color, #2196f3);
}
/* Empty State */
.ta-empty {
text-align: center;
padding: 24px;
color: var(--text-color-secondary, #666);
font-style: italic;
}
/* IP display */
.ta-ip {
font-family: monospace;
font-size: 13px;
}
/* Scenario display */
.ta-scenario {
font-size: 13px;
}
/* Time display */
.ta-time {
font-size: 12px;
color: var(--text-color-secondary, #666);
}
/* Health Grid */
.ta-health {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
}
.ta-health-item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px;
background: var(--background-color-alt, #f9f9f9);
border-radius: 6px;
}
.ta-health-icon {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-size: 14px;
}
.ta-health-icon.ok {
background: #e8f5e9;
color: #4caf50;
}
.ta-health-icon.error {
background: #ffebee;
color: #f44336;
}
.ta-health-icon.warning {
background: #fff3e0;
color: #ff9800;
}
.ta-health-label {
font-weight: 500;
font-size: 13px;
}
.ta-health-value {
font-size: 12px;
color: var(--text-color-secondary, #666);
}
/* Targets Grid */
.ta-targets {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
.ta-target {
padding: 16px;
text-align: center;
background: var(--background-color-alt, #f9f9f9);
border-radius: 8px;
cursor: pointer;
transition: all 0.2s;
border: 2px solid transparent;
}
.ta-target:hover {
border-color: var(--primary-color, #2196f3);
}
.ta-target-icon {
font-size: 24px;
margin-bottom: 8px;
}
.ta-target-name {
font-weight: 600;
font-size: 14px;
}
.ta-target-desc {
font-size: 11px;
color: var(--text-color-secondary, #666);
margin-top: 4px;
}
/* CVE Styles */
.ta-cve-link {
display: inline-block;
padding: 2px 6px;
background: #ffebee;
color: #c62828;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
font-family: monospace;
text-decoration: none;
transition: background 0.2s;
}
.ta-cve-link:hover {
background: #ef9a9a;
text-decoration: none;
}
.ta-no-cve {
color: var(--text-color-secondary, #999);
}
.ta-cve-row {
background: rgba(244, 67, 54, 0.05);
}
.ta-cve-row:hover {
background: rgba(244, 67, 54, 0.1) !important;
}

View File

@ -3,188 +3,241 @@
'require dom';
'require poll';
'require ui';
'require threat-analyst/api as api';
'require threat-analyst.api as api';
/**
* Threat Analyst Dashboard - v0.1.0
* Generative AI-powered threat filtering
*
* Following CrowdSec Dashboard KISS template pattern
*/
return view.extend({
chatHistory: [],
load: function() {
return Promise.all([
api.status(),
api.getThreats(20),
api.getPending()
]);
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = L.resource('threat-analyst/dashboard.css');
document.head.appendChild(link);
return api.getOverview().catch(function() { return {}; });
},
render: function(data) {
var status = data[0] || {};
var threats = (data[1] || {}).threats || [];
var pending = (data[2] || {}).pending || [];
var self = this;
var s = data.status || {};
var threats = data.threats || [];
var pending = data.pending || [];
// Add CSS
var style = E('style', {}, `
.ta-dashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.ta-card { background: var(--bg-alt, #f8f9fa); border-radius: 8px; padding: 16px; }
.ta-card h3 { margin: 0 0 12px 0; font-size: 14px; text-transform: uppercase; opacity: 0.7; }
.ta-status-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.ta-stat { text-align: center; padding: 12px; background: var(--bg, #fff); border-radius: 6px; }
.ta-stat-value { font-size: 24px; font-weight: bold; color: var(--primary, #2196f3); }
.ta-stat-label { font-size: 11px; opacity: 0.6; margin-top: 4px; }
.ta-stat.warning .ta-stat-value { color: #ff9800; }
.ta-stat.danger .ta-stat-value { color: #f44336; }
.ta-stat.success .ta-stat-value { color: #4caf50; }
.ta-chat { grid-column: span 2; }
.ta-chat-messages { height: 300px; overflow-y: auto; background: var(--bg, #fff); border-radius: 6px; padding: 12px; margin-bottom: 12px; }
.ta-message { margin-bottom: 12px; }
.ta-message.user { text-align: right; }
.ta-message-bubble { display: inline-block; max-width: 80%; padding: 8px 12px; border-radius: 12px; }
.ta-message.user .ta-message-bubble { background: #2196f3; color: white; }
.ta-message.ai .ta-message-bubble { background: var(--bg-alt, #e3e3e3); }
.ta-message-time { font-size: 10px; opacity: 0.5; margin-top: 4px; }
.ta-chat-input { display: flex; gap: 8px; }
.ta-chat-input input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 6px; }
.ta-chat-input button { padding: 10px 20px; background: #2196f3; color: white; border: none; border-radius: 6px; cursor: pointer; }
.ta-threats { grid-column: span 2; }
.ta-threats-table { width: 100%; border-collapse: collapse; }
.ta-threats-table th, .ta-threats-table td { padding: 8px; text-align: left; border-bottom: 1px solid #eee; }
.ta-threats-table th { font-size: 11px; text-transform: uppercase; opacity: 0.6; }
.ta-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; }
.ta-badge.critical { background: #f44336; color: white; }
.ta-badge.high { background: #ff9800; color: white; }
.ta-badge.medium { background: #ffc107; color: black; }
.ta-badge.low { background: #4caf50; color: white; }
.ta-actions { display: flex; gap: 8px; margin-top: 16px; }
.ta-btn { padding: 8px 16px; border: none; border-radius: 6px; cursor: pointer; font-size: 13px; }
.ta-btn-primary { background: #2196f3; color: white; }
.ta-btn-success { background: #4caf50; color: white; }
.ta-btn-warning { background: #ff9800; color: white; }
.ta-pending { margin-top: 20px; }
.ta-pending-item { display: flex; justify-content: space-between; align-items: center; padding: 10px; background: var(--bg, #fff); border-radius: 6px; margin-bottom: 8px; }
`);
var statusCard = E('div', { 'class': 'ta-card' }, [
E('h3', {}, 'Agent Status'),
E('div', { 'class': 'ta-status-grid' }, [
E('div', { 'class': 'ta-stat ' + (status.daemon_running ? 'success' : 'warning') }, [
E('div', { 'class': 'ta-stat-value' }, status.daemon_running ? 'ON' : 'OFF'),
E('div', { 'class': 'ta-stat-label' }, 'Daemon')
]),
E('div', { 'class': 'ta-stat ' + (status.localai_status === 'online' ? 'success' : 'danger') }, [
E('div', { 'class': 'ta-stat-value' }, status.localai_status === 'online' ? 'OK' : 'OFF'),
E('div', { 'class': 'ta-stat-label' }, 'LocalAI')
]),
E('div', { 'class': 'ta-stat ' + (status.recent_threats > 10 ? 'danger' : status.recent_threats > 0 ? 'warning' : 'success') }, [
E('div', { 'class': 'ta-stat-value' }, status.recent_threats || 0),
E('div', { 'class': 'ta-stat-label' }, 'Threats (1h)')
var view = E('div', { 'class': 'ta-view' }, [
// Header
E('div', { 'class': 'ta-header' }, [
E('div', { 'class': 'ta-title' }, 'Threat Analyst'),
E('div', { 'class': 'ta-status' }, [
E('span', { 'class': 'ta-dot ' + (s.daemon_running ? 'online' : 'offline') }),
s.daemon_running ? 'Running' : 'Stopped'
])
]),
// Stats
E('div', { 'class': 'ta-stats', 'id': 'ta-stats' }, this.renderStats(s, pending)),
// Two column layout
E('div', { 'class': 'ta-grid-2' }, [
// Health card
E('div', { 'class': 'ta-card' }, [
E('div', { 'class': 'ta-card-header' }, 'System Health'),
E('div', { 'class': 'ta-card-body' }, this.renderHealth(s))
]),
// Pending Rules card
E('div', { 'class': 'ta-card' }, [
E('div', { 'class': 'ta-card-header' }, 'Pending Rules (' + pending.length + ')'),
E('div', { 'class': 'ta-card-body', 'id': 'ta-pending' }, this.renderPending(pending))
])
]),
// Generate Rules card
E('div', { 'class': 'ta-card' }, [
E('div', { 'class': 'ta-card-header' }, 'Generate Filter Rules'),
E('div', { 'class': 'ta-card-body' }, this.renderTargets())
]),
// Threats card
E('div', { 'class': 'ta-card' }, [
E('div', { 'class': 'ta-card-header' }, 'Recent Threats from CrowdSec'),
E('div', { 'class': 'ta-card-body', 'id': 'ta-threats' }, this.renderThreats(threats))
]),
// AI Chat card
E('div', { 'class': 'ta-card' }, [
E('div', { 'class': 'ta-card-header' }, 'AI Security Assistant'),
E('div', { 'class': 'ta-card-body' }, this.renderChat())
])
]);
poll.add(L.bind(this.pollData, this), 30);
return view;
},
renderStats: function(s, pending) {
var stats = [
{ label: 'Daemon', value: s.daemon_running ? 'ON' : 'OFF', type: s.daemon_running ? 'success' : 'danger' },
{ label: 'LocalAI', value: s.localai_status === 'online' ? 'OK' : 'OFF', type: s.localai_status === 'online' ? 'success' : 'danger' },
{ label: 'Threats (1h)', value: s.recent_threats || 0, type: (s.recent_threats || 0) > 10 ? 'danger' : (s.recent_threats || 0) > 0 ? 'warning' : 'success' },
{ label: 'Pending', value: pending.length || 0, type: (pending.length || 0) > 0 ? 'warning' : '' }
];
return stats.map(function(st) {
return E('div', { 'class': 'ta-stat ' + st.type }, [
E('div', { 'class': 'ta-stat-value' }, String(st.value)),
E('div', { 'class': 'ta-stat-label' }, st.label)
]);
});
},
renderHealth: function(s) {
var cveCount = s.cve_alerts || 0;
var checks = [
{ label: 'Daemon', ok: s.daemon_running },
{ label: 'LocalAI', ok: s.localai_status === 'online' },
{ label: 'CrowdSec', ok: s.recent_threats !== undefined },
{ label: 'CVE Alerts', ok: cveCount === 0, value: cveCount > 0 ? cveCount + ' Active' : 'None', warn: cveCount > 0 },
{ label: 'Auto-Apply', ok: s.enabled, value: s.enabled ? 'Enabled' : 'Manual' }
];
return E('div', { 'class': 'ta-health' }, checks.map(function(c) {
var valueText = c.value ? c.value : (c.ok ? 'OK' : 'Unavailable');
var iconClass = c.warn ? 'warning' : (c.ok ? 'ok' : 'error');
var iconChar = c.warn ? '\u26A0' : (c.ok ? '\u2713' : '\u2717');
return E('div', { 'class': 'ta-health-item' }, [
E('div', { 'class': 'ta-health-icon ' + iconClass }, iconChar),
E('div', {}, [
E('div', { 'class': 'ta-health-label' }, c.label),
E('div', { 'class': 'ta-health-value' }, valueText)
])
]);
}));
},
renderPending: function(pending) {
var self = this;
if (!pending.length) {
return E('div', { 'class': 'ta-empty' }, 'No pending rules for approval');
}
return E('div', { 'class': 'ta-pending-list' }, pending.map(function(rule) {
return E('div', { 'class': 'ta-pending-item' }, [
E('div', { 'class': 'ta-pending-info' }, [
E('div', { 'class': 'ta-pending-type' }, [
E('span', { 'class': 'ta-badge ' + rule.type }, rule.type)
]),
E('div', { 'class': 'ta-pending-date' }, (rule.created || '').substring(0, 10))
]),
E('div', { 'class': 'ta-pending-actions' }, [
E('button', {
'class': 'ta-btn ta-btn-success ta-btn-sm',
'click': function() { self.approveRule(rule.id); }
}, 'Approve'),
E('button', {
'class': 'ta-btn ta-btn-danger ta-btn-sm',
'click': function() { self.rejectRule(rule.id); }
}, 'Reject')
])
]);
}));
},
renderTargets: function() {
var self = this;
var targets = [
{ id: 'crowdsec', name: 'CrowdSec', desc: 'Generate autoban scenarios', icon: '\uD83D\uDEE1' },
{ id: 'mitmproxy', name: 'mitmproxy', desc: 'Generate Python filters', icon: '\uD83D\uDD0D' },
{ id: 'waf', name: 'WAF', desc: 'Generate ModSecurity rules', icon: '\uD83D\uDEA7' }
];
return E('div', {}, [
E('div', { 'class': 'ta-targets' }, targets.map(function(t) {
return E('div', {
'class': 'ta-target',
'click': function() { self.generateRules(t.id); }
}, [
E('div', { 'class': 'ta-target-icon' }, t.icon),
E('div', { 'class': 'ta-target-name' }, t.name),
E('div', { 'class': 'ta-target-desc' }, t.desc)
]);
})),
E('div', { 'class': 'ta-actions' }, [
E('button', {
'class': 'ta-btn ta-btn-primary',
'click': function() { self.runCycle(); }
}, 'Run Analysis'),
'click': function() { self.runAnalysis(); }
}, 'Run Analysis Cycle'),
E('button', {
'class': 'ta-btn ta-btn-success',
'click': function() { self.generateRules('all'); }
}, 'Generate Rules')
}, 'Generate All Rules')
])
]);
},
var pendingCard = E('div', { 'class': 'ta-card' }, [
E('h3', {}, 'Pending Rules (' + pending.length + ')'),
E('div', { 'class': 'ta-pending', 'id': 'pending-rules' },
pending.length === 0 ? E('em', {}, 'No pending rules') :
pending.map(function(rule) {
return E('div', { 'class': 'ta-pending-item' }, [
E('span', {}, rule.type + ' - ' + (rule.created || '').substring(0, 10)),
E('div', {}, [
E('button', {
'class': 'ta-btn ta-btn-success',
'style': 'padding: 4px 8px; margin-right: 4px;',
'click': function() { self.approveRule(rule.id); }
}, 'Approve'),
E('button', {
'class': 'ta-btn ta-btn-warning',
'style': 'padding: 4px 8px;',
'click': function() { self.rejectRule(rule.id); }
}, 'Reject')
])
]);
})
)
renderThreats: function(threats) {
if (!threats.length) {
return E('div', { 'class': 'ta-empty' }, 'No recent threats detected');
}
return E('table', { 'class': 'ta-table' }, [
E('thead', {}, E('tr', {}, [
E('th', {}, 'Time'),
E('th', {}, 'Source IP'),
E('th', {}, 'Scenario'),
E('th', {}, 'CVE'),
E('th', {}, 'Severity')
])),
E('tbody', {}, threats.slice(0, 10).map(function(t) {
var src = t.source || {};
var severity = api.getSeverityClass(t.scenario);
var cveId = api.extractCVE(t.scenario);
var cveCell = cveId ?
E('a', {
'class': 'ta-cve-link',
'href': 'https://nvd.nist.gov/vuln/detail/' + cveId,
'target': '_blank',
'rel': 'noopener'
}, cveId) :
E('span', { 'class': 'ta-no-cve' }, '-');
return E('tr', { 'class': cveId ? 'ta-cve-row' : '' }, [
E('td', { 'class': 'ta-time' }, api.formatRelativeTime(t.created_at)),
E('td', {}, E('span', { 'class': 'ta-ip' }, src.ip || '-')),
E('td', {}, E('span', { 'class': 'ta-scenario' }, api.parseScenario(t.scenario))),
E('td', {}, cveCell),
E('td', {}, E('span', { 'class': 'ta-badge ' + severity }, severity))
]);
}))
]);
},
var chatCard = E('div', { 'class': 'ta-card ta-chat' }, [
E('h3', {}, 'AI Security Chat'),
E('div', { 'class': 'ta-chat-messages', 'id': 'chat-messages' },
renderChat: function() {
var self = this;
return E('div', { 'class': 'ta-chat' }, [
E('div', { 'class': 'ta-chat-messages', 'id': 'ta-chat-messages' }, [
E('div', { 'class': 'ta-message ai' }, [
E('div', { 'class': 'ta-message-bubble' }, 'Hello! I\'m your SecuBox Threat Analyst. Ask me about security threats, or request filter rules for mitmproxy, CrowdSec, or WAF.')
E('div', { 'class': 'ta-message-bubble' },
'Hello! I\'m your Threat Analyst AI. Ask me about security threats, ' +
'or request rules for CrowdSec, mitmproxy, or WAF.'),
E('div', { 'class': 'ta-message-time' }, 'System')
])
),
]),
E('div', { 'class': 'ta-chat-input' }, [
E('input', {
'type': 'text',
'id': 'chat-input',
'placeholder': 'Ask about threats or request rules...',
'id': 'ta-chat-input',
'placeholder': 'Ask about threats or request filter rules...',
'keypress': function(e) { if (e.key === 'Enter') self.sendChat(); }
}),
E('button', { 'click': function() { self.sendChat(); } }, 'Send')
])
]);
var threatsCard = E('div', { 'class': 'ta-card ta-threats' }, [
E('h3', {}, 'Recent Threats'),
E('table', { 'class': 'ta-threats-table' }, [
E('thead', {}, [
E('tr', {}, [
E('th', {}, 'Time'),
E('th', {}, 'Source'),
E('th', {}, 'Scenario'),
E('th', {}, 'IP'),
E('th', {}, 'Severity')
])
]),
E('tbody', { 'id': 'threats-body' },
threats.slice(0, 10).map(function(t) {
var severity = 'medium';
if (t.scenario && (t.scenario.includes('malware') || t.scenario.includes('exploit'))) severity = 'critical';
else if (t.scenario && t.scenario.includes('scan')) severity = 'high';
else if (t.scenario && t.scenario.includes('http')) severity = 'low';
return E('tr', {}, [
E('td', {}, (t.created_at || '').substring(11, 19)),
E('td', {}, (t.source || {}).ip || '-'),
E('td', {}, t.scenario || '-'),
E('td', {}, (t.source || {}).ip || '-'),
E('td', {}, E('span', { 'class': 'ta-badge ' + severity }, severity))
]);
})
)
])
]);
return E('div', {}, [
style,
E('h2', {}, 'Threat Analyst'),
E('div', { 'class': 'ta-dashboard' }, [
statusCard,
pendingCard,
chatCard,
threatsCard
E('button', {
'class': 'ta-btn ta-btn-primary',
'click': function() { self.sendChat(); }
}, 'Send')
])
]);
},
sendChat: function() {
var input = document.getElementById('chat-input');
var messages = document.getElementById('chat-messages');
var input = document.getElementById('ta-chat-input');
var messages = document.getElementById('ta-chat-messages');
var message = input.value.trim();
var self = this;
if (!message) return;
@ -197,26 +250,24 @@ return view.extend({
input.value = '';
messages.scrollTop = messages.scrollHeight;
// Add loading indicator
var loading = E('div', { 'class': 'ta-message ai', 'id': 'chat-loading' }, [
// Add loading
var loading = E('div', { 'class': 'ta-message ai', 'id': 'ta-chat-loading' }, [
E('div', { 'class': 'ta-message-bubble' }, 'Analyzing...')
]);
messages.appendChild(loading);
// Call API
api.chat(message).then(function(result) {
var loadingEl = document.getElementById('chat-loading');
var loadingEl = document.getElementById('ta-chat-loading');
if (loadingEl) loadingEl.remove();
var response = result.response || result.error || 'No response';
messages.appendChild(E('div', { 'class': 'ta-message ai' }, [
E('div', { 'class': 'ta-message-bubble' }, response),
E('div', { 'class': 'ta-message-time' }, new Date().toLocaleTimeString())
]));
messages.scrollTop = messages.scrollHeight;
}).catch(function(err) {
var loadingEl = document.getElementById('chat-loading');
var loadingEl = document.getElementById('ta-chat-loading');
if (loadingEl) loadingEl.remove();
messages.appendChild(E('div', { 'class': 'ta-message ai' }, [
@ -225,7 +276,7 @@ return view.extend({
});
},
runCycle: function() {
runAnalysis: function() {
ui.showModal('Running Analysis', [
E('p', { 'class': 'spinning' }, 'Running threat analysis cycle...')
]);
@ -233,31 +284,39 @@ return view.extend({
api.runCycle().then(function() {
ui.hideModal();
ui.addNotification(null, E('p', {}, 'Analysis cycle started'), 'success');
}).catch(function() {
ui.hideModal();
ui.addNotification(null, E('p', {}, 'Failed to start analysis'), 'error');
});
},
generateRules: function(target) {
var targetName = target === 'all' ? 'All' : target;
ui.showModal('Generating Rules', [
E('p', { 'class': 'spinning' }, 'Generating ' + target + ' rules with AI...')
E('p', { 'class': 'spinning' }, 'Generating ' + targetName + ' rules with AI...')
]);
api.generateRules(target).then(function(result) {
ui.hideModal();
if (result.rules) {
ui.addNotification(null, E('p', {}, 'Rules generated. Check pending queue.'), 'success');
ui.addNotification(null, E('p', {}, 'Rules generated. Check pending queue for approval.'), 'success');
window.location.reload();
} else {
ui.addNotification(null, E('p', {}, 'Failed to generate rules'), 'error');
ui.addNotification(null, E('p', {}, 'No rules generated'), 'warning');
}
}).catch(function() {
ui.hideModal();
ui.addNotification(null, E('p', {}, 'Failed to generate rules'), 'error');
});
},
approveRule: function(id) {
var self = this;
api.approveRule(id).then(function(result) {
if (result.success) {
ui.addNotification(null, E('p', {}, 'Rule approved and applied'), 'success');
window.location.reload();
} else {
ui.addNotification(null, E('p', {}, 'Failed to approve rule'), 'error');
}
});
},
@ -269,6 +328,24 @@ return view.extend({
});
},
pollData: function() {
var self = this;
return api.getOverview().then(function(data) {
var s = data.status || {};
var pending = data.pending || [];
var threats = data.threats || [];
var el = document.getElementById('ta-stats');
if (el) dom.content(el, self.renderStats(s, pending));
el = document.getElementById('ta-pending');
if (el) dom.content(el, self.renderPending(pending));
el = document.getElementById('ta-threats');
if (el) dom.content(el, self.renderThreats(threats));
});
},
handleSaveApply: null,
handleSave: null,
handleReset: null

View File

@ -61,10 +61,16 @@ EOF
[ -f "$STATE_DIR/pending_rules.json" ] && \
pending_count=$(jsonfilter -i "$STATE_DIR/pending_rules.json" -e '@[*]' 2>/dev/null | wc -l)
# Count recent threats
# Count recent threats and CVE alerts
threat_count=0
command -v cscli >/dev/null 2>&1 && \
threat_count=$(cscli alerts list -o json --since 1h 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
cve_count=0
if command -v cscli >/dev/null 2>&1; then
alerts_json=$(cscli alerts list -o json --since 1h 2>/dev/null)
threat_count=$(echo "$alerts_json" | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
# Count CVE-related alerts
cve_count=$(echo "$alerts_json" | grep -ic 'cve-' 2>/dev/null)
[ -z "$cve_count" ] && cve_count=0
fi
cat <<EOF
{
@ -75,7 +81,8 @@ EOF
"localai_status": "$localai_status",
"localai_url": "$localai_url",
"pending_rules": $pending_count,
"recent_threats": $threat_count
"recent_threats": $threat_count,
"cve_alerts": $cve_count
}
EOF
;;

View File

@ -8,7 +8,7 @@ Architecture: all
Installed-Size: 71680
Description: Comprehensive authentication and session management with captive portal, OAuth2/OIDC integration, voucher system, and time-based access control
Filename: luci-app-auth-guardian_0.4.0-r3_all.ipk
Size: 11735
Size: 11736
Package: luci-app-bandwidth-manager
Version: 0.5.0-r2
@ -32,7 +32,7 @@ Architecture: all
Installed-Size: 122880
Description: Dashboard for managing local CDN caching proxy on OpenWrt
Filename: luci-app-cdn-cache_0.5.0-r3_all.ipk
Size: 23185
Size: 23182
Package: luci-app-client-guardian
Version: 0.4.0-r7
@ -44,7 +44,7 @@ Architecture: all
Installed-Size: 286720
Description: Network Access Control with client monitoring, zone management, captive portal, parental controls, and SMS/email alerts
Filename: luci-app-client-guardian_0.4.0-r7_all.ipk
Size: 54535
Size: 54536
Package: luci-app-crowdsec-dashboard
Version: 0.7.0-r32
@ -56,7 +56,7 @@ Architecture: all
Installed-Size: 184320
Description: Real-time security monitoring dashboard for CrowdSec on OpenWrt
Filename: luci-app-crowdsec-dashboard_0.7.0-r32_all.ipk
Size: 33740
Size: 33739
Package: luci-app-cyberfeed
Version: 0.1.1-r1
@ -68,7 +68,7 @@ Architecture: all
Installed-Size: 71680
Description: Cyberpunk-themed RSS feed aggregator dashboard with social media support
Filename: luci-app-cyberfeed_0.1.1-r1_all.ipk
Size: 12839
Size: 12837
Package: luci-app-device-intel
Version: 1.0.0-r1
@ -80,7 +80,7 @@ Architecture: all
Installed-Size: 61440
Description: LuCI SecuBox Device Intelligence
Filename: luci-app-device-intel_1.0.0-r1_all.ipk
Size: 10862
Size: 10859
Package: luci-app-dnsguard
Version: 1.1.0-r1
@ -111,7 +111,7 @@ Architecture: all
Installed-Size: 40960
Description: LuCI DNS Provider Manager
Filename: luci-app-dns-provider_1.0.0-r1_all.ipk
Size: 7127
Size: 7130
Package: luci-app-exposure
Version: 1.0.0-r3
@ -123,7 +123,7 @@ Architecture: all
Installed-Size: 61440
Description: LuCI SecuBox Service Exposure Manager
Filename: luci-app-exposure_1.0.0-r3_all.ipk
Size: 9838
Size: 9841
Package: luci-app-gitea
Version: 1.0.0-r2
@ -135,7 +135,7 @@ Architecture: all
Installed-Size: 81920
Description: Modern dashboard for Gitea Platform management on OpenWrt
Filename: luci-app-gitea_1.0.0-r2_all.ipk
Size: 15299
Size: 15300
Package: luci-app-glances
Version: 1.0.0-r2
@ -147,7 +147,7 @@ Architecture: all
Installed-Size: 40960
Description: Modern dashboard for Glances system monitoring with SecuBox theme
Filename: luci-app-glances_1.0.0-r2_all.ipk
Size: 6968
Size: 6969
Package: luci-app-haproxy
Version: 1.0.0-r8
@ -171,7 +171,7 @@ Architecture: all
Installed-Size: 184320
Description: Modern dashboard for Hexo static site generator on OpenWrt
Filename: luci-app-hexojs_1.0.0-r3_all.ipk
Size: 30311
Size: 30307
Package: luci-app-jellyfin
Version: 1.0.0-r1
@ -183,7 +183,7 @@ Architecture: all
Installed-Size: 30720
Description: LuCI Jellyfin Media Server Configuration
Filename: luci-app-jellyfin_1.0.0-r1_all.ipk
Size: 6060
Size: 6061
Package: luci-app-jitsi
Version: 1.0.0-r1
@ -195,7 +195,7 @@ Architecture: all
Installed-Size: 30720
Description: LuCI Jitsi Meet Configuration
Filename: luci-app-jitsi_1.0.0-r1_all.ipk
Size: 5139
Size: 5134
Package: luci-app-ksm-manager
Version: 0.4.0-r2
@ -207,7 +207,7 @@ Architecture: all
Installed-Size: 112640
Description: Centralized cryptographic key management with hardware security module (HSM) support for Nitrokey and YubiKey devices. Provides secure key storage, certificate management, SSH key handling, and secret storage with audit logging.
Filename: luci-app-ksm-manager_0.4.0-r2_all.ipk
Size: 18724
Size: 18719
Package: luci-app-localai
Version: 0.1.0-r15
@ -219,7 +219,7 @@ Architecture: all
Installed-Size: 71680
Description: Modern dashboard for LocalAI LLM management on OpenWrt
Filename: luci-app-localai_0.1.0-r15_all.ipk
Size: 13181
Size: 13182
Package: luci-app-lyrion
Version: 1.0.0-r1
@ -231,7 +231,7 @@ Architecture: all
Installed-Size: 40960
Description: LuCI support for Lyrion Music Server
Filename: luci-app-lyrion_1.0.0-r1_all.ipk
Size: 6727
Size: 6725
Package: luci-app-mac-guardian
Version: 0.5.0-r1
@ -243,7 +243,7 @@ Architecture: all
Installed-Size: 40960
Description: LuCI MAC Guardian - WiFi MAC Security Monitor
Filename: luci-app-mac-guardian_0.5.0-r1_all.ipk
Size: 6512
Size: 6509
Package: luci-app-magicmirror2
Version: 0.4.0-r6
@ -279,7 +279,7 @@ Architecture: all
Installed-Size: 30720
Description: LuCI SecuBox Master-Link Mesh Management
Filename: luci-app-master-link_1.0.0-r1_all.ipk
Size: 6248
Size: 6245
Package: luci-app-media-flow
Version: 0.6.4-r1
@ -291,7 +291,7 @@ Architecture: all
Installed-Size: 133120
Description: Real-time detection and monitoring of streaming services (Netflix, YouTube, Spotify, etc.) with quality estimation, history tracking, and alerts. Supports nDPId local DPI and netifyd.
Filename: luci-app-media-flow_0.6.4-r1_all.ipk
Size: 25416
Size: 25418
Package: luci-app-metablogizer
Version: 1.0.0-r5
@ -327,7 +327,7 @@ Architecture: all
Installed-Size: 61440
Description: Modern dashboard for mitmproxy HTTPS traffic inspection with SecuBox theme
Filename: luci-app-mitmproxy_0.5.0-r2_all.ipk
Size: 11152
Size: 11149
Package: luci-app-mmpm
Version: 0.2.0-r3
@ -339,7 +339,7 @@ Architecture: all
Installed-Size: 51200
Description: Web interface for MMPM - MagicMirror Package Manager
Filename: luci-app-mmpm_0.2.0-r3_all.ipk
Size: 7901
Size: 7899
Package: luci-app-mqtt-bridge
Version: 0.4.0-r4
@ -351,7 +351,7 @@ Architecture: all
Installed-Size: 122880
Description: USB-to-MQTT IoT hub with SecuBox theme
Filename: luci-app-mqtt-bridge_0.4.0-r4_all.ipk
Size: 22779
Size: 22780
Package: luci-app-ndpid
Version: 1.1.2-r2
@ -363,7 +363,7 @@ Architecture: all
Installed-Size: 122880
Description: Modern dashboard for nDPId deep packet inspection on OpenWrt
Filename: luci-app-ndpid_1.1.2-r2_all.ipk
Size: 22653
Size: 22654
Package: luci-app-netdata-dashboard
Version: 0.5.0-r2
@ -375,7 +375,7 @@ Architecture: all
Installed-Size: 112640
Description: Real-time system monitoring dashboard with Netdata integration for OpenWrt
Filename: luci-app-netdata-dashboard_0.5.0-r2_all.ipk
Size: 20488
Size: 20484
Package: luci-app-network-modes
Version: 0.5.0-r3
@ -387,7 +387,7 @@ Architecture: all
Installed-Size: 286720
Description: Configure OpenWrt for different network modes: Sniffer, Access Point, Relay, Router
Filename: luci-app-network-modes_0.5.0-r3_all.ipk
Size: 54148
Size: 54149
Package: luci-app-network-tweaks
Version: 1.0.0-r7
@ -399,7 +399,7 @@ Architecture: all
Installed-Size: 81920
Description: Unified network services dashboard with DNS/hosts sync, CDN cache control, and WPAD auto-proxy configuration
Filename: luci-app-network-tweaks_1.0.0-r7_all.ipk
Size: 14960
Size: 14957
Package: luci-app-nextcloud
Version: 1.0.0-r1
@ -411,7 +411,7 @@ Architecture: all
Installed-Size: 30720
Description: LuCI support for Nextcloud
Filename: luci-app-nextcloud_1.0.0-r1_all.ipk
Size: 6486
Size: 6489
Package: luci-app-ollama
Version: 0.1.0-r1
@ -423,7 +423,7 @@ Architecture: all
Installed-Size: 61440
Description: Modern dashboard for Ollama LLM management on OpenWrt
Filename: luci-app-ollama_0.1.0-r1_all.ipk
Size: 12355
Size: 12352
Package: luci-app-picobrew
Version: 1.0.0-r1
@ -435,7 +435,7 @@ Architecture: all
Installed-Size: 51200
Description: Modern dashboard for PicoBrew Server management on OpenWrt
Filename: luci-app-picobrew_1.0.0-r1_all.ipk
Size: 9458
Size: 9459
Package: luci-app-secubox
Version: 0.7.1-r4
@ -458,7 +458,7 @@ Architecture: all
Installed-Size: 337920
Description: Unified admin control center for SecuBox appstore plugins with system monitoring
Filename: luci-app-secubox-admin_1.0.0-r19_all.ipk
Size: 57247
Size: 57245
Package: luci-app-secubox-crowdsec
Version: 1.0.0-r3
@ -470,7 +470,7 @@ Architecture: all
Installed-Size: 81920
Description: LuCI SecuBox CrowdSec Dashboard
Filename: luci-app-secubox-crowdsec_1.0.0-r3_all.ipk
Size: 13917
Size: 13923
Package: luci-app-secubox-netdiag
Version: 1.0.0-r1
@ -482,7 +482,7 @@ Architecture: all
Installed-Size: 81920
Description: Real-time DSA switch port statistics, error monitoring, and network health diagnostics
Filename: luci-app-secubox-netdiag_1.0.0-r1_all.ipk
Size: 15308
Size: 15306
Package: luci-app-secubox-netifyd
Version: 1.2.1-r1
@ -506,7 +506,7 @@ Architecture: all
Installed-Size: 235520
Description: LuCI SecuBox P2P Hub
Filename: luci-app-secubox-p2p_0.1.0-r1_all.ipk
Size: 44085
Size: 44086
Package: luci-app-secubox-portal
Version: 0.7.0-r2
@ -518,7 +518,7 @@ Architecture: all
Installed-Size: 122880
Description: Unified entry point for all SecuBox applications with tabbed navigation
Filename: luci-app-secubox-portal_0.7.0-r2_all.ipk
Size: 24646
Size: 24644
Package: luci-app-secubox-security-threats
Version: 1.0.0-r4
@ -542,7 +542,7 @@ Architecture: all
Installed-Size: 194560
Description: Unified service aggregation with HAProxy vhosts, Tor hidden services, and QR-coded landing page
Filename: luci-app-service-registry_1.0.0-r1_all.ipk
Size: 39826
Size: 39828
Package: luci-app-simplex
Version: 1.0.0-r1
@ -554,7 +554,7 @@ Architecture: all
Installed-Size: 40960
Description: LuCI SimpleX Chat Server Configuration
Filename: luci-app-simplex_1.0.0-r1_all.ipk
Size: 6999
Size: 7000
Package: luci-app-streamlit
Version: 1.0.0-r11
@ -566,7 +566,7 @@ Architecture: all
Installed-Size: 81920
Description: Multi-instance Streamlit management with Gitea integration
Filename: luci-app-streamlit_1.0.0-r11_all.ipk
Size: 14748
Size: 14749
Package: luci-app-system-hub
Version: 0.5.1-r4
@ -578,7 +578,7 @@ Architecture: all
Installed-Size: 317440
Description: Central system control with monitoring, services, logs, and backup
Filename: luci-app-system-hub_0.5.1-r4_all.ipk
Size: 61106
Size: 61105
Package: luci-app-threat-analyst
Version: 1.0.0-r1
@ -587,10 +587,10 @@ License: MIT
Section: luci
Maintainer: OpenWrt LuCI community
Architecture: all
Installed-Size: 40960
Installed-Size: 51200
Description: LuCI Threat Analyst Dashboard
Filename: luci-app-threat-analyst_1.0.0-r1_all.ipk
Size: 6951
Size: 9753
Package: luci-app-tor-shield
Version: 1.0.0-r10
@ -602,7 +602,7 @@ Architecture: all
Installed-Size: 122880
Description: Modern dashboard for Tor anonymization on OpenWrt
Filename: luci-app-tor-shield_1.0.0-r10_all.ipk
Size: 22361
Size: 22362
Package: luci-app-traffic-shaper
Version: 0.4.0-r2
@ -614,7 +614,7 @@ Architecture: all
Installed-Size: 81920
Description: Advanced traffic shaping with TC/CAKE for precise bandwidth control
Filename: luci-app-traffic-shaper_0.4.0-r2_all.ipk
Size: 14537
Size: 14535
Package: luci-app-vhost-manager
Version: 0.5.0-r5
@ -626,7 +626,7 @@ Architecture: all
Installed-Size: 153600
Description: Nginx reverse proxy manager with Let's Encrypt SSL certificates, authentication, and WebSocket support
Filename: luci-app-vhost-manager_0.5.0-r5_all.ipk
Size: 26181
Size: 26186
Package: luci-app-wireguard-dashboard
Version: 0.7.0-r5
@ -638,7 +638,7 @@ Architecture: all
Installed-Size: 204800
Description: Modern dashboard for WireGuard VPN monitoring on OpenWrt
Filename: luci-app-wireguard-dashboard_0.7.0-r5_all.ipk
Size: 39609
Size: 39607
Package: luci-app-zigbee2mqtt
Version: 1.0.0-r2
@ -650,7 +650,7 @@ Architecture: all
Installed-Size: 40960
Description: Graphical interface for managing the Zigbee2MQTT docker application.
Filename: luci-app-zigbee2mqtt_1.0.0-r2_all.ipk
Size: 6815
Size: 6813
Package: luci-theme-secubox
Version: 0.4.7-r1
@ -662,7 +662,7 @@ Architecture: all
Installed-Size: 450560
Description: Global CyberMood design system (CSS/JS/i18n) shared by all SecuBox dashboards.
Filename: luci-theme-secubox_0.4.7-r1_all.ipk
Size: 110241
Size: 110239
Package: secubox-app
Version: 1.0.0-r2
@ -673,7 +673,7 @@ Installed-Size: 92160
Description: Command line helper for SecuBox App Store manifests. Installs /usr/sbin/secubox-app
and ships the default manifests under /usr/share/secubox/plugins/.
Filename: secubox-app_1.0.0-r2_all.ipk
Size: 11182
Size: 11184
Package: secubox-app-adguardhome
Version: 1.0.0-r2
@ -687,7 +687,7 @@ Description: Installer, configuration, and service manager for running AdGuard
inside Docker on SecuBox-powered OpenWrt systems. Network-wide ad blocker
with DNS-over-HTTPS/TLS support and detailed analytics.
Filename: secubox-app-adguardhome_1.0.0-r2_all.ipk
Size: 2882
Size: 2880
Package: secubox-app-auth-logger
Version: 1.2.2-r1
@ -705,7 +705,7 @@ Description: Logs authentication failures from LuCI/rpcd and Dropbear SSH
- JavaScript hook to intercept login failures
- CrowdSec parser and bruteforce scenario
Filename: secubox-app-auth-logger_1.2.2-r1_all.ipk
Size: 9375
Size: 9379
Package: secubox-app-crowdsec-custom
Version: 1.1.0-r1
@ -728,7 +728,7 @@ Description: Custom CrowdSec configurations for SecuBox web interface protectio
- Webapp generic auth bruteforce protection
- Whitelist for trusted networks
Filename: secubox-app-crowdsec-custom_1.1.0-r1_all.ipk
Size: 5758
Size: 5761
Package: secubox-app-cs-firewall-bouncer
Version: 0.0.31-r4
@ -755,7 +755,7 @@ Description: SecuBox CrowdSec Firewall Bouncer for OpenWrt.
- Automatic restart on firewall reload
- procd service management
Filename: secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk
Size: 5049326
Size: 5049328
Package: secubox-app-cyberfeed
Version: 0.2.1-r1
@ -769,7 +769,7 @@ Description: Cyberpunk-themed RSS feed aggregator for OpenWrt/SecuBox.
Features emoji injection, neon styling, and RSS-Bridge support
for social media feeds (Facebook, Twitter, Mastodon).
Filename: secubox-app-cyberfeed_0.2.1-r1_all.ipk
Size: 12453
Size: 12454
Package: secubox-app-device-intel
Version: 1.0.0-r1
@ -783,7 +783,7 @@ Description: Unified device inventory aggregating mac-guardian, client-guardian
P2P mesh, and exposure scanner data. Includes heuristic classification
and pluggable emulator modules for MQTT, Zigbee, and USB devices.
Filename: secubox-app-device-intel_1.0.0-r1_all.ipk
Size: 13005
Size: 13004
Package: secubox-app-dns-provider
Version: 1.0.0-r1
@ -797,7 +797,7 @@ Description: Programmatic DNS record management via provider APIs (OVH, Gandi
Cloudflare). Provides the dnsctl CLI for record CRUD, zone sync
DNS propagation verification, and ACME DNS-01 challenge support.
Filename: secubox-app-dns-provider_1.0.0-r1_all.ipk
Size: 5590
Size: 6702
Package: secubox-app-domoticz
Version: 1.0.0-r2
@ -810,7 +810,7 @@ Installed-Size: 10240
Description: Installer, configuration, and service manager for running Domoticz
inside Docker on SecuBox-powered OpenWrt systems.
Filename: secubox-app-domoticz_1.0.0-r2_all.ipk
Size: 2546
Size: 2548
Package: secubox-app-exposure
Version: 1.0.0-r1
@ -825,7 +825,7 @@ Description: Unified service exposure manager for SecuBox.
- Dynamic Tor hidden service management
- HAProxy SSL reverse proxy configuration
Filename: secubox-app-exposure_1.0.0-r1_all.ipk
Size: 6936
Size: 6934
Package: secubox-app-gitea
Version: 1.0.0-r5
@ -848,7 +848,7 @@ Description: Gitea Git Platform - Self-hosted lightweight Git service
Runs in LXC container with Alpine Linux.
Configure in /etc/config/gitea.
Filename: secubox-app-gitea_1.0.0-r5_all.ipk
Size: 9402
Size: 9407
Package: secubox-app-glances
Version: 1.0.0-r1
@ -871,7 +871,7 @@ Description: Glances - Cross-platform system monitoring tool for SecuBox.
Runs in LXC container for isolation and security.
Configure in /etc/config/glances.
Filename: secubox-app-glances_1.0.0-r1_all.ipk
Size: 5536
Size: 5538
Package: secubox-app-haproxy
Version: 1.0.0-r23
@ -891,7 +891,7 @@ Description: HAProxy load balancer and reverse proxy running in an LXC containe
- Stats dashboard
- Rate limiting and ACLs
Filename: secubox-app-haproxy_1.0.0-r23_all.ipk
Size: 15683
Size: 15687
Package: secubox-app-hexojs
Version: 1.0.0-r8
@ -915,7 +915,7 @@ Description: Hexo CMS - Self-hosted static blog generator for OpenWrt
Runs in LXC container with Alpine Linux.
Configure in /etc/config/hexojs.
Filename: secubox-app-hexojs_1.0.0-r8_all.ipk
Size: 94937
Size: 94940
Package: secubox-app-jellyfin
Version: 1.0.0-r1
@ -929,7 +929,7 @@ Description: Installer, configuration, and service manager for running Jellyfin
inside Docker on SecuBox-powered OpenWrt systems. Free media server
for streaming movies, TV shows, music, and photos.
Filename: secubox-app-jellyfin_1.0.0-r1_all.ipk
Size: 6182
Size: 6185
Package: secubox-app-jitsi
Version: 1.0.0-r1
@ -954,7 +954,7 @@ Description: Jitsi Meet - Secure, fully featured video conferencing for SecuBox
Integrates with HAProxy for SSL termination.
Configure in /etc/config/jitsi.
Filename: secubox-app-jitsi_1.0.0-r1_all.ipk
Size: 8913
Size: 8914
Package: secubox-app-localai
Version: 2.25.0-r1
@ -976,7 +976,7 @@ Description: LocalAI native binary package for OpenWrt.
API: http://<router-ip>:8081/v1
Filename: secubox-app-localai_2.25.0-r1_all.ipk
Size: 5722
Size: 5720
Package: secubox-app-localai-wb
Version: 2.25.0-r1
@ -1000,7 +1000,7 @@ Description: LocalAI native binary package for OpenWrt.
API: http://<router-ip>:8080/v1
Filename: secubox-app-localai-wb_2.25.0-r1_all.ipk
Size: 7953
Size: 7951
Package: secubox-app-lyrion
Version: 2.0.2-r1
@ -1020,7 +1020,7 @@ Description: Lyrion Media Server (formerly Logitech Media Server / Squeezebox S
Auto-detects available runtime, preferring LXC for lower resource usage.
Configure runtime in /etc/config/lyrion.
Filename: secubox-app-lyrion_2.0.2-r1_all.ipk
Size: 7288
Size: 7287
Package: secubox-app-mac-guardian
Version: 0.5.0-r1
@ -1035,7 +1035,7 @@ Description: WiFi MAC address security monitor for SecuBox.
and spoofing. Integrates with CrowdSec and provides
real-time hostapd hotplug detection.
Filename: secubox-app-mac-guardian_0.5.0-r1_all.ipk
Size: 12095
Size: 12099
Package: secubox-app-magicmirror2
Version: 0.4.0-r8
@ -1057,7 +1057,7 @@ Description: MagicMirror² - Open source modular smart mirror platform for Secu
Runs in LXC container for isolation and security.
Configure in /etc/config/magicmirror2.
Filename: secubox-app-magicmirror2_0.4.0-r8_all.ipk
Size: 9254
Size: 9253
Package: secubox-app-mailinabox
Version: 2.0.0-r1
@ -1082,7 +1082,7 @@ Description: Complete email server solution using docker-mailserver for SecuBox
Commands: mailinaboxctl --help
Filename: secubox-app-mailinabox_2.0.0-r1_all.ipk
Size: 7571
Size: 7572
Package: secubox-app-metabolizer
Version: 1.0.0-r3
@ -1130,7 +1130,7 @@ Description: mitmproxy - Interactive HTTPS proxy for SecuBox-powered OpenWrt sy
Runs in LXC container for isolation and security.
Configure in /etc/config/mitmproxy.
Filename: secubox-app-mitmproxy_0.5.0-r19_all.ipk
Size: 22954
Size: 22962
Package: secubox-app-mmpm
Version: 0.2.0-r5
@ -1151,7 +1151,7 @@ Description: MMPM (MagicMirror Package Manager) for SecuBox.
Runs inside the MagicMirror2 LXC container.
Filename: secubox-app-mmpm_0.2.0-r5_all.ipk
Size: 3977
Size: 3975
Package: secubox-app-nextcloud
Version: 1.0.0-r2
@ -1165,7 +1165,7 @@ Description: Installer, configuration, and service manager for running Nextclou
inside Docker on SecuBox-powered OpenWrt systems. Self-hosted file
sync and share with calendar, contacts, and collaboration.
Filename: secubox-app-nextcloud_1.0.0-r2_all.ipk
Size: 2955
Size: 2958
Package: secubox-app-ollama
Version: 0.1.0-r1
@ -1187,7 +1187,7 @@ Description: Ollama - Simple local LLM runtime for SecuBox-powered OpenWrt syst
Runs in Docker/Podman container.
Configure in /etc/config/ollama.
Filename: secubox-app-ollama_0.1.0-r1_all.ipk
Size: 5736
Size: 5739
Package: secubox-app-picobrew
Version: 1.0.0-r7
@ -1209,7 +1209,7 @@ Description: PicoBrew Server - Self-hosted brewing controller for PicoBrew devi
Runs in LXC container with Python/Flask backend.
Configure in /etc/config/picobrew.
Filename: secubox-app-picobrew_1.0.0-r7_all.ipk
Size: 5539
Size: 5540
Package: secubox-app-simplex
Version: 1.0.0-r1
@ -1233,7 +1233,7 @@ Description: SimpleX Chat self-hosted messaging infrastructure for SecuBox.
Privacy-first messaging relay that you control.
Configure in /etc/config/simplex.
Filename: secubox-app-simplex_1.0.0-r1_all.ipk
Size: 9233
Size: 9235
Package: secubox-app-streamlit
Version: 1.0.0-r5
@ -1283,7 +1283,7 @@ Description: SecuBox Tor Shield - One-click Tor anonymization for OpenWrt
Configure in /etc/config/tor-shield.
Filename: secubox-app-tor_1.0.0-r1_all.ipk
Size: 7370
Size: 7371
Package: secubox-app-webapp
Version: 1.5.0-r7
@ -1301,7 +1301,7 @@ Description: SecuBox Control Center Dashboard - A web-based dashboard for monit
- Service management
- Network interface control
Filename: secubox-app-webapp_1.5.0-r7_all.ipk
Size: 39173
Size: 39175
Package: secubox-app-zigbee2mqtt
Version: 1.0.0-r3
@ -1314,7 +1314,7 @@ Installed-Size: 20480
Description: Installer, configuration, and service manager for running Zigbee2MQTT
inside an Alpine LXC container on SecuBox-powered OpenWrt systems.
Filename: secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk
Size: 5507
Size: 5510
Package: secubox-core
Version: 0.10.0-r11
@ -1334,7 +1334,7 @@ Description: SecuBox Core Framework provides the foundational infrastructure fo
- Unified CLI interface
- ubus RPC backend
Filename: secubox-core_0.10.0-r11_all.ipk
Size: 87977
Size: 87975
Package: secubox-dns-guard
Version: 1.0.0-r1
@ -1353,7 +1353,7 @@ Description: SecuBox DNS Guard provides AI-powered DNS anomaly detection using
- Unusual TLD pattern detection
- Automatic blocklist generation with approval workflow
Filename: secubox-dns-guard_1.0.0-r1_all.ipk
Size: 12476
Size: 12473
Package: secubox-master-link
Version: 1.0.0-r1
@ -1375,7 +1375,7 @@ Description: Secure mesh onboarding for SecuBox nodes via master/peer link.
Configure in /etc/config/master-link.
Filename: secubox-master-link_1.0.0-r1_all.ipk
Size: 12453
Size: 12456
Package: secubox-mcp-server
Version: 1.0.0-r1
@ -1403,7 +1403,7 @@ Description: Model Context Protocol (MCP) server for SecuBox.
- ai.explain_ban (Explain CrowdSec decisions)
- ai.security_posture (Security assessment)
Filename: secubox-mcp-server_1.0.0-r1_all.ipk
Size: 11430
Size: 11431
Package: secubox-p2p
Version: 0.6.0-r3
@ -1422,7 +1422,7 @@ Description: SecuBox P2P Hub backend providing peer discovery, mesh networking
and MirrorBox NetMesh Catalog for cross-chain distributed service
registry with HAProxy vhost discovery and multi-endpoint access URLs.
Filename: secubox-p2p_0.6.0-r3_all.ipk
Size: 47675
Size: 47677
Package: secubox-threat-analyst
Version: 1.0.0-r1
@ -1441,5 +1441,5 @@ Description: Autonomous threat analysis agent for SecuBox.
Part of SecuBox AI Gateway (Couche 2).
Filename: secubox-threat-analyst_1.0.0-r1_all.ipk
Size: 9868
Size: 9867

View File

@ -1,12 +1,12 @@
{
"feed_url": "/secubox-feed",
"generated": "2026-02-05T06:06:11+01:00",
"generated": "2026-02-05T09:12:05+01:00",
"packages": [
{
"name": "luci-app-auth-guardian",
"version": "0.4.0-r3",
"filename": "luci-app-auth-guardian_0.4.0-r3_all.ipk",
"size": 11735,
"size": 11736,
"category": "security",
"icon": "key",
"description": "Authentication management",
@ -30,7 +30,7 @@
"name": "luci-app-cdn-cache",
"version": "0.5.0-r3",
"filename": "luci-app-cdn-cache_0.5.0-r3_all.ipk",
"size": 23185,
"size": 23182,
"category": "network",
"icon": "globe",
"description": "CDN caching",
@ -42,7 +42,7 @@
"name": "luci-app-client-guardian",
"version": "0.4.0-r7",
"filename": "luci-app-client-guardian_0.4.0-r7_all.ipk",
"size": 54535,
"size": 54536,
"category": "network",
"icon": "users",
"description": "Client management and monitoring",
@ -54,7 +54,7 @@
"name": "luci-app-crowdsec-dashboard",
"version": "0.7.0-r32",
"filename": "luci-app-crowdsec-dashboard_0.7.0-r32_all.ipk",
"size": 33740,
"size": 33739,
"category": "security",
"icon": "shield",
"description": "CrowdSec security monitoring",
@ -66,7 +66,7 @@
"name": "luci-app-cyberfeed",
"version": "0.1.1-r1",
"filename": "luci-app-cyberfeed_0.1.1-r1_all.ipk",
"size": 12839,
"size": 12837,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -78,7 +78,7 @@
"name": "luci-app-device-intel",
"version": "1.0.0-r1",
"filename": "luci-app-device-intel_1.0.0-r1_all.ipk",
"size": 10862,
"size": 10859,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -102,7 +102,7 @@
"name": "luci-app-dns-provider",
"version": "1.0.0-r1",
"filename": "luci-app-dns-provider_1.0.0-r1_all.ipk",
"size": 7127,
"size": 7130,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -114,7 +114,7 @@
"name": "luci-app-exposure",
"version": "1.0.0-r3",
"filename": "luci-app-exposure_1.0.0-r3_all.ipk",
"size": 9838,
"size": 9841,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -126,7 +126,7 @@
"name": "luci-app-gitea",
"version": "1.0.0-r2",
"filename": "luci-app-gitea_1.0.0-r2_all.ipk",
"size": 15299,
"size": 15300,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -138,7 +138,7 @@
"name": "luci-app-glances",
"version": "1.0.0-r2",
"filename": "luci-app-glances_1.0.0-r2_all.ipk",
"size": 6968,
"size": 6969,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -162,7 +162,7 @@
"name": "luci-app-hexojs",
"version": "1.0.0-r3",
"filename": "luci-app-hexojs_1.0.0-r3_all.ipk",
"size": 30311,
"size": 30307,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -174,7 +174,7 @@
"name": "luci-app-jellyfin",
"version": "1.0.0-r1",
"filename": "luci-app-jellyfin_1.0.0-r1_all.ipk",
"size": 6060,
"size": 6061,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -186,7 +186,7 @@
"name": "luci-app-jitsi",
"version": "1.0.0-r1",
"filename": "luci-app-jitsi_1.0.0-r1_all.ipk",
"size": 5139,
"size": 5134,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -198,7 +198,7 @@
"name": "luci-app-ksm-manager",
"version": "0.4.0-r2",
"filename": "luci-app-ksm-manager_0.4.0-r2_all.ipk",
"size": 18724,
"size": 18719,
"category": "system",
"icon": "cpu",
"description": "Kernel memory management",
@ -210,7 +210,7 @@
"name": "luci-app-localai",
"version": "0.1.0-r15",
"filename": "luci-app-localai_0.1.0-r15_all.ipk",
"size": 13181,
"size": 13182,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -222,7 +222,7 @@
"name": "luci-app-lyrion",
"version": "1.0.0-r1",
"filename": "luci-app-lyrion_1.0.0-r1_all.ipk",
"size": 6727,
"size": 6725,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -234,7 +234,7 @@
"name": "luci-app-mac-guardian",
"version": "0.5.0-r1",
"filename": "luci-app-mac-guardian_0.5.0-r1_all.ipk",
"size": 6512,
"size": 6509,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -270,7 +270,7 @@
"name": "luci-app-master-link",
"version": "1.0.0-r1",
"filename": "luci-app-master-link_1.0.0-r1_all.ipk",
"size": 6248,
"size": 6245,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -282,7 +282,7 @@
"name": "luci-app-media-flow",
"version": "0.6.4-r1",
"filename": "luci-app-media-flow_0.6.4-r1_all.ipk",
"size": 25416,
"size": 25418,
"category": "media",
"icon": "film",
"description": "Media streaming",
@ -318,7 +318,7 @@
"name": "luci-app-mitmproxy",
"version": "0.5.0-r2",
"filename": "luci-app-mitmproxy_0.5.0-r2_all.ipk",
"size": 11152,
"size": 11149,
"category": "security",
"icon": "lock",
"description": "HTTPS proxy and traffic inspection",
@ -330,7 +330,7 @@
"name": "luci-app-mmpm",
"version": "0.2.0-r3",
"filename": "luci-app-mmpm_0.2.0-r3_all.ipk",
"size": 7901,
"size": 7899,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -342,7 +342,7 @@
"name": "luci-app-mqtt-bridge",
"version": "0.4.0-r4",
"filename": "luci-app-mqtt-bridge_0.4.0-r4_all.ipk",
"size": 22779,
"size": 22780,
"category": "iot",
"icon": "message-square",
"description": "MQTT bridge",
@ -354,7 +354,7 @@
"name": "luci-app-ndpid",
"version": "1.1.2-r2",
"filename": "luci-app-ndpid_1.1.2-r2_all.ipk",
"size": 22653,
"size": 22654,
"category": "security",
"icon": "eye",
"description": "Deep packet inspection",
@ -366,7 +366,7 @@
"name": "luci-app-netdata-dashboard",
"version": "0.5.0-r2",
"filename": "luci-app-netdata-dashboard_0.5.0-r2_all.ipk",
"size": 20488,
"size": 20484,
"category": "monitoring",
"icon": "bar-chart-2",
"description": "System monitoring dashboard",
@ -378,7 +378,7 @@
"name": "luci-app-network-modes",
"version": "0.5.0-r3",
"filename": "luci-app-network-modes_0.5.0-r3_all.ipk",
"size": 54148,
"size": 54149,
"category": "network",
"icon": "wifi",
"description": "Network configuration",
@ -390,7 +390,7 @@
"name": "luci-app-network-tweaks",
"version": "1.0.0-r7",
"filename": "luci-app-network-tweaks_1.0.0-r7_all.ipk",
"size": 14960,
"size": 14957,
"category": "network",
"icon": "wifi",
"description": "Network configuration",
@ -402,7 +402,7 @@
"name": "luci-app-nextcloud",
"version": "1.0.0-r1",
"filename": "luci-app-nextcloud_1.0.0-r1_all.ipk",
"size": 6486,
"size": 6489,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -414,7 +414,7 @@
"name": "luci-app-ollama",
"version": "0.1.0-r1",
"filename": "luci-app-ollama_0.1.0-r1_all.ipk",
"size": 12355,
"size": 12352,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -426,7 +426,7 @@
"name": "luci-app-picobrew",
"version": "1.0.0-r1",
"filename": "luci-app-picobrew_1.0.0-r1_all.ipk",
"size": 9458,
"size": 9459,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -450,7 +450,7 @@
"name": "luci-app-secubox-admin",
"version": "1.0.0-r19",
"filename": "luci-app-secubox-admin_1.0.0-r19_all.ipk",
"size": 57247,
"size": 57245,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@ -462,7 +462,7 @@
"name": "luci-app-secubox-crowdsec",
"version": "1.0.0-r3",
"filename": "luci-app-secubox-crowdsec_1.0.0-r3_all.ipk",
"size": 13917,
"size": 13923,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@ -474,7 +474,7 @@
"name": "luci-app-secubox-netdiag",
"version": "1.0.0-r1",
"filename": "luci-app-secubox-netdiag_1.0.0-r1_all.ipk",
"size": 15308,
"size": 15306,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@ -498,7 +498,7 @@
"name": "luci-app-secubox-p2p",
"version": "0.1.0-r1",
"filename": "luci-app-secubox-p2p_0.1.0-r1_all.ipk",
"size": 44085,
"size": 44086,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@ -510,7 +510,7 @@
"name": "luci-app-secubox-portal",
"version": "0.7.0-r2",
"filename": "luci-app-secubox-portal_0.7.0-r2_all.ipk",
"size": 24646,
"size": 24644,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@ -534,7 +534,7 @@
"name": "luci-app-service-registry",
"version": "1.0.0-r1",
"filename": "luci-app-service-registry_1.0.0-r1_all.ipk",
"size": 39826,
"size": 39828,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -546,7 +546,7 @@
"name": "luci-app-simplex",
"version": "1.0.0-r1",
"filename": "luci-app-simplex_1.0.0-r1_all.ipk",
"size": 6999,
"size": 7000,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -558,7 +558,7 @@
"name": "luci-app-streamlit",
"version": "1.0.0-r11",
"filename": "luci-app-streamlit_1.0.0-r11_all.ipk",
"size": 14748,
"size": 14749,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -570,7 +570,7 @@
"name": "luci-app-system-hub",
"version": "0.5.1-r4",
"filename": "luci-app-system-hub_0.5.1-r4_all.ipk",
"size": 61106,
"size": 61105,
"category": "system",
"icon": "settings",
"description": "System management",
@ -582,7 +582,7 @@
"name": "luci-app-threat-analyst",
"version": "1.0.0-r1",
"filename": "luci-app-threat-analyst_1.0.0-r1_all.ipk",
"size": 6951,
"size": 9753,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -594,7 +594,7 @@
"name": "luci-app-tor-shield",
"version": "1.0.0-r10",
"filename": "luci-app-tor-shield_1.0.0-r10_all.ipk",
"size": 22361,
"size": 22362,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -606,7 +606,7 @@
"name": "luci-app-traffic-shaper",
"version": "0.4.0-r2",
"filename": "luci-app-traffic-shaper_0.4.0-r2_all.ipk",
"size": 14537,
"size": 14535,
"category": "network",
"icon": "filter",
"description": "Traffic shaping and QoS",
@ -618,7 +618,7 @@
"name": "luci-app-vhost-manager",
"version": "0.5.0-r5",
"filename": "luci-app-vhost-manager_0.5.0-r5_all.ipk",
"size": 26181,
"size": 26186,
"category": "network",
"icon": "server",
"description": "Virtual host management",
@ -630,7 +630,7 @@
"name": "luci-app-wireguard-dashboard",
"version": "0.7.0-r5",
"filename": "luci-app-wireguard-dashboard_0.7.0-r5_all.ipk",
"size": 39609,
"size": 39607,
"category": "vpn",
"icon": "shield",
"description": "WireGuard VPN dashboard",
@ -642,7 +642,7 @@
"name": "luci-app-zigbee2mqtt",
"version": "1.0.0-r2",
"filename": "luci-app-zigbee2mqtt_1.0.0-r2_all.ipk",
"size": 6815,
"size": 6813,
"category": "iot",
"icon": "radio",
"description": "Zigbee device management",
@ -654,7 +654,7 @@
"name": "luci-theme-secubox",
"version": "0.4.7-r1",
"filename": "luci-theme-secubox_0.4.7-r1_all.ipk",
"size": 110241,
"size": 110239,
"category": "theme",
"icon": "palette",
"description": "LuCI theme",
@ -666,7 +666,7 @@
"name": "secubox-app",
"version": "1.0.0-r2",
"filename": "secubox-app_1.0.0-r2_all.ipk",
"size": 11182,
"size": 11184,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -678,7 +678,7 @@
"name": "secubox-app-adguardhome",
"version": "1.0.0-r2",
"filename": "secubox-app-adguardhome_1.0.0-r2_all.ipk",
"size": 2882,
"size": 2880,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -690,7 +690,7 @@
"name": "secubox-app-auth-logger",
"version": "1.2.2-r1",
"filename": "secubox-app-auth-logger_1.2.2-r1_all.ipk",
"size": 9375,
"size": 9379,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -702,7 +702,7 @@
"name": "secubox-app-crowdsec-custom",
"version": "1.1.0-r1",
"filename": "secubox-app-crowdsec-custom_1.1.0-r1_all.ipk",
"size": 5758,
"size": 5761,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -714,7 +714,7 @@
"name": "secubox-app-cs-firewall-bouncer",
"version": "0.0.31-r4_aarch64",
"filename": "secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk",
"size": 5049326,
"size": 5049328,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -726,7 +726,7 @@
"name": "secubox-app-cyberfeed",
"version": "0.2.1-r1",
"filename": "secubox-app-cyberfeed_0.2.1-r1_all.ipk",
"size": 12453,
"size": 12454,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -738,7 +738,7 @@
"name": "secubox-app-device-intel",
"version": "1.0.0-r1",
"filename": "secubox-app-device-intel_1.0.0-r1_all.ipk",
"size": 13005,
"size": 13004,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -750,7 +750,7 @@
"name": "secubox-app-dns-provider",
"version": "1.0.0-r1",
"filename": "secubox-app-dns-provider_1.0.0-r1_all.ipk",
"size": 5590,
"size": 6702,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -762,7 +762,7 @@
"name": "secubox-app-domoticz",
"version": "1.0.0-r2",
"filename": "secubox-app-domoticz_1.0.0-r2_all.ipk",
"size": 2546,
"size": 2548,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -774,7 +774,7 @@
"name": "secubox-app-exposure",
"version": "1.0.0-r1",
"filename": "secubox-app-exposure_1.0.0-r1_all.ipk",
"size": 6936,
"size": 6934,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -786,7 +786,7 @@
"name": "secubox-app-gitea",
"version": "1.0.0-r5",
"filename": "secubox-app-gitea_1.0.0-r5_all.ipk",
"size": 9402,
"size": 9407,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -798,7 +798,7 @@
"name": "secubox-app-glances",
"version": "1.0.0-r1",
"filename": "secubox-app-glances_1.0.0-r1_all.ipk",
"size": 5536,
"size": 5538,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -810,7 +810,7 @@
"name": "secubox-app-haproxy",
"version": "1.0.0-r23",
"filename": "secubox-app-haproxy_1.0.0-r23_all.ipk",
"size": 15683,
"size": 15687,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -822,7 +822,7 @@
"name": "secubox-app-hexojs",
"version": "1.0.0-r8",
"filename": "secubox-app-hexojs_1.0.0-r8_all.ipk",
"size": 94937,
"size": 94940,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -834,7 +834,7 @@
"name": "secubox-app-jellyfin",
"version": "1.0.0-r1",
"filename": "secubox-app-jellyfin_1.0.0-r1_all.ipk",
"size": 6182,
"size": 6185,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -846,7 +846,7 @@
"name": "secubox-app-jitsi",
"version": "1.0.0-r1",
"filename": "secubox-app-jitsi_1.0.0-r1_all.ipk",
"size": 8913,
"size": 8914,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -858,7 +858,7 @@
"name": "secubox-app-localai",
"version": "2.25.0-r1",
"filename": "secubox-app-localai_2.25.0-r1_all.ipk",
"size": 5722,
"size": 5720,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -870,7 +870,7 @@
"name": "secubox-app-localai-wb",
"version": "2.25.0-r1",
"filename": "secubox-app-localai-wb_2.25.0-r1_all.ipk",
"size": 7953,
"size": 7951,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -882,7 +882,7 @@
"name": "secubox-app-lyrion",
"version": "2.0.2-r1",
"filename": "secubox-app-lyrion_2.0.2-r1_all.ipk",
"size": 7288,
"size": 7287,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -894,7 +894,7 @@
"name": "secubox-app-mac-guardian",
"version": "0.5.0-r1",
"filename": "secubox-app-mac-guardian_0.5.0-r1_all.ipk",
"size": 12095,
"size": 12099,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -906,7 +906,7 @@
"name": "secubox-app-magicmirror2",
"version": "0.4.0-r8",
"filename": "secubox-app-magicmirror2_0.4.0-r8_all.ipk",
"size": 9254,
"size": 9253,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -918,7 +918,7 @@
"name": "secubox-app-mailinabox",
"version": "2.0.0-r1",
"filename": "secubox-app-mailinabox_2.0.0-r1_all.ipk",
"size": 7571,
"size": 7572,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -942,7 +942,7 @@
"name": "secubox-app-mitmproxy",
"version": "0.5.0-r19",
"filename": "secubox-app-mitmproxy_0.5.0-r19_all.ipk",
"size": 22954,
"size": 22962,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -954,7 +954,7 @@
"name": "secubox-app-mmpm",
"version": "0.2.0-r5",
"filename": "secubox-app-mmpm_0.2.0-r5_all.ipk",
"size": 3977,
"size": 3975,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -966,7 +966,7 @@
"name": "secubox-app-nextcloud",
"version": "1.0.0-r2",
"filename": "secubox-app-nextcloud_1.0.0-r2_all.ipk",
"size": 2955,
"size": 2958,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -978,7 +978,7 @@
"name": "secubox-app-ollama",
"version": "0.1.0-r1",
"filename": "secubox-app-ollama_0.1.0-r1_all.ipk",
"size": 5736,
"size": 5739,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -990,7 +990,7 @@
"name": "secubox-app-picobrew",
"version": "1.0.0-r7",
"filename": "secubox-app-picobrew_1.0.0-r7_all.ipk",
"size": 5539,
"size": 5540,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -1002,7 +1002,7 @@
"name": "secubox-app-simplex",
"version": "1.0.0-r1",
"filename": "secubox-app-simplex_1.0.0-r1_all.ipk",
"size": 9233,
"size": 9235,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -1026,7 +1026,7 @@
"name": "secubox-app-tor",
"version": "1.0.0-r1",
"filename": "secubox-app-tor_1.0.0-r1_all.ipk",
"size": 7370,
"size": 7371,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -1038,7 +1038,7 @@
"name": "secubox-app-webapp",
"version": "1.5.0-r7",
"filename": "secubox-app-webapp_1.5.0-r7_all.ipk",
"size": 39173,
"size": 39175,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -1050,7 +1050,7 @@
"name": "secubox-app-zigbee2mqtt",
"version": "1.0.0-r3",
"filename": "secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk",
"size": 5507,
"size": 5510,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@ -1062,7 +1062,7 @@
"name": "secubox-core",
"version": "0.10.0-r11",
"filename": "secubox-core_0.10.0-r11_all.ipk",
"size": 87977,
"size": 87975,
"category": "system",
"icon": "box",
"description": "SecuBox core components",
@ -1074,7 +1074,7 @@
"name": "secubox-dns-guard",
"version": "1.0.0-r1",
"filename": "secubox-dns-guard_1.0.0-r1_all.ipk",
"size": 12476,
"size": 12473,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -1086,7 +1086,7 @@
"name": "secubox-master-link",
"version": "1.0.0-r1",
"filename": "secubox-master-link_1.0.0-r1_all.ipk",
"size": 12453,
"size": 12456,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -1098,7 +1098,7 @@
"name": "secubox-mcp-server",
"version": "1.0.0-r1",
"filename": "secubox-mcp-server_1.0.0-r1_all.ipk",
"size": 11430,
"size": 11431,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -1110,7 +1110,7 @@
"name": "secubox-p2p",
"version": "0.6.0-r3",
"filename": "secubox-p2p_0.6.0-r3_all.ipk",
"size": 47675,
"size": 47677,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@ -1122,7 +1122,7 @@
"name": "secubox-threat-analyst",
"version": "1.0.0-r1",
"filename": "secubox-threat-analyst_1.0.0-r1_all.ipk",
"size": 9868,
"size": 9867,
"category": "utility",
"icon": "package",
"description": "SecuBox package",

Some files were not shown because too many files have changed in this diff Show More