一劳永逸的无人值守安装
在 KVM 上全新自动安装 Omarchy 4.0.2(Arch + Hyprland),并一次性配好 RDP 远程桌面。网络固定 IP、网关、DNS 直接写进无人值守脚本,装完即是固定 IP。用 <占位符> 替换成你自己的值即可(密码 = 用户名)。
关键三步
1. 强制 UEFI(必须)
Omarchy 按 UEFI + Limine 装系统,传统 BIOS(SeaBIOS)会黑屏装不上。libvirt XML 指定 OVMF:
<os firmware="efi">
<loader type="pflash" readonly="yes">/usr/share/OVMF/OVMF_CODE_4M.fd</loader>
<nvram>/var/lib/libvirt/qemu/nvram/omarchy_VARS.fd</nvram>
</os>
2. 磁盘大小两处配套
- 虚拟盘:
qemu-img create -f qcow2 ...qcow2 <大小>G - 根分区:
user_configuration.json的disk_config里第二个分区size.value用 MiB(如 100GiB =101887) - ⚠️ 虚拟盘必须 ≥ 分区总量 + 余量(≥128G 起步),否则报
Partition overlaps backup GPT header
3. cidata 无人值守(就两个文件)
cidata/
├── user_configuration.json # 分区 + 引导器 + 主机名 + 固定IP + 密码哈希
└── user_credentials.json # 用户名 + 密码(密码 = 用户名)
固定 IP 关键:custom_commands 里 printf 写入 NetworkManager keyfile lan.nmconnection:
"custom_commands": [
"mkdir -p /etc/NetworkManager/system-connections",
"printf '[connection]\\nid=lan\\ntype=ethernet\\ninterface-name=enp1s0\\nautoconnect=true\\n\\n[ipv4]\\nmethod=manual\\naddress1=<VM_IP>/24,<网关DNS_IP>\\ndns=<网关DNS_IP>;\\n\\n[ipv6]\\nmethod=ignore\\n' > /etc/NetworkManager/system-connections/lan.nmconnection",
"chmod 600 /etc/NetworkManager/system-connections/lan.nmconnection",
"systemctl enable NetworkManager"
]
密码哈希用 openssl passwd -6 '<用户名>' 生成,登录时用户名和密码填同一个。
打包启动
genisoimage -output cidata.iso -volid cidata -joliet -rock cidata/
# 或 xorriso -as mkisofs -o cidata.iso -V cidata -J -r cidata/
cdrom1= Omarchy 系统 ISOcdrom2=cidata.iso(卷标 cidata)- 接任意能出网的网络即可(固定 IP 在脚本里,网段无 DHCP 也不受影响)
装完自动进 Hyprland 桌面。
装后:sudo 免密 + RDP
sudo 免密(VM 关机时,host 端离线做):
sudo virt-customize -a omarchy.qcow2 --run-command \
'echo "<用户名> ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/<用户名>-nopass && chmod 440 /etc/sudoers.d/<用户名>-nopass'
RDP 用 hypr-rdp(Hyprland 是 Wayland,xrdp 不可用且只服务 X11):
yay -S --noconfirm --needed hypr-rdp
# ~/.config/hypr-rdp/config.toml
cat > ~/.config/hypr-rdp/config.toml <<EOF
bind = "0.0.0.0:3389"
username = "<用户名>"
password = "<用户名>"
capture_mode = "wlr"
fps = 30
EOF
echo 'o.launch_on_start("hypr-rdp")' >> ~/.config/hypr/autostart.lua
printf '[Autologin]\nSession=hyprland\nUser=<用户名>\n' | sudo tee /etc/sddm.conf.d/autologin.conf
sudo ufw allow 3389/tcp
sudo systemctl reboot
微软远程桌面连 <VM_IP>,用户名密码都填 <用户名>,自签证书点接受即进桌面。
踩过的坑
- Secure Boot 固件(.ms.fd) → 卡死 UEFI 阶段:
virt-install --boot uefi会自动选OVMF_CODE_4M.ms.fd(Secure Boot 固件)并加secure='yes',而 Omarchy 手册强制要求关闭 Secure Boot/TPM,否则 VM 卡死在 UEFI 阶段。修:用非 Secure Boot 固件OVMF_CODE_4M.fd、<loader secure='no'>、别用.ms.fd。(整合包 create-vm.sh 已内置防呆自动拦截) - BIOS/UEFI 不匹配 → 黑屏:必须 UEFI(OVMF) + Limine;KVM 下 Hyprland 花屏可在 Limine cmdline 加
nomodeset - 网卡名:virtio 默认
enp1s0,用别的型号改interface-name - 磁盘太小 → GPT 头重叠:虚拟盘 ≥ 分区总量 + 余量(≥128G)
/boot缺esp→ Installation halted:分区 flags 必须含"esp"- ACPI 重启无效:KVM guest 常不响应
virsh reboot,用 guest 内sudo systemctl reboot;改盘前确认真关机 - 无 root 密码 → sudo 免密必备:装完只有「用户名=密码」能登录,提权靠注入的 sudo 规则
- 嵌套 SSH / 引号坏:命令写脚本文件
scp过去、ssh host "bash -s" < script.sh喂执行,别用深层嵌套引号 - RDP 用 hypr-rdp,别用 xrdp:xrdp 只服务 X11,连不了 Hyprland
配套脚本
🎁 完整一键安装整合包可直接下载(含全部脚本 + 配置模板 + 指南): ⬇ 下载 omarchy-kvm-pack.zip (11 KB)
整合包结构:
install.sh(一键编排)+config.env.example(配置模板)+scripts/(build-cidata.sh / create-vm.sh / virt-inject.sh / rdp-setup.sh / fix-cidata.py)+GUIDE.md。 用法:cp config.env.example config.env→ 填好 →./install.sh,自动完成 打包 cidata 盘 + 建 UEFI VM + 启动安装。下方是核心脚本要点,完整可运行版以上面整合包为准。
无人值守安装配套的 3 个脚本,直接复制保存使用(完整版见上方整合包)。
make-cidata.sh —— 打包无人值守盘
#!/bin/bash
# make-cidata.sh — 把 cidata 目录打包成无人值守安装盘(密码登录,无公钥)
# 用法: bash make-cidata.sh <cidata目录> [输出iso]
set -e
SRC="${1:?用法: make-cidata.sh <cidata目录> [输出iso]}"
OUT="${2:-/tmp/cidata.iso}"
for f in user_configuration.json user_credentials.json; do
[ -f "$SRC/$f" ] || { echo "缺少 $SRC/$f" >&2; exit 1; }
done
if command -v genisoimage >/dev/null; then
genisoimage -output "$OUT" -volid cidata -joliet -rock "$SRC"
elif command -v xorriso >/dev/null; then
xorriso -as mkisofs -o "$OUT" -V cidata -J -r "$SRC"
else
echo "需要 genisoimage 或 xorriso" >&2; exit 1
fi
echo "OK: $OUT (用户名/密码见 user_credentials.json,密码=用户名)"
virt-inject.sh —— 装后提权(VM 关机时,host 端)
#!/bin/bash
# virt-inject.sh — 无人值守装完后的"提权配置"(不使用公钥)
# 用法(在 KVM host 上, VM 已关机): bash virt-inject.sh <qcow2路径> <用户名>
set -e
QCOW="${1:?用法: virt-inject.sh <qcow2路径> <用户名>}"
USER="${2:?缺少用户名}"
command -v virt-customize >/dev/null || { echo "需要 libguestfs-tools" >&2; exit 1; }
sudo virt-customize -a "$QCOW" --run-command \
"systemctl enable sshd 2>/dev/null || true; \
mkdir -p /etc/ssh/sshd_config.d && echo 'PasswordAuthentication yes' > /etc/ssh/sshd_config.d/10-passwd.conf"
sudo virt-customize -a "$QCOW" \
--run-command "echo \"$USER ALL=(ALL) NOPASSWD: ALL\" > /etc/sudoers.d/${USER}-nopass && chmod 440 /etc/sudoers.d/${USER}-nopass"
echo "=== 完成:开机后用「用户名 = 密码」SSH 登录(不依赖公钥)==="
rdp-setup.sh —— RDP 一键配置
#!/bin/bash
# rdp-setup.sh — Hyprland 原生 RDP(hypr-rdp) + 自动登录 + 防火墙 一键配置
# 在 guest(omarchy) 内以普通用户执行;sudo 需可用(建议先 virt-inject)
set -e
RDP_USER="${RDP_USER:-<用户名>}"
RDP_PASS="${RDP_PASS:-$RDP_USER}" # 密码 = 用户名
echo "=== 1. 安装 hypr-rdp (AUR, 约5分钟编译) ==="
yay -S --noconfirm --needed hypr-rdp || sudo -n pacman -S --noconfirm hypr-rdp
echo "=== 2. 写配置 ~/.config/hypr-rdp/config.toml ==="
mkdir -p ~/.config/hypr-rdp
cat > ~/.config/hypr-rdp/config.toml <<EOF
bind = "0.0.0.0:3389"
username = "$RDP_USER"
password = "$RDP_PASS"
capture_mode = "wlr"
fps = 30
EOF
echo "=== 3. 随 Hyprland 自启 (Omarchy lua 配置) ==="
grep -q 'hypr-rdp' ~/.config/hypr/autostart.lua 2>/dev/null || \
echo 'o.launch_on_start("hypr-rdp")' >> ~/.config/hypr/autostart.lua
echo "=== 4. sddm 自动登录 Hyprland ==="
printf '[Autologin]\nSession=hyprland\nUser=%s\n' "$RDP_USER" | sudo -n tee /etc/sddm.conf.d/autologin.conf >/dev/null
echo "=== 5. 防火墙放行 3389 ==="
sudo -n ufw allow 3389/tcp 2>/dev/null || sudo -n ufw allow 3389
echo "=== 6. 重启系统生效 ==="
echo "建议: sudo systemctl reboot;之后用微软远程桌面连 <此机IP>,用户名密码都填 $RDP_USER"
另有
fix-cidata.py(自动补/boot的esp标记并重打包)和完整的cidata/两个 json,随原文档一起提供。
适合人群
需要在 KVM/虚拟机里跑 Omarchy(Arch + Hyprland)桌面、且要远程桌面访问的折腾型用户;无人值守 + 固定 IP 适合测试环境或远程开箱。