Proxmox:VM migrate 後「所有 VM Console 失效 / Failed to run vncproxy」完整診斷與修復紀錄(node1)

本文完整記錄「如何一步步定位問題」與「如何修復」,而不是只留下最後的解法。

環境與前提

叢集與 NAS2 之間有一條 10G 內網(172.16.0.0/24):

  • node1:172.16.0.20
  • node2:172.16.0.21
  • NAS2(Synology):172.16.0.10

另外 NAS2 也提供另一個可達的服務 IP:

  • NAS2 服務 IP:192.168.10.132

0. 現象(Symptoms)

  • VM 從 node2 migrate 到 node1 後:
    • 所有 VM 的 Console 都打不開
    • Web UI 顯示:failed to run vnc proxy
  • 但 node1 的 Node → Shell(左上角 node 的 shell)仍然能正常開啟
  • 手動在 node1 執行 qm vncproxy <vmid> 時出現:
    • LC_PVE_TICKET not set, VNC proxy without password is forbidden

說明:qm vncproxy 本來就需要 PVE ticket(通常由 Web UI / API 帶入),因此單獨在 shell 直接執行會看到此訊息;這個訊息本身不是根因。


1. 先確認 Web / PVE 核心服務是否正常

1.1 PVE 服務狀態

systemctl status pveproxy pvedaemon pve-cluster --no-pager

觀察重點:

  • pveproxypvedaemonpve-cluster (pmxcfs) 都是 active
  • pveproxy log 常見 proxy detected vanished client connection(console 連線失敗時很容易看到)

1.2 Cluster / quorum 狀態

pvecm status

觀察重點:

  • node1 顯示 Quorate: Yes,代表 pve-cluster 正常運作
  • 即使成員看起來只剩 node1 + qdevice,仍不構成 console 全滅的直接原因

2. 轉向 Console 相關:termproxy / vncproxy 是否有啟動與監聽?

2.1 檢查 5900/5901 等連線埠與相關程序

ss -ltnp | egrep ':(59[0-9]{2})\b'
ps aux | egrep 'termproxy|vncproxy' | grep -v grep

觀察:

  • 可以看到 termproxy 5900 --path /nodes/node1 --perm Sys.Console ...
  • 但 VM console 仍失敗,代表問題不只是「proxy 沒起來」

3. 從日誌抓到真正原因:vncproxy 為何失敗?

3.1 近 10 分鐘 pvedaemon / pveproxy log

journalctl -u pvedaemon -u pveproxy --since "10 min ago" -l --no-pager | tail -200

關鍵訊息:

  • 大量 VM 出現:
    • VM XXX qmp command failed ... unable to connect to VM XXX qmp socket - timeout after 51 retries
  • 在嘗試開 VM console 時會出現:
    • starting vnc proxy ...
    • qmp command 'set_password' failed ... unable to connect to VM XXX qmp socket ...
    • Failed to run vncproxy.

第一層結論:

  • console 不是「proxy 不能跑」,而是 Proxmox 需要透過 QMP 跟 QEMU 溝通(設定 VNC 密碼/權限)時,連不到該 VM 的 QMP socket
  • 因此要往「VM 的 qemu/QMP 實際狀態」追

4. 驗證 VM 狀態:顯示 running 但 QMP 連不上(矛盾點)

以 VM 502 為例。

4.1 檢查 VM 狀態與 socket 檔案是否存在

qm status 502
ls -l /run/qemu-server/502.qmp /run/qemu-server/502.vnc 2>/dev/null || true

現象:

  • qm status 顯示 running
  • /run/qemu-server/502.qmp502.vnc 也都存在

4.2 進入 monitor 後仍然 QMP timeout

由於此版本 qm monitor 沒有支援 --cmd / --command,改用互動模式:

qm monitor 502
# qm> info status

結果:

  • human-monitor-command 仍然因 QMP socket timeout 而失敗

4.3 檢查 qemu process 是否真的存在

pgrep -af "qemu.*-id 502" || ps -ef | grep -E "qemu.*-id 502" | grep -v grep

現象:

  • 找不到對應的 qemu process
  • 但 Proxmox 又顯示 VM running,且 socket file 存在

第二層結論:

  • 這是一種典型的「狀態殘留 / I/O 卡住 / 管理層與實際執行層不同步」徵兆
  • 下一步應該從 storage / NFS / I/O 角度找異常

5. 另外一個明顯徵兆:node1 的某個共用 NFS storage 變成灰色問號(inactive)

