Skip to content

Commit 2eb3517

Browse files
committed
feat: expand addon configuration options
Added 15 new configurable options with sensible defaults: Settings: - no_2fa: Disable two-factor authentication requirement - max_invalid_login_count/time: Brute-force login protection policy - allow_high_quality_desktop: Control remote desktop image quality cap - agent_port: Optional dedicated agent-only HTTPS port - allow_framing: Allow embedding MeshCentral in an iframe Domain / UI: - site_style: Login page style (1 or 2) - welcome_text: Custom text shown on the login screen - new_accounts_pass: Password required to create a new account - guest_device_sharing: Enable/disable guest desktop sharing links - auto_remove_inactive_devices: Auto-remove devices inactive N days Backup: - backup_interval_hours: How often automatic backups run (default 24h) - backup_keep_days: How many days of backups to retain (default 10) - backup_zip_password: Optional password for backup ZIP archives run.sh updated to handle all new options. All new options have defaults that work out of the box.
1 parent 1951142 commit 2eb3517

2 files changed

Lines changed: 118 additions & 39 deletions

File tree

meshcentral/config.yaml

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,76 @@
2020
},
2121
"options": {
2222
"server_mode": "lan",
23+
"cert_url": "",
2324
"new_accounts": true,
25+
"new_accounts_pass": "",
2426
"domain_title": "MeshCentral",
27+
"domain_title2": "",
28+
"site_style": 2,
29+
"welcome_text": "",
2530
"session_time": 60,
2631
"tls_offload": false,
32+
"trusted_proxy": "",
2733
"web_rtc": false,
28-
"compression": false,
34+
"compression": true,
35+
"allow_high_quality_desktop": true,
2936
"self_update": false,
3037
"maintenance_mode": false,
31-
"smtp_enabled": false
38+
"no_2fa": false,
39+
"max_invalid_login_count": 10,
40+
"max_invalid_login_time": 10,
41+
"auto_remove_inactive_devices": 0,
42+
"guest_device_sharing": true,
43+
"allow_framing": false,
44+
"user_allowed_ip": "",
45+
"user_blocked_ip": "",
46+
"agent_allowed_ip": "",
47+
"agent_blocked_ip": "",
48+
"agent_port": 0,
49+
"mps_port": 4433,
50+
"backup_interval_hours": 24,
51+
"backup_keep_days": 10,
52+
"backup_zip_password": "",
53+
"smtp_enabled": false,
54+
"smtp_host": "",
55+
"smtp_port": 587,
56+
"smtp_from": "",
57+
"smtp_user": "",
58+
"smtp_pass": "",
59+
"smtp_tls": true
3260
},
3361
"schema": {
3462
"server_mode": "list(lan|wan|hybrid)",
63+
"cert_url": "str?",
3564
"new_accounts": "bool",
65+
"new_accounts_pass": "str?",
3666
"domain_title": "str",
3767
"domain_title2": "str?",
38-
"hostname": "str?",
39-
"cert_url": "str?",
40-
"session_key": "password?",
68+
"site_style": "list(1|2)",
69+
"welcome_text": "str?",
4170
"session_time": "int",
4271
"tls_offload": "bool",
4372
"trusted_proxy": "str?",
44-
"user_allowed_ip": "str?",
45-
"user_blocked_ip": "str?",
46-
"agent_allowed_ip": "str?",
47-
"agent_blocked_ip": "str?",
4873
"web_rtc": "bool",
4974
"compression": "bool",
75+
"allow_high_quality_desktop": "bool",
5076
"self_update": "bool",
5177
"maintenance_mode": "bool",
78+
"no_2fa": "bool",
79+
"max_invalid_login_count": "int",
80+
"max_invalid_login_time": "int",
81+
"auto_remove_inactive_devices": "int",
82+
"guest_device_sharing": "bool",
83+
"allow_framing": "bool",
84+
"user_allowed_ip": "str?",
85+
"user_blocked_ip": "str?",
86+
"agent_allowed_ip": "str?",
87+
"agent_blocked_ip": "str?",
88+
"agent_port": "int",
89+
"mps_port": "int",
90+
"backup_interval_hours": "int",
91+
"backup_keep_days": "int",
92+
"backup_zip_password": "password?",
5293
"smtp_enabled": "bool",
5394
"smtp_host": "str?",
5495
"smtp_port": "int?",

meshcentral/run.sh

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
#!/usr/bin/with-contenv bashio
22

3-
# Read required options
3+
# ── Read options ──────────────────────────────────────────────────────────────
44
SERVER_MODE=$(bashio::config 'server_mode')
55
NEW_ACCOUNTS=$(bashio::config 'new_accounts')
66
DOMAIN_TITLE=$(bashio::config 'domain_title')
77
SESSION_TIME=$(bashio::config 'session_time')
88
TLS_OFFLOAD=$(bashio::config 'tls_offload')
99
WEB_RTC=$(bashio::config 'web_rtc')
1010
COMPRESSION=$(bashio::config 'compression')
11+
ALLOW_HQ_DESKTOP=$(bashio::config 'allow_high_quality_desktop')
1112
SELF_UPDATE=$(bashio::config 'self_update')
1213
MAINTENANCE=$(bashio::config 'maintenance_mode')
14+
NO_2FA=$(bashio::config 'no_2fa')
15+
SITE_STYLE=$(bashio::config 'site_style')
16+
GUEST_SHARING=$(bashio::config 'guest_device_sharing')
17+
ALLOW_FRAMING=$(bashio::config 'allow_framing')
18+
LOGIN_COUNT=$(bashio::config 'max_invalid_login_count')
19+
LOGIN_TIME=$(bashio::config 'max_invalid_login_time')
20+
AUTO_REMOVE=$(bashio::config 'auto_remove_inactive_devices')
21+
AGENT_PORT=$(bashio::config 'agent_port')
22+
MPS_PORT=$(bashio::config 'mps_port')
23+
BACKUP_INTERVAL=$(bashio::config 'backup_interval_hours')
24+
BACKUP_KEEP=$(bashio::config 'backup_keep_days')
1325
SMTP_ENABLED=$(bashio::config 'smtp_enabled')
1426

15-
# Data path — fixed location inside HA addon data
27+
# ── Paths ─────────────────────────────────────────────────────────────────────
1628
DATA_PATH="/data/meshcentral-data"
1729
FILES_PATH="${DATA_PATH}/meshcentral-files"
1830
BACKUP_PATH="/data/meshcentral-backups"
1931
RECORDINGS_PATH="${DATA_PATH}/meshcentral-recordings"
2032
CONFIG_FILE="${DATA_PATH}/config.json"
2133

22-
# Use HA hostname as fallback
34+
# ── Hostname ──────────────────────────────────────────────────────────────────
2335
HOSTNAME=$(bashio::info.hostname)
2436
if bashio::config.has_value 'hostname'; then
2537
HOSTNAME=$(bashio::config 'hostname')
@@ -31,16 +43,14 @@ bashio::log.info "Hostname: ${HOSTNAME}"
3143

3244
mkdir -p "${DATA_PATH}" "${FILES_PATH}" "${BACKUP_PATH}" "${RECORDINGS_PATH}"
3345

34-
# Remove old certs on every start so MeshCentral regenerates them with current config
35-
# This ensures the cert CN always matches the current IP/hostname
46+
# ── Remove old certs so MeshCentral regenerates with current config ───────────
3647
MESHDATA="${DATA_PATH}/meshcentral-data"
3748
if [ -d "$MESHDATA" ]; then
3849
rm -f "$MESHDATA"/*.crt "$MESHDATA"/*.key 2>/dev/null || true
3950
bashio::log.info "Old certificates removed — will be regenerated with current settings."
4051
fi
4152

4253
# ── Build settings ────────────────────────────────────────────────────────────
43-
4454
SETTINGS="{}"
4555

4656
# Network mode
@@ -49,14 +59,18 @@ if [ "$SERVER_MODE" = "wan" ]; then
4959
elif [ "$SERVER_MODE" = "lan" ]; then
5060
SETTINGS=$(echo "$SETTINGS" | jq '. + {LANonly: true}')
5161
fi
52-
# hybrid: neither flag set — MeshCentral default behaviour
5362

54-
# Ports — MeshCentral listens directly on external ports to avoid origin mismatch
55-
SETTINGS=$(echo "$SETTINGS" | jq '. + {port: 4430, redirPort: 4431, mpsPort: 4433}')
63+
# Ports
64+
SETTINGS=$(echo "$SETTINGS" | jq \
65+
--argjson mps "$MPS_PORT" \
66+
'. + {port: 4430, redirPort: 4431, mpsPort: $mps}')
67+
68+
# Optional dedicated agent port
69+
if [ "$AGENT_PORT" -gt 0 ] 2>/dev/null; then
70+
SETTINGS=$(echo "$SETTINGS" | jq --argjson v "$AGENT_PORT" '. + {agentPort: $v}')
71+
fi
5672

57-
# Cert — determines what hostname MeshCentral uses for its certificate
58-
# and origin validation. Use cert_url if set (external), otherwise
59-
# homeassistant.local which works on any local network without knowing IP.
73+
# Cert / hostname
6074
if bashio::config.has_value 'cert_url'; then
6175
CERT_HOST=$(bashio::config 'cert_url' | sed 's|https://||' | sed 's|http://||' | sed 's|/.*||')
6276
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$CERT_HOST" '. + {cert: $v}')
@@ -67,28 +81,38 @@ SETTINGS=$(echo "$SETTINGS" | jq --argjson v "$TLS_OFFLOAD" '. + {tlsOffload: $v
6781

6882
# Trusted proxy (optional)
6983
if bashio::config.has_value 'trusted_proxy'; then
70-
TRUSTED_PROXY=$(bashio::config 'trusted_proxy')
71-
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$TRUSTED_PROXY" '. + {trustedProxy: $v}')
84+
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$(bashio::config 'trusted_proxy')" '. + {trustedProxy: $v}')
7285
fi
7386

7487
# Session
7588
SETTINGS=$(echo "$SETTINGS" | jq --argjson v "$SESSION_TIME" '. + {sessionTime: $v}')
7689
if bashio::config.has_value 'session_key'; then
77-
SESSION_KEY=$(bashio::config 'session_key')
78-
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$SESSION_KEY" '. + {sessionKey: $v}')
90+
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$(bashio::config 'session_key')" '. + {sessionKey: $v}')
7991
fi
8092

8193
# Features
8294
SETTINGS=$(echo "$SETTINGS" | jq \
83-
--argjson rtc "$WEB_RTC" \
95+
--argjson rtc "$WEB_RTC" \
8496
--argjson comp "$COMPRESSION" \
85-
--argjson upd "$SELF_UPDATE" \
86-
'. + {webRTC: $rtc, compression: $comp, selfUpdate: $upd}')
97+
--argjson hq "$ALLOW_HQ_DESKTOP" \
98+
--argjson upd "$SELF_UPDATE" \
99+
--argjson fr "$ALLOW_FRAMING" \
100+
'. + {webRTC: $rtc, compression: $comp, allowHighQualityDesktop: $hq, selfUpdate: $upd, allowFraming: $fr}')
87101

88102
if [ "$MAINTENANCE" = "true" ]; then
89103
SETTINGS=$(echo "$SETTINGS" | jq '. + {maintenanceMode: true}')
90104
fi
91105

106+
if [ "$NO_2FA" = "true" ]; then
107+
SETTINGS=$(echo "$SETTINGS" | jq '. + {no2FactorAuth: true}')
108+
fi
109+
110+
# Invalid login rate limiting
111+
SETTINGS=$(echo "$SETTINGS" | jq \
112+
--argjson cnt "$LOGIN_COUNT" \
113+
--argjson tim "$LOGIN_TIME" \
114+
'. + {maxInvalidLogin: {count: $cnt, time: $tim}}')
115+
92116
# IP access control (all optional)
93117
if bashio::config.has_value 'user_allowed_ip'; then
94118
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$(bashio::config 'user_allowed_ip')" '. + {userAllowedIP: $v}')
@@ -103,30 +127,47 @@ if bashio::config.has_value 'agent_blocked_ip'; then
103127
SETTINGS=$(echo "$SETTINGS" | jq --arg v "$(bashio::config 'agent_blocked_ip')" '. + {agentBlockedIP: $v}')
104128
fi
105129

106-
# Autobackup — placeres uden for DATA_PATH
107-
SETTINGS=$(echo "$SETTINGS" | jq --arg bp "$BACKUP_PATH" '. + {autoBackup: {backupPath: $bp}}')
130+
# Autobackup
131+
BACKUP_JSON=$(jq -n \
132+
--arg bp "$BACKUP_PATH" \
133+
--argjson ivl "$BACKUP_INTERVAL" \
134+
--argjson kp "$BACKUP_KEEP" \
135+
'{backupPath: $bp, backupIntervalHours: $ivl, keepLastDaysBackup: $kp}')
136+
if bashio::config.has_value 'backup_zip_password'; then
137+
BACKUP_JSON=$(echo "$BACKUP_JSON" | jq --arg v "$(bashio::config 'backup_zip_password')" '. + {zipPassword: $v}')
138+
fi
139+
SETTINGS=$(echo "$SETTINGS" | jq --argjson v "$BACKUP_JSON" '. + {autoBackup: $v}')
108140

109141
# ── Build domain ──────────────────────────────────────────────────────────────
110-
111142
DOMAIN="{}"
112-
DOMAIN=$(echo "$DOMAIN" | jq --arg v "$DOMAIN_TITLE" '. + {title: $v}')
143+
DOMAIN=$(echo "$DOMAIN" | jq \
144+
--arg ttl "$DOMAIN_TITLE" \
145+
--argjson na "$NEW_ACCOUNTS" \
146+
--argjson ss "$SITE_STYLE" \
147+
--argjson gs "$GUEST_SHARING" \
148+
--argjson ar "$AUTO_REMOVE" \
149+
'. + {title: $ttl, newAccounts: $na, siteStyle: $ss, guestDeviceSharing: $gs, autoRemoveInactiveDevices: $ar}')
113150

114151
if bashio::config.has_value 'domain_title2'; then
115152
DOMAIN=$(echo "$DOMAIN" | jq --arg v "$(bashio::config 'domain_title2')" '. + {title2: $v}')
116153
fi
117154

118-
DOMAIN=$(echo "$DOMAIN" | jq --argjson v "$NEW_ACCOUNTS" '. + {newAccounts: $v}')
155+
if bashio::config.has_value 'welcome_text'; then
156+
DOMAIN=$(echo "$DOMAIN" | jq --arg v "$(bashio::config 'welcome_text')" '. + {welcomeText: $v}')
157+
fi
158+
159+
if bashio::config.has_value 'new_accounts_pass'; then
160+
DOMAIN=$(echo "$DOMAIN" | jq --arg v "$(bashio::config 'new_accounts_pass')" '. + {newAccountsPass: $v}')
161+
fi
119162

120-
# certUrl — required for agents connecting from outside LAN
121163
if bashio::config.has_value 'cert_url'; then
122164
DOMAIN=$(echo "$DOMAIN" | jq --arg v "$(bashio::config 'cert_url')" '. + {certUrl: $v}')
123165
fi
124166

125167
DOMAIN=$(echo "$DOMAIN" | jq --arg rp "$RECORDINGS_PATH" \
126168
'. + {sessionRecording: {filepath: $rp}}')
127169

128-
# ── Build SMTP (only if enabled and host is set) ──────────────────────────────
129-
170+
# ── Build SMTP ────────────────────────────────────────────────────────────────
130171
SMTP_JSON="null"
131172
if [ "$SMTP_ENABLED" = "true" ] && bashio::config.has_value 'smtp_host'; then
132173
SMTP_PORT=587
@@ -146,7 +187,6 @@ if [ "$SMTP_ENABLED" = "true" ] && bashio::config.has_value 'smtp_host'; then
146187
fi
147188

148189
# ── Assemble and write config.json ────────────────────────────────────────────
149-
150190
if [ "$SMTP_JSON" = "null" ]; then
151191
CONFIG=$(jq -n \
152192
--argjson settings "$SETTINGS" \
@@ -168,7 +208,6 @@ if [ "$NEW_ACCOUNTS" = "true" ]; then
168208
fi
169209

170210
# ── Start MeshCentral ─────────────────────────────────────────────────────────
171-
172211
bashio::log.info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
173212
bashio::log.info " MeshCentral is starting..."
174213
bashio::log.info " Open in browser (accept certificate warning):"
@@ -177,7 +216,6 @@ bashio::log.info " Or via HTTP redirect:"
177216
bashio::log.info " http://homeassistant.local:4431"
178217
bashio::log.info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
179218

180-
bashio::log.info "Starting MeshCentral node process..."
181219
exec node /opt/meshcentral/node_modules/meshcentral \
182220
--datapath "${DATA_PATH}" \
183221
--filespath "${FILES_PATH}"

0 commit comments

Comments
 (0)