feat(vm-builder): Add QCOW2 support for Proxmox/KVM

- Add convert_to_qcow2() function using qemu-img
- Add QCOW2_FILE output path variable
- Create proxmox-import.sh helper script for easy VM import
- Update distribution package to include QCOW2 and Proxmox script
- Add Proxmox VE instructions to README
- Update usage help with QCOW2 output

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-02-23 16:14:56 +01:00
parent 11833410aa
commit 379fe8e4fe
4 changed files with 190 additions and 7 deletions

View File

@ -395,7 +395,9 @@
"Bash(__NEW_LINE_722c25da6bf58fe1__ rm -f \"$COOKIES\" /tmp/login.html)",
"WebFetch(domain:portal.nextcloud.com)",
"WebFetch(domain:arnowelzel.de)",
"Bash(__NEW_LINE_5c2a7272ff3658b1__ ssh root@192.168.255.1 '\n# Test different sizes to find the limit\nfor size in 1000 5000 10000 20000 40000 60000; do\n CONTENT=$\\(head -c $size /tmp/test-upload.html | base64 -w0\\)\n CSIZE=$\\(echo -n \"\"$CONTENT\"\" | wc -c\\)\n RESULT=$\\(ubus call luci.metablogizer upload_and_create_site \"\"{\\\\\"\"name\\\\\"\":\\\\\"\"sizetest\\\\\"\",\\\\\"\"domain\\\\\"\":\\\\\"\"sizetest.gk2.secubox.in\\\\\"\",\\\\\"\"content\\\\\"\":\\\\\"\"$CONTENT\\\\\"\",\\\\\"\"is_zip\\\\\"\":\\\\\"\"0\\\\\"\"}\"\" 2>&1\\)\n \n if echo \"\"$RESULT\"\" | grep -q \"\"success.*true\"\"; then\n echo \"\"Size $size \\($CSIZE base64\\): OK\"\"\n ubus call luci.metablogizer delete_site \"\"{\\\\\"\"id\\\\\"\":\\\\\"\"site_sizetest\\\\\"\"}\"\" >/dev/null 2>&1\n else\n ERROR=$\\(echo \"\"$RESULT\"\" | head -1\\)\n echo \"\"Size $size \\($CSIZE base64\\): FAILED - $ERROR\"\"\n break\n fi\ndone\n')"
"Bash(__NEW_LINE_5c2a7272ff3658b1__ ssh root@192.168.255.1 '\n# Test different sizes to find the limit\nfor size in 1000 5000 10000 20000 40000 60000; do\n CONTENT=$\\(head -c $size /tmp/test-upload.html | base64 -w0\\)\n CSIZE=$\\(echo -n \"\"$CONTENT\"\" | wc -c\\)\n RESULT=$\\(ubus call luci.metablogizer upload_and_create_site \"\"{\\\\\"\"name\\\\\"\":\\\\\"\"sizetest\\\\\"\",\\\\\"\"domain\\\\\"\":\\\\\"\"sizetest.gk2.secubox.in\\\\\"\",\\\\\"\"content\\\\\"\":\\\\\"\"$CONTENT\\\\\"\",\\\\\"\"is_zip\\\\\"\":\\\\\"\"0\\\\\"\"}\"\" 2>&1\\)\n \n if echo \"\"$RESULT\"\" | grep -q \"\"success.*true\"\"; then\n echo \"\"Size $size \\($CSIZE base64\\): OK\"\"\n ubus call luci.metablogizer delete_site \"\"{\\\\\"\"id\\\\\"\":\\\\\"\"site_sizetest\\\\\"\"}\"\" >/dev/null 2>&1\n else\n ERROR=$\\(echo \"\"$RESULT\"\" | head -1\\)\n echo \"\"Size $size \\($CSIZE base64\\): FAILED - $ERROR\"\"\n break\n fi\ndone\n')",
"WebFetch(domain:admin.gk2.secubox.in)",
"WebFetch(domain:tdah.gk2.secubox.in)"
]
}
}

View File