當時的直覺觀察:

  • nas2-pxshare 在 node2 正常顯示容量
  • 但在 node1 顯示灰色問號

5.1 用 CLI 確認 storage 狀態

timeout 5 pvesm status || echo "pvesm status timeout"

結果:

  • nas2-pxshare 顯示 inactive,Total/Used/Avail 全是 0

5.2 檢查 storage.cfg

grep -n "nas2-pxshare" -A6 -B2 /etc/pve/storage.cfg

重點:

  • export /volume1/PxShare
  • path /mnt/pve/nas2-pxshare
  • server 預期應該是 172.16.0.10(10G 內網)

5.3 先排除網路與 NAS NFS 服務問題

ping -c 2 172.16.0.10
ip route get 172.16.0.10
rpcinfo -p 172.16.0.10 | head -30
showmount -e 172.16.0.10

觀察:

  • ping 正常且延遲極低
  • route 走 vmbr1、src 是 172.16.0.20
  • rpcinfo / showmount 正常列出 exports
  • export ACL 也包含 172.16.0.20172.16.0.21

第三層結論:

  • 網路與 NAS NFS 服務正常
  • 問題更像是「node1 端掛載狀態/來源不一致」導致 Proxmox 誤判 inactive

6. 真正關鍵:實際掛載來源與 storage.cfg 不一致,甚至出現同一路徑疊掛

6.1 先看 mountpoint 實際來源

findmnt /mnt/pve/nas2-pxshare || echo "NOT MOUNTED"
cat /proc/self/mountinfo | grep "/mnt/pve/nas2-pxshare"

早期觀察到:

  • findmnt 的 SOURCE 顯示成:
    • 192.168.10.132:/volume1/PxShare
  • 但 storage.cfg 的 server 則是(或期望是):
    • 172.16.0.10

補充背景(事後檢討):

  • 先前 nas2-pxshare 很可能是以 192.168.10.132 建立
  • 後來刪除後重新建立同名 nas2-pxshare,改指向 172.16.0.10
  • node2 沒出現異常,但 node1 仍保留舊的掛載狀態,導致「名稱相同但掛載來源不一致」的殘留情形

這種狀況很容易讓 Proxmox 在判定 storage 狀態時出現不一致,進而把 storage 判成 inactive。

6.2 更明顯的證據:同一個 mountpoint 同時存在兩層掛載

在修復過程中,停掉 PVE service 後檢查:

findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS

竟然同一路徑出現兩行:

  • /mnt/pve/nas2-pxshare 192.168.10.132:/volume1/PxShare nfs4 ...
  • /mnt/pve/nas2-pxshare 172.16.0.10:/volume1/PxShare nfs ...

代表同一路徑疊掛(stacked mount):

  • 底層是 NFSv4(顯示 192.168.10.132)
  • 上層是 NFSv3(顯示 172.16.0.10)

確認沒有使用者程序佔用(只有 kernel mount):

fuser -vm /mnt/pve/nas2-pxshare

7. 最終修復(不建立新路徑):完整卸掉疊掛,重新只掛單一來源的 NFSv3

目標:

  • 保持 /mnt/pve/nas2-pxshare 不變
  • 移除疊掛狀態(可能需要卸載多次)
  • 重新以 172.16.0.10 的 NFSv3 掛回來
  • 讓 Proxmox 重新判定 storage 為 active

7.1 先停掉會干擾 storage 檢查/重掛的 PVE 服務

systemctl stop pvestatd pvedaemon pveproxy

7.2 逐層卸載,直到完全 NOT MOUNTED

由於是疊掛,可能要卸兩次(或多次),直到 mountpoint 真的消失:

umount -f /mnt/pve/nas2-pxshare 2>/dev/null || umount -l /mnt/pve/nas2-pxshare
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS || echo "NOT MOUNTED"

umount -f /mnt/pve/nas2-pxshare 2>/dev/null || umount -l /mnt/pve/nas2-pxshare
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS || echo "NOT MOUNTED"

確認輸出為:

NOT MOUNTED

7.3 重新掛載為 NFSv3(同一路徑)

mount -v -t nfs -o vers=3,proto=tcp 172.16.0.10:/volume1/PxShare /mnt/pve/nas2-pxshare
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS

確認只剩一行,來源為:

/mnt/pve/nas2-pxshare 172.16.0.10:/volume1/PxShare nfs ...

7.4 啟動 PVE 服務

