fix(multi): Exposure fixes, MagicMirror2 port, Tor Shield health card
Exposure Manager: - Fix RPCD subshell issues in status and ssl_list methods - Fix JS views to handle both array and object API responses MagicMirror2: - Change default port from 8082 to 8085 (avoid CyberFeed conflict) - Update mm2ctl, RPCD, settings.js, dashboard.js, config Tor Shield: - Add restart method to RPCD and API - Add health status minicard (Service, Bootstrap, DNS, Kill Switch) Portal: - Add 'active-ports' section for detected services - Separate portal apps (Services) from detected ports (Active Ports) Service Detection: - Prioritize port-based identification over process name Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7566014096
commit
a1bad31807
@ -14,8 +14,10 @@ return view.extend({
|
||||
|
||||
render: function(data) {
|
||||
var status = data[0] || {};
|
||||
var conflicts = data[1] || [];
|
||||
var conflictsResult = data[1] || {};
|
||||
|
||||
// Handle both direct array and wrapped object responses
|
||||
var conflicts = Array.isArray(conflictsResult) ? conflictsResult : (conflictsResult.conflicts || []);
|
||||
var services = status.services || {};
|
||||
var tor = status.tor || {};
|
||||
var ssl = status.ssl || {};
|
||||
|
||||
@ -13,8 +13,10 @@ return view.extend({
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var services = data[0] || [];
|
||||
var config = data[1] || [];
|
||||
var scanResult = data[0] || {};
|
||||
var configResult = data[1] || {};
|
||||
var services = Array.isArray(scanResult) ? scanResult : (scanResult.services || []);
|
||||
var config = Array.isArray(configResult) ? configResult : (configResult.known_services || []);
|
||||
var self = this;
|
||||
|
||||
// Inject CSS
|
||||
|
||||
@ -13,8 +13,10 @@ return view.extend({
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var sslBackends = data[0] || [];
|
||||
var allServices = data[1] || [];
|
||||
var sslResult = data[0] || {};
|
||||
var scanResult = data[1] || {};
|
||||
var sslBackends = Array.isArray(sslResult) ? sslResult : (sslResult.backends || []);
|
||||
var allServices = Array.isArray(scanResult) ? scanResult : (scanResult.services || []);
|
||||
var self = this;
|
||||
|
||||
// Inject CSS
|
||||
|
||||
@ -13,8 +13,10 @@ return view.extend({
|
||||
},
|
||||
|
||||
render: function(data) {
|
||||
var torServices = data[0] || [];
|
||||
var allServices = data[1] || [];
|
||||
var torResult = data[0] || {};
|
||||
var scanResult = data[1] || {};
|
||||
var torServices = Array.isArray(torResult) ? torResult : (torResult.services || []);
|
||||
var allServices = Array.isArray(scanResult) ? scanResult : (scanResult.services || []);
|
||||
var self = this;
|
||||
|
||||
// Inject CSS
|
||||
|
||||
@ -137,23 +137,32 @@ case "$1" in
|
||||
json_close_array
|
||||
json_close_object
|
||||
|
||||
# HAProxy SSL backends
|
||||
# HAProxy SSL backends - use temp file to avoid subshell
|
||||
HAPROXY_CONFIG="/srv/lxc/haproxy/rootfs/etc/haproxy/haproxy.cfg"
|
||||
ssl_count=0
|
||||
[ -f "$HAPROXY_CONFIG" ] && ssl_count=$(grep -c "^backend.*_backend$" "$HAPROXY_CONFIG" 2>/dev/null || echo 0)
|
||||
|
||||
json_add_object "ssl"
|
||||
json_add_int "count" "$ssl_count"
|
||||
json_add_array "backends"
|
||||
TMP_SSL="/tmp/exposure_ssl_$$"
|
||||
if [ -f "$HAPROXY_CONFIG" ]; then
|
||||
grep -E "^backend .+_backend$" "$HAPROXY_CONFIG" 2>/dev/null | while read line; do
|
||||
backend=$(echo "$line" | awk '{print $2}' | sed 's/_backend$//')
|
||||
domain=$(grep "acl host_${backend} " "$HAPROXY_CONFIG" 2>/dev/null | awk '{print $NF}')
|
||||
echo "$backend ${domain:-N/A}"
|
||||
done > "$TMP_SSL"
|
||||
fi
|
||||
|
||||
json_add_object "ssl"
|
||||
json_add_int "count" "$ssl_count"
|
||||
json_add_array "backends"
|
||||
if [ -f "$TMP_SSL" ]; then
|
||||
while read backend domain; do
|
||||
[ -z "$backend" ] && continue
|
||||
json_add_object ""
|
||||
json_add_string "service" "$backend"
|
||||
json_add_string "domain" "${domain:-N/A}"
|
||||
json_add_string "domain" "$domain"
|
||||
json_close_object
|
||||
done
|
||||
done < "$TMP_SSL"
|
||||
rm -f "$TMP_SSL"
|
||||
fi
|
||||
json_close_array
|
||||
json_close_object
|
||||
@ -195,23 +204,32 @@ case "$1" in
|
||||
|
||||
ssl_list)
|
||||
HAPROXY_CONFIG="/srv/lxc/haproxy/rootfs/etc/haproxy/haproxy.cfg"
|
||||
TMP_SSLLIST="/tmp/exposure_ssllist_$$"
|
||||
|
||||
json_init
|
||||
json_add_array "backends"
|
||||
|
||||
# Extract backend info to temp file to avoid subshell issues
|
||||
if [ -f "$HAPROXY_CONFIG" ]; then
|
||||
grep -E "^backend .+_backend$" "$HAPROXY_CONFIG" 2>/dev/null | while read line; do
|
||||
backend=$(echo "$line" | awk '{print $2}')
|
||||
service=$(echo "$backend" | sed 's/_backend$//')
|
||||
domain=$(grep "acl host_${service} " "$HAPROXY_CONFIG" 2>/dev/null | awk '{print $NF}')
|
||||
server=$(grep -A5 "backend $backend" "$HAPROXY_CONFIG" 2>/dev/null | grep "server " | awk '{print $3}')
|
||||
echo "$service|${domain:-N/A}|${server:-N/A}"
|
||||
done > "$TMP_SSLLIST"
|
||||
fi
|
||||
|
||||
json_init
|
||||
json_add_array "backends"
|
||||
|
||||
if [ -f "$TMP_SSLLIST" ]; then
|
||||
while IFS='|' read service domain server; do
|
||||
[ -z "$service" ] && continue
|
||||
json_add_object ""
|
||||
json_add_string "service" "$service"
|
||||
json_add_string "domain" "${domain:-N/A}"
|
||||
json_add_string "backend" "${server:-N/A}"
|
||||
json_add_string "domain" "$domain"
|
||||
json_add_string "backend" "$server"
|
||||
json_close_object
|
||||
done
|
||||
done < "$TMP_SSLLIST"
|
||||
rm -f "$TMP_SSLLIST"
|
||||
fi
|
||||
|
||||
json_close_array
|
||||
|
||||
@ -126,7 +126,7 @@ return view.extend({
|
||||
]),
|
||||
E('div', { 'class': 'mm2-card' }, [
|
||||
E('div', { 'class': 'mm2-stat' }, [
|
||||
E('div', { 'class': 'mm2-stat-value' }, ':' + (config.port || 8082)),
|
||||
E('div', { 'class': 'mm2-stat-value' }, ':' + (config.port || 8085)),
|
||||
E('div', { 'class': 'mm2-stat-label' }, _('Web Port'))
|
||||
])
|
||||
]),
|
||||
|
||||
@ -67,7 +67,7 @@ return view.extend({
|
||||
|
||||
o = s.option(form.Value, 'port', _('Web Port'));
|
||||
o.datatype = 'port';
|
||||
o.default = '8082';
|
||||
o.default = '8085';
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'address', _('Listen Address'));
|
||||
|
||||
@ -26,7 +26,7 @@ get_status() {
|
||||
fi
|
||||
|
||||
local enabled=$(uci -q get magicmirror2.main.enabled || echo "0")
|
||||
local port=$(uci -q get magicmirror2.main.port || echo "8082")
|
||||
local port=$(uci -q get magicmirror2.main.port || echo "8085")
|
||||
local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1")
|
||||
|
||||
[ "$running" = "1" ] && web_url="http://${router_ip}:${port}"
|
||||
@ -54,7 +54,7 @@ EOF
|
||||
# Get main configuration
|
||||
get_config() {
|
||||
local enabled=$(uci -q get magicmirror2.main.enabled || echo "0")
|
||||
local port=$(uci -q get magicmirror2.main.port || echo "8082")
|
||||
local port=$(uci -q get magicmirror2.main.port || echo "8085")
|
||||
local address=$(uci -q get magicmirror2.main.address || echo "0.0.0.0")
|
||||
local data_path=$(uci -q get magicmirror2.main.data_path || echo "/srv/magicmirror2")
|
||||
local memory_limit=$(uci -q get magicmirror2.main.memory_limit || echo "512M")
|
||||
@ -327,7 +327,7 @@ set_config() {
|
||||
# Get web URL for iframe
|
||||
get_web_url() {
|
||||
local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1")
|
||||
local port=$(uci -q get magicmirror2.main.port || echo "8082")
|
||||
local port=$(uci -q get magicmirror2.main.port || echo "8085")
|
||||
|
||||
cat <<EOF
|
||||
{
|
||||
|
||||
@ -440,6 +440,13 @@ return baseclass.extend({
|
||||
icon: '\ud83d\udce6',
|
||||
path: 'admin/secubox/services',
|
||||
order: 8
|
||||
},
|
||||
'active-ports': {
|
||||
id: 'active-ports',
|
||||
name: 'Active Ports',
|
||||
icon: '\ud83d\udd0c',
|
||||
path: 'admin/secubox/services',
|
||||
order: 9
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -156,7 +156,8 @@ return view.extend({
|
||||
this.renderNetworkSection(),
|
||||
this.renderMonitoringSection(),
|
||||
this.renderSystemSection(),
|
||||
this.renderServicesSection()
|
||||
this.renderServicesAppsSection(),
|
||||
this.renderActivePortsSection()
|
||||
])
|
||||
]);
|
||||
|
||||
@ -171,7 +172,7 @@ return view.extend({
|
||||
var sections = portal.getSections();
|
||||
// Sections that link to other pages vs tabs within portal
|
||||
var linkSections = ['portal', 'hub', 'admin'];
|
||||
var tabSections = ['security', 'network', 'monitoring', 'system', 'services'];
|
||||
var tabSections = ['security', 'network', 'monitoring', 'system', 'services', 'active-ports'];
|
||||
|
||||
return E('div', { 'class': 'sb-portal-header' }, [
|
||||
// Brand
|
||||
@ -443,7 +444,13 @@ return view.extend({
|
||||
'System administration and configuration tools', apps);
|
||||
},
|
||||
|
||||
renderServicesSection: function() {
|
||||
renderServicesAppsSection: function() {
|
||||
var apps = portal.getInstalledAppsBySection('services', this.installedApps);
|
||||
return this.renderAppSection('services', 'Services',
|
||||
'Application services running on your network', apps);
|
||||
},
|
||||
|
||||
renderActivePortsSection: function() {
|
||||
var self = this;
|
||||
var services = this.detectedServices || [];
|
||||
|
||||
@ -514,9 +521,9 @@ return view.extend({
|
||||
});
|
||||
|
||||
if (serviceCards.length === 0) {
|
||||
return E('div', { 'class': 'sb-portal-section', 'data-section': 'services' }, [
|
||||
return E('div', { 'class': 'sb-portal-section', 'data-section': 'active-ports' }, [
|
||||
E('div', { 'class': 'sb-section-header' }, [
|
||||
E('h2', { 'class': 'sb-section-title' }, '🔌 Active Services'),
|
||||
E('h2', { 'class': 'sb-section-title' }, '🔌 Active Ports'),
|
||||
E('p', { 'class': 'sb-section-subtitle' }, 'Detected services listening on network ports')
|
||||
]),
|
||||
E('div', { 'class': 'sb-section-empty' }, [
|
||||
@ -527,9 +534,9 @@ return view.extend({
|
||||
]);
|
||||
}
|
||||
|
||||
return E('div', { 'class': 'sb-portal-section', 'data-section': 'services' }, [
|
||||
return E('div', { 'class': 'sb-portal-section', 'data-section': 'active-ports' }, [
|
||||
E('div', { 'class': 'sb-section-header' }, [
|
||||
E('h2', { 'class': 'sb-section-title' }, '🔌 Active Services'),
|
||||
E('h2', { 'class': 'sb-section-title' }, '🔌 Active Ports'),
|
||||
E('p', { 'class': 'sb-section-subtitle' }, 'Detected services listening on network ports')
|
||||
]),
|
||||
E('div', { 'class': 'sb-app-grid' }, serviceCards)
|
||||
|
||||
@ -27,6 +27,12 @@ var callDisable = rpc.declare({
|
||||
expect: { success: false }
|
||||
});
|
||||
|
||||
var callRestart = rpc.declare({
|
||||
object: 'luci.tor-shield',
|
||||
method: 'restart',
|
||||
expect: { success: false }
|
||||
});
|
||||
|
||||
var callCircuits = rpc.declare({
|
||||
object: 'luci.tor-shield',
|
||||
method: 'circuits',
|
||||
@ -161,6 +167,7 @@ return baseclass.extend({
|
||||
getStatus: callStatus,
|
||||
enable: callEnable,
|
||||
disable: callDisable,
|
||||
restart: callRestart,
|
||||
getCircuits: callCircuits,
|
||||
newIdentity: callNewIdentity,
|
||||
checkLeaks: callCheckLeaks,
|
||||
|
||||
@ -87,6 +87,27 @@ return view.extend({
|
||||
});
|
||||
},
|
||||
|
||||
// Handle restart
|
||||
handleRestart: function() {
|
||||
var self = this;
|
||||
|
||||
ui.showModal(_('Restart Tor Shield'), [
|
||||
E('p', { 'class': 'spinning' }, _('Restarting Tor Shield service...'))
|
||||
]);
|
||||
|
||||
api.restart().then(function(result) {
|
||||
ui.hideModal();
|
||||
if (result.success) {
|
||||
ui.addNotification(null, E('p', _('Tor Shield is restarting. Please wait for bootstrap to complete.')), 'info');
|
||||
} else {
|
||||
ui.addNotification(null, E('p', result.error || _('Failed to restart')), 'error');
|
||||
}
|
||||
}).catch(function(err) {
|
||||
ui.hideModal();
|
||||
ui.addNotification(null, E('p', _('Error: %s').format(err.message || err)), 'error');
|
||||
});
|
||||
},
|
||||
|
||||
// Handle leak test
|
||||
handleLeakTest: function() {
|
||||
var self = this;
|
||||
@ -373,6 +394,54 @@ return view.extend({
|
||||
])
|
||||
]),
|
||||
|
||||
// Health Status Minicard
|
||||
E('div', { 'class': 'tor-health-card', 'style': 'display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-bottom: 20px;' }, [
|
||||
E('div', { 'class': 'tor-health-item', 'style': 'display: flex; align-items: center; gap: 12px; padding: 16px; background: var(--tor-bg-card, #1a1a24); border-radius: 12px; border: 1px solid rgba(255,255,255,0.05);' }, [
|
||||
E('div', {
|
||||
'class': 'tor-health-indicator',
|
||||
'style': 'width: 12px; height: 12px; border-radius: 50%; background: ' + (isProtected ? '#10b981' : isConnecting ? '#f59e0b' : '#6b7280') + '; box-shadow: 0 0 8px ' + (isProtected ? '#10b981' : isConnecting ? '#f59e0b' : 'transparent') + ';'
|
||||
}),
|
||||
E('div', {}, [
|
||||
E('div', { 'style': 'font-size: 14px; font-weight: 600; color: var(--tor-text, #fff);' }, _('Service')),
|
||||
E('div', { 'style': 'font-size: 12px; color: var(--tor-text-muted, #a0a0b0);' },
|
||||
status.running ? _('Running') : _('Stopped'))
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'tor-health-item', 'style': 'display: flex; align-items: center; gap: 12px; padding: 16px; background: var(--tor-bg-card, #1a1a24); border-radius: 12px; border: 1px solid rgba(255,255,255,0.05);' }, [
|
||||
E('div', {
|
||||
'class': 'tor-health-indicator',
|
||||
'style': 'width: 12px; height: 12px; border-radius: 50%; background: ' + (status.bootstrap >= 100 ? '#10b981' : status.bootstrap > 0 ? '#f59e0b' : '#6b7280') + '; box-shadow: 0 0 8px ' + (status.bootstrap >= 100 ? '#10b981' : status.bootstrap > 0 ? '#f59e0b' : 'transparent') + ';'
|
||||
}),
|
||||
E('div', {}, [
|
||||
E('div', { 'style': 'font-size: 14px; font-weight: 600; color: var(--tor-text, #fff);' }, _('Bootstrap')),
|
||||
E('div', { 'style': 'font-size: 12px; color: var(--tor-text-muted, #a0a0b0);' },
|
||||
status.bootstrap >= 100 ? _('Complete') : status.bootstrap + '%')
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'tor-health-item', 'style': 'display: flex; align-items: center; gap: 12px; padding: 16px; background: var(--tor-bg-card, #1a1a24); border-radius: 12px; border: 1px solid rgba(255,255,255,0.05);' }, [
|
||||
E('div', {
|
||||
'class': 'tor-health-indicator',
|
||||
'style': 'width: 12px; height: 12px; border-radius: 50%; background: ' + (status.dns_over_tor ? '#10b981' : '#f59e0b') + '; box-shadow: 0 0 8px ' + (status.dns_over_tor ? '#10b981' : '#f59e0b') + ';'
|
||||
}),
|
||||
E('div', {}, [
|
||||
E('div', { 'style': 'font-size: 14px; font-weight: 600; color: var(--tor-text, #fff);' }, _('DNS')),
|
||||
E('div', { 'style': 'font-size: 12px; color: var(--tor-text-muted, #a0a0b0);' },
|
||||
status.dns_over_tor ? _('Protected') : _('Exposed'))
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'tor-health-item', 'style': 'display: flex; align-items: center; gap: 12px; padding: 16px; background: var(--tor-bg-card, #1a1a24); border-radius: 12px; border: 1px solid rgba(255,255,255,0.05);' }, [
|
||||
E('div', {
|
||||
'class': 'tor-health-indicator',
|
||||
'style': 'width: 12px; height: 12px; border-radius: 50%; background: ' + (status.kill_switch ? '#10b981' : '#6b7280') + '; box-shadow: 0 0 8px ' + (status.kill_switch ? '#10b981' : 'transparent') + ';'
|
||||
}),
|
||||
E('div', {}, [
|
||||
E('div', { 'style': 'font-size: 14px; font-weight: 600; color: var(--tor-text, #fff);' }, _('Kill Switch')),
|
||||
E('div', { 'style': 'font-size: 12px; color: var(--tor-text-muted, #a0a0b0);' },
|
||||
status.kill_switch ? _('Active') : _('Disabled'))
|
||||
])
|
||||
])
|
||||
]),
|
||||
|
||||
// Actions Card
|
||||
E('div', { 'class': 'tor-card' }, [
|
||||
E('div', { 'class': 'tor-card-header' }, [
|
||||
@ -393,6 +462,11 @@ return view.extend({
|
||||
'click': L.bind(this.handleLeakTest, this),
|
||||
'disabled': !isActive
|
||||
}, ['\uD83D\uDD0D ', _('Leak Test')]),
|
||||
E('button', {
|
||||
'class': 'tor-btn tor-btn-warning',
|
||||
'click': L.bind(this.handleRestart, this),
|
||||
'disabled': !status.enabled
|
||||
}, ['\u21BB ', _('Restart')]),
|
||||
E('a', {
|
||||
'class': 'tor-btn',
|
||||
'href': L.url('admin', 'services', 'tor-shield', 'circuits')
|
||||
|
||||
@ -707,9 +707,21 @@ save_settings() {
|
||||
}
|
||||
|
||||
# Main dispatcher
|
||||
# Restart Tor Shield service
|
||||
do_restart() {
|
||||
json_init
|
||||
|
||||
/etc/init.d/tor-shield restart >/dev/null 2>&1 &
|
||||
|
||||
json_add_boolean "success" 1
|
||||
json_add_string "message" "Tor Shield restarting"
|
||||
|
||||
json_dump
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
list)
|
||||
echo '{"status":{},"enable":{"preset":"str"},"disable":{},"circuits":{},"new_identity":{},"check_leaks":{},"hidden_services":{},"add_hidden_service":{"name":"str","local_port":"int","virtual_port":"int"},"remove_hidden_service":{"name":"str"},"exit_ip":{},"bandwidth":{},"presets":{},"bridges":{},"set_bridges":{"enabled":"bool","type":"str"},"settings":{},"save_settings":{"mode":"str","dns_over_tor":"bool","kill_switch":"bool","socks_port":"int","trans_port":"int","dns_port":"int","exit_nodes":"str","exclude_exit_nodes":"str","strict_nodes":"bool"}}'
|
||||
echo '{"status":{},"enable":{"preset":"str"},"disable":{},"restart":{},"circuits":{},"new_identity":{},"check_leaks":{},"hidden_services":{},"add_hidden_service":{"name":"str","local_port":"int","virtual_port":"int"},"remove_hidden_service":{"name":"str"},"exit_ip":{},"bandwidth":{},"presets":{},"bridges":{},"set_bridges":{"enabled":"bool","type":"str"},"settings":{},"save_settings":{"mode":"str","dns_over_tor":"bool","kill_switch":"bool","socks_port":"int","trans_port":"int","dns_port":"int","exit_nodes":"str","exclude_exit_nodes":"str","strict_nodes":"bool"}}'
|
||||
;;
|
||||
call)
|
||||
case "$2" in
|
||||
@ -722,6 +734,9 @@ case "$1" in
|
||||
disable)
|
||||
do_disable
|
||||
;;
|
||||
restart)
|
||||
do_restart
|
||||
;;
|
||||
circuits)
|
||||
get_circuits
|
||||
;;
|
||||
|
||||
@ -60,7 +60,7 @@ define Package/secubox-app-magicmirror2/postinst
|
||||
echo " mm2ctl install"
|
||||
echo " /etc/init.d/magicmirror2 start"
|
||||
echo ""
|
||||
echo "Web interface: http://<router-ip>:8082"
|
||||
echo "Web interface: http://<router-ip>:8085"
|
||||
echo ""
|
||||
echo "To manage modules:"
|
||||
echo " mm2ctl module list"
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
config magicmirror2 'main'
|
||||
option enabled '0'
|
||||
option port '8082'
|
||||
option port '8085'
|
||||
option address '0.0.0.0'
|
||||
option data_path '/srv/magicmirror2'
|
||||
option memory_limit '512M'
|
||||
|
||||
@ -51,7 +51,7 @@ Examples:
|
||||
mm2ctl module list
|
||||
mm2ctl config
|
||||
|
||||
Web Interface: http://<router-ip>:8082
|
||||
Web Interface: http://<router-ip>:8085
|
||||
EOF
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ uci_set() { uci set ${CONFIG}.$1="$2" && uci commit ${CONFIG}; }
|
||||
|
||||
# Load configuration with defaults
|
||||
load_config() {
|
||||
port="$(uci_get main.port || echo 8082)"
|
||||
port="$(uci_get main.port || echo 8085)"
|
||||
address="$(uci_get main.address || echo 0.0.0.0)"
|
||||
data_path="$(uci_get main.data_path || echo /srv/magicmirror2)"
|
||||
memory_limit="$(uci_get main.memory_limit || echo 512M)"
|
||||
@ -255,7 +255,7 @@ lxc_create_docker_rootfs() {
|
||||
cat >> "$rootfs/opt/start-mm2.sh" << 'START'
|
||||
export PATH="/usr/local/bin:/usr/bin:/bin:$PATH"
|
||||
export NODE_ENV=production
|
||||
export MM_PORT="${MM2_PORT:-8082}"
|
||||
export MM_PORT="${MM2_PORT:-8085}"
|
||||
export MM_ADDRESS="${MM2_ADDRESS:-0.0.0.0}"
|
||||
|
||||
MM_DIR="/opt/magic_mirror"
|
||||
|
||||
@ -1200,40 +1200,19 @@ case "$1" in
|
||||
addr=$(echo "$local" | sed 's/:[^:]*$//')
|
||||
name=""; icon=""; category="other"; path=""
|
||||
|
||||
# First: identify by process name (most accurate)
|
||||
case "$proc" in
|
||||
sshd|dropbear) name="SSH"; icon="lock"; category="system" ;;
|
||||
dnsmasq|named|unbound) name="DNS"; icon="globe"; category="system" ;;
|
||||
haproxy) name="HAProxy"; icon="arrow"; category="proxy" ;;
|
||||
nginx|uhttpd) name="Web Server"; icon="settings"; category="system" ;;
|
||||
gitea) name="Gitea"; icon="git"; path=":$port"; category="app" ;;
|
||||
hexo|node) [ "$port" = "4000" ] && { name="HexoJS"; icon="blog"; path=":$port"; category="app"; } ;;
|
||||
crowdsec|lapi) name="CrowdSec"; icon="security"; category="security" ;;
|
||||
netifyd) name="Netifyd"; icon="chart"; path=":$port"; category="monitoring" ;;
|
||||
streamlit|python*)
|
||||
[ "$port" = "8501" ] && { name="Streamlit"; icon="app"; path=":$port"; category="app"; }
|
||||
;;
|
||||
slimserver|squeezeboxserver) name="Lyrion"; icon="music"; path=":$port"; category="media" ;;
|
||||
tor) name="Tor"; icon="onion"; category="privacy" ;;
|
||||
cyberfeed*) name="CyberFeed"; icon="feed"; path=":$port"; category="app" ;;
|
||||
metabolizer*) name="Metabolizer"; icon="blog"; path=":$port"; category="app" ;;
|
||||
magicmirror*|electron) name="MagicMirror"; icon="app"; path=":$port"; category="app" ;;
|
||||
picobrew*) name="PicoBrew"; icon="app"; path=":$port"; category="app" ;;
|
||||
esac
|
||||
|
||||
# Fallback: identify by port number if process didn't match
|
||||
if [ -z "$name" ]; then
|
||||
# First: identify by well-known port (most reliable for multi-service ports)
|
||||
case "$port" in
|
||||
22) name="SSH"; icon="lock"; category="system" ;;
|
||||
53) name="DNS"; icon="globe"; category="system" ;;
|
||||
80) name="HTTP"; icon="arrow"; path="/"; category="proxy" ;;
|
||||
443) name="HTTPS"; icon="shield"; path="/"; category="proxy" ;;
|
||||
2222) name="Gitea SSH"; icon="git"; category="app" ;;
|
||||
3000) name="Gitea"; icon="git"; path=":3000"; category="app" ;;
|
||||
3483) name="Squeezebox"; icon="music"; category="media" ;;
|
||||
4000) name="HexoJS"; icon="blog"; path=":4000"; category="app" ;;
|
||||
6060) name="CrowdSec LAPI"; icon="security"; category="security" ;;
|
||||
8080) name="Web App"; icon="app"; path=":8080"; category="app" ;;
|
||||
8081) name="LuCI"; icon="settings"; path=":8081"; category="system" ;;
|
||||
8082) name="CyberFeed"; icon="feed"; path=":8082"; category="app" ;;
|
||||
8085) name="MagicMirror2"; icon="app"; path=":8085"; category="app" ;;
|
||||
8086) name="Netifyd"; icon="chart"; path=":8086"; category="monitoring" ;;
|
||||
8404) name="HAProxy Stats"; icon="stats"; path=":8404/stats"; category="monitoring" ;;
|
||||
8444) name="LuCI HTTPS"; icon="admin"; path=":8444"; category="system" ;;
|
||||
@ -1241,8 +1220,27 @@ case "$1" in
|
||||
9000) name="Lyrion"; icon="music"; path=":9000"; category="media" ;;
|
||||
9050) name="Tor SOCKS"; icon="onion"; category="privacy" ;;
|
||||
9090) name="Lyrion CLI"; icon="music"; category="media" ;;
|
||||
2222) name="Gitea SSH"; icon="git"; category="app" ;;
|
||||
3483) name="Squeezebox"; icon="music"; category="media" ;;
|
||||
esac
|
||||
|
||||
# Fallback: identify by process name if port didn't match
|
||||
if [ -z "$name" ]; then
|
||||
case "$proc" in
|
||||
sshd|dropbear) name="SSH"; icon="lock"; category="system" ;;
|
||||
dnsmasq|named|unbound) name="DNS"; icon="globe"; category="system" ;;
|
||||
haproxy) name="HAProxy"; icon="arrow"; category="proxy" ;;
|
||||
nginx|uhttpd) name="Web Server"; icon="settings"; category="system" ;;
|
||||
gitea) name="Gitea"; icon="git"; path=":$port"; category="app" ;;
|
||||
hexo|node) name="HexoJS"; icon="blog"; path=":$port"; category="app" ;;
|
||||
crowdsec|lapi) name="CrowdSec"; icon="security"; category="security" ;;
|
||||
netifyd) name="Netifyd"; icon="chart"; path=":$port"; category="monitoring" ;;
|
||||
slimserver|squeezeboxserver) name="Lyrion"; icon="music"; path=":$port"; category="media" ;;
|
||||
tor) name="Tor"; icon="onion"; category="privacy" ;;
|
||||
cyberfeed*) name="CyberFeed"; icon="feed"; path=":$port"; category="app" ;;
|
||||
metabolizer*) name="Metabolizer"; icon="blog"; path=":$port"; category="app" ;;
|
||||
magicmirror*|electron) name="MagicMirror"; icon="app"; path=":$port"; category="app" ;;
|
||||
picobrew*) name="PicoBrew"; icon="app"; path=":$port"; category="app" ;;
|
||||
streamlit) name="Streamlit"; icon="app"; path=":$port"; category="app" ;;
|
||||
python*) name="Python App"; icon="app"; path=":$port"; category="app" ;;
|
||||
*) name="$proc"; icon=""; category="other"; path=":$port" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
Loading…
Reference in New Issue
Block a user