diff --git a/DOCS/ARCHITECTURE_NOTES.md b/DOCS/ARCHITECTURE_NOTES.md index baebdc5..4ac043a 100644 --- a/DOCS/ARCHITECTURE_NOTES.md +++ b/DOCS/ARCHITECTURE_NOTES.md @@ -22,6 +22,8 @@ These notes summarize the repository structure, conventions, and supporting tool - `DOCS/` + `docs/`: mirrored, versioned documentation tree (design system, prompts, module templates, validation, permissions, etc.). - `EXAMPLES/` and `templates/`: snippets and scaffolding. - CI workflows live in `.github/workflows/` (referenced from README badges). +- **Profiles & App Manifests** + - App manifests (`/usr/share/secubox/plugins/`) and profile presets (`/usr/share/secubox/profiles/`) feed both the SecuBox wizard UI and the `secubox-app` CLI for automated installs. --- diff --git a/DOCS/DOCUMENTATION-INDEX.md b/DOCS/DOCUMENTATION-INDEX.md index 97f58e9..27285a1 100644 --- a/DOCS/DOCUMENTATION-INDEX.md +++ b/DOCS/DOCUMENTATION-INDEX.md @@ -223,6 +223,11 @@ Pointer: see `docs/embedded/vhost-manager.md` for the canonical version. Pointer: see `docs/embedded/app-store.md` for the canonical version. +#### **embedded/wizard-profiles.md** 🧭 +*First-run wizard and OS-like profiles.* + +Pointer: see `docs/embedded/wizard-profiles.md` for the canonical version. + --- ### 5. Tools & Scripts Documentation diff --git a/DOCS/embedded/wizard-profiles.md b/DOCS/embedded/wizard-profiles.md new file mode 100644 index 0000000..98a508c --- /dev/null +++ b/DOCS/embedded/wizard-profiles.md @@ -0,0 +1,74 @@ +# SecuBox Wizard & Profiles + +**Version:** 1.0.0 +**Last Updated:** 2025-12-28 +**Status:** Active + +The SecuBox hub now includes a guided setup wizard (LuCI → SecuBox → Wizard) and profile system. Use them to finish the first-run checklist, review app manifests, and apply predefined OS-like configurations (Home, Lab, Hardened, Gateway + DMZ). + +--- + +## First-Run Checklist + +The wizard queries `luci.secubox`’s `first_run_status` ubus method to determine whether critical items are configured: + +1. **Administrator password** – links to the LuCI password page. +2. **Timezone** – dropdown populated with common timezones; applying calls `apply_first_run` with `{ timezone: "Europe/Paris" }`. +3. **Storage path** – defaults to `/srv/secubox`; prepares the directory and stores it in `uci set secubox.main.storage_path`. +4. **Network mode** – uses the existing Network Modes RPC to switch between `router` and `dmz` presets. + +Each action can be run independently and is idempotent. + +--- + +## App Wizards (Manifests) + +Apps ship manifests under `/usr/share/secubox/plugins//manifest.json`. `secubox-app` (installed at `/usr/sbin/secubox-app`) uses the same manifests for CLI installs, and the wizard consumes the `wizard.fields` section to build forms. Example snippet: + +```json +{ + "id": "zigbee2mqtt", + "wizard": { + "uci": { "config": "zigbee2mqtt", "section": "main" }, + "fields": [ + { "id": "serial_port", "label": "Serial Port", "uci_option": "serial_port" }, + { "id": "mqtt_host", "label": "MQTT Host", "uci_option": "mqtt_host" } + ] + } +} +``` + +Clicking “Configure” opens a modal that writes the provided values into the specified UCI section. + +--- + +## Profiles + +Profiles are stored as JSON in `/usr/share/secubox/profiles/` and can bundle: + +- `network_mode`: target SecuBox network mode (`router`, `dmz`, …) +- `apps`: manifest IDs to install via `secubox-app install ` +- `packages`: additional packages to ensure via opkg/apk +- `uci`: array of `{config, section, option, value}` entries applied via UCI + +Baseline profiles: + +| ID | Description | Highlights | +|----|-------------|------------| +| `home` | Home router + Zigbee2MQTT | Router mode, installs Zigbee2MQTT + Netdata | +| `lab` | Monitoring lab | Router mode, ensures Netifyd & Bandwidth Manager | +| `hardened` | Security-focused | Enables CrowdSec + Client Guardian | +| `gateway_dmz` | Router + DMZ segment | Switches to DMZ mode and enables VHost manager | + +`apply_profile` automatically tars `/etc/config` to `/etc/secubox-profiles/backups/` before modifying settings, so the **Rollback last profile** button (or `rollback_profile` RPC) instantly restores prior UCI files. + +--- + +## CLI References + +- `secubox-app list|install|status` – manage app manifests (installed by `luci-app-secubox`). +- `ubus call luci.secubox list_profiles` – enumerate available profile manifests. +- `ubus call luci.secubox apply_profile '{"profile_id":"home"}'` – apply a preset programmatically. +- `secubox-app` respects `SECUBOX_PLUGINS_DIR` if you need to point to custom manifest trees. + +Combine the wizard UI with these commands to automate deployments or build higher-level orchestration (e.g., App Store pages, onboarding scripts). diff --git a/docs/ARCHITECTURE_NOTES.md b/docs/ARCHITECTURE_NOTES.md index 75eedaa..27bc8c6 100644 --- a/docs/ARCHITECTURE_NOTES.md +++ b/docs/ARCHITECTURE_NOTES.md @@ -28,6 +28,9 @@ These notes capture the current repository structure, conventions, and supportin - **Docs** Two mirrored trees (`docs/` and uppercase `DOCS/`) feed MkDocs and the GitHub wiki. All Markdown follows the metadata template defined in `docs/documentation-index.md`. +- **Profiles & App Manifests** + App manifests now live under `/usr/share/secubox/plugins/`, profiles under `/usr/share/secubox/profiles/`. `luci-app-secubox` exposes both through the wizard (UI) and `secubox-app` CLI (automation). + --- ## 2. Target Platforms & Build System diff --git a/docs/documentation-index.md b/docs/documentation-index.md index 79716c3..f9389f5 100644 --- a/docs/documentation-index.md +++ b/docs/documentation-index.md @@ -247,6 +247,18 @@ Follow this template when creating or revising documentation: **Size:** Short (~120 lines) +#### **embedded/wizard-profiles.md** 🧭 +*First-run wizard + OS-like profiles.* + +**Contents:** +- First-run checklist (password, timezone, storage, network mode) +- Using manifest-driven app wizards +- Baseline profiles (Home, Lab, Hardened, Gateway+DMZ) and rollback mechanics + +**When to use:** Guiding new deployments or applying pre-made bundles. + +**Size:** Short (~130 lines) + --- ### 5. Tools & Scripts Documentation diff --git a/docs/embedded/wizard-profiles.md b/docs/embedded/wizard-profiles.md new file mode 100644 index 0000000..98a508c --- /dev/null +++ b/docs/embedded/wizard-profiles.md @@ -0,0 +1,74 @@ +# SecuBox Wizard & Profiles + +**Version:** 1.0.0 +**Last Updated:** 2025-12-28 +**Status:** Active + +The SecuBox hub now includes a guided setup wizard (LuCI → SecuBox → Wizard) and profile system. Use them to finish the first-run checklist, review app manifests, and apply predefined OS-like configurations (Home, Lab, Hardened, Gateway + DMZ). + +--- + +## First-Run Checklist + +The wizard queries `luci.secubox`’s `first_run_status` ubus method to determine whether critical items are configured: + +1. **Administrator password** – links to the LuCI password page. +2. **Timezone** – dropdown populated with common timezones; applying calls `apply_first_run` with `{ timezone: "Europe/Paris" }`. +3. **Storage path** – defaults to `/srv/secubox`; prepares the directory and stores it in `uci set secubox.main.storage_path`. +4. **Network mode** – uses the existing Network Modes RPC to switch between `router` and `dmz` presets. + +Each action can be run independently and is idempotent. + +--- + +## App Wizards (Manifests) + +Apps ship manifests under `/usr/share/secubox/plugins//manifest.json`. `secubox-app` (installed at `/usr/sbin/secubox-app`) uses the same manifests for CLI installs, and the wizard consumes the `wizard.fields` section to build forms. Example snippet: + +```json +{ + "id": "zigbee2mqtt", + "wizard": { + "uci": { "config": "zigbee2mqtt", "section": "main" }, + "fields": [ + { "id": "serial_port", "label": "Serial Port", "uci_option": "serial_port" }, + { "id": "mqtt_host", "label": "MQTT Host", "uci_option": "mqtt_host" } + ] + } +} +``` + +Clicking “Configure” opens a modal that writes the provided values into the specified UCI section. + +--- + +## Profiles + +Profiles are stored as JSON in `/usr/share/secubox/profiles/` and can bundle: + +- `network_mode`: target SecuBox network mode (`router`, `dmz`, …) +- `apps`: manifest IDs to install via `secubox-app install ` +- `packages`: additional packages to ensure via opkg/apk +- `uci`: array of `{config, section, option, value}` entries applied via UCI + +Baseline profiles: + +| ID | Description | Highlights | +|----|-------------|------------| +| `home` | Home router + Zigbee2MQTT | Router mode, installs Zigbee2MQTT + Netdata | +| `lab` | Monitoring lab | Router mode, ensures Netifyd & Bandwidth Manager | +| `hardened` | Security-focused | Enables CrowdSec + Client Guardian | +| `gateway_dmz` | Router + DMZ segment | Switches to DMZ mode and enables VHost manager | + +`apply_profile` automatically tars `/etc/config` to `/etc/secubox-profiles/backups/` before modifying settings, so the **Rollback last profile** button (or `rollback_profile` RPC) instantly restores prior UCI files. + +--- + +## CLI References + +- `secubox-app list|install|status` – manage app manifests (installed by `luci-app-secubox`). +- `ubus call luci.secubox list_profiles` – enumerate available profile manifests. +- `ubus call luci.secubox apply_profile '{"profile_id":"home"}'` – apply a preset programmatically. +- `secubox-app` respects `SECUBOX_PLUGINS_DIR` if you need to point to custom manifest trees. + +Combine the wizard UI with these commands to automate deployments or build higher-level orchestration (e.g., App Store pages, onboarding scripts). diff --git a/luci-app-secubox/Makefile b/luci-app-secubox/Makefile index b05f1f7..87888ba 100644 --- a/luci-app-secubox/Makefile +++ b/luci-app-secubox/Makefile @@ -26,6 +26,10 @@ define Package/$(PKG_NAME)/install $(call Package/luci/install,$(1)) $(INSTALL_DIR) $(1)/usr/share/secubox/plugins/zigbee2mqtt $(INSTALL_DATA) $(CURDIR)/../plugins/zigbee2mqtt/manifest.json $(1)/usr/share/secubox/plugins/zigbee2mqtt/manifest.json + $(INSTALL_DIR) $(1)/usr/share/secubox/profiles + for file in $(CURDIR)/../profiles/*.json; do \ + $(INSTALL_DATA) $$file $(1)/usr/share/secubox/profiles/$$(basename $$file); \ + done $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(CURDIR)/../secubox-tools/secubox-app $(1)/usr/sbin/secubox-app endef diff --git a/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js b/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js index 83915da..f228e3c 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js +++ b/luci-app-secubox/htdocs/luci-static/resources/secubox/api.js @@ -174,6 +174,23 @@ var callApplyAppWizard = rpc.declare({ params: ['app_id', 'values'] }); +var callListProfiles = rpc.declare({ + object: 'luci.secubox', + method: 'list_profiles', + expect: { profiles: [] } +}); + +var callApplyProfile = rpc.declare({ + object: 'luci.secubox', + method: 'apply_profile', + params: ['profile_id'] +}); + +var callRollbackProfile = rpc.declare({ + object: 'luci.secubox', + method: 'rollback_profile' +}); + function formatUptime(seconds) { if (!seconds) return '0s'; var d = Math.floor(seconds / 86400); @@ -222,6 +239,9 @@ return baseclass.extend({ listApps: callListApps, getAppManifest: callGetAppManifest, applyAppWizard: callApplyAppWizard, + listProfiles: callListProfiles, + applyProfile: callApplyProfile, + rollbackProfile: callRollbackProfile, // Utilities formatUptime: formatUptime, formatBytes: formatBytes diff --git a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/wizard.js b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/wizard.js index ef7ddfb..40299be 100644 --- a/luci-app-secubox/htdocs/luci-static/resources/view/secubox/wizard.js +++ b/luci-app-secubox/htdocs/luci-static/resources/view/secubox/wizard.js @@ -22,18 +22,21 @@ return view.extend({ load: function() { return Promise.all([ API.getFirstRunStatus(), - API.listApps() + API.listApps(), + API.listProfiles() ]); }, render: function(payload) { this.firstRun = payload[0] || {}; this.appList = (payload[1] && payload[1].apps) || []; + this.profileList = (payload[2] && payload[2].profiles) || []; var container = E('div', { 'class': 'secubox-wizard-page' }, [ E('link', { 'rel': 'stylesheet', 'href': L.resource('secubox/common.css') }), SecuNav.renderTabs('wizard'), this.renderHeader(), this.renderFirstRunCard(), + this.renderProfilesCard(), this.renderAppsCard() ]); return container; @@ -142,6 +145,44 @@ return view.extend({ ]); }, + renderProfilesCard: function() { + var profiles = this.profileList || []; + return E('div', { 'class': 'sb-wizard-card' }, [ + E('div', { 'class': 'sb-wizard-title' }, ['🧱 ', _('Profiles')]), + profiles.length ? E('div', { 'class': 'sb-app-grid' }, profiles.map(this.renderProfileCard, this)) : + E('div', { 'class': 'secubox-empty-state' }, [ + E('div', { 'class': 'secubox-empty-icon' }, '📭'), + E('div', { 'class': 'secubox-empty-title' }, _('No profiles available')), + E('div', { 'class': 'secubox-empty-text' }, _('Profiles are stored in /usr/share/secubox/profiles/.')) + ]), + profiles.length ? E('div', { 'class': 'right', 'style': 'margin-top:12px;' }, [ + E('button', { + 'class': 'cbi-button cbi-button-action', + 'click': this.rollbackProfile.bind(this) + }, _('Rollback last profile')) + ]) : '' + ]); + }, + + renderProfileCard: function(profile) { + var apps = profile.apps || []; + return E('div', { 'class': 'sb-app-card' }, [ + E('div', { 'class': 'sb-app-card-info' }, [ + E('div', { 'class': 'sb-app-name' }, [profile.name || profile.id]), + E('div', { 'class': 'sb-app-desc' }, profile.description || ''), + E('div', { 'class': 'sb-app-desc' }, _('Network mode: %s').format(profile.network_mode || '—')), + apps.length ? E('div', { 'class': 'sb-app-desc' }, _('Apps: %s').format(apps.join(', '))) : '' + ]), + E('div', { 'class': 'sb-app-actions' }, [ + E('span', { 'class': 'sb-app-state' + (profile.state === 'installed' ? ' ok' : '') }, profile.state || 'n/a'), + E('button', { + 'class': 'cbi-button cbi-button-action', + 'click': this.applyProfile.bind(this, profile.id) + }, _('Apply')) + ]) + ]); + }, + renderAppCard: function(app) { return E('div', { 'class': 'sb-app-card' }, [ E('div', { 'class': 'sb-app-card-info' }, [ @@ -241,5 +282,31 @@ return view.extend({ ui.addNotification(null, E('p', {}, _('Failed to apply wizard.')), 'error'); } }).catch(this.showError); + }, + + applyProfile: function(profileId) { + if (!profileId) + return; + ui.showModal(_('Applying profile…'), [E('div', { 'class': 'spinning' })]); + API.applyProfile(profileId).then(function(result) { + ui.hideModal(); + if (result && result.success) { + ui.addNotification(null, E('p', {}, _('Profile applied. A reboot may be required.')), 'info'); + } else { + ui.addNotification(null, E('p', {}, (result && result.error) || _('Failed to apply profile')), 'error'); + } + }).catch(this.showError); + }, + + rollbackProfile: function() { + ui.showModal(_('Rolling back…'), [E('div', { 'class': 'spinning' })]); + API.rollbackProfile().then(function(result) { + ui.hideModal(); + if (result && result.success) { + ui.addNotification(null, E('p', {}, result.message || _('Rollback completed.')), 'info'); + } else { + ui.addNotification(null, E('p', {}, (result && result.error) || _('Rollback failed.')), 'error'); + } + }).catch(this.showError); } }); diff --git a/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox b/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox index 2c0c23b..8cf6769 100755 --- a/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox +++ b/luci-app-secubox/root/usr/libexec/rpcd/luci.secubox @@ -55,7 +55,11 @@ get_pkg_version() { PKG_VERSION="$(get_pkg_version)" PLUGIN_DIR="/usr/share/secubox/plugins" +PROFILE_DIR="/usr/share/secubox/profiles" +PROFILE_BACKUP_DIR="/etc/secubox-profiles/backups" DEFAULT_STORAGE_PATH="/srv/secubox" +SECOBOX_APP="/usr/sbin/secubox-app" +OPKG_UPDATED=0 # Module registry - auto-detected from /usr/libexec/rpcd/ detect_modules() { @@ -127,6 +131,34 @@ ensure_directory() { [ -d "$dir" ] || mkdir -p "$dir" } +apply_network_mode() { + local mode="$1" + [ -n "$mode" ] || return + if command -v ubus >/dev/null 2>&1; then + if ubus call luci.network-modes set_mode "{\"mode\":\"$mode\"}" >/dev/null 2>&1; then + ubus call luci.network-modes apply_mode >/dev/null 2>&1 + fi + fi +} + +ensure_opkg_updated() { + [ "$OPKG_UPDATED" -eq 1 ] && return + if command -v opkg >/dev/null 2>&1; then + opkg update >/dev/null 2>&1 && OPKG_UPDATED=1 + fi +} + +install_package_if_missing() { + local pkg="$1" + package_installed "$pkg" && return + if command -v opkg >/dev/null 2>&1; then + ensure_opkg_updated + opkg install "$pkg" >/dev/null 2>&1 + elif command -v apk >/dev/null 2>&1; then + apk add "$pkg" >/dev/null 2>&1 + fi +} + # Check if a module is installed (supports both opkg and apk) check_module_installed() { local module="$1" @@ -1324,6 +1356,136 @@ apply_app_wizard() { json_add_boolean "success" 1 json_dump } + +list_profiles() { + ensure_directory "$PROFILE_DIR" + json_init + json_add_array "profiles" + local profile_file + for profile_file in "$PROFILE_DIR"/*.json; do + [ -f "$profile_file" ] || continue + local profile_json id name description network_mode apps state + profile_json=$(cat "$profile_file") + id=$(jsonfilter -s "$profile_json" -e '@.id' 2>/dev/null) + name=$(jsonfilter -s "$profile_json" -e '@.name' 2>/dev/null) + description=$(jsonfilter -s "$profile_json" -e '@.description' 2>/dev/null) + network_mode=$(jsonfilter -s "$profile_json" -e '@.network_mode' 2>/dev/null) + apps=$(jsonfilter -s "$profile_json" -e '@.apps[*]' 2>/dev/null) + state=$(packages_state "$profile_json") + [ -n "$id" ] || continue + json_add_object + json_add_string "id" "$id" + json_add_string "name" "$name" + json_add_string "description" "$description" + json_add_string "network_mode" "$network_mode" + json_add_string "state" "$state" + json_add_array "apps" + for app in $apps; do + json_add_string "" "$app" + done + json_close_array + json_close_object + done + json_close_array + json_dump +} + +apply_profile() { + local input profile_id profile_file profile_json network_mode packages apps backup_file notes="" + read input + json_load "$input" + json_get_var profile_id profile_id + json_cleanup + [ -n "$profile_id" ] || { + json_init; json_add_boolean "success" 0; json_add_string "error" "profile_id required"; json_dump; return; + } + profile_file="$PROFILE_DIR/$profile_id.json" + if [ ! -f "$profile_file" ]; then + json_init; json_add_boolean "success" 0; json_add_string "error" "Profile not found"; json_dump; return; + fi + profile_json=$(cat "$profile_file") + ensure_directory "$PROFILE_BACKUP_DIR" + local timestamp=$(date +%Y%m%d_%H%M%S) + backup_file="$PROFILE_BACKUP_DIR/profile_${profile_id}_${timestamp}.tar.gz" + tar -czf "$backup_file" /etc/config 2>/dev/null + notes="${notes}Backup saved to $backup_file\n" + uci set secubox.profile.last_backup="$backup_file" + uci set secubox.profile.last_profile="$profile_id" + uci commit secubox + network_mode=$(jsonfilter -s "$profile_json" -e '@.network_mode' 2>/dev/null) + if [ -n "$network_mode" ]; then + notes="${notes}Switched network mode to $network_mode\n" + apply_network_mode "$network_mode" + fi + packages=$(jsonfilter -s "$profile_json" -e '@.packages[*]' 2>/dev/null) + for pkg in $packages; do + install_package_if_missing "$pkg" + notes="${notes}Ensured package $pkg\n" + done + apps=$(jsonfilter -s "$profile_json" -e '@.apps[*]' 2>/dev/null) + for app in $apps; do + if [ -x "$SECOBOX_APP" ]; then + $SECOBOX_APP install "$app" >/dev/null 2>&1 && notes="${notes}Installed app $app\n" + fi + done + json_load "$profile_json" + local uci_configs="" + if json_select uci >/dev/null 2>&1; then + local entries + json_get_keys entries + for entry in $entries; do + json_select "$entry" + local cfg section option value + json_get_var cfg config + json_get_var section section + json_get_var option option + json_get_var value value + section=${section:-main} + if [ -n "$cfg" ] && [ -n "$option" ]; then + uci set ${cfg}.${section}.${option}="$value" + uci_configs="${uci_configs} $cfg" + notes="${notes}Set ${cfg}.${section}.${option}=${value}\n" + fi + json_select .. + done + json_select .. + fi + json_cleanup + local committed="" + for cfg in $uci_configs; do + case " $committed " in + *" $cfg "*) continue;; + esac + uci commit "$cfg" + committed="$committed $cfg" + done + json_init + json_add_boolean "success" 1 + json_add_array "messages" + printf '%b' "$notes" | while IFS= read -r line; do + [ -n "$line" ] && json_add_string "" "$line" + done + json_close_array + json_add_string "backup" "$backup_file" + json_dump +} + +rollback_profile() { + local latest_backup + latest_backup=$(ls -t "$PROFILE_BACKUP_DIR"/profile_*.tar.gz 2>/dev/null | head -1) + if [ -z "$latest_backup" ]; then + json_init; json_add_boolean "success" 0; json_add_string "error" "No backups available"; json_dump; return; + fi + cd / + tar -xzf "$latest_backup" 2>/dev/null + /etc/init.d/network reload >/dev/null 2>&1 + /etc/init.d/firewall reload >/dev/null 2>&1 + /etc/init.d/dnsmasq reload >/dev/null 2>&1 + json_init + json_add_boolean "success" 1 + json_add_string "message" "Restored $latest_backup" + json_dump +} case "$1" in list) json_init @@ -1392,6 +1554,25 @@ case "$1" in json_add_object "apply_app_wizard" json_add_string "app_id" "string" json_close_object + json_add_object "list_profiles" + json_close_object + json_add_object "apply_profile" + json_add_string "profile_id" "string" + json_close_object + json_add_object "rollback_profile" + json_close_object + json_add_object "first_run_status" + json_close_object + json_add_object "apply_first_run" + json_close_object + json_add_object "list_apps" + json_close_object + json_add_object "get_app_manifest" + json_add_string "app_id" "string" + json_close_object + json_add_object "apply_app_wizard" + json_add_string "app_id" "string" + json_close_object json_dump ;; call) @@ -1507,6 +1688,15 @@ case "$1" in apply_app_wizard) apply_app_wizard ;; + list_profiles) + list_profiles + ;; + apply_profile) + apply_profile + ;; + rollback_profile) + rollback_profile + ;; *) echo '{"error":"Unknown method"}' ;; diff --git a/luci-app-secubox/root/usr/share/rpcd/acl.d/luci-app-secubox.json b/luci-app-secubox/root/usr/share/rpcd/acl.d/luci-app-secubox.json index 4cfdd0c..1203586 100644 --- a/luci-app-secubox/root/usr/share/rpcd/acl.d/luci-app-secubox.json +++ b/luci-app-secubox/root/usr/share/rpcd/acl.d/luci-app-secubox.json @@ -17,7 +17,8 @@ "get_theme", "first_run_status", "list_apps", - "get_app_manifest" + "get_app_manifest", + "list_profiles" ], "uci": [ "get", @@ -42,7 +43,9 @@ "clear_alerts", "fix_permissions", "apply_first_run", - "apply_app_wizard" + "apply_app_wizard", + "apply_profile", + "rollback_profile" ], "uci": [ "set", diff --git a/profiles/gateway_dmz.json b/profiles/gateway_dmz.json new file mode 100644 index 0000000..75edca5 --- /dev/null +++ b/profiles/gateway_dmz.json @@ -0,0 +1,11 @@ +{ + "id": "gateway_dmz", + "name": "Gateway + DMZ", + "description": "Router with isolated DMZ segment for exposed services.", + "network_mode": "dmz", + "apps": ["zigbee2mqtt"], + "packages": ["luci-app-vhost-manager"], + "uci": [ + { "config": "secubox", "section": "vhost_manager", "option": "enabled", "value": "1" } + ] +} diff --git a/profiles/hardened.json b/profiles/hardened.json new file mode 100644 index 0000000..596be34 --- /dev/null +++ b/profiles/hardened.json @@ -0,0 +1,12 @@ +{ + "id": "hardened", + "name": "Hardened", + "description": "Security-focused preset enabling CrowdSec and Client Guardian.", + "network_mode": "router", + "apps": [], + "packages": ["luci-app-crowdsec-dashboard", "luci-app-client-guardian"], + "uci": [ + { "config": "secubox", "section": "crowdsec", "option": "enabled", "value": "1" }, + { "config": "secubox", "section": "client_guardian", "option": "enabled", "value": "1" } + ] +} diff --git a/profiles/home.json b/profiles/home.json new file mode 100644 index 0000000..b6dfce4 --- /dev/null +++ b/profiles/home.json @@ -0,0 +1,12 @@ +{ + "id": "home", + "name": "Home", + "description": "Default home router with Zigbee and monitoring enabled.", + "network_mode": "router", + "apps": ["zigbee2mqtt"], + "packages": ["luci-app-netdata-dashboard"], + "uci": [ + { "config": "secubox", "section": "netdata", "option": "enabled", "value": "1" }, + { "config": "secubox", "section": "zigbee2mqtt", "option": "enabled", "value": "1" } + ] +} diff --git a/profiles/lab.json b/profiles/lab.json new file mode 100644 index 0000000..2f4a1f5 --- /dev/null +++ b/profiles/lab.json @@ -0,0 +1,12 @@ +{ + "id": "lab", + "name": "Lab", + "description": "Extended monitoring and DPI for test environments.", + "network_mode": "router", + "apps": [], + "packages": ["luci-app-netifyd-dashboard", "luci-app-netdata-dashboard"], + "uci": [ + { "config": "secubox", "section": "netifyd", "option": "enabled", "value": "1" }, + { "config": "secubox", "section": "bandwidth_manager", "option": "enabled", "value": "1" } + ] +}