systemctl start pveproxy pvedaemon pvestatd

7.5 確認 Proxmox 判定 storage active

pvesm status | grep nas2-pxshare

實際成功輸出:

nas2-pxshare         nfs     active     18739479296     16557377408      2182101888   88.36%

8. 結論(Root cause)

  • node1 的 nas2-pxshare 出現了掛載來源不一致與疊掛:
    • 同一個 mountpoint 同時存在 NFSv4(顯示 192.168.10.132)與 NFSv3(顯示 172.16.0.10
  • 事後檢討高度懷疑是以下流程造成殘留:
    • 一開始用 192.168.10.132 建立了 nas2-pxshare
    • 後來刪除並用同名重新建立,但改指向 172.16.0.10
    • node2 沒出現異常,但 node1 保留舊的掛載狀態,進而導致來源漂移與疊掛
  • Proxmox 對 storage 的判定會依照 storage.cfg 的 server/export 與實際掛載狀態做檢查,當這兩者不一致時,storage 會被判為 inactive
  • 在 storage 狀態異常的情況下,PVE 對 VM 的管理操作會出現大量 timeout(包含 QMP 操作),進而導致 VM console / vncproxy 失敗

9. 後續建議(避免復發)

  • 若要變更 NFS storage 指向的 NAS IP,建議避免「刪除後用同名重建但改 server」而沒有清掉各節點上的舊掛載狀態
  • 當 UI 出現 storage 灰色問號或 pvesm status 顯示 inactive 時,第一時間先做:
findmnt /mnt/pve/nas2-pxshare -o TARGET,SOURCE,FSTYPE,OPTIONS
  • 若同一路徑出現多行,優先處理疊掛(停 PVE 服務後逐層卸載乾淨,再重新掛載成單一來源)

Onboard 虛擬鍵盤 Debian 13 + KDE Plasma 6 + Wayland 完整設定教學(uinput 方案)

前言:從幾乎放棄,到終於能打字

老實說,這篇文章是我在幾乎準備放棄 KDE Plasma Wayland 的虛擬鍵盤時寫下的。

在 Debian 13 + KDE Plasma 6 + Wayland 環境下,官方唯一支援的螢幕鍵盤是 Maliit
但實際使用後,我遇到的是一連串幾乎無解的問題:

  • 鍵盤只出現一次
  • swipe 收起後再也叫不回來
  • 必須重啟 KWin 或整個桌面
  • 與實際平板/二合一裝置使用情境完全不相容

在反覆搜尋解法、翻 GitHub issue、KDE Discuss 討論串的過程中,我一度覺得:
「也許觸控平板選 KDE Wayland 就是死路一條。」

直到我 Google 到一篇 2022 年的 KDE Discuss 討論串

Plasma 6 and Wayland no on-screen keyboard working - Help - KDE Discuss

其中有一位使用者 @INVICTRA 提到:

I managed to get Onboard working on wayland. Kubuntu 25.04

1 Edit the shortcut in the menu. Within the KDE Menu Editor look for the Environment variables field and add “GDK_BACKEND=x11”.

2 Go to Onboard preferences page. Under Keyboard – >Advanced set:

Input Options → Input event source: GTK
Key-stroke Generation → Key-stroke generator: uinput

If you have time please try it. I would like to know if it works for others too.

我拿去問 ChatGPT 5.2,指出:Onboard + X11 backend + uinput,可能是突破口。

於是我開始實驗,補齊權限、kernel、udev 等細節,最後真的在 Debian 13 + KDE Plasma 6 + Wayland 上,
得到一個 穩定、可重複呼叫、不會卡死 的虛擬鍵盤解法。

這篇文章,就是完整整理後的結果。


一、為什麼需要這樣做(背景說明)

  • 2025 年末 KDE Plasma Wayland 官方仍只支援 Maliit
  • Maliit 目前在 KDE Plasma 存在嚴重 bug(收起後無法再叫出)
  • Wayland 設計上禁止 synthetic input(模擬鍵盤/滑鼠)
  • Onboard 可透過 Linux kernel 的 uinput 建立「虛擬鍵盤裝置」
  • uinput 屬於 kernel input device,不受 Wayland 限制

簡單說:

Wayland 不讓你「假裝按鍵」,
但 uinput 讓你「真的插一把虛擬鍵盤」。

在目前 Debian + KDE Plasma Wayland 的條件下,
這幾乎是唯一實際可用的方案。


二、系統需求

  • Debian 13

  • KDE Plasma 6

  • Wayland session

  • 已安裝 XWayland(通常預設已有)

  • 使用者具備 sudo 權限

    • *

三、安裝必要套件

sudo apt update
sudo apt install onboard xwayland

四、啟用 kernel uinput 模組

1. 確認是否已載入

lsmod | grep uinput

若沒有任何輸出,請手動載入:

sudo modprobe uinput

2. 設定開機自動載入

echo uinput | sudo tee /etc/modules-load.d/uinput.conf

五、設定 uinput 權限(關鍵步驟)

1. 建立群組

sudo groupadd -f uinput

2. 將使用者加入群組(以 hln 為例)

sudo usermod -aG uinput hln

注意:這一步完成後,一定要重新登入或重開機。


3. 建立 udev 規則

sudo nano /etc/udev/rules.d/99-uinput.rules

內容如下:

KERNEL=="uinput", MODE="0660", GROUP="uinput"

重新載入規則:

sudo udevadm control --reload
sudo udevadm trigger

4. 重開機後確認

ls -l /dev/uinput

正確結果應類似:

crw-rw---- 1 root uinput /dev/uinput

確認自己在群組內:

groups

必須看到 uinput


六、以 X11 backend 啟動 Onboard(非常重要)

在 Wayland 下,一定要強制使用 X11 backend

GDK_BACKEND=x11 onboard

建議先在 Konsole 中測試,確認鍵盤能正常顯示。


七、Onboard 設定(必做)

開啟 Onboard → Preferences → Keyboard → Advanced

請設定為:

  • Input Options

    • Input event source:GTK
  • Keystroke Generation

    • Key-stroke generator:uinput

如果你之前試過 uinput 但沒有反應,
完成權限設定後一定要重新測試。


八、實際驗證方式

  1. 開啟可輸入文字的程式(Kate / Firefox / Konsole)
  2. 點擊輸入框取得 focus
  3. 使用 Onboard 點擊鍵盤

成功狀態:

  • 文字實際輸入到程式中

  • 可反覆叫出 / 收起

  • 不需重啟 KWin

  • 不會卡死

  • 不受 Maliit bug 影響

    • *

九、建立桌面捷徑(推薦)

nano ~/.local/share/applications/onboard-x11.desktop

內容:

[Desktop Entry]
Name=Onboard (Wayland Safe)
Exec=env GDK_BACKEND=x11 onboard
Type=Application
Icon=onboard
Categories=Utility;Accessibility;

之後可以:

  • 加到 KDE 工作列

  • 加到桌面

  • 當作一鍵呼叫虛擬鍵盤

    • *

十、限制與注意事項

已知限制

  • SDDM 登入畫面無法使用
  • 非 Wayland 原生(透過 XWayland)
  • 提升輸入層權限,適合個人裝置

優點

  • 不會 swipe-down 卡死

  • 支援 Ctrl / Alt / Function keys

  • 可搭配 Fcitx5 新酷音

  • Synergy / KVM 正常

  • 長時間穩定可用

    • *

十一、回復原狀(可逆)

sudo rm /etc/udev/rules.d/99-uinput.rules
sudo gpasswd -d hln uinput
sudo reboot

十二、結論

在 Debian 13 + KDE Plasma Wayland 環境下:

Onboard + uinput 是目前唯一實際可用的虛擬鍵盤方案。

這不是官方完美解法,但 KDE 社群畢竟是做無償,你不能過度給予不符比例的期待。

最重要的是問題解決,我現在可以拿著沒有鍵盤的平板,打注音或英文操作系統了!

Debian Linux 設置 WireGuard L3 路由+NAT 連線

前言

公司目前的 DrayTek 路由器型號 不支援 WireGuard。我改在一台 Debian VM 上自建 WireGuard,帶來幾個好處:

  • 效能不再受限於 DrayTek 硬體:VM 可自行調整資源(CPU/RAM/網卡),加密吞吐量更彈性。
  • 路由規則更好控:只把特定內網(例:192.168.0.0/24192.168.10.0/24)走 VPN,不用額外在客戶端打一堆指令。
  • 維持個人上網體驗:一般上網不走公司出口,避免外部網站看到公司 IP,也不讓自己網速被公司端拖慢。
  • 相容性佳:Windows/macOS/Linux/手機端都容易配置。

目標:外部 Win11 透過 WireGuard 連入公司,能存取 192.168.0.0/24192.168.10.0/24(DrayTek 兩個 VLAN 可互通)。
做法:Layer-3 路由 + NAT;實際出口介面為 ens18


0) 伺服器環境

  • Debian 12
  • KDE Plasma

    設置 GUI 方便同事操作,會影響到網路連線的管理指令。

