secubox-openwrt/package/secubox/secubox-app-mailinabox/files/usr/sbin/mailinaboxctl
CyberMind-FR e7c9411d79 feat: Release v0.8.2 - Admin Control Center, Documentation Mirror & Docker Automation
This release adds major new features for SecuBox management and deployment:

## New Features

### 1. LuCI Admin Control Center (luci-app-secubox-admin)
- Unified admin dashboard for managing all SecuBox appstore plugins
- **Control Panel**: Real-time stats, system health, alerts, quick actions
- **Apps Manager**: Browse catalog, install/remove apps with search & filtering
- **App Settings**: Per-app configuration, start/stop controls
- **System Health**: Live monitoring (CPU, RAM, disk) with auto-refresh
- **System Logs**: Centralized log viewer with download capability
- Fully integrated with existing RPCD backend (luci.secubox)
- Mobile-responsive design with polished UI components

### 2. Documentation Mirror in SecuBox Bonus
- Integrated complete development documentation into luci-app-secubox-bonus
- 64+ documentation files now available offline at /luci-static/secubox/docs/
- Beautiful landing page (index-main.html) with 4 sections:
  - Development guides & references
  - Live module demos
  - Tutorials & blog posts
  - Marketing campaign pages
- Accessible locally on router without internet connection

### 3. Automated Docker Plugin Installation
- Enhanced secubox-appstore CLI with full Docker automation
- One-click installation from web UI now fully automated:
  - Auto-detects Docker runtime from catalog
  - Discovers and executes control scripts (*ctl install)
  - Pulls Docker images automatically
  - Creates directories and configures UCI
  - Enables init services
- No manual CLI steps required for Docker apps
- Works for all Docker apps: AdGuard Home, Mail-in-a-Box, Nextcloud, etc.

### 4. Mail-in-a-Box Plugin
- New Docker-based email server plugin (secubox-app-mailinabox)
- Complete package with:
  - UCI configuration (8 port mappings, feature flags)
  - Control script (mailinaboxctl) with install/check/update/status/logs
  - Procd init script with auto-restart
  - Catalog manifest (category: hosting, maturity: beta)
- Network mode: host (required for mail server)
- Persistent storage: mail, SSL, data, DNS volumes

## Improvements

### Build System
- Updated local-build.sh to include luci-app-* packages from package/secubox/
- Now automatically discovers and builds luci-app-secubox-admin and similar packages
- Fixed Makefile include paths for feed structure

### Package Releases
- Incremented PKG_RELEASE for all 31 SecuBox packages
- Ensures clean upgrade path from previous versions

### Catalog Updates
- Mail-in-a-Box entry moved from "productivity" to "hosting" category
- Status changed to "beta" reflecting community Docker image maturity
- Storage requirement increased: 1024MB → 2048MB
- Added port 25 accessibility note

## Files Changed

### New Packages (2)
- package/secubox/luci-app-secubox-admin/ (12 files)
- package/secubox/secubox-app-mailinabox/ (4 files)

### Enhanced Packages (1)
- package/secubox/luci-app-secubox-bonus/ (65 new docs files)

### Modified Core (3)
- package/secubox/secubox-core/root/usr/sbin/secubox-appstore
- package/secubox/secubox-core/root/usr/share/secubox/catalog.json
- secubox-tools/local-build.sh

### All Makefiles (31 packages)
- Incremented PKG_RELEASE for clean upgrade path

## Technical Details

**Admin Control Center Architecture:**
- Frontend: 5 views (dashboard, apps, settings, health, logs)
- API: Wrapper around luci.secubox RPCD methods
- Components: Reusable UI library (cards, badges, alerts, loaders)
- Styling: Common + admin-specific CSS with responsive design
- Auto-refresh: Polling for live updates (5-30s intervals)

**Docker Automation Flow:**
```
Web UI → RPCD → secubox-appstore CLI → opkg install → *ctl install →
docker pull → directories → UCI config → init enable → ✓ Ready
```

**Access Points:**
- Admin Control: http://router/cgi-bin/luci/admin/secubox/admin/
- Documentation: http://router/luci-static/secubox/index-main.html
- Demos: http://router/luci-static/secubox/demo-*.html

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-04 08:29:31 +01:00

