lxc: add foundational CLI and docs
This commit is contained in:
parent
3c0003614d
commit
da8eeb27ca
66
DOCS/embedded/lxc-framework.md
Normal file
66
DOCS/embedded/lxc-framework.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# SecuBox LXC Framework (Preview)
|
||||||
|
|
||||||
|
**Version:** 1.0.0
|
||||||
|
**Last Updated:** 2025-12-28
|
||||||
|
**Status:** Active
|
||||||
|
|
||||||
|
This document captures the baseline LXC tooling added in Step 8. It is a foundation for future “SecuBox Apps” packaged as LXC containers (e.g., Lyrion) and explains the combined CLI/UCI workflow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
1. **UCI config:** `/etc/config/lxcapps` (one section per container).
|
||||||
|
2. **Storage root:** `/srv/lxc/<name>/` (rootfs, config, logs).
|
||||||
|
3. **Templates:** `/usr/share/secubox/lxc/templates/` (scripts/tarballs; default `debian`).
|
||||||
|
4. **CLI helper:** `secubox-tools/lxc/secubox-lxc` (install to `/usr/sbin/secubox-lxc`).
|
||||||
|
|
||||||
|
`secubox-lxc` requires standard OpenWrt LXC packages and uses BusyBox-friendly syntax.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CLI Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
secubox-lxc list # show defined containers
|
||||||
|
secubox-lxc create lyrion --bridge br-dmz --ip 192.168.50.10
|
||||||
|
secubox-lxc start lyrion
|
||||||
|
secubox-lxc stop lyrion
|
||||||
|
secubox-lxc status lyrion
|
||||||
|
secubox-lxc delete lyrion
|
||||||
|
```
|
||||||
|
|
||||||
|
Each `create` call ensures the container directory under `/srv/lxc/<name>` and writes a matching `config container '<name>'` section in `/etc/config/lxcapps`. That makes it discoverable for future LuCI integrations.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UCI Schema
|
||||||
|
|
||||||
|
```uci
|
||||||
|
config container 'lyrion'
|
||||||
|
option bridge 'br-dmz'
|
||||||
|
option ip '192.168.50.10'
|
||||||
|
option gateway '192.168.50.1'
|
||||||
|
option dns '1.1.1.1'
|
||||||
|
option memory '1024'
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional options (template, rootfs, custom scripts) can be added later; the CLI already supports `--template`, `--memory`, `--bridge`, `--ip`, `--gateway`, and `--dns` flags.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Storage & Templates
|
||||||
|
|
||||||
|
- Default rootfs path: `/srv/lxc/<name>/rootfs`.
|
||||||
|
- Template lookup: CLI `--template` arg → `/usr/share/secubox/lxc/templates/<name>` → system `lxc-create -t debian`.
|
||||||
|
- Bridge defaults to `br-lan`; pass `--bridge br-dmz` for DMZ containers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Work
|
||||||
|
|
||||||
|
- Expose `/etc/config/lxcapps` via RPC + LuCI so manifests/profiles can declare LXC apps.
|
||||||
|
- Ship Lyrion and other container templates alongside Docker apps in the App Store.
|
||||||
|
- Reuse the profile system to install LXC dependencies and provision containers automatically.
|
||||||
|
|
||||||
|
For now, this tooling lets power users validate LXC on OpenWrt ARM64 and gives the App Store a consistent foundation.
|
||||||
78
docs/embedded/lxc-framework.md
Normal file
78
docs/embedded/lxc-framework.md
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# SecuBox LXC Framework (Preview)
|
||||||
|
|
||||||
|
**Version:** 1.0.0
|
||||||
|
**Last Updated:** 2025-12-28
|
||||||
|
**Status:** Active
|
||||||
|
|
||||||
|
This document captures the baseline LXC tooling added in Step 8. It is a foundation for future “SecuBox Apps” packaged as LXC containers (e.g., Lyrion) and explains the combined CLI/UCI workflow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
1. **UCI config:** `/etc/config/lxcapps` (one section per container).
|
||||||
|
2. **Storage root:** `/srv/lxc/<name>/` (rootfs, config, logs).
|
||||||
|
3. **Templates:** `/usr/share/secubox/lxc/templates/` (scripts/tarballs; default `debian`).
|
||||||
|
4. **CLI helper:** `secubox-tools/lxc/secubox-lxc` (install to `/usr/sbin/secubox-lxc`).
|
||||||
|
|
||||||
|
`secubox-lxc` requires standard OpenWrt LXC packages (`lxc`, `lxc-templates`, `lxc-start`, etc.) and uses BusyBox-friendly syntax.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CLI Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# List defined containers
|
||||||
|
secubox-lxc list
|
||||||
|
|
||||||
|
# Create container using the debian template and attach to br-dmz
|
||||||
|
secubox-lxc create lyrion --bridge br-dmz --ip 192.168.50.10
|
||||||
|
|
||||||
|
# Start / stop lifecycle
|
||||||
|
secubox-lxc start lyrion
|
||||||
|
secubox-lxc stop lyrion
|
||||||
|
|
||||||
|
# Show detailed config or status
|
||||||
|
secubox-lxc show lyrion
|
||||||
|
secubox-lxc status lyrion
|
||||||
|
|
||||||
|
# Remove
|
||||||
|
secubox-lxc delete lyrion
|
||||||
|
```
|
||||||
|
|
||||||
|
`secubox-lxc create <name>` automatically creates a `config` section under `lxcapps.<name>` capturing bridge/IP/memory metadata, so LuCI (future apps) can introspect containers in a consistent way.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## UCI Schema (`/etc/config/lxcapps`)
|
||||||
|
|
||||||
|
```uci
|
||||||
|
config container 'lyrion'
|
||||||
|
option bridge 'br-dmz'
|
||||||
|
option ip '192.168.50.10'
|
||||||
|
option gateway '192.168.50.1'
|
||||||
|
option dns '1.1.1.1'
|
||||||
|
option memory '1024'
|
||||||
|
```
|
||||||
|
|
||||||
|
This initial version does not yet tie into LuCI, but the schema is ready for future RPC endpoints and wizards (e.g., mapping profile entries to LXC containers).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Storage & Templates
|
||||||
|
|
||||||
|
- Default rootfs path: `/srv/lxc/<name>/rootfs`.
|
||||||
|
- Template lookup order: CLI `--template` → `/usr/share/secubox/lxc/templates/<name>` → fallback to system `lxc-create -t debian`.
|
||||||
|
- Bridge defaults to `br-lan`; pass `--bridge br-dmz` to isolate DMZ containers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
This foundation enables the remaining roadmap items:
|
||||||
|
|
||||||
|
- Expose `/etc/config/lxcapps` via `luci-app-secubox` RPC for integration with the App Store/wizard.
|
||||||
|
- Add profiles or manifests referencing specific LXC definitions (e.g., `type": "lxc"`).
|
||||||
|
- Ship ready-made templates (Lyrion, etc.) and document cgroup requirements alongside Docker apps.
|
||||||
|
|
||||||
|
For now, use the CLI + UCI schema to experiment with LXC containers on OpenWrt ARM64 and validate storage/network assumptions.
|
||||||
@ -59,6 +59,7 @@ Baseline profiles:
|
|||||||
| `lab` | Monitoring lab | Router mode, ensures Netifyd & Bandwidth Manager |
|
| `lab` | Monitoring lab | Router mode, ensures Netifyd & Bandwidth Manager |
|
||||||
| `hardened` | Security-focused | Enables CrowdSec + Client Guardian |
|
| `hardened` | Security-focused | Enables CrowdSec + Client Guardian |
|
||||||
| `gateway_dmz` | Router + DMZ segment | Switches to DMZ mode and enables VHost manager |
|
| `gateway_dmz` | Router + DMZ segment | Switches to DMZ mode and enables VHost manager |
|
||||||
|
| `lxc_base` | (Upcoming) baseline LXC container | Reserved for future `secubox-lxc` integrations |
|
||||||
|
|
||||||
`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.
|
`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.
|
||||||
|
|
||||||
|
|||||||
10
profiles/README.md
Normal file
10
profiles/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# SecuBox Profiles
|
||||||
|
|
||||||
|
This directory defines baseline profile manifests consumed by `luci-app-secubox`.
|
||||||
|
|
||||||
|
- `home.json`: Home router baseline (router mode, Zigbee2MQTT + Netdata).
|
||||||
|
- `lab.json`: Lab monitoring preset (Netifyd + Bandwidth Manager).
|
||||||
|
- `hardened.json`: Security preset (CrowdSec + Client Guardian).
|
||||||
|
- `gateway_dmz.json`: Gateway + DMZ preset (switches to DMZ mode, enables vhost manager).
|
||||||
|
|
||||||
|
These JSON files also serve as examples for future LXC or Docker app bundles.
|
||||||
171
secubox-tools/lxc/secubox-lxc
Executable file
171
secubox-tools/lxc/secubox-lxc
Executable file
@ -0,0 +1,171 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# SecuBox LXC helper: create/start/stop LXC containers following SecuBox conventions
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
CONFIG="/etc/config/lxcapps"
|
||||||
|
STORAGE_ROOT="/srv/lxc"
|
||||||
|
TEMPLATE_DIR="${SECUBOX_LXC_TEMPLATES:-/usr/share/secubox/lxc/templates}"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'USAGE'
|
||||||
|
SecuBox LXC Manager
|
||||||
|
Usage: secubox-lxc <command> [options]
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
list Show containers defined in /etc/config/lxcapps
|
||||||
|
show <name> Display config values for a container
|
||||||
|
create <name> [options] Create container (downloads template if needed)
|
||||||
|
start <name> Start container via lxc-start
|
||||||
|
stop <name> Stop container via lxc-stop
|
||||||
|
delete <name> Stop and remove container directory
|
||||||
|
status <name> Show runtime state
|
||||||
|
|
||||||
|
Options (create):
|
||||||
|
--template PATH Rootfs tarball or template script (default debian)
|
||||||
|
--bridge BRIDGE Bridge to attach (default br-lan)
|
||||||
|
--ip ADDRESS Static IP address (optional)
|
||||||
|
--gateway ADDRESS Gateway (optional)
|
||||||
|
--dns ADDRESS DNS server (optional)
|
||||||
|
--memory MB Memory limit (optional)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
secubox-lxc list
|
||||||
|
secubox-lxc create secubox-lyrion --bridge br-dmz --ip 192.168.50.10
|
||||||
|
secubox-lxc start secubox-lyrion
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
require_tool() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || { echo "[ERROR] Missing dependency: $1" >&2; exit 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_storage() {
|
||||||
|
mkdir -p "$STORAGE_ROOT"
|
||||||
|
}
|
||||||
|
|
||||||
|
uci_get_container() {
|
||||||
|
local name="$1" option="$2"
|
||||||
|
uci -q get lxcapps."$name"."$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
uci_set_container() {
|
||||||
|
local name="$1" option="$2" value="$3"
|
||||||
|
uci set lxcapps."$name"."$option"="$value"
|
||||||
|
}
|
||||||
|
|
||||||
|
list_containers() {
|
||||||
|
uci -q show lxcapps 2>/dev/null | grep '=container$' | cut -d. -f2 | cut -d= -f1
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_list() {
|
||||||
|
require_tool lxc-info
|
||||||
|
ensure_storage
|
||||||
|
printf '%-18s %-20s %-10s %-16s\n' "Name" "Bridge" "State" "RootFS"
|
||||||
|
printf '%-18s %-20s %-10s %-16s\n' "----" "------" "-----" "------"
|
||||||
|
for name in $(list_containers); do
|
||||||
|
local bridge rootfs state
|
||||||
|
bridge=$(uci_get_container "$name" bridge || printf 'br-lan')
|
||||||
|
rootfs="$STORAGE_ROOT/$name/rootfs"
|
||||||
|
if lxc-info -n "$name" >/dev/null 2>&1; then
|
||||||
|
state=$(lxc-info -n "$name" -s 2>/dev/null | awk '{print $2}')
|
||||||
|
else
|
||||||
|
state="N/A"
|
||||||
|
fi
|
||||||
|
printf '%-18s %-20s %-10s %-16s\n' "$name" "$bridge" "$state" "$rootfs"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_show() {
|
||||||
|
local name="$1"
|
||||||
|
uci -q show lxcapps."$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_create() {
|
||||||
|
require_tool lxc-create
|
||||||
|
local name="$1"; shift
|
||||||
|
local template="debian"
|
||||||
|
local bridge="br-lan"
|
||||||
|
local ip=""
|
||||||
|
local gateway=""
|
||||||
|
local dns=""
|
||||||
|
local memory=""
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--template) template="$2"; shift 2;;
|
||||||
|
--bridge) bridge="$2"; shift 2;;
|
||||||
|
--ip) ip="$2"; shift 2;;
|
||||||
|
--gateway) gateway="$2"; shift 2;;
|
||||||
|
--dns) dns="$2"; shift 2;;
|
||||||
|
--memory) memory="$2"; shift 2;;
|
||||||
|
*) echo "Unknown option: $1" >&2; exit 1;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
[ -n "$name" ] || { echo "Container name required" >&2; exit 1; }
|
||||||
|
ensure_storage
|
||||||
|
local container_dir="$STORAGE_ROOT/$name"
|
||||||
|
if [ -d "$container_dir" ]; then
|
||||||
|
echo "[WARN] Container directory already exists, skipping rootfs creation."
|
||||||
|
else
|
||||||
|
mkdir -p "$container_dir"
|
||||||
|
local tmpl_path="$template"
|
||||||
|
if [ -f "$TEMPLATE_DIR/$template" ]; then
|
||||||
|
tmpl_path="$TEMPLATE_DIR/$template"
|
||||||
|
fi
|
||||||
|
lxc-create -n "$name" -P "$STORAGE_ROOT" -t "$tmpl_path"
|
||||||
|
fi
|
||||||
|
uci batch <<-EOF
|
||||||
|
set lxcapps.$name=container
|
||||||
|
set lxcapps.$name.bridge='$bridge'
|
||||||
|
EOF
|
||||||
|
[ -n "$ip" ] && uci_set_container "$name" ip "$ip"
|
||||||
|
[ -n "$gateway" ] && uci_set_container "$name" gateway "$gateway"
|
||||||
|
[ -n "$dns" ] && uci_set_container "$name" dns "$dns"
|
||||||
|
[ -n "$memory" ] && uci_set_container "$name" memory "$memory"
|
||||||
|
uci commit lxcapps
|
||||||
|
cat <<MSG
|
||||||
|
[INFO] Container $name created.
|
||||||
|
Rootfs: $container_dir
|
||||||
|
Bridge: $bridge
|
||||||
|
MSG
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_start() {
|
||||||
|
require_tool lxc-start
|
||||||
|
local name="$1"
|
||||||
|
lxc-start -n "$name" -d
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_stop() {
|
||||||
|
require_tool lxc-stop
|
||||||
|
local name="$1"
|
||||||
|
lxc-stop -n "$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_delete() {
|
||||||
|
require_tool lxc-destroy
|
||||||
|
local name="$1"
|
||||||
|
lxc-stop -n "$name" >/dev/null 2>&1 || true
|
||||||
|
lxc-destroy -n "$name"
|
||||||
|
rm -rf "$STORAGE_ROOT/$name"
|
||||||
|
uci delete lxcapps."$name"
|
||||||
|
uci commit lxcapps
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_status() {
|
||||||
|
require_tool lxc-info
|
||||||
|
local name="$1"
|
||||||
|
lxc-info -n "$name"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
list) shift; cmd_list "$@" ;;
|
||||||
|
show) shift; [ $# -ge 1 ] || { usage; exit 1; }; cmd_show "$1" ;;
|
||||||
|
create) shift; [ $# -ge 1 ] || { usage; exit 1; }; cmd_create "$@" ;;
|
||||||
|
start) shift; [ $# -ge 1 ] || { usage; exit 1; }; cmd_start "$1" ;;
|
||||||
|
stop) shift; [ $# -ge 1 ] || { usage; exit 1; }; cmd_stop "$1" ;;
|
||||||
|
delete) shift; [ $# -ge 1 ] || { usage; exit 1; }; cmd_delete "$1" ;;
|
||||||
|
status) shift; [ $# -ge 1 ] || { usage; exit 1; }; cmd_status "$1" ;;
|
||||||
|
help|--help|-h|'') usage ;;
|
||||||
|
*) usage; exit 1 ;;
|
||||||
|
esac
|
||||||
0
secubox-tools/lxc/templates/debian
Normal file
0
secubox-tools/lxc/templates/debian
Normal file
Loading…
Reference in New Issue
Block a user