1) 拓樸與參數

  • WG 伺服器(Debian VM)

    • 介面:ens18
    • LAN IP:192.168.0.70/24
    • Gateway:192.168.0.251(DrayTek)
    • WG 隧道 IP:10.10.0.1/24
  • Win11 用戶端10.10.0.2/32
  • DrayTek:需 Port Forward UDP 51820 → 192.168.0.70:51820;VLAN 0/10 可路由。

1.5) 路由器/連接埠轉發(DrayTek 或你的實際路由器)

你的路由器必須把從網際網路進來的 WireGuard UDP 流量轉發到 Debian WG 伺服器。

以 DrayTek 為例(如果你用別款路由器,請做等效設定):

  • 類型: Port Forward / NAT
  • 協定: UDP
  • 外部連接埠: 51820
  • 內部主機(伺服器): 192.168.0.70
  • 內部連接埠: 51820
  • 備註: WireGuard
  • 若有 WAN 防火牆 規則,請同時允許 UDP/51820

使用其他廠牌/型號?
請做等效的動作:

  1. 建立一條 UDP 51820埠轉發,從 WAN 指向 WG 伺服器的 LAN IP(192.168.0.70)。
  2. 若路由器有獨立的防火牆頁面,新增一條允許 UDP/51820 的入站規則。
  3. 若處於 雙重 NAT(ISP 數據機 + 你的路由器),需在兩層都設定轉發,或把上游設備改成 橋接/DMZ 模式。
  4. 若 ISP 使用 CGNAT (日本常見),通常無法做入站轉發—請改用公共 IP、VPS 中繼,或請能接收入站連線的一端當 WG 伺服器。

