mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-28 21:17:36 +00:00
feat(migration): Extend migration tools v2.1.0 with 19 modules
Add comprehensive data migration covering all SecuBox services: Export modules (migration-export.sh): - dns: BIND zones, Vortex RPZ blocklists, Unbound, AdGuard, Pi-hole - databases: SQLite, MySQL/MariaDB, PostgreSQL, Redis dumps - scripts: Custom scripts, systemd units, rc.local, cron jobs - services: All /srv/* directories including: - Streamlit instances - Metablogizer/Metabolizer apps - Gitea/Git repositories with full history - Docker compose configurations - LXC container configs - mitmproxy, config-vault, saas-relay Import modules (migration-import.sh): - Corresponding restore functions for all new modules - Service detection and systemd integration - Database restore with owner/permission handling Enhanced HAProxy export: - conf.d modular architecture - Certificate management - Lua scripts and maps - mitmproxy route integration Total modules: 19 (network, firewall, wireguard, crowdsec, dhcp, haproxy, nginx, certs, content, vhosts, users, state, git, media, mail, accounts, dns, databases, scripts, services) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a8b80ff9c4
commit
6edd343019
|
|
@ -15,7 +15,7 @@ set -euo pipefail
|
|||
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
readonly REPO="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
readonly VERSION="2.0.0"
|
||||
readonly VERSION="2.1.0"
|
||||
readonly TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
|
||||
|
||||
# ── Colors ──
|
||||
|
|
@ -59,7 +59,7 @@ Options:
|
|||
-m, --modules LIST Comma-separated module list (default: all)
|
||||
Available: network,firewall,wireguard,crowdsec,dhcp,
|
||||
haproxy,nginx,certs,content,vhosts,users,
|
||||
git,media,mail,accounts
|
||||
git,media,mail,accounts,dns,databases,scripts
|
||||
--help Show this help
|
||||
|
||||
Examples:
|
||||
|
|
@ -243,17 +243,66 @@ export_dhcp() {
|
|||
}
|
||||
|
||||
export_haproxy() {
|
||||
section "Exporting: HAProxy Configuration"
|
||||
section "Exporting: HAProxy Configuration (Full)"
|
||||
local dst="$WORKDIR/configs/haproxy"
|
||||
mkdir -p "$dst"
|
||||
local secrets_dst="$WORKDIR/secrets/haproxy"
|
||||
mkdir -p "$dst" "$secrets_dst"
|
||||
|
||||
# Main config
|
||||
ssh_run "cat /etc/haproxy/haproxy.cfg 2>/dev/null" > "$dst/haproxy.cfg" || warn "No HAProxy config"
|
||||
|
||||
# Additional configs
|
||||
ssh_run "tar -czf - /etc/haproxy/conf.d 2>/dev/null" | tar -xzf - -C "$dst" --strip-components=2 || true
|
||||
# conf.d directory (backend definitions, ACLs, routing)
|
||||
if ssh_run "[ -d '/etc/haproxy/conf.d' ]" 2>/dev/null; then
|
||||
log " Exporting HAProxy conf.d..."
|
||||
mkdir -p "$dst/conf.d"
|
||||
ssh_run "tar -czf - /etc/haproxy/conf.d 2>/dev/null" | tar -xzf - -C "$dst/conf.d" --strip-components=3 || true
|
||||
local conf_count=$(ls "$dst/conf.d"/*.cfg 2>/dev/null | wc -l || echo "0")
|
||||
log " Found $conf_count config snippets"
|
||||
fi
|
||||
|
||||
ok "HAProxy exported"
|
||||
# HAProxy certificates (secrets)
|
||||
if ssh_run "[ -d '/etc/haproxy/certs' ]" 2>/dev/null; then
|
||||
log " Exporting HAProxy certificates..."
|
||||
mkdir -p "$secrets_dst/certs"
|
||||
ssh_run "tar -czf - /etc/haproxy/certs 2>/dev/null" | tar -xzf - -C "$secrets_dst/certs" --strip-components=3 || true
|
||||
local cert_count=$(ssh_run "ls /etc/haproxy/certs/*.pem 2>/dev/null | wc -l" || echo "0")
|
||||
log " Found $cert_count certificate files"
|
||||
fi
|
||||
|
||||
# HAProxy maps (domain → backend mappings)
|
||||
if ssh_run "[ -d '/etc/haproxy/maps' ]" 2>/dev/null; then
|
||||
log " Exporting HAProxy maps..."
|
||||
mkdir -p "$dst/maps"
|
||||
ssh_run "tar -czf - /etc/haproxy/maps 2>/dev/null" | tar -xzf - -C "$dst/maps" --strip-components=3 || true
|
||||
fi
|
||||
|
||||
# HAProxy errors directory (custom error pages)
|
||||
if ssh_run "[ -d '/etc/haproxy/errors' ]" 2>/dev/null; then
|
||||
log " Exporting HAProxy error pages..."
|
||||
mkdir -p "$dst/errors"
|
||||
ssh_run "tar -czf - /etc/haproxy/errors 2>/dev/null" | tar -xzf - -C "$dst/errors" --strip-components=3 || true
|
||||
fi
|
||||
|
||||
# ACME/Let's Encrypt HAProxy integration
|
||||
if ssh_run "[ -f '/etc/haproxy/acme.cfg' ]" 2>/dev/null; then
|
||||
ssh_run "cat /etc/haproxy/acme.cfg 2>/dev/null" > "$dst/acme.cfg" || true
|
||||
fi
|
||||
|
||||
# HAProxy Lua scripts
|
||||
if ssh_run "[ -d '/etc/haproxy/lua' ]" 2>/dev/null; then
|
||||
log " Exporting HAProxy Lua scripts..."
|
||||
mkdir -p "$dst/lua"
|
||||
ssh_run "tar -czf - /etc/haproxy/lua 2>/dev/null" | tar -xzf - -C "$dst/lua" --strip-components=3 || true
|
||||
fi
|
||||
|
||||
# mitmproxy routes mapping (SecuBox specific)
|
||||
if ssh_run "[ -f '/srv/mitmproxy/haproxy-routes.json' ]" 2>/dev/null; then
|
||||
log " Exporting mitmproxy routes..."
|
||||
ssh_run "cat /srv/mitmproxy/haproxy-routes.json 2>/dev/null" > "$dst/mitmproxy-routes.json" || true
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$dst" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "HAProxy exported ($size)"
|
||||
}
|
||||
|
||||
export_nginx() {
|
||||
|
|
@ -563,6 +612,285 @@ export_accounts() {
|
|||
ok "User accounts exported ($user_count users, $size)"
|
||||
}
|
||||
|
||||
export_dns() {
|
||||
section "Exporting: DNS Services (BIND, Vortex, AdGuard)"
|
||||
local dst="$WORKDIR/configs/dns"
|
||||
local secrets_dst="$WORKDIR/secrets/dns"
|
||||
mkdir -p "$dst" "$secrets_dst"
|
||||
|
||||
# BIND/named configuration
|
||||
if ssh_run "[ -d '/etc/bind' ]" 2>/dev/null; then
|
||||
log " Exporting BIND configuration..."
|
||||
mkdir -p "$dst/bind"
|
||||
ssh_run "tar -czf - /etc/bind 2>/dev/null" | tar -xzf - -C "$dst/bind" --strip-components=2 || true
|
||||
|
||||
# Zones directory separately (may be large)
|
||||
if ssh_run "[ -d '/etc/bind/zones' ]" 2>/dev/null; then
|
||||
log " Exporting DNS zones..."
|
||||
mkdir -p "$dst/bind/zones"
|
||||
ssh_run "tar -czf - /etc/bind/zones 2>/dev/null" | tar -xzf - -C "$dst/bind/zones" --strip-components=3 || true
|
||||
local zone_count=$(ls "$dst/bind/zones"/*.zone 2>/dev/null | wc -l || echo "0")
|
||||
log " Found $zone_count zone files"
|
||||
fi
|
||||
|
||||
# RNDC key (secret)
|
||||
ssh_run "cat /etc/bind/rndc.key 2>/dev/null" > "$secrets_dst/rndc.key" || true
|
||||
fi
|
||||
|
||||
# Unbound configuration
|
||||
if ssh_run "[ -d '/etc/unbound' ]" 2>/dev/null; then
|
||||
log " Exporting Unbound configuration..."
|
||||
mkdir -p "$dst/unbound"
|
||||
ssh_run "tar -czf - /etc/unbound 2>/dev/null" | tar -xzf - -C "$dst/unbound" --strip-components=2 || true
|
||||
fi
|
||||
|
||||
# Vortex DNS (dnsmasq-based blocklists)
|
||||
if ssh_run "[ -d '/etc/dnsmasq.d/vortex' ]" 2>/dev/null; then
|
||||
log " Exporting Vortex DNS blocklists..."
|
||||
mkdir -p "$dst/vortex"
|
||||
ssh_run "tar -czf - /etc/dnsmasq.d/vortex 2>/dev/null" | tar -xzf - -C "$dst/vortex" --strip-components=3 || true
|
||||
ssh_run "cat /etc/dnsmasq.d/vortex*.conf 2>/dev/null" > "$dst/vortex/vortex-main.conf" || true
|
||||
fi
|
||||
|
||||
# Vortex RPZ zone (Response Policy Zone for blocking)
|
||||
if ssh_run "[ -f '/etc/bind/zones/rpz.vortex.zone' ]" 2>/dev/null; then
|
||||
log " Exporting Vortex RPZ zone (blocklist)..."
|
||||
ssh_run "cat /etc/bind/zones/rpz.vortex.zone 2>/dev/null" > "$dst/bind/zones/rpz.vortex.zone" || true
|
||||
local rpz_size=$(ssh_run "du -h /etc/bind/zones/rpz.vortex.zone 2>/dev/null | cut -f1" || echo "0")
|
||||
log " RPZ zone size: $rpz_size"
|
||||
fi
|
||||
|
||||
# AdGuard Home
|
||||
if ssh_run "[ -f '/etc/adguardhome/AdGuardHome.yaml' ]" 2>/dev/null; then
|
||||
log " Exporting AdGuard Home configuration..."
|
||||
mkdir -p "$dst/adguardhome"
|
||||
ssh_run "cat /etc/adguardhome/AdGuardHome.yaml 2>/dev/null" > "$dst/adguardhome/AdGuardHome.yaml" || true
|
||||
|
||||
# AdGuard Home data (filters, stats)
|
||||
if ssh_run "[ -d '/var/lib/adguardhome/data' ]" 2>/dev/null; then
|
||||
mkdir -p "$dst/adguardhome/data"
|
||||
ssh_run "tar -czf - /var/lib/adguardhome/data 2>/dev/null" | tar -xzf - -C "$dst/adguardhome/data" --strip-components=4 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Pi-hole (if present)
|
||||
if ssh_run "[ -d '/etc/pihole' ]" 2>/dev/null; then
|
||||
log " Exporting Pi-hole configuration..."
|
||||
mkdir -p "$dst/pihole"
|
||||
ssh_run "tar -czf - /etc/pihole 2>/dev/null" | tar -xzf - -C "$dst/pihole" --strip-components=2 || true
|
||||
fi
|
||||
|
||||
# Additional dnsmasq configs
|
||||
ssh_run "cat /etc/dnsmasq.d/*.conf 2>/dev/null" > "$dst/dnsmasq.d.conf" || true
|
||||
|
||||
local size=$(du -sh "$dst" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "DNS services exported ($size)"
|
||||
}
|
||||
|
||||
export_databases() {
|
||||
section "Exporting: Databases (SQLite, MySQL dumps)"
|
||||
local dst="$WORKDIR/state/databases"
|
||||
mkdir -p "$dst"
|
||||
|
||||
# SQLite databases from common locations
|
||||
local db_paths="/var/lib/*.db /srv/*.db /var/lib/*/data/*.db /var/lib/*/*/*.db"
|
||||
local db_count=0
|
||||
|
||||
for db_pattern in $db_paths; do
|
||||
ssh_run "ls $db_pattern 2>/dev/null" | while read -r db_file; do
|
||||
[[ -z "$db_file" ]] && continue
|
||||
local db_name=$(basename "$db_file")
|
||||
local db_dir=$(dirname "$db_file" | tr '/' '_' | sed 's/^_//')
|
||||
mkdir -p "$dst/$db_dir"
|
||||
log " Exporting: $db_file"
|
||||
ssh_run "cat '$db_file' 2>/dev/null" > "$dst/$db_dir/$db_name" || true
|
||||
((db_count++))
|
||||
done || true
|
||||
done
|
||||
|
||||
# MySQL/MariaDB dump (if mysqldump available)
|
||||
if ssh_run "which mysqldump >/dev/null 2>&1"; then
|
||||
log " Creating MySQL dump..."
|
||||
mkdir -p "$dst/mysql"
|
||||
ssh_run "mysqldump --all-databases --single-transaction 2>/dev/null" > "$dst/mysql/all-databases.sql" || warn "MySQL dump failed"
|
||||
fi
|
||||
|
||||
# PostgreSQL dump (if pg_dumpall available)
|
||||
if ssh_run "which pg_dumpall >/dev/null 2>&1"; then
|
||||
log " Creating PostgreSQL dump..."
|
||||
mkdir -p "$dst/postgresql"
|
||||
ssh_run "su - postgres -c 'pg_dumpall' 2>/dev/null" > "$dst/postgresql/all-databases.sql" || warn "PostgreSQL dump failed"
|
||||
fi
|
||||
|
||||
# Redis dump
|
||||
if ssh_run "[ -f '/var/lib/redis/dump.rdb' ]" 2>/dev/null; then
|
||||
log " Exporting Redis dump..."
|
||||
mkdir -p "$dst/redis"
|
||||
ssh_run "cat /var/lib/redis/dump.rdb 2>/dev/null" > "$dst/redis/dump.rdb" || true
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$dst" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "Databases exported ($size)"
|
||||
}
|
||||
|
||||
export_scripts() {
|
||||
section "Exporting: Custom Scripts and Systemd Units"
|
||||
local dst="$WORKDIR/configs/scripts"
|
||||
mkdir -p "$dst"
|
||||
|
||||
# Custom scripts from common locations
|
||||
local script_dirs="/usr/local/bin /usr/local/sbin /root/scripts /root/bin /opt/scripts"
|
||||
for script_dir in $script_dirs; do
|
||||
if ssh_run "[ -d '$script_dir' ]" 2>/dev/null; then
|
||||
log " Exporting: $script_dir"
|
||||
local dir_name=$(echo "$script_dir" | tr '/' '_' | sed 's/^_//')
|
||||
mkdir -p "$dst/$dir_name"
|
||||
ssh_run "tar -czf - '$script_dir' 2>/dev/null" | tar -xzf - -C "$dst/$dir_name" --strip-components=3 || true
|
||||
fi
|
||||
done
|
||||
|
||||
# Systemd unit overrides
|
||||
if ssh_run "[ -d '/etc/systemd/system' ]" 2>/dev/null; then
|
||||
log " Exporting systemd unit overrides..."
|
||||
mkdir -p "$dst/systemd"
|
||||
ssh_run "find /etc/systemd/system -name '*.service' -o -name '*.d' -type d 2>/dev/null" | while read -r unit; do
|
||||
[[ -z "$unit" ]] && continue
|
||||
local unit_name=$(basename "$unit")
|
||||
if [[ -d "$unit" ]]; then
|
||||
ssh_run "tar -czf - '$unit' 2>/dev/null" | tar -xzf - -C "$dst/systemd" --strip-components=3 || true
|
||||
else
|
||||
ssh_run "cat '$unit' 2>/dev/null" > "$dst/systemd/$unit_name" || true
|
||||
fi
|
||||
done || true
|
||||
fi
|
||||
|
||||
# Init.d scripts (OpenWrt style)
|
||||
if ssh_run "[ -d '/etc/init.d' ]" 2>/dev/null; then
|
||||
log " Exporting init.d scripts..."
|
||||
mkdir -p "$dst/init.d"
|
||||
ssh_run "tar -czf - /etc/init.d 2>/dev/null" | tar -xzf - -C "$dst/init.d" --strip-components=2 || true
|
||||
fi
|
||||
|
||||
# RC.local
|
||||
ssh_run "cat /etc/rc.local 2>/dev/null" > "$dst/rc.local" || true
|
||||
|
||||
# Environment files
|
||||
mkdir -p "$dst/environment"
|
||||
ssh_run "cat /etc/environment 2>/dev/null" > "$dst/environment/environment" || true
|
||||
ssh_run "cat /etc/default/* 2>/dev/null" > "$dst/environment/defaults" || true
|
||||
|
||||
local size=$(du -sh "$dst" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "Scripts and units exported ($size)"
|
||||
}
|
||||
|
||||
export_services() {
|
||||
section "Exporting: Application Services (/srv/*)"
|
||||
local dst="$WORKDIR/content/services"
|
||||
mkdir -p "$dst"
|
||||
|
||||
# List of service directories to export from /srv/
|
||||
local services="
|
||||
streamlit
|
||||
gitea
|
||||
metablogizer
|
||||
metabolizer
|
||||
metacatalog
|
||||
mitmproxy
|
||||
mitmproxy-in
|
||||
mitmproxy-out
|
||||
secubox
|
||||
config-vault
|
||||
saas-relay
|
||||
hexojs
|
||||
gotosocial
|
||||
nextcloud
|
||||
peertube
|
||||
matrix
|
||||
simplex
|
||||
voip
|
||||
webradio
|
||||
zigbee2mqtt
|
||||
domoticz
|
||||
photoprism
|
||||
rezapp
|
||||
haproxy
|
||||
crowdsec
|
||||
dns
|
||||
dns-master
|
||||
lxc
|
||||
jabber
|
||||
jitsi
|
||||
localai
|
||||
sherlock
|
||||
maltego
|
||||
"
|
||||
|
||||
for svc in $services; do
|
||||
svc=$(echo "$svc" | tr -d ' ')
|
||||
[[ -z "$svc" ]] && continue
|
||||
|
||||
if ssh_run "[ -d '/srv/$svc' ]" 2>/dev/null; then
|
||||
log " Exporting: /srv/$svc"
|
||||
mkdir -p "$dst/$svc"
|
||||
|
||||
# Export service directory (excluding large binary/cache dirs)
|
||||
ssh_run "tar -czf - \
|
||||
--exclude='*.log' \
|
||||
--exclude='node_modules' \
|
||||
--exclude='__pycache__' \
|
||||
--exclude='.cache' \
|
||||
--exclude='cache' \
|
||||
--exclude='*.pyc' \
|
||||
--exclude='.venv' \
|
||||
--exclude='venv' \
|
||||
/srv/$svc 2>/dev/null" | tar -xzf - -C "$dst/$svc" --strip-components=2 || warn "Partial export: $svc"
|
||||
fi
|
||||
done
|
||||
|
||||
# Export Streamlit apps specifically
|
||||
if ssh_run "[ -d '/srv/streamlit/apps' ]" 2>/dev/null; then
|
||||
log " Exporting Streamlit apps..."
|
||||
mkdir -p "$dst/streamlit-apps"
|
||||
ssh_run "tar -czf - /srv/streamlit/apps 2>/dev/null" | tar -xzf - -C "$dst/streamlit-apps" --strip-components=3 || true
|
||||
local app_count=$(ssh_run "ls -d /srv/streamlit/apps/*/ 2>/dev/null | wc -l" || echo "0")
|
||||
log " Found $app_count Streamlit apps"
|
||||
fi
|
||||
|
||||
# Export Git repositories (full repos with history)
|
||||
log " Discovering Git repositories..."
|
||||
ssh_run "find /srv -maxdepth 4 -name '.git' -type d 2>/dev/null" | while read -r git_dir; do
|
||||
[[ -z "$git_dir" ]] && continue
|
||||
local repo_path=$(dirname "$git_dir")
|
||||
local repo_name=$(echo "$repo_path" | sed 's|/srv/||' | tr '/' '_')
|
||||
log " Exporting repo: $repo_name"
|
||||
mkdir -p "$dst/git-repos"
|
||||
ssh_run "tar -czf - '$repo_path' 2>/dev/null" > "$dst/git-repos/${repo_name}.tar.gz" || true
|
||||
done || true
|
||||
|
||||
# Export Docker/Podman compose files
|
||||
log " Exporting Docker compose files..."
|
||||
mkdir -p "$dst/docker-compose"
|
||||
ssh_run "find /srv -name 'docker-compose*.yml' -o -name 'docker-compose*.yaml' 2>/dev/null" | while read -r compose_file; do
|
||||
[[ -z "$compose_file" ]] && continue
|
||||
local compose_name=$(echo "$compose_file" | tr '/' '_' | sed 's/^_srv_//')
|
||||
ssh_run "cat '$compose_file' 2>/dev/null" > "$dst/docker-compose/$compose_name" || true
|
||||
done || true
|
||||
|
||||
# Export LXC container configs
|
||||
if ssh_run "[ -d '/srv/lxc' ]" 2>/dev/null; then
|
||||
log " Exporting LXC container configs..."
|
||||
mkdir -p "$dst/lxc"
|
||||
ssh_run "ls /srv/lxc 2>/dev/null" | while read -r container; do
|
||||
[[ -z "$container" ]] && continue
|
||||
ssh_run "cat /srv/lxc/$container/config 2>/dev/null" > "$dst/lxc/${container}.config" || true
|
||||
done || true
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$dst" 2>/dev/null | cut -f1 || echo "0")
|
||||
local svc_count=$(ls -d "$dst"/*/ 2>/dev/null | wc -l || echo "0")
|
||||
ok "Services exported ($svc_count services, $size)"
|
||||
}
|
||||
|
||||
# ── Module selection ──
|
||||
declare -A MODULE_FUNCS=(
|
||||
[network]=export_network
|
||||
|
|
@ -581,9 +909,13 @@ declare -A MODULE_FUNCS=(
|
|||
[media]=export_media
|
||||
[mail]=export_mail
|
||||
[accounts]=export_accounts
|
||||
[dns]=export_dns
|
||||
[databases]=export_databases
|
||||
[scripts]=export_scripts
|
||||
[services]=export_services
|
||||
)
|
||||
|
||||
ALL_MODULES="network,firewall,wireguard,crowdsec,dhcp,haproxy,nginx,certs,content,vhosts,users,state,git,media,mail,accounts"
|
||||
ALL_MODULES="network,firewall,wireguard,crowdsec,dhcp,haproxy,nginx,certs,content,vhosts,users,state,git,media,mail,accounts,dns,databases,scripts,services"
|
||||
|
||||
if [[ "$MODULES" == "all" ]]; then
|
||||
MODULES="$ALL_MODULES"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ set -euo pipefail
|
|||
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
readonly REPO="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
readonly VERSION="2.0.0"
|
||||
readonly VERSION="2.1.0"
|
||||
readonly TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
|
||||
|
||||
# ── Colors ──
|
||||
|
|
@ -55,6 +55,9 @@ MEDIA_DIR="/srv/media"
|
|||
MAIL_DIR="/var/vmail"
|
||||
POSTFIX_DIR="/etc/postfix"
|
||||
DOVECOT_DIR="/etc/dovecot"
|
||||
BIND_DIR="/etc/bind"
|
||||
UNBOUND_DIR="/etc/unbound"
|
||||
ADGUARD_DIR="/etc/adguardhome"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
|
|
@ -76,7 +79,7 @@ Options:
|
|||
-m, --modules LIST Comma-separated module list (default: all)
|
||||
Available: network,firewall,wireguard,crowdsec,dhcp,
|
||||
haproxy,nginx,certs,content,vhosts,users,state,
|
||||
git,media,mail,accounts
|
||||
git,media,mail,accounts,dns,databases,scripts
|
||||
--help Show this help
|
||||
|
||||
Examples:
|
||||
|
|
@ -879,6 +882,288 @@ import_accounts() {
|
|||
fi
|
||||
}
|
||||
|
||||
import_dns() {
|
||||
section "Importing: DNS Services"
|
||||
|
||||
local src="$WORKDIR/configs/dns"
|
||||
local secrets_src="$WORKDIR/secrets/dns"
|
||||
|
||||
if [[ -d "$src" && -n "$(ls -A "$src" 2>/dev/null)" ]]; then
|
||||
# BIND/named
|
||||
if [[ -d "$src/bind" ]]; then
|
||||
log " Importing BIND configuration..."
|
||||
run "mkdir -p '$BIND_DIR'"
|
||||
run "cp -r '$src/bind/'* '$BIND_DIR/' 2>/dev/null || true"
|
||||
|
||||
# Import zones
|
||||
if [[ -d "$src/bind/zones" ]]; then
|
||||
run "mkdir -p '$BIND_DIR/zones'"
|
||||
run "cp -r '$src/bind/zones/'* '$BIND_DIR/zones/' 2>/dev/null || true"
|
||||
local zone_count=$(ls "$src/bind/zones"/*.zone 2>/dev/null | wc -l || echo "0")
|
||||
log " Imported $zone_count zone files"
|
||||
fi
|
||||
|
||||
# Import RNDC key from secrets
|
||||
if [[ -f "$secrets_src/rndc.key" ]]; then
|
||||
run "cp '$secrets_src/rndc.key' '$BIND_DIR/'"
|
||||
run "chmod 600 '$BIND_DIR/rndc.key'"
|
||||
fi
|
||||
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
chown -R bind:bind "$BIND_DIR" 2>/dev/null || true
|
||||
systemctl restart named 2>/dev/null || systemctl restart bind9 2>/dev/null || warn "BIND restart failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Unbound
|
||||
if [[ -d "$src/unbound" ]]; then
|
||||
log " Importing Unbound configuration..."
|
||||
run "mkdir -p '$UNBOUND_DIR'"
|
||||
run "cp -r '$src/unbound/'* '$UNBOUND_DIR/' 2>/dev/null || true"
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
systemctl restart unbound 2>/dev/null || warn "Unbound restart failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Vortex DNS (dnsmasq blocklists)
|
||||
if [[ -d "$src/vortex" ]]; then
|
||||
log " Importing Vortex DNS blocklists..."
|
||||
run "mkdir -p '/etc/dnsmasq.d/vortex'"
|
||||
run "cp -r '$src/vortex/'* '/etc/dnsmasq.d/vortex/' 2>/dev/null || true"
|
||||
fi
|
||||
|
||||
# AdGuard Home
|
||||
if [[ -d "$src/adguardhome" ]]; then
|
||||
log " Importing AdGuard Home configuration..."
|
||||
run "mkdir -p '$ADGUARD_DIR'"
|
||||
run "cp '$src/adguardhome/AdGuardHome.yaml' '$ADGUARD_DIR/' 2>/dev/null || true"
|
||||
if [[ -d "$src/adguardhome/data" ]]; then
|
||||
run "mkdir -p '/var/lib/adguardhome/data'"
|
||||
run "cp -r '$src/adguardhome/data/'* '/var/lib/adguardhome/data/' 2>/dev/null || true"
|
||||
fi
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
systemctl restart AdGuardHome 2>/dev/null || warn "AdGuard Home restart failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Pi-hole
|
||||
if [[ -d "$src/pihole" ]]; then
|
||||
log " Importing Pi-hole configuration..."
|
||||
run "mkdir -p '/etc/pihole'"
|
||||
run "cp -r '$src/pihole/'* '/etc/pihole/' 2>/dev/null || true"
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
pihole restartdns 2>/dev/null || warn "Pi-hole restart failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$src" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "DNS services imported ($size)"
|
||||
else
|
||||
warn "No DNS configuration to import"
|
||||
fi
|
||||
}
|
||||
|
||||
import_databases() {
|
||||
section "Importing: Databases"
|
||||
|
||||
local src="$WORKDIR/state/databases"
|
||||
|
||||
if [[ -d "$src" && -n "$(ls -A "$src" 2>/dev/null)" ]]; then
|
||||
# SQLite databases - restore to original locations
|
||||
for db_dir in "$src"/var_lib_*; do
|
||||
[[ -d "$db_dir" ]] || continue
|
||||
local original_path=$(echo "$db_dir" | sed 's/_/\//g' | sed 's/.*var/\/var/')
|
||||
log " Restoring databases to: $original_path"
|
||||
run "mkdir -p '$original_path'"
|
||||
run "cp -r '$db_dir/'* '$original_path/' 2>/dev/null || true"
|
||||
done
|
||||
|
||||
# MySQL restore
|
||||
if [[ -f "$src/mysql/all-databases.sql" ]]; then
|
||||
log " Restoring MySQL databases..."
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
mysql < "$src/mysql/all-databases.sql" 2>/dev/null || warn "MySQL restore failed"
|
||||
else
|
||||
log " Would restore MySQL from all-databases.sql"
|
||||
fi
|
||||
fi
|
||||
|
||||
# PostgreSQL restore
|
||||
if [[ -f "$src/postgresql/all-databases.sql" ]]; then
|
||||
log " Restoring PostgreSQL databases..."
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
su - postgres -c "psql < $src/postgresql/all-databases.sql" 2>/dev/null || warn "PostgreSQL restore failed"
|
||||
else
|
||||
log " Would restore PostgreSQL from all-databases.sql"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Redis restore
|
||||
if [[ -f "$src/redis/dump.rdb" ]]; then
|
||||
log " Restoring Redis dump..."
|
||||
run "mkdir -p '/var/lib/redis'"
|
||||
run "cp '$src/redis/dump.rdb' '/var/lib/redis/'"
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
chown redis:redis /var/lib/redis/dump.rdb 2>/dev/null || true
|
||||
systemctl restart redis 2>/dev/null || warn "Redis restart failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$src" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "Databases imported ($size)"
|
||||
else
|
||||
warn "No databases to import"
|
||||
fi
|
||||
}
|
||||
|
||||
import_scripts() {
|
||||
section "Importing: Custom Scripts and Units"
|
||||
|
||||
local src="$WORKDIR/configs/scripts"
|
||||
|
||||
if [[ -d "$src" && -n "$(ls -A "$src" 2>/dev/null)" ]]; then
|
||||
# Custom scripts
|
||||
for script_dir in "$src"/usr_local_*; do
|
||||
[[ -d "$script_dir" ]] || continue
|
||||
local target="/usr/local/bin"
|
||||
log " Importing scripts to: $target"
|
||||
run "mkdir -p '$target'"
|
||||
run "cp -r '$script_dir/'* '$target/' 2>/dev/null || true"
|
||||
run "chmod +x '$target/'* 2>/dev/null || true"
|
||||
done
|
||||
|
||||
for script_dir in "$src"/root_*; do
|
||||
[[ -d "$script_dir" ]] || continue
|
||||
local target="/root/scripts"
|
||||
log " Importing scripts to: $target"
|
||||
run "mkdir -p '$target'"
|
||||
run "cp -r '$script_dir/'* '$target/' 2>/dev/null || true"
|
||||
run "chmod +x '$target/'* 2>/dev/null || true"
|
||||
done
|
||||
|
||||
# Systemd unit overrides
|
||||
if [[ -d "$src/systemd" ]]; then
|
||||
log " Importing systemd unit overrides..."
|
||||
for unit in "$src/systemd"/*; do
|
||||
[[ -e "$unit" ]] || continue
|
||||
local unit_name=$(basename "$unit")
|
||||
if [[ -d "$unit" ]]; then
|
||||
run "mkdir -p '/etc/systemd/system/$unit_name'"
|
||||
run "cp -r '$unit/'* '/etc/systemd/system/$unit_name/' 2>/dev/null || true"
|
||||
else
|
||||
run "cp '$unit' '/etc/systemd/system/$unit_name'"
|
||||
fi
|
||||
log " Imported: $unit_name"
|
||||
done
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
systemctl daemon-reload 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# RC.local
|
||||
if [[ -f "$src/rc.local" && -s "$src/rc.local" ]]; then
|
||||
log " Importing rc.local..."
|
||||
run "cp '$src/rc.local' '/etc/rc.local'"
|
||||
run "chmod +x '/etc/rc.local'"
|
||||
fi
|
||||
|
||||
# Environment files
|
||||
if [[ -d "$src/environment" ]]; then
|
||||
if [[ -f "$src/environment/environment" && -s "$src/environment/environment" ]]; then
|
||||
log " Importing /etc/environment..."
|
||||
run "cp '$src/environment/environment' '/etc/environment'"
|
||||
fi
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$src" 2>/dev/null | cut -f1 || echo "0")
|
||||
ok "Scripts and units imported ($size)"
|
||||
else
|
||||
warn "No scripts to import"
|
||||
fi
|
||||
}
|
||||
|
||||
import_services() {
|
||||
section "Importing: Application Services"
|
||||
|
||||
local src="$WORKDIR/content/services"
|
||||
|
||||
if [[ -d "$src" && -n "$(ls -A "$src" 2>/dev/null)" ]]; then
|
||||
# Import service directories to /srv/
|
||||
for svc_dir in "$src"/*/; do
|
||||
[[ -d "$svc_dir" ]] || continue
|
||||
local svc_name=$(basename "$svc_dir")
|
||||
|
||||
# Skip special directories
|
||||
[[ "$svc_name" == "git-repos" || "$svc_name" == "docker-compose" || "$svc_name" == "lxc" || "$svc_name" == "streamlit-apps" ]] && continue
|
||||
|
||||
log " Importing service: $svc_name"
|
||||
run "mkdir -p '/srv/$svc_name'"
|
||||
run "cp -r '$svc_dir'* '/srv/$svc_name/' 2>/dev/null || true"
|
||||
done
|
||||
|
||||
# Import Streamlit apps
|
||||
if [[ -d "$src/streamlit-apps" ]]; then
|
||||
log " Importing Streamlit apps..."
|
||||
run "mkdir -p '/srv/streamlit/apps'"
|
||||
run "cp -r '$src/streamlit-apps/'* '/srv/streamlit/apps/' 2>/dev/null || true"
|
||||
fi
|
||||
|
||||
# Import Git repositories
|
||||
if [[ -d "$src/git-repos" ]]; then
|
||||
log " Importing Git repositories..."
|
||||
run "mkdir -p '/srv/repos'"
|
||||
for repo_tar in "$src/git-repos"/*.tar.gz; do
|
||||
[[ -f "$repo_tar" ]] || continue
|
||||
local repo_name=$(basename "$repo_tar" .tar.gz)
|
||||
log " Importing repo: $repo_name"
|
||||
run "mkdir -p '/srv/repos/$repo_name'"
|
||||
run "tar -xzf '$repo_tar' -C '/srv/repos/$repo_name' --strip-components=2 2>/dev/null || true"
|
||||
done
|
||||
fi
|
||||
|
||||
# Import Docker compose files
|
||||
if [[ -d "$src/docker-compose" ]]; then
|
||||
log " Importing Docker compose files..."
|
||||
for compose in "$src/docker-compose"/*; do
|
||||
[[ -f "$compose" ]] || continue
|
||||
local compose_name=$(basename "$compose")
|
||||
local target_path=$(echo "$compose_name" | sed 's/_/\//g' | sed 's/^srv/\/srv/')
|
||||
local target_dir=$(dirname "$target_path")
|
||||
run "mkdir -p '$target_dir'"
|
||||
run "cp '$compose' '$target_path'"
|
||||
log " Imported: $compose_name"
|
||||
done
|
||||
fi
|
||||
|
||||
# Import LXC configs
|
||||
if [[ -d "$src/lxc" ]]; then
|
||||
log " Importing LXC container configs..."
|
||||
run "mkdir -p '/srv/lxc'"
|
||||
for lxc_config in "$src/lxc"/*.config; do
|
||||
[[ -f "$lxc_config" ]] || continue
|
||||
local container=$(basename "$lxc_config" .config)
|
||||
run "mkdir -p '/srv/lxc/$container'"
|
||||
run "cp '$lxc_config' '/srv/lxc/$container/config'"
|
||||
log " Imported: $container"
|
||||
done
|
||||
fi
|
||||
|
||||
# Fix ownership
|
||||
if [[ $DRY_RUN -eq 0 ]]; then
|
||||
chown -R root:root /srv/* 2>/dev/null || true
|
||||
# Fix specific service ownership
|
||||
chown -R www-data:www-data /srv/nextcloud 2>/dev/null || true
|
||||
chown -R gitea:gitea /srv/gitea 2>/dev/null || true
|
||||
fi
|
||||
|
||||
local size=$(du -sh "$src" 2>/dev/null | cut -f1 || echo "0")
|
||||
local svc_count=$(ls -d "$src"/*/ 2>/dev/null | wc -l || echo "0")
|
||||
ok "Services imported ($svc_count services, $size)"
|
||||
else
|
||||
warn "No services to import"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Module selection ──
|
||||
declare -A MODULE_FUNCS=(
|
||||
[network]=import_network
|
||||
|
|
@ -897,9 +1182,13 @@ declare -A MODULE_FUNCS=(
|
|||
[media]=import_media
|
||||
[mail]=import_mail
|
||||
[accounts]=import_accounts
|
||||
[dns]=import_dns
|
||||
[databases]=import_databases
|
||||
[scripts]=import_scripts
|
||||
[services]=import_services
|
||||
)
|
||||
|
||||
ALL_MODULES="network,firewall,wireguard,crowdsec,dhcp,haproxy,nginx,certs,content,vhosts,users,state,git,media,mail,accounts"
|
||||
ALL_MODULES="network,firewall,wireguard,crowdsec,dhcp,haproxy,nginx,certs,content,vhosts,users,state,git,media,mail,accounts,dns,databases,scripts,services"
|
||||
|
||||
if [[ "$MODULES" == "all" ]]; then
|
||||
MODULES="$ALL_MODULES"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user