228 lines
6.6 KiB
Bash
Executable File

#!/bin/sh
# SecuBox Mail-in-a-Box manager
CONFIG="mailinabox"
CONTAINER="secbx-mailinabox"
OPKG_UPDATED=0
usage() {
cat <<'USAGE'
Usage: mailinaboxctl <command>
Commands:
install Install prerequisites, prepare directories, pull image
check Run prerequisite checks
update Pull new image and restart
status Show container status
logs Show container logs (use -f to follow)
admin Open admin interface in browser (shows URL)
service-run Internal: run container via procd
service-stop Stop container
Post-Installation:
1. Configure hostname and admin_email in /etc/config/mailinabox
2. Ensure proper DNS configuration (A, MX, SPF, DKIM, DMARC records)
3. Start with: /etc/init.d/mailinabox start
4. Access admin panel at https://your-hostname/admin
Important Notes:
- Requires public IP and proper DNS configuration
- Port 25 must be open (some ISPs block it)
- Valid domain name required for SSL certificates
- Initial setup may take 10-15 minutes
USAGE
}
require_root() { [ "$(id -u)" -eq 0 ]; }
uci_get() { uci -q get ${CONFIG}.main.$1; }
defaults() {
image="$(uci_get image || echo docker-mailserver/docker-mailserver:latest)"
data_path="$(uci_get data_path || echo /srv/mailinabox)"
hostname="$(uci_get hostname || echo mail.example.com)"
admin_email="$(uci_get admin_email || echo admin@example.com)"
timezone="$(uci_get timezone || echo UTC)"
smtp_port="$(uci_get smtp_port || echo 25)"
dns_port="$(uci_get dns_port || echo 53)"
http_port="$(uci_get http_port || echo 80)"
https_port="$(uci_get https_port || echo 443)"
submission_port="$(uci_get submission_port || echo 587)"
imaps_port="$(uci_get imaps_port || echo 993)"
pop3s_port="$(uci_get pop3s_port || echo 995)"
sieve_port="$(uci_get sieve_port || echo 4190)"
enable_dns="$(uci_get enable_dns || echo 1)"
enable_webmail="$(uci_get enable_webmail || echo 1)"
letsencrypt="$(uci_get letsencrypt || echo 1)"
}
ensure_dir() { [ -d "$1" ] || mkdir -p "$1"; }
ensure_packages() {
for pkg in "$@"; do
if ! opkg status "$pkg" >/dev/null 2>&1; then
if [ "$OPKG_UPDATED" -eq 0 ]; then
opkg update || return 1
OPKG_UPDATED=1
fi
opkg install "$pkg" || return 1
fi
done
}
check_prereqs() {
defaults
# Check hostname configuration
if [ "$hostname" = "mail.example.com" ]; then
echo "[WARNING] Please configure hostname in /etc/config/mailinabox" >&2
echo "[WARNING] Mail-in-a-Box requires a valid domain name" >&2
fi
# Create data directories
ensure_dir "$data_path"
ensure_dir "$data_path/mail"
ensure_dir "$data_path/ssl"
ensure_dir "$data_path/data"
ensure_dir "$data_path/dns"
# Check system requirements
[ -d /sys/fs/cgroup ] || { echo "[ERROR] /sys/fs/cgroup missing" >&2; return 1; }
# Install Docker
ensure_packages dockerd docker containerd
/etc/init.d/dockerd enable >/dev/null 2>&1
/etc/init.d/dockerd start >/dev/null 2>&1
# Port conflict checks
if [ "$smtp_port" = "25" ]; then
if netstat -tln 2>/dev/null | grep -q ":25 "; then
echo "[WARNING] Port 25 already in use - potential conflict" >&2
fi
fi
if [ "$dns_port" = "53" ] && [ "$enable_dns" = "1" ]; then
if netstat -uln 2>/dev/null | grep -q ":53 "; then
echo "[WARNING] Port 53 already in use - DNS may conflict with dnsmasq" >&2
echo "[WARNING] Consider disabling Mail-in-a-Box DNS or moving dnsmasq" >&2
fi
fi
}
pull_image() { defaults; docker pull "$image"; }
stop_container() {
docker stop "$CONTAINER" >/dev/null 2>&1 || true
docker rm "$CONTAINER" >/dev/null 2>&1 || true
}
cmd_install() {
require_root || { echo Root required >&2; exit 1; }
check_prereqs || exit 1
pull_image || exit 1
uci set ${CONFIG}.main.enabled='1'
uci commit ${CONFIG}
/etc/init.d/mailinabox enable
echo ""
echo "Mail-in-a-Box prerequisites installed."
echo ""
echo "CRITICAL NEXT STEPS:"
echo " 1. Edit /etc/config/mailinabox and set:"
echo " - hostname (must be a valid FQDN)"
echo " - admin_email"
echo " 2. Configure DNS records for your domain:"
echo " - A record: $hostname -> your-public-ip"
echo " - MX record: @ -> $hostname"
echo " 3. Ensure port 25 is not blocked by your ISP"
echo " 4. Start with: /etc/init.d/mailinabox start"
echo " 5. Access admin at: https://$hostname/admin"
echo ""
}
cmd_check() {
check_prereqs
echo "Prerequisite check completed."
echo ""
defaults
echo "Current configuration:"
echo " Hostname: $hostname"
echo " Admin email: $admin_email"
echo " Data path: $data_path"
echo " DNS enabled: $enable_dns"
echo ""
}
cmd_update() {
require_root || { echo Root required >&2; exit 1; }
pull_image || exit 1
/etc/init.d/mailinabox restart
}
cmd_status() { docker ps -a --filter "name=$CONTAINER"; }
cmd_logs() { docker logs "$@" "$CONTAINER"; }
cmd_admin() {
defaults
echo "Admin interface: https://$hostname/admin"
echo ""
echo "If accessing locally, you may need to:"
echo " - Add '$hostname' to your hosts file"
echo " - Or use: https://$(uci get network.lan.ipaddr 2>/dev/null || echo 'router-ip')/admin"
}
cmd_service_run() {
require_root || { echo Root required >&2; exit 1; }
check_prereqs || exit 1
defaults
stop_container
local docker_args="--name $CONTAINER"
# Network mode: host for mail server functionality
docker_args="$docker_args --network host"
# Volume mounts
docker_args="$docker_args -v $data_path/mail:/var/mail"
docker_args="$docker_args -v $data_path/ssl:/etc/ssl/mail"
docker_args="$docker_args -v $data_path/data:/var/mail-state"
docker_args="$docker_args -v $data_path/dns:/etc/bind"
# Environment variables for docker-mailserver
docker_args="$docker_args -e TZ=$timezone"
docker_args="$docker_args -e OVERRIDE_HOSTNAME=$hostname"
docker_args="$docker_args -e ENABLE_SPAMASSASSIN=1"
docker_args="$docker_args -e ENABLE_CLAMAV=1"
docker_args="$docker_args -e ENABLE_FAIL2BAN=1"
docker_args="$docker_args -e SSL_TYPE=letsencrypt"
# Capabilities for mail server
docker_args="$docker_args --cap-add=NET_ADMIN"
docker_args="$docker_args --cap-add=NET_BIND_SERVICE"
# Restart policy
docker_args="$docker_args --restart=unless-stopped"
exec docker run --rm $docker_args "$image"
}
cmd_service_stop() {
require_root || { echo Root required >&2; exit 1; }
stop_container
}
case "${1:-}" in
install) shift; cmd_install "$@" ;;
check) shift; cmd_check "$@" ;;
update) shift; cmd_update "$@" ;;
status) shift; cmd_status "$@" ;;
logs) shift; cmd_logs "$@" ;;
admin) shift; cmd_admin "$@" ;;
service-run) shift; cmd_service_run "$@" ;;
service-stop) shift; cmd_service_stop "$@" ;;
help|--help|-h|'') usage ;;
*) echo "Unknown command: $1" >&2; usage >&2; exit 1 ;;
esac