可選(純路由、不做 NAT):
若你在 Debian 伺服器上移除 NAT,請在路由器新增靜態路由
目的: 10.10.0.0/24下一跳: 192.168.0.70


2) NetworkManager:建立 ens18(一次完成)

nmcli connection add type ethernet ifname ens18 con-name ens18 \
  ipv4.addresses 192.168.0.70/24 ipv4.gateway 192.168.0.251 \
  ipv4.dns "1.1.1.1 8.8.8.8" ipv4.method manual \
  ipv6.method ignore autoconnect yes

nmcli connection up ens18
# 驗證
ip addr show ens18
ip route get 192.168.0.251   # 應為 dev ens18 src 192.168.0.70

你已刪除 br0;不需要 bridge


3) 伺服器安裝與金鑰

apt update && apt install -y wireguard iptables tcpdump
( umask 077; wg genkey | tee /etc/wireguard/server.key | wg pubkey > /etc/wireguard/server.pub )
( umask 077; wg genpsk > /etc/wireguard/psk )   # 可選(建議)
chmod 600 /etc/wireguard/server.key /etc/wireguard/psk

4) /etc/wireguard/wg0.conf(NAT 出口 = ens18)

[Interface]
Address    = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <server.key>

# 將 10.10.0.0/24 經 ens18 做 NAT
PostUp   = iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o ens18 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.10.0.0/24 -o ens18 -j MASQUERADE

# 第一台用戶端
[Peer]
PublicKey    = <client1.pub>
PresharedKey = <psk>                  # 若有
AllowedIPs   = 10.10.0.2/32

5) IP 轉送與 rp_filter

cat >/etc/sysctl.d/99-wg.conf <<'EOF'
net.ipv4.ip_forward=1
# 避免回路徑檢查丟棄 wg0→ens18 的轉送封包
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.wg0.rp_filter=0
net.ipv4.conf.ens18.rp_filter=0
EOF
sysctl --system

6) 防火牆(若有)

iptables -A INPUT -p udp --dport 51820 -j ACCEPT
iptables -A FORWARD -i wg0  -o ens18 -j ACCEPT
iptables -A FORWARD -i ens18 -o wg0  -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

7) 啟動與開機自動

wg-quick up wg0
systemctl enable wg-quick@wg0
wg show

8) Win11 用戶端 client.conf

[Interface]
PrivateKey = <client.key>
Address    = 10.10.0.2/32
DNS        = 192.168.0.251