@ -486,6 +486,31 @@ generate_certs_list() {
# Configuration Generation
# ===========================================
# Helper to print a single userlist from UCI
_print_uci_userlist() {
local section="$1"
local name user
config_get name "$section" name
config_get user "$section" user
[ -z "$name" ] && return
[ -z "$user" ] && return
echo "userlist $name"
# user format in UCI: username:password_hash
local username="${user%%:*}"
local password="${user#*:}"
echo " user $username password $password"
echo ""
}
# Generate all UCI-defined userlists
_generate_uci_userlists() {
config_load haproxy
config_foreach _print_uci_userlist userlist
}
generate_config() {
load_config
@ -541,6 +566,9 @@ EOF
echo "" >> "$cfg_file"
fi
# Generate UCI-defined userlists
_generate_uci_userlists >> "$cfg_file"
# Stats frontend
if [ "$stats_enabled" = "1" ]; then
cat >> "$cfg_file" << EOF
@ -609,6 +637,14 @@ frontend https-in
mode http
http-request set-header X-Forwarded-Proto https
http-request set-header X-Real-IP %[src]
# Security: Block access to sensitive paths
acl is_sensitive_path path_beg /.git
acl is_sensitive_path path_beg /.svn
acl is_sensitive_path path_beg /.env
acl is_sensitive_path path_beg /.htaccess
acl is_sensitive_path path_beg /.htpasswd
http-request deny if is_sensitive_path
EOF
else
# Fallback to directory mode if no certs.list
@ -618,6 +654,14 @@ frontend https-in
mode http
http-request set-header X-Forwarded-Proto https
http-request set-header X-Real-IP %[src]
# Security: Block access to sensitive paths
acl is_sensitive_path path_beg /.git
acl is_sensitive_path path_beg /.svn
acl is_sensitive_path path_beg /.env
acl is_sensitive_path path_beg /.htaccess
acl is_sensitive_path path_beg /.htpasswd
http-request deny if is_sensitive_path
EOF
fi
# Add path-based ACLs BEFORE vhost ACLs (path rules take precedence)
@ -800,10 +844,12 @@ _add_vhost_acl() {
esac
# Add auth requirement for private vhosts
local auth_enabled
local auth_enabled auth_realm auth_userlist
config_get auth_enabled "$section" auth_enabled "0"
if [ "$auth_enabled" = "1" ]; then
echo " http-request auth realm \"SecuBox\" if host_${acl_name} !{ http_auth(secubox_users) }"
config_get auth_realm "$section" auth_realm "SecuBox"
config_get auth_userlist "$section" auth_userlist "secubox_users"
echo " http-request auth realm \"$auth_realm\" if host_${acl_name} !{ http_auth($auth_userlist) }"
# Log auth user in header for backend (http_auth_user only works after successful auth)
echo " http-request set-header X-Auth-User %[http_auth_user] if host_${acl_name}"
fi

View File

@ -41,6 +41,7 @@ IMG_FILE="$OUTPUT_DIR/c3box-combined-ext4.img"
VMDK_FILE="$OUTPUT_DIR/$VM_NAME.vmdk"
OVA_FILE="$OUTPUT_DIR/$VM_NAME.ova"
VDI_FILE="$OUTPUT_DIR/$VM_NAME.vdi"
QCOW2_FILE="$OUTPUT_DIR/$VM_NAME.qcow2"
print_header() {
echo ""
@ -365,6 +366,23 @@ convert_to_vdi() {
fi
}
convert_to_qcow2() {
print_header "Converting to QCOW2 (Proxmox/KVM)"
cd "$OUTPUT_DIR"
if ! command -v qemu-img &>/dev/null; then
print_error "qemu-img not found. Install: sudo apt install qemu-utils"
return 1
fi
print_info "Converting to QCOW2 format..."
qemu-img convert -f raw -O qcow2 -o preallocation=metadata "$IMG_FILE" "$QCOW2_FILE"
print_success "QCOW2 created: $QCOW2_FILE"
print_info "Size: $(du -h "$QCOW2_FILE" | cut -f1)"
}
create_vmx_file() {
print_header "Creating VMware Configuration"
@ -521,7 +539,9 @@ create_package() {
cp -v "$VMDK_FILE" "$pkg_dir/" 2>/dev/null || true
cp -v "$OVA_FILE" "$pkg_dir/" 2>/dev/null || true
cp -v "$VDI_FILE" "$pkg_dir/" 2>/dev/null || true
cp -v "$QCOW2_FILE" "$pkg_dir/" 2>/dev/null || true
cp -v "$OUTPUT_DIR/$VM_NAME.vmx" "$pkg_dir/" 2>/dev/null || true
cp -v "$BUILD_DIR/proxmox-import.sh" "$pkg_dir/" 2>/dev/null || true
# Create README
cat > "$pkg_dir/README.md" << 'README'
@ -543,6 +563,30 @@ create_package() {
3. Configure: Linux 64-bit, 2GB RAM, Bridged Network
4. Start the VM
### Proxmox VE
**Option 1: GUI Import**
1. Upload `C3Box-SecuBox.qcow2` to Proxmox storage
2. Create VM: 2 cores, 2GB RAM, VirtIO SCSI
3. Import disk via Hardware → Add → Hard Disk
**Option 2: CLI Import**
```bash
scp C3Box-SecuBox.qcow2 root@proxmox:/tmp/
ssh root@proxmox
./proxmox-import.sh 200 local-lvm
qm start 200
```
**Option 3: Manual qm commands**
```bash
qm create 200 --name secubox --memory 2048 --cores 2 \
--net0 virtio,bridge=vmbr0 --ostype l26
qm importdisk 200 C3Box-SecuBox.qcow2 local-lvm
qm set 200 --scsi0 local-lvm:vm-200-disk-0 --boot order=scsi0
qm start 200
```
### Default Credentials
- **Username:** root
@ -614,6 +658,7 @@ cmd_convert() {
convert_to_vmdk
convert_to_vdi
convert_to_qcow2
create_vmx_file
create_ova
@ -659,10 +704,11 @@ Examples:
./c3box-vm-builder.sh package
Output:
c3box-vm/output/C3Box-SecuBox.vmdk - VMware disk
c3box-vm/output/C3Box-SecuBox.ova - VMware appliance
c3box-vm/output/C3Box-SecuBox.vdi - VirtualBox disk
c3box-vm/output/C3Box-SecuBox.vmx - VMware config
c3box-vm/output/C3Box-SecuBox.vmdk - VMware disk
c3box-vm/output/C3Box-SecuBox.qcow2 - Proxmox/KVM disk
c3box-vm/output/C3Box-SecuBox.ova - VMware appliance
c3box-vm/output/C3Box-SecuBox.vdi - VirtualBox disk
c3box-vm/output/C3Box-SecuBox.vmx - VMware config
USAGE
}

View File

@ -0,0 +1,89 @@
#!/bin/bash
#
# proxmox-import.sh - Import SecuBox VM into Proxmox VE
#
# Usage: ./proxmox-import.sh [VMID] [STORAGE] [QCOW2_FILE]
#
# Examples:
# ./proxmox-import.sh 200 local-lvm
# ./proxmox-import.sh 201 local-zfs C3Box-SecuBox.qcow2
#
set -e
VMID="${1:-200}"
STORAGE="${2:-local-lvm}"
QCOW2_FILE="${3:-C3Box-SecuBox.qcow2}"
# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}SecuBox VM Import for Proxmox VE${NC}"
echo "=================================="
echo ""
echo "VMID: $VMID"
echo "Storage: $STORAGE"
echo "Image: $QCOW2_FILE"
echo ""
# Check if file exists
if [ ! -f "$QCOW2_FILE" ]; then
echo "Error: QCOW2 file not found: $QCOW2_FILE"
exit 1
fi
# Check if qm command exists
if ! command -v qm &>/dev/null; then
echo "Error: qm command not found. Are you running this on Proxmox?"
exit 1
fi
# Check if VMID already exists
if qm status $VMID &>/dev/null; then
echo "Error: VM $VMID already exists. Choose a different VMID."
exit 1
fi
echo "Creating VM $VMID..."
# Create VM with basic settings
qm create $VMID \
--name c3box-secubox \
--memory 2048 \
--cores 2 \
--cpu host \
--net0 virtio,bridge=vmbr0 \
--ostype l26 \
--agent enabled=1
echo "Importing disk..."
# Import disk
qm importdisk $VMID "$QCOW2_FILE" $STORAGE --format qcow2
echo "Attaching disk..."
# Attach disk with VirtIO SCSI
qm set $VMID \
--scsihw virtio-scsi-pci \
--scsi0 $STORAGE:vm-$VMID-disk-0
# Set boot order
qm set $VMID --boot order=scsi0
# Add serial console for troubleshooting
qm set $VMID --serial0 socket
echo ""
echo -e "${GREEN}VM $VMID created successfully!${NC}"
echo ""
echo "Next steps:"
echo " 1. Start VM: qm start $VMID"
echo " 2. Open console: qm terminal $VMID"
echo " 3. Get IP: qm guest cmd $VMID network-get-interfaces"
echo " 4. Web UI: https://<vm-ip>"
echo ""
echo "Default credentials: root / c3box"
echo "IMPORTANT: Change the password on first login!"