feat(netifyd/network-modes): add wizard views

This commit is contained in:
CyberMind-FR 2025-12-30 15:11:32 +01:00
parent 280dd91798
commit 4c70874fff
7 changed files with 661 additions and 227 deletions

View File

@ -40,6 +40,12 @@ var callProtocols = rpc.declare({
expect: { protocols: [] }
});
var callDevices = rpc.declare({
object: 'luci.netifyd-dashboard',
method: 'devices',
expect: { devices: [] }
});
var callStats = rpc.declare({
object: 'luci.netifyd-dashboard',
method: 'stats',
@ -72,6 +78,7 @@ return baseclass.extend({
getApplications: callApplications,
getHosts: callHosts,
getProtocols: callProtocols,
getDevices: callDevices,
getStats: callStats,
getSecuboxLogs: callSecuboxLogs,
collectDebugSnapshot: callCollectDebug,

View File

@ -12,239 +12,250 @@ return view.extend({
render: function(status) {
status = status || {};
var view = E('div', { 'class': 'cbi-map' }, [
E('h2', {}, _('Netifyd Settings')),
E('div', { 'class': 'cbi-map-descr' },
_('Configure and manage Netifyd deep packet inspection service.')),
// Service Status
E('div', { 'class': 'cbi-section' }, [
E('h3', {}, _('Service Status')),
E('div', { 'class': 'table cbi-section-table' }, [
E('div', { 'class': 'tr cbi-section-table-row' }, [
E('div', { 'class': 'td left', 'style': 'width: 33%; font-weight: bold;' }, _('Service Status')),
E('div', { 'class': 'td left' }, [
E('span', {
'class': 'badge',
'style': 'background: ' + (status.running ? '#28a745' : '#dc3545') + '; color: white; padding: 0.25em 0.6em; border-radius: 3px;'
}, status.running ? _('Running') : _('Stopped'))
])
]),
E('div', { 'class': 'tr cbi-section-table-row' }, [
E('div', { 'class': 'td left', 'style': 'width: 33%; font-weight: bold;' }, _('Version')),
E('div', { 'class': 'td left' }, status.version || 'Unknown')
]),
status.running ? E('div', { 'class': 'tr cbi-section-table-row' }, [
E('div', { 'class': 'td left', 'style': 'width: 33%; font-weight: bold;' }, _('Process ID')),
E('div', { 'class': 'td left' }, [
E('code', {}, (status.pid || 'N/A').toString())
])
]) : null,
status.running && status.uptime ? E('div', { 'class': 'tr cbi-section-table-row' }, [
E('div', { 'class': 'td left', 'style': 'width: 33%; font-weight: bold;' }, _('Uptime')),
E('div', { 'class': 'td left' }, this.formatUptime(status.uptime))
]) : null,
status.running && status.memory_kb ? E('div', { 'class': 'tr cbi-section-table-row' }, [
E('div', { 'class': 'td left', 'style': 'width: 33%; font-weight: bold;' }, _('Memory Usage')),
E('div', { 'class': 'td left' }, Math.round(status.memory_kb / 1024) + ' MB')
]) : null,
E('div', { 'class': 'tr cbi-section-table-row' }, [
E('div', { 'class': 'td left', 'style': 'width: 33%; font-weight: bold;' }, _('Monitored Interfaces')),
E('div', { 'class': 'td left' }, [
status.interfaces && status.interfaces.length > 0
? status.interfaces.map(function(iface) {
return E('span', {
'class': 'badge',
'style': 'background: #0088cc; color: white; padding: 0.25em 0.6em; border-radius: 3px; margin-right: 0.5em;'
}, iface);
})
: E('span', { 'style': 'color: #999;' }, _('None configured'))
])
])
])
var container = E('div', {
'class': 'netifyd-settings',
'style': 'max-width: 1200px; margin: 0 auto;'
}, [
// Header
E('div', { 'style': 'margin-bottom: 2em;' }, [
E('h1', {
'style': 'font-size: 2em; margin: 0 0 0.5em 0; background: linear-gradient(135deg, #8b5cf6 0%, #3b82f6 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;'
}, _('Netifyd Settings')),
E('p', { 'style': 'color: #94a3b8; font-size: 1.05em;' },
_('Configure and manage Netifyd deep packet inspection service'))
]),
// What is Netifyd
E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2em;' }, [
E('h3', {}, _('About Netifyd')),
E('div', { 'style': 'background: #f8f9fa; padding: 1em; border-radius: 4px;' }, [
E('p', {}, _('Netifyd is a deep packet inspection (DPI) daemon that classifies network traffic by application protocol and category.')),
E('p', { 'style': 'margin-top: 0.5em;' }, _('It provides real-time insights into:')),
E('ul', { 'style': 'margin: 0.5em 0; padding-left: 2em;' }, [
E('li', {}, _('Application detection (HTTP, HTTPS, DNS, SSH, etc.)')),
E('li', {}, _('Protocol identification (TCP, UDP, ICMP)')),
E('li', {}, _('Traffic categorization (Streaming, VoIP, Gaming, etc.)')),
E('li', {}, _('Device fingerprinting and tracking')),
E('li', {}, _('Bandwidth usage per application'))
]),
E('p', { 'style': 'margin-top: 1em; padding: 0.75em; background: #e8f4f8; border-radius: 4px;' }, [
E('strong', {}, _('Note:')),
' ',
_('Netifyd uses kernel conntrack for flow tracking and deep packet inspection for application detection.')
])
])
]),
// Configuration Files
E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2em;' }, [
E('h3', {}, _('Configuration Files')),
E('div', { 'style': 'background: #f8f9fa; padding: 1em; border-radius: 4px;' }, [
E('p', {}, [
E('strong', {}, _('Main Configuration:')),
' ',
E('code', {}, '/etc/netifyd.conf')
]),
E('p', {}, [
E('strong', {}, _('Service Configuration:')),
' ',
E('code', {}, '/etc/config/netifyd')
]),
E('p', {}, [
E('strong', {}, _('Runtime Data:')),
' ',
E('code', {}, '/var/run/netifyd/')
]),
E('p', { 'style': 'margin-top: 1em; padding: 0.75em; background: #fff3cd; border-radius: 4px;' }, [
E('strong', {}, _('Note:')),
' ',
_('After modifying configuration files, restart netifyd from the command line.')
])
])
]),
// Common Configuration Examples
E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2em;' }, [
E('h3', {}, _('Common Configuration Examples')),
// Monitor Specific Interfaces
E('div', { 'style': 'margin-bottom: 1.5em;' }, [
E('h4', {}, _('Monitor Specific Interfaces')),
E('p', {}, _('Edit /etc/config/netifyd to specify which interfaces to monitor:')),
E('pre', { 'style': 'background: #f5f5f5; padding: 1em; border-radius: 4px; overflow-x: auto;' },
'config netifyd\n' +
' option enabled \'1\'\n' +
' list internal_if \'br-lan\'\n' +
' list internal_if \'wlan0\'\n' +
' list external_if \'eth0\'\n'
),
E('p', { 'style': 'color: #666; font-size: 0.9em;' },
_('Internal interfaces are monitored for client traffic, external for WAN traffic.'))
// Service Status Card
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; margin-bottom: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, status.running ? '✅' : '⚠️'),
_('Service Status')
]),
// Enable Protocol Detection
E('div', { 'style': 'margin-bottom: 1.5em;' }, [
E('h4', {}, _('Enable Advanced Detection')),
E('p', {}, _('Edit /etc/netifyd.conf for advanced DPI options:')),
E('pre', { 'style': 'background: #f5f5f5; padding: 1em; border-radius: 4px; overflow-x: auto;' },
'# Enable deep packet inspection\n' +
'enable_dpi=yes\n\n' +
'# Enable DNS resolution\n' +
'enable_dns_hint=yes\n\n' +
'# Detection sensitivity (high, medium, low)\n' +
'detection_sensitivity=high\n\n' +
'# Flow idle timeout (seconds)\n' +
'flow_idle_timeout=300\n'
E('div', { 'style': 'display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5em; margin-top: 1.5em;' }, [
// Status
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b;' }, [
E('div', { 'style': 'color: #64748b; font-size: 0.9em; margin-bottom: 0.5em;' }, _('Status')),
E('div', {
'class': 'badge',
'style': 'display: inline-block; padding: 0.5em 1em; border-radius: 6px; font-weight: bold; background: ' + (status.running ? 'linear-gradient(135deg, #10b981, #059669)' : 'linear-gradient(135deg, #ef4444, #dc2626)') + '; color: white;'
}, status.running ? _('Running') : _('Stopped'))
]),
// Version
status.version ? E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b;' }, [
E('div', { 'style': 'color: #64748b; font-size: 0.9em; margin-bottom: 0.5em;' }, _('Version')),
E('div', { 'style': 'color: #8b5cf6; font-size: 1.5em; font-weight: bold;' }, status.version)
]) : null,
// Uptime
status.running && status.uptime ? E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b;' }, [
E('div', { 'style': 'color: #64748b; font-size: 0.9em; margin-bottom: 0.5em;' }, _('Uptime')),
E('div', { 'style': 'color: #3b82f6; font-size: 1.5em; font-weight: bold;' }, this.formatUptime(status.uptime))
]) : null,
// Memory
status.running && status.memory_kb ? E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b;' }, [
E('div', { 'style': 'color: #64748b; font-size: 0.9em; margin-bottom: 0.5em;' }, _('Memory')),
E('div', { 'style': 'color: #06b6d4; font-size: 1.5em; font-weight: bold;' }, Math.round(status.memory_kb / 1024) + ' MB')
]) : null
]),
// Monitored Interfaces
status.interfaces && status.interfaces.length > 0 ? E('div', { 'style': 'margin-top: 1.5em; padding-top: 1.5em; border-top: 1px solid #1e293b;' }, [
E('div', { 'style': 'color: #cbd5e1; font-size: 0.95em; margin-bottom: 1em;' }, _('Monitored Interfaces')),
E('div', { 'style': 'display: flex; gap: 0.75em; flex-wrap: wrap;' },
status.interfaces.map(function(iface) {
return E('span', {
'style': 'background: linear-gradient(135deg, #8b5cf6, #3b82f6); color: white; padding: 0.5em 1em; border-radius: 6px; font-weight: 500;'
}, iface);
})
)
]) : null
]),
// Configuration Info
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; margin-bottom: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '⚙️'),
_('Configuration Files')
]),
// Performance Tuning
E('div', { 'style': 'margin-bottom: 1.5em;' }, [
E('h4', {}, _('Performance Tuning')),
E('p', {}, _('Adjust resource usage in /etc/netifyd.conf:')),
E('pre', { 'style': 'background: #f5f5f5; padding: 1em; border-radius: 4px; overflow-x: auto;' },
'# Maximum flows to track\n' +
'max_flows=65536\n\n' +
'# Thread pool size\n' +
'thread_pool_size=4\n\n' +
'# Flow hash table size\n' +
'flow_hash_size=32768\n'
),
E('p', { 'style': 'color: #666; font-size: 0.9em;' },
_('Reduce values on low-memory devices, increase for high-traffic networks.'))
E('div', { 'style': 'display: grid; gap: 1em; margin-top: 1.5em;' }, [
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b; display: flex; justify-content: space-between; align-items: center;' }, [
E('div', {}, [
E('div', { 'style': 'color: #cbd5e1; font-weight: 500; margin-bottom: 0.25em;' }, _('Main Configuration')),
E('div', { 'style': 'color: #64748b; font-size: 0.9em;' }, _('Service and interface settings'))
]),
E('code', { 'style': 'color: #8b5cf6; background: #020617; padding: 0.5em 1em; border-radius: 4px; font-size: 0.95em;' }, '/etc/netifyd.conf')
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b; display: flex; justify-content: space-between; align-items: center;' }, [
E('div', {}, [
E('div', { 'style': 'color: #cbd5e1; font-weight: 500; margin-bottom: 0.25em;' }, _('UCI Configuration')),
E('div', { 'style': 'color: #64748b; font-size: 0.9em;' }, _('OpenWrt system integration'))
]),
E('code', { 'style': 'color: #3b82f6; background: #020617; padding: 0.5em 1em; border-radius: 4px; font-size: 0.95em;' }, '/etc/config/netifyd')
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.25em; border: 1px solid #1e293b; display: flex; justify-content: space-between; align-items: center;' }, [
E('div', {}, [
E('div', { 'style': 'color: #cbd5e1; font-weight: 500; margin-bottom: 0.25em;' }, _('Runtime Data')),
E('div', { 'style': 'color: #64748b; font-size: 0.9em;' }, _('Real-time flow and status data'))
]),
E('code', { 'style': 'color: #06b6d4; background: #020617; padding: 0.5em 1em; border-radius: 4px; font-size: 0.95em;' }, '/var/run/netifyd/')
])
]),
E('div', { 'style': 'background: linear-gradient(135deg, #92400e, #b45309); border-radius: 8px; padding: 1.25em; margin-top: 1.5em; border: 1px solid #f59e0b;' }, [
E('div', { 'style': 'display: flex; align-items: flex-start; gap: 0.75em;' }, [
E('span', { 'style': 'font-size: 1.3em; flex-shrink: 0;' }, '⚠️'),
E('div', {}, [
E('strong', { 'style': 'color: #fcd34d; font-size: 1.05em;' }, _('Note')),
E('p', { 'style': 'color: #fde68a; margin: 0.5em 0 0 0;' },
_('After modifying configuration files, restart netifyd from the command line:') + ' ' +
E('code', { 'style': 'background: #451a03; padding: 0.25em 0.5em; border-radius: 3px;' }, '/etc/init.d/netifyd restart'))
])
])
])
]),
// Useful Commands
E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2em; background: #e8f4f8; padding: 1em;' }, [
E('h3', {}, _('Useful Commands')),
E('pre', { 'style': 'background: white; padding: 1em; border-radius: 4px; overflow-x: auto;' }, [
'# Service control\n',
'/etc/init.d/netifyd start\n',
'/etc/init.d/netifyd stop\n',
'/etc/init.d/netifyd restart\n',
'/etc/init.d/netifyd status\n',
'\n',
'# View logs\n',
'logread | grep netifyd\n',
'\n',
'# Check version\n',
'netifyd --version\n',
'\n',
'# View current flows\n',
'cat /var/run/netifyd/flows.json\n',
'\n',
'# Check process status\n',
'ps | grep netifyd\n',
'top -n 1 | grep netifyd\n',
'\n',
'# Debug mode\n',
'netifyd -d -I br-lan\n'
// Quick Commands
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; margin-bottom: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '💻'),
_('Useful Commands')
]),
E('div', { 'style': 'background: #020617; border-radius: 8px; padding: 1.5em; margin-top: 1.5em; border: 1px solid #1e293b;' }, [
E('pre', {
'style': 'color: #e2e8f0; margin: 0; font-family: monospace; font-size: 0.95em; line-height: 1.8;'
}, [
E('div', { 'style': 'color: #64748b;' }, '# Service control'),
'/etc/init.d/netifyd start\n',
'/etc/init.d/netifyd stop\n',
'/etc/init.d/netifyd restart\n',
'/etc/init.d/netifyd status\n\n',
E('div', { 'style': 'color: #64748b;' }, '# View logs'),
'logread | grep netifyd\n\n',
E('div', { 'style': 'color: #64748b;' }, '# Check version'),
'netifyd --version\n\n',
E('div', { 'style': 'color: #64748b;' }, '# View current flows'),
'cat /var/run/netifyd/flows.json'
])
])
]),
// Integration & API
E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2em;' }, [
E('h3', {}, _('Integration & API')),
E('div', { 'style': 'background: #f8f9fa; padding: 1em; border-radius: 4px;' }, [
E('p', {}, _('Netifyd provides a Unix socket interface for real-time data access:')),
E('ul', { 'style': 'margin: 0.5em 0; padding-left: 2em;' }, [
E('li', {}, [
E('strong', {}, _('Socket:')),
' ',
E('code', {}, '/var/run/netifyd/netifyd.sock')
]),
E('li', {}, [
E('strong', {}, _('Status JSON:')),
' ',
E('code', {}, '/var/run/netifyd/status.json')
]),
E('li', {}, [
E('strong', {}, _('Flows JSON:')),
' ',
E('code', {}, '/var/run/netifyd/flows.json')
// Documentation Section (Collapsed by default)
E('details', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; margin-bottom: 2em; border: 1px solid #334155;' }, [
E('summary', {
'style': 'color: #f1f5f9; font-size: 1.3em; font-weight: bold; cursor: pointer; display: flex; align-items: center; gap: 0.5em; user-select: none;'
}, [
E('span', {}, '📚'),
_('Documentation & Resources')
]),
E('div', { 'style': 'margin-top: 2em;' }, [
// About Netifyd
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin-bottom: 1.5em; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #cbd5e1; margin-top: 0;' }, _('What is Netifyd?')),
E('p', { 'style': 'color: #94a3b8; line-height: 1.6;' },
_('Netifyd is a deep packet inspection (DPI) daemon that classifies network traffic by application protocol and category. It provides real-time insights into network activity without relying on cloud services.')),
E('div', { 'style': 'display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1em; margin-top: 1em;' }, [
E('div', { 'style': 'background: #020617; padding: 1em; border-radius: 6px; border-left: 3px solid #8b5cf6;' }, [
E('div', { 'style': 'color: #8b5cf6; font-weight: bold; margin-bottom: 0.5em;' }, '300+'),
E('div', { 'style': 'color: #94a3b8; font-size: 0.9em;' }, _('Protocol Signatures'))
]),
E('div', { 'style': 'background: #020617; padding: 1em; border-radius: 6px; border-left: 3px solid #3b82f6;' }, [
E('div', { 'style': 'color: #3b82f6; font-weight: bold; margin-bottom: 0.5em;' }, '1000+'),
E('div', { 'style': 'color: #94a3b8; font-size: 0.9em;' }, _('Application Signatures'))
]),
E('div', { 'style': 'background: #020617; padding: 1em; border-radius: 6px; border-left: 3px solid #10b981;' }, [
E('div', { 'style': 'color: #10b981; font-weight: bold; margin-bottom: 0.5em;' }, _('Real-time')),
E('div', { 'style': 'color: #94a3b8; font-size: 0.9em;' }, _('DPI Classification'))
])
])
]),
E('p', { 'style': 'margin-top: 1em;' }, _('This dashboard uses the RPCD backend to parse conntrack data and provide DPI insights.')),
E('p', { 'style': 'margin-top: 0.5em; color: #666; font-size: 0.9em;' },
_('For advanced integrations, consider using netify-fwa (Flow Web API) for RESTful access to flow data.'))
])
]),
// Documentation Links
E('div', { 'class': 'cbi-section', 'style': 'margin-top: 2em;' }, [
E('h3', {}, _('Documentation & Resources')),
E('ul', { 'style': 'margin-top: 0.5em;' }, [
E('li', {}, [
E('a', { 'href': 'https://www.netify.ai/', 'target': '_blank' },
_('Official Netify Website'))
// Configuration Examples
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin-bottom: 1.5em; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #cbd5e1; margin-top: 0;' }, _('Configuration Examples')),
E('div', { 'style': 'margin-bottom: 1.5em;' }, [
E('h4', { 'style': 'color: #8b5cf6; margin: 0.5em 0;' }, _('Monitor Specific Interfaces')),
E('pre', {
'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b; margin: 0.5em 0;'
},
'config netifyd\n' +
' option enabled \'1\'\n' +
' list internal_if \'br-lan\'\n' +
' list internal_if \'wlan0\'\n' +
' list external_if \'eth0\''
)
]),
E('div', { 'style': 'margin-bottom: 1.5em;' }, [
E('h4', { 'style': 'color: #3b82f6; margin: 0.5em 0;' }, _('Advanced DPI Options')),
E('pre', {
'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b; margin: 0.5em 0;'
},
'enable_dpi=yes\n' +
'enable_dns_hint=yes\n' +
'detection_sensitivity=high\n' +
'flow_idle_timeout=300'
)
]),
E('div', {}, [
E('h4', { 'style': 'color: #10b981; margin: 0.5em 0;' }, _('Performance Tuning')),
E('pre', {
'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b; margin: 0.5em 0;'
},
'max_flows=65536\n' +
'thread_pool_size=4\n' +
'flow_hash_size=32768'
),
E('div', { 'style': 'color: #64748b; font-size: 0.9em; margin-top: 0.5em; font-style: italic;' },
_('💡 Reduce values on low-memory devices'))
])
]),
E('li', {}, [
E('a', { 'href': 'https://gitlab.com/netify.ai/public/netify-daemon', 'target': '_blank' },
_('Netifyd GitLab Repository'))
]),
E('li', {}, [
E('a', { 'href': 'https://www.netify.ai/documentation', 'target': '_blank' },
_('Netify Documentation'))
]),
E('li', {}, [
E('a', { 'href': 'https://openwrt.org/packages/pkgdata/netifyd', 'target': '_blank' },
_('OpenWrt Package Info'))
// Resources
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #cbd5e1; margin-top: 0;' }, _('External Resources')),
E('div', { 'style': 'display: grid; gap: 0.75em;' }, [
E('a', {
'href': 'https://www.netify.ai/',
'target': '_blank',
'style': 'color: #8b5cf6; text-decoration: none; display: flex; align-items: center; gap: 0.5em; padding: 0.75em; background: #020617; border-radius: 6px; border: 1px solid #1e293b;'
}, [
E('span', {}, '🔗'),
_('Official Netify Website')
]),
E('a', {
'href': 'https://www.netify.ai/documentation',
'target': '_blank',
'style': 'color: #3b82f6; text-decoration: none; display: flex; align-items: center; gap: 0.5em; padding: 0.75em; background: #020617; border-radius: 6px; border: 1px solid #1e293b;'
}, [
E('span', {}, '📖'),
_('Netify Documentation')
]),
E('a', {
'href': 'https://gitlab.com/netify.ai/public/netify-daemon',
'target': '_blank',
'style': 'color: #06b6d4; text-decoration: none; display: flex; align-items: center; gap: 0.5em; padding: 0.75em; background: #020617; border-radius: 6px; border: 1px solid #1e293b;'
}, [
E('span', {}, '💻'),
_('GitLab Repository')
])
])
])
])
])
]);
return view;
return container;
},
formatUptime: function(seconds) {
@ -252,13 +263,11 @@ return view.extend({
var d = Math.floor(seconds / 86400);
var h = Math.floor((seconds % 86400) / 3600);
var m = Math.floor((seconds % 3600) / 60);
var s = seconds % 60;
var parts = [];
if (d > 0) parts.push(d + 'd');
if (h > 0) parts.push(h + 'h');
if (m > 0) parts.push(m + 'm');
if (s > 0 && parts.length === 0) parts.push(s + 's');
return parts.join(' ') || '0s';
return parts.join(' ') || '< 1m';
},
handleSaveApply: null,

View File

@ -0,0 +1,420 @@
'use strict';
'require view';
'require ui';
'require rpc';
'require secubox-theme/theme as Theme';
'require netifyd-dashboard.api as API';
return view.extend({
currentStep: 1,
totalSteps: 4,
load: function() {
return API.getStatus();
},
render: function(status) {
var self = this;
status = status || {};
var container = E('div', {
'class': 'netifyd-wizard-container',
'style': 'max-width: 900px; margin: 2em auto; padding: 2em;'
}, [
// Header
E('div', { 'style': 'text-align: center; margin-bottom: 3em;' }, [
E('div', {
'style': 'font-size: 3em; margin-bottom: 0.5em;'
}, '🔍'),
E('h1', {
'style': 'font-size: 2.5em; margin: 0.2em 0; background: linear-gradient(135deg, #8b5cf6 0%, #3b82f6 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent;'
}, 'Netifyd Setup Wizard'),
E('p', {
'style': 'color: #94a3b8; font-size: 1.1em; margin-top: 0.5em;'
}, 'Deep Packet Inspection for OpenWrt')
]),
// Progress Bar
this.renderProgressBar(),
// Steps Container
E('div', { 'id': 'wizard-steps', 'style': 'margin-top: 3em;' }, [
this.renderStep1(status),
this.renderStep2(status),
this.renderStep3(status),
this.renderStep4(status)
]),
// Navigation
this.renderNavigation()
]);
return container;
},
renderProgressBar: function() {
var steps = ['Check Status', 'Install', 'Configure', 'Verify'];
return E('div', { 'style': 'display: flex; justify-content: space-between; align-items: center; margin: 2em 0; position: relative;' }, [
E('div', {
'style': 'position: absolute; top: 20px; left: 0; right: 0; height: 2px; background: #1e293b; z-index: 0;'
}),
E('div', {
'id': 'progress-fill',
'style': 'position: absolute; top: 20px; left: 0; height: 2px; background: linear-gradient(90deg, #8b5cf6, #3b82f6); transition: width 0.3s ease; z-index: 1; width: ' + ((this.currentStep - 1) / (this.totalSteps - 1) * 100) + '%;'
}),
steps.map(function(step, index) {
var stepNum = index + 1;
var isActive = stepNum === this.currentStep;
var isComplete = stepNum < this.currentStep;
return E('div', {
'style': 'display: flex; flex-direction: column; align-items: center; z-index: 2; position: relative;'
}, [
E('div', {
'class': 'wizard-step-circle',
'style': 'width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; border: 2px solid ' + (isComplete ? '#8b5cf6' : isActive ? '#3b82f6' : '#1e293b') + '; background: ' + (isComplete ? '#8b5cf6' : isActive ? '#1e293b' : '#0f172a') + '; color: ' + (isComplete || isActive ? 'white' : '#475569') + '; transition: all 0.3s ease;'
}, isComplete ? '✓' : stepNum),
E('div', {
'style': 'margin-top: 0.5em; font-size: 0.9em; color: ' + (isActive ? '#3b82f6' : isComplete ? '#8b5cf6' : '#64748b') + '; font-weight: ' + (isActive ? 'bold' : 'normal') + ';'
}, step)
]);
}.bind(this))
]);
},
renderStep1: function(status) {
return E('div', {
'id': 'step-1',
'class': 'wizard-step',
'style': 'display: ' + (this.currentStep === 1 ? 'block' : 'none') + ';'
}, [
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '✅'),
'Step 1: Check Installation'
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin: 1.5em 0; border: 1px solid #1e293b;' }, [
E('div', { 'style': 'display: flex; justify-content: space-between; align-items: center; margin-bottom: 1em;' }, [
E('span', { 'style': 'color: #cbd5e1; font-size: 1.1em;' }, 'Netifyd Service Status'),
E('span', {
'class': 'badge',
'style': 'padding: 0.5em 1em; border-radius: 6px; font-weight: bold; background: ' + (status.running ? 'linear-gradient(135deg, #10b981, #059669)' : 'linear-gradient(135deg, #ef4444, #dc2626)') + '; color: white;'
}, status.running ? '✓ Running' : '✗ Stopped')
]),
status.version ? E('div', { 'style': 'color: #94a3b8; margin-top: 0.5em;' }, [
'Version: ',
E('code', { 'style': 'color: #8b5cf6; background: #1e293b; padding: 0.25em 0.5em; border-radius: 4px;' }, status.version)
]) : null,
status.running && status.pid ? E('div', { 'style': 'color: #94a3b8; margin-top: 0.5em;' }, [
'Process ID: ',
E('code', { 'style': 'color: #3b82f6; background: #1e293b; padding: 0.25em 0.5em; border-radius: 4px;' }, status.pid)
]) : null
]),
status.running ? E('div', { 'style': 'background: linear-gradient(135deg, #064e3b, #065f46); border-radius: 8px; padding: 1.5em; margin-top: 1.5em; border: 1px solid #10b981;' }, [
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5em; margin-bottom: 0.5em;' }, [
E('span', { 'style': 'font-size: 1.5em;' }, '✓'),
E('strong', { 'style': 'color: #d1fae5; font-size: 1.1em;' }, 'Netifyd is installed and running')
]),
E('p', { 'style': 'color: #a7f3d0; margin: 0.5em 0 0 2em;' }, 'You can proceed to the next step to configure monitoring.')
]) : E('div', { 'style': 'background: linear-gradient(135deg, #7f1d1d, #991b1b); border-radius: 8px; padding: 1.5em; margin-top: 1.5em; border: 1px solid #ef4444;' }, [
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5em; margin-bottom: 0.5em;' }, [
E('span', { 'style': 'font-size: 1.5em;' }, '⚠️'),
E('strong', { 'style': 'color: #fecaca; font-size: 1.1em;' }, 'Netifyd is not installed')
]),
E('p', { 'style': 'color: #fca5a5; margin: 0.5em 0 0 2em;' }, 'Please proceed to Step 2 to install it.')
])
])
]);
},
renderStep2: function(status) {
return E('div', {
'id': 'step-2',
'class': 'wizard-step',
'style': 'display: ' + (this.currentStep === 2 ? 'block' : 'none') + ';'
}, [
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '📦'),
'Step 2: Install Netifyd'
]),
E('p', { 'style': 'color: #cbd5e1; font-size: 1.05em; line-height: 1.6;' },
'Netifyd is a deep packet inspection daemon that provides real-time network intelligence. It detects applications, protocols, and devices on your network.'),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin: 1.5em 0; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '💡'),
'Installation via SSH'
]),
E('p', { 'style': 'color: #94a3b8; margin-bottom: 1em;' }, 'Connect to your router via SSH and run these commands:'),
E('pre', { 'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b;' },
'# Update package lists\n' +
'opkg update\n\n' +
'# Install netifyd\n' +
'opkg install netifyd\n\n' +
'# Enable service at boot\n' +
'/etc/init.d/netifyd enable\n\n' +
'# Start the service\n' +
'/etc/init.d/netifyd start'
)
]),
E('div', { 'style': 'background: linear-gradient(135deg, #1e3a8a, #1e40af); border-radius: 8px; padding: 1.5em; margin-top: 1.5em; border: 1px solid #3b82f6;' }, [
E('div', { 'style': 'display: flex; align-items: flex-start; gap: 0.75em;' }, [
E('span', { 'style': 'font-size: 1.3em; flex-shrink: 0;' }, ''),
E('div', {}, [
E('strong', { 'style': 'color: #dbeafe; font-size: 1.05em;' }, 'System Requirements'),
E('ul', { 'style': 'color: #bfdbfe; margin: 0.5em 0; padding-left: 1.5em;' }, [
E('li', {}, 'OpenWrt 21.02 or later'),
E('li', {}, 'At least 128MB RAM'),
E('li', {}, '~5MB storage space'),
E('li', {}, 'Active network interfaces to monitor')
])
])
])
])
])
]);
},
renderStep3: function(status) {
return E('div', {
'id': 'step-3',
'class': 'wizard-step',
'style': 'display: ' + (this.currentStep === 3 ? 'block' : 'none') + ';'
}, [
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '⚙️'),
'Step 3: Configure Monitoring'
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin: 1.5em 0; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #f1f5f9; margin-top: 0;' }, 'Configure Monitored Interfaces'),
E('p', { 'style': 'color: #94a3b8;' }, 'Edit /etc/config/netifyd to specify which interfaces to monitor:'),
E('pre', { 'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b; margin: 1em 0;' },
'config netifyd\n' +
' option enabled \'1\'\n' +
' list internal_if \'br-lan\' # LAN bridge\n' +
' list internal_if \'wlan0\' # WiFi\n' +
' list external_if \'eth0\' # WAN interface'
),
E('p', { 'style': 'color: #64748b; font-size: 0.95em; font-style: italic;' },
'💡 Tip: Internal interfaces are monitored for client traffic, external for WAN traffic.')
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin: 1.5em 0; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #f1f5f9; margin-top: 0;' }, 'Advanced Configuration (Optional)'),
E('p', { 'style': 'color: #94a3b8;' }, 'Edit /etc/netifyd.conf for advanced DPI options:'),
E('pre', { 'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b; margin: 1em 0;' },
'# Enable deep packet inspection\n' +
'enable_dpi=yes\n\n' +
'# Enable DNS resolution hints\n' +
'enable_dns_hint=yes\n\n' +
'# Detection sensitivity (high, medium, low)\n' +
'detection_sensitivity=high\n\n' +
'# Flow idle timeout in seconds\n' +
'flow_idle_timeout=300'
)
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin: 1.5em 0; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #f1f5f9; margin-top: 0;' }, 'Apply Configuration'),
E('p', { 'style': 'color: #94a3b8;' }, 'After making changes, restart netifyd:'),
E('pre', { 'style': 'background: #020617; color: #e2e8f0; padding: 1em; border-radius: 6px; overflow-x: auto; border: 1px solid #1e293b; margin: 1em 0;' },
'/etc/init.d/netifyd restart'
)
])
])
]);
},
renderStep4: function(status) {
return E('div', {
'id': 'step-4',
'class': 'wizard-step',
'style': 'display: ' + (this.currentStep === 4 ? 'block' : 'none') + ';'
}, [
E('div', { 'style': 'background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%); border-radius: 12px; padding: 2em; border: 1px solid #334155;' }, [
E('h2', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '🎉'),
'Step 4: Verify & Explore'
]),
status.running ? E('div', { 'style': 'background: linear-gradient(135deg, #064e3b, #065f46); border-radius: 8px; padding: 2em; margin: 1.5em 0; border: 1px solid #10b981; text-align: center;' }, [
E('div', { 'style': 'font-size: 4em; margin-bottom: 0.5em;' }, '✓'),
E('h3', { 'style': 'color: #d1fae5; margin: 0.5em 0; font-size: 1.5em;' }, 'Setup Complete!'),
E('p', { 'style': 'color: #a7f3d0; font-size: 1.1em; margin: 1em 0;' },
'Netifyd is running and monitoring your network traffic.'),
E('div', { 'style': 'display: flex; gap: 1em; justify-content: center; flex-wrap: wrap; margin-top: 2em;' }, [
E('div', { 'style': 'background: #0f172a; padding: 1em 1.5em; border-radius: 8px; border: 1px solid #10b981;' }, [
E('div', { 'style': 'font-size: 2em; color: #10b981;' }, status.interfaces ? status.interfaces.length : 0),
E('div', { 'style': 'color: #a7f3d0; font-size: 0.9em; margin-top: 0.25em;' }, 'Interfaces')
]),
status.version ? E('div', { 'style': 'background: #0f172a; padding: 1em 1.5em; border-radius: 8px; border: 1px solid #10b981;' }, [
E('div', { 'style': 'font-size: 2em; color: #10b981;' }, status.version),
E('div', { 'style': 'color: #a7f3d0; font-size: 0.9em; margin-top: 0.25em;' }, 'Version')
]) : null
])
]) : E('div', { 'style': 'background: linear-gradient(135deg, #7f1d1d, #991b1b); border-radius: 8px; padding: 2em; margin: 1.5em 0; border: 1px solid #ef4444; text-align: center;' }, [
E('div', { 'style': 'font-size: 4em; margin-bottom: 0.5em;' }, '⚠️'),
E('h3', { 'style': 'color: #fecaca; margin: 0.5em 0; font-size: 1.5em;' }, 'Service Not Running'),
E('p', { 'style': 'color: #fca5a5; font-size: 1.1em;' },
'Please complete Steps 2 and 3 to install and start Netifyd.')
]),
E('div', { 'style': 'background: #0f172a; border-radius: 8px; padding: 1.5em; margin: 1.5em 0; border: 1px solid #1e293b;' }, [
E('h3', { 'style': 'color: #f1f5f9; margin-top: 0; display: flex; align-items: center; gap: 0.5em;' }, [
E('span', {}, '🚀'),
'Next Steps'
]),
E('ul', { 'style': 'color: #cbd5e1; line-height: 1.8; margin: 1em 0;' }, [
E('li', {}, [
E('strong', { 'style': 'color: #8b5cf6;' }, 'Overview:'),
' Real-time statistics and protocol distribution'
]),
E('li', {}, [
E('strong', { 'style': 'color: #3b82f6;' }, 'Applications:'),
' Detected applications with traffic breakdown'
]),
E('li', {}, [
E('strong', { 'style': 'color: #06b6d4;' }, 'Devices:'),
' Network device discovery and identification'
]),
E('li', {}, [
E('strong', { 'style': 'color: #10b981;' }, 'Flows:'),
' Live connection tracking with DPI data'
]),
E('li', {}, [
E('strong', { 'style': 'color: #f59e0b;' }, 'Top Talkers:'),
' Bandwidth usage by host'
])
])
]),
E('div', { 'style': 'background: linear-gradient(135deg, #1e3a8a, #1e40af); border-radius: 8px; padding: 1.5em; margin-top: 1.5em; border: 1px solid #3b82f6;' }, [
E('h3', { 'style': 'color: #dbeafe; margin-top: 0;' }, '📚 Learn More'),
E('div', { 'style': 'display: grid; gap: 0.75em;' }, [
E('a', {
'href': 'https://www.netify.ai/',
'target': '_blank',
'style': 'color: #93c5fd; text-decoration: none; display: flex; align-items: center; gap: 0.5em;'
}, [
E('span', {}, '🔗'),
'Official Netify Website'
]),
E('a', {
'href': 'https://www.netify.ai/documentation',
'target': '_blank',
'style': 'color: #93c5fd; text-decoration: none; display: flex; align-items: center; gap: 0.5em;'
}, [
E('span', {}, '📖'),
'Netify Documentation'
]),
E('a', {
'href': 'https://gitlab.com/netify.ai/public/netify-daemon',
'target': '_blank',
'style': 'color: #93c5fd; text-decoration: none; display: flex; align-items: center; gap: 0.5em;'
}, [
E('span', {}, '💻'),
'Netifyd GitLab Repository'
])
])
])
])
]);
},
renderNavigation: function() {
var self = this;
return E('div', {
'style': 'display: flex; justify-content: space-between; margin-top: 3em; padding-top: 2em; border-top: 1px solid #334155;'
}, [
E('button', {
'class': 'cbi-button cbi-button-neutral',
'style': 'padding: 0.75em 2em; font-size: 1em; background: #1e293b; border: 1px solid #334155; color: #cbd5e1; border-radius: 6px; cursor: pointer; display: ' + (this.currentStep === 1 ? 'none' : 'block') + ';',
'click': function() {
if (self.currentStep > 1) {
self.currentStep--;
self.updateView();
}
}
}, '← Previous'),
E('div', { 'style': 'flex: 1;' }),
this.currentStep < this.totalSteps ? E('button', {
'class': 'cbi-button cbi-button-action',
'style': 'padding: 0.75em 2em; font-size: 1em; background: linear-gradient(135deg, #8b5cf6, #3b82f6); border: none; color: white; border-radius: 6px; cursor: pointer; font-weight: bold;',
'click': function() {
if (self.currentStep < self.totalSteps) {
self.currentStep++;
self.updateView();
}
}
}, 'Next →') : E('a', {
'href': L.url('admin/secubox/security/netifyd/overview'),
'class': 'cbi-button cbi-button-positive',
'style': 'padding: 0.75em 2em; font-size: 1em; background: linear-gradient(135deg, #10b981, #059669); border: none; color: white; border-radius: 6px; text-decoration: none; font-weight: bold; display: inline-block;'
}, 'Go to Dashboard →')
]);
},
updateView: function() {
// Hide all steps
for (var i = 1; i <= this.totalSteps; i++) {
var step = document.getElementById('step-' + i);
if (step) step.style.display = 'none';
}
// Show current step
var currentStep = document.getElementById('step-' + this.currentStep);
if (currentStep) currentStep.style.display = 'block';
// Update progress bar
var progressFill = document.getElementById('progress-fill');
if (progressFill) {
progressFill.style.width = ((this.currentStep - 1) / (this.totalSteps - 1) * 100) + '%';
}
// Update step circles
var circles = document.querySelectorAll('.wizard-step-circle');
circles.forEach(function(circle, index) {
var stepNum = index + 1;
var isActive = stepNum === this.currentStep;
var isComplete = stepNum < this.currentStep;
circle.style.borderColor = isComplete ? '#8b5cf6' : isActive ? '#3b82f6' : '#1e293b';
circle.style.background = isComplete ? '#8b5cf6' : isActive ? '#1e293b' : '#0f172a';
circle.style.color = isComplete || isActive ? 'white' : '#475569';
circle.textContent = isComplete ? '✓' : stepNum;
}.bind(this));
// Re-render to update navigation buttons
var container = document.querySelector('.netifyd-wizard-container');
if (container) {
var nav = container.querySelector('.netifyd-wizard-container > div:last-child');
if (nav && nav.style.display === 'flex') {
var newNav = this.renderNavigation();
nav.replaceWith(newNav);
}
}
},
handleSaveApply: null,
handleSave: null,
handleReset: null
});

View File

@ -9,6 +9,14 @@
"acl": ["luci-app-netifyd-dashboard"]
}
},
"admin/secubox/security/netifyd/wizard": {
"title": "Setup Wizard",
"order": 5,
"action": {
"type": "view",
"path": "netifyd-dashboard/wizard"
}
},
"admin/secubox/security/netifyd/overview": {
"title": "Overview",
"order": 10,

View File

@ -13,7 +13,8 @@
"risks",
"category_bandwidth",
"top_talkers",
"dns_queries"
"dns_queries",
"seccubox_logs"
],
"system": [ "info", "board" ],
"file": [ "read", "stat" ]

View File

@ -396,15 +396,3 @@ return baseclass.extend({
return callEnableTcpBbr();
}
});
dmz: {
id: 'dmz',
name: 'Router + DMZ',
icon: '🛡️',
description: 'Traditional router with an additional DMZ interface isolated from LAN but allowed to reach WAN.',
features: [
'Dedicated DMZ subnet',
'Separate firewall zone',
'Optional DHCP for DMZ clients',
'Quick rollback timer'
]
},

View File

@ -3,6 +3,7 @@
'require form';
'require ui';
'require uci';
'require network-modes/api as api';
'require network-modes.helpers as helpers';
return view.extend({