[Peer]
PublicKey    = <server.pub>
PresharedKey = <psk>                           # 若伺服器啟用 PSK
Endpoint     = <你的公網IP或DDNS>:51820
AllowedIPs   = 10.10.0.1/32, 192.168.0.0/24, 192.168.10.0/24
PersistentKeepalive = 25

若用戶端所在網路也是 192.168.0.0/24,可先改為精確主機 /32(例如只加目標 IP),或暫用 0.0.0.0/0 驗證。


9) 驗證

Win11:

ping 10.10.0.1
ping 192.168.0.70
ping 192.168.0.251
ping 192.168.0.203
ping 192.168.10.20

伺服器(同時):

iptables -t nat -v -n -L POSTROUTING   # 應見 -o ens18 的 MASQUERADE 計數 > 0
wg show                                # 該 peer 的 rx/tx 會跳動
tcpdump -ni wg0 icmp
tcpdump -ni ens18 host 192.168.0.203 and icmp
ip route get 192.168.0.203             # 應為 dev ens18 src 192.168.0.70

10) 常見問題速解

  • 只能 ping 10.10.0.1 / 192.168.0.70 → 檢查:
    ip_forward=1rp_filter=0iptables -t nat 是否有
    -A POSTROUTING -s 10.10.0.0/24 -o ens18 -j MASQUERADE
  • Win11 沒有 192.168.0.0/24 路由AllowedIPs 未包含或本地段衝突。先用 /320.0.0.0/0 驗證。
  • 需要連 VLAN10 → 用戶端 AllowedIPs192.168.10.0/24 即可(DrayTek 會在 VLAN 間路由)。
  • 想改純路由(不 NAT) → 在 DrayTek 加:目的 10.10.0.0/24 → 下一跳 192.168.0.70,並移除 wg0 的 NAT。

將 IBM Windows Server 2003 實體機轉換成 Proxmox 虛擬機並縮小磁碟空間

這次紀錄的是一台相當老舊的 IBM 實體主機,系統為 Windows Server 2003。由於硬碟老化與備援需求,我希望把它完整轉換成虛擬機,運行在 Proxmox VE 環境中,並進一步縮小原本 2TB 的系統磁碟,以節省儲存空間。


一、使用 VMware vCenter Converter (XP 可用版本) 進行 P2V

由於這台主機仍在 Windows XP 時代的軟體相容範圍內,我選擇了舊版的 VMware vCenter Converter (P2V Virtual Machine Converter),這是少數仍能在 XP/Server 2003 上執行的版本。

步驟如下:

  1. 在 IBM 主機上安裝 VMware vCenter Converter。
  2. 選擇「Convert Local Machine」。
  3. 目標格式設定為 VMware Workstation / Other VMware Virtual Machine
  4. 輸出 .vmdk 虛擬磁碟到外接硬碟或網路共享資料夾。

這一步結束後,就能得到一組 Windows2003.vmdk.vmx 等檔案。


二、將 vmdk 轉換為 Proxmox 可用的 qcow2

將輸出的 vmdk 檔案複製到 Proxmox 環境,例如:

/mnt/pve/nas2-in/images/602/

使用以下指令轉換為 qcow2:

qemu-img convert -O qcow2 Windows2003.vmdk vm-602-disk-0.qcow2

Proxmox 便能直接掛載這顆虛擬磁碟。


三、啟動測試並確認系統可開機

  1. 建立新的虛擬機,BIOS 設定為 SeaBIOS,顯示卡設為 VGA。
  2. 掛載 vm-602-disk-0.qcow2 為主磁碟。
  3. 啟動後確認能正常進入桌面,檢查 IIS、應用程式與服務運作是否正常。

若遇到「NTLDR is missing」等啟動錯誤,可用 Windows Server 2003 安裝光碟修復開機:

fixboot
fixmbr
bootcfg /rebuild

四、進行系統內部磁碟縮小準備

原始磁碟為 2TB,實際使用空間不到 50GB。
縮小前必須確保檔案系統一致性並釋放未使用區塊。

1. 執行磁碟重組

在 Windows 2003 內執行系統內建的「磁碟重組 (Defragmenter)」,將資料集中於磁碟前段。

2. 使用 SDelete 填零釋放空間

下載 Sysinternals 的 sdelete.exe,執行以下指令:

sdelete -z C:

這會將所有未使用的磁區以零填滿,讓後續壓縮與縮小能更有效。
由於這台主機的虛擬磁碟格式為 IDE 模擬介面,磁碟 I/O 速度極慢,整個過程耗時極長。

在我的情況下,SDelete 執行將近兩週才完成,CPU 與 I/O 幾乎全程滿載。若使用 VirtIO 或 SCSI 介面,時間可望縮短至數小時內。


五、在 Windows 7 環境中進行磁碟縮小

Windows Server 2003 無法原生縮小系統分割區,因此我原本打算使用 ClonezillaGParted Live 進行分割區調整。
然而實際操作時,無論是在 Clonezilla 還是 GParted Live 環境中,系統都會顯示「硬碟毀損」或「檔案系統錯誤」,導致無法執行縮小。

我嘗試重新開回 XP / 2003 系統執行磁碟檢查 (chkdsk /f) 並重新操作,但依然無法通過 GParted 的檢查。
後來推測是 NTFS metadata 結構與 GParted 的 NTFS 驅動版本不完全相容,導致誤判為壞軌。

最終解法是改用 Windows 7 環境的磁碟管理工具 (diskmgmt.msc)
步驟如下:

  1. 關閉 2003 VM,將其 qcow2 掛載為 Win7 VM 的第二顆硬碟。
  2. 在 Win7 內開啟「磁碟管理」。
  3. 對 C: 點選「壓縮磁碟區」,將容量縮至 49GB
  4. 完成後會看到後段變成 未配置 (Unallocated)

這種方式穩定、可直接作用於 NTFS 系統分割區,是整個流程中最有效的一步。


六、在 Proxmox 縮小 qcow2 檔案

  1. 掛載磁碟到 nbd 驗證分割區長度:

    qemu-nbd -r -c /dev/nbd0 vm-602-disk-0.qcow2
    fdisk -l /dev/nbd0

    輸出確認 /dev/nbd0p1 約為 49GB。

  2. 卸載 nbd:

    qemu-nbd -d /dev/nbd0
  3. 執行安全縮減(預留少許緩衝):

    qemu-img resize --shrink vm-602-disk-0.qcow2 52G
  4. 進一步壓縮虛擬磁碟:

    qemu-img convert -O qcow2 vm-602-disk-0.qcow2 vm-602-disk-0-slim.qcow2

轉換後檔案大小從原本 2TB 減至約 30~35GB。


七、替換與測試

  1. 在 Proxmox 網頁介面中 Detach 原本的 qcow2。
  2. 掛上新的 vm-602-disk-0-slim.qcow2
  3. 啟動虛擬機,確認能正常進入桌面並運行應用程式。
  4. 測試無誤後,可刪除舊檔或保留為備份。

八、結果與心得

整個過程中最關鍵的部分包括:

  • 使用 XP 可用版本的 VMware vCenter Converter 成功進行 P2V。
  • 在新版系統中進行分割區壓縮,避開 2003 無法 shrink 的限制。
  • 避免使用 Clonezilla 或 GParted Live 直接操作 NTFS 系統磁碟,否則容易被誤判為壞軌。
  • 使用 sdelete -z 填零未使用空間,配合 qemu-img convert 達成真正的磁碟瘦身。

最終結果:

  • 原始 2TB 的磁碟映像,成功縮減至 52GB 並壓縮成約 35GB。
  • 系統能正常開機、IIS 與內部應用程式皆正常運作。
  • 整個流程最耗時的步驟是 SDelete,在 IDE 虛擬介面下執行近兩週,若能改用 VirtIO,效能將大幅改善。

阻擋內網電腦對外 SMB 連線異常流量 — DrayTek Vigor2925 實戰紀錄

問題背景

近期在公司網路中發現多台內部電腦持續對外發起 SMB(445 / 139 / NetBIOS)連線,這些連線目標為多個公網 IP。由於公司僅允許內部電腦連接至公司內部指定的 NAS 以使用 SMB,本次行為被視為異常,暗示存在惡意程式或系統誤行為。

除了安全風險外,這些大量的對外 SMB 嘗試也導致整體網路效能明顯下降。
公司員工反映多個網站載入速度變慢,甚至無法開啟部分頁面。
在檢查防火牆日誌後,確認異常的 outbound SMB 流量已佔用大量頻寬並造成負載平衡異常。


進一步調查與防毒處理

在發現異常後,對受影響的電腦進行了端點檢查與惡意程式掃描。使用 Kaspersky Virus Removal Tool(KVRT)進行多台電腦的離線或線上掃描與清除。掃描結果顯示多台機器有木馬或蠕蟲活動跡象,而部分惡意程式會利用 SMB 嘗試對外掃描或橫向感染。

