#!/usr/bin/env bash # raiden-cold.sh — open/close/status encrypted container # Usage: raiden-cold.sh open | close | status IMG="/mnt/sektor/.local/raiden-cold.img" MAP_NAME="raiden-cold" MOUNT_POINT="/mnt/raiden/cold" # ── colors ────────────────────────────────────────────────────────────────── RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' info() { echo -e "${GREEN}[✔]${NC} $*"; } warn() { echo -e "${YELLOW}[!]${NC} $*"; } error() { echo -e "${RED}[✘]${NC} $*"; exit 1; } # ── helpers ─────────────────────────────────────────────────────────────────── is_mounted() { mountpoint -q "$MOUNT_POINT"; } is_mapped() { [ -e "/dev/mapper/$MAP_NAME" ]; } find_loop() { losetup -j "$IMG" | awk -F: '{print $1}'; } # find loop already attached to image # ── open ────────────────────────────────────────────────────────────────────── cmd_open() { [ -f "$IMG" ] || error "Image not found: $IMG — is the NFS share mounted?" # Auto-pick a free loop device, reuse if image already attached local LOOP LOOP=$(find_loop) if [ -n "$LOOP" ]; then warn "Image already attached as $LOOP — reusing" else info "Attaching loop device..." LOOP=$(losetup -fP --show "$IMG") || error "losetup failed" info "Loop device attached: $LOOP" fi if is_mapped; then warn "/dev/mapper/$MAP_NAME already exists — skipping cryptsetup" else info "Opening LUKS container (enter passphrase)..." cryptsetup open "$LOOP" "$MAP_NAME" || error "cryptsetup open failed" info "LUKS container open: /dev/mapper/$MAP_NAME" fi if is_mounted; then warn "$MOUNT_POINT already mounted — skipping" else mkdir -p "$MOUNT_POINT" mount "/dev/mapper/$MAP_NAME" "$MOUNT_POINT" || error "mount failed" info "Mounted at $MOUNT_POINT" fi echo "" df -h "$MOUNT_POINT" } # ── close ───────────────────────────────────────────────────────────────────── cmd_close() { # Resolve loop device before closing LUKS (after close it's gone) local LOOP LOOP=$(cryptsetup status "$MAP_NAME" 2>/dev/null | awk '/device:/{print $2}') if is_mounted; then info "Unmounting $MOUNT_POINT..." umount "$MOUNT_POINT" || error "umount failed — files still open?" info "Unmounted" else warn "$MOUNT_POINT not mounted — skipping" fi if is_mapped; then info "Closing LUKS container..." cryptsetup close "$MAP_NAME" || error "cryptsetup close failed" info "LUKS container closed" else warn "/dev/mapper/$MAP_NAME not found — skipping" fi if [ -n "$LOOP" ] && losetup "$LOOP" &>/dev/null; then info "Detaching loop device $LOOP..." losetup -d "$LOOP" || error "losetup detach failed" info "Loop device detached" else warn "No loop device to detach — skipping" fi info "Vault closed." } # ── status ──────────────────────────────────────────────────────────────────── cmd_status() { local LOOP LOOP=$(find_loop) echo -e "\n Image : $IMG" [ -f "$IMG" ] && echo -e " NFS share : ${GREEN}reachable${NC}" \ || echo -e " NFS share : ${RED}not reachable${NC}" [ -n "$LOOP" ] && echo -e " Loop dev : ${GREEN}$LOOP${NC}" \ || echo -e " Loop dev : ${RED}not attached${NC}" is_mapped && echo -e " LUKS : ${GREEN}open${NC}" \ || echo -e " LUKS : ${RED}closed${NC}" is_mounted && echo -e " Mounted : ${GREEN}$MOUNT_POINT${NC}" \ || echo -e " Mounted : ${RED}no${NC}" is_mounted && { echo ""; df -h "$MOUNT_POINT"; } echo "" } # ── main ────────────────────────────────────────────────────────────────────── [ "$EUID" -eq 0 ] || error "Run as root" case "$1" in open) cmd_open ;; close) cmd_close ;; status) cmd_status ;; *) echo "Usage: $(basename "$0") open | close | status" exit 1 ;; esac