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:
parent
11833410aa
commit
379fe8e4fe
@ -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)"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
89
secubox-tools/c3box-vm/proxmox-import.sh
Executable file
89
secubox-tools/c3box-vm/proxmox-import.sh
Executable 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!"
|
||||
Loading…
Reference in New Issue
Block a user