對感染的主機執行 KVRT 清除後,防火牆日誌中可觀察到可辨識的可疑外連量減少,但仍以網路層面加強控制以防復發。


目標

  1. 阻斷內網指定範圍內電腦對 Internet 的 SMB(445、137–139)出站流量。
  2. 保留內網電腦對公司內部 NAS 的 SMB 存取權限。
  3. 不干擾 NAS 的既有業務需求(若 NAS 同時對外提供服務,需另行評估安全機制)。

網路環境概述

  • 路由器:DrayTek Vigor2925(雙 WAN,負載平衡啟用)

  • 內網電腦:公司內部某一子網段(表示為「受控子網」)

  • NAS:公司內部指定伺服器(表示為「受許可 NAS」)

  • 防火牆日誌:顯示來源為受控子網,多筆 outbound SMB 至多個公網 IP

    • *

問題分析

  1. 防火牆預設規則允許 LAN → WAN 流量,使得內部感染主機能直接向外連線。
  2. 日誌顯示大量對外 445/139 的連線嘗試與短時間內頻繁 SYN/ESTABLISHED 狀態,符合掃描或自動傳播行為。
  3. 單靠端點掃毒雖能清除已知惡意程式,但仍需在網路層建立有條件的封鎖,預防尚未偵測或變種的再度外掃。

解決方案(防火牆面)

以下示範以 DrayTek Vigor 的 Data Filter 設定為例(步驟為概念化描述,實際操作請對應你路由介面):

1. 建立 SMB 服務物件與群組

在路由器的 Service / Objects 設定中新增:

  • 服務 A:TCP/UDP port 445(SMB)
  • 服務 B:TCP/UDP port 137–139(NetBIOS) 然後建立服務群組(名稱如 SMB),把上述兩個服務加入群組。

2. 建立 Data Filter 規則(順序很重要)

在 Data Filter(或 Firewall Filter)中建立兩條規則,並確定「允許規則」在「封鎖規則」上方:

  • 允許規則(Allow NAS)
    • 方向:LAN → WAN
    • 來源:受控子網(只對需保留的電腦範圍)
    • 目的:受許可 NAS(內部 NAS 的 IP)
    • Service:SMB 群組
    • 動作:Pass Immediately
  • 封鎖規則(Block other SMB)
    • 方向:LAN → WAN
    • 來源:受控子網(同上)
    • 目的:Any(所有外部目標)
    • Service:SMB 群組
    • 動作:Block Immediately

註:若路由器支援 IPv6,請同時考慮 IPv6 流量的檢查與封鎖。

3. 啟用 Data Filter

在 Firewall General 或同類選項中啟用 Data Filter,並指定剛剛建立的 Filter Set 為啟動集。開啟嚴格安全選項(若有),並確認過濾套用於 IPv4/IPv6 的情況。


驗證方式

建議驗證項目(在安全環境下執行):

  • 檢查防火牆日誌(Syslog),確認封鎖規則被觸發,且公網 445 連線被阻擋。

  • 測試內部存取受許可 NAS 是否正常(以內部路徑或映射磁碟方式測試)。

  • 在受影響主機端使用 netstat -ano 檢查是否仍有可疑的 445 連線,以及確認對應的進程 PID,進一步比對該程序是否為合法應用。

    • *

補充建議(端點與長期防護)

  1. 端點掃毒:持續使用 KVRT 或其他企業級掃描工具進行全面掃描與根除病毒、漏洞利用程式。
  2. 雙層防護:在 Windows 防火牆或端點防護程式端也加入「阻擋出站 SMB」規則,形成備援。
  3. 最小權限原則:限制內部帳號權限,減少共享/網路傳播的攻擊面。
  4. 外部存取方案:若需要讓 NAS 對外提供服務,建議以 VPN、Reverse Proxy 或專用檔案分享方案替代直接對外開放 SMB。
  5. 定期稽核:設定定期檢查與日誌告警,若有大量外向 SMB 嘗試立即通知管理員。

結論

本案結合端點(KVRT 清除惡意程式)與網路層(DrayTek Data Filter)兩面向的防護策略,達成以下效果:

  • 有效封鎖內網主機對外的 SMB 掃描與傳播行為。
  • 保留內部對指定 NAS 的合法 SMB 存取。
  • 降低未來横向擴散與外洩風險。

這是企業在面對內網感染時一個較完整的實務流程:偵測 → 端點清除 → 網路層隔離與限制 → 持續監控與稽核。