Bối cảnh & Tại sao cần
2 giờ sáng, server reboot sau đợt cập nhật kernel tự động rồi đứng hình ở màn hình đen: Please enter passphrase for disk.... Qua web console giật lag với độ trễ cả giây, gõ chuỗi mật khẩu ngẫu nhiên 35 ký tự sai đến lần thứ tư khiến hệ thống lock tạm thời. Anh em nào từng ôm laptop trực sự cố prod trong cơn ngái ngủ hẳn hiểu cảm giác này.
Trên chiếc ThinkPad chạy Fedora Workstation của mình, mỗi lần reboot để nhận kernel mới là một lần phải gõ lại passphrase đĩa. Một số người chọn cách tiện hơn: lưu file key thô vào USB cắm thường trực rồi mount qua /etc/crypttab. Tiện thì có, nhưng rủi ro bảo mật quá lớn. Cầm được chiếc USB đó coi như lấy trọn dữ liệu trong ổ cứng.
FIDO2 kết hợp với systemd-cryptenroll mang lại giải pháp cân bằng hơn nhiều. Thay vì lưu keyfile tĩnh trên đĩa, công cụ này tận dụng extension hmac-secret của chuẩn FIDO2 phần cứng. Cơ chế hoạt động rất chặt chẽ: LUKS2 tạo một keyslot mới gắn với chip bảo mật trên YubiKey.
Khi boot, systemd-cryptsetup gửi một salt ngẫu nhiên sang khóa. Token dùng secret bên trong phần cứng để tính mã HMAC rồi trả về khóa giải mã. Bạn chỉ cần cắm YubiKey, gõ mã PIN ngắn 4–6 số và chạm ngón tay vào viền kim loại. Rút khóa ra, không ai trích xuất hay sao chép được master key.
Chuẩn bị & Cài đặt gói
Trước khi thao tác, bạn cần xác nhận phân vùng hiện tại dùng chuẩn LUKS2. systemd-cryptenroll từ chối làm việc với chuẩn LUKS1 cũ.
Liệt kê các phân vùng ổ đĩa trên máy:
lsblk -f
Giả sử phân vùng mã hóa là /dev/nvme0n1p3 (FSTYPE là crypto_LUKS). Kiểm tra phiên bản header:
sudo cryptsetup luksDump /dev/nvme0n1p3 | head -n 5
Nếu thấy Version: 2, hệ thống đã sẵn sàng. Trường hợp máy cài từ bản Fedora cũ vẫn còn Version: 1, bạn cần chuyển đổi trước: sudo cryptsetup convert /dev/nvme0n1p3 --type luks2.
Cài đặt các thư viện FIDO2 cần thiết trên Fedora:
sudo dnf install -y libfido2 fido2-tools cryptsetup
Cắm YubiKey vào cổng USB rồi kiểm tra khả năng nhận diện:
systemd-cryptenroll --fido2-device=list
Kết quả sẽ hiển thị đường dẫn dạng /dev/hidrawX cùng tên thiết bị (chẳng hạn: Yubico YubiKey OTP+FIDO+CCID). Nếu danh sách trống, hãy thử đổi cổng USB hoặc khởi động lại service pcscd.
Các bước cấu hình
Thao tác trực tiếp vào header LUKS luôn tiềm ẩn rủi ro hỏng bảng khóa nếu mất nguồn giữa chừng. Hãy sao lưu header ra USB ngoài trước tiên:
sudo cryptsetup luksHeaderBackup /dev/nvme0n1p3 --header-backup-file ~/luks2-header-backup.img
Bước 1: Gán YubiKey vào Keyslot LUKS2
Chạy systemd-cryptenroll để tạo khóa giải mã mới vào keyslot trống. Mình khuyên bạn nên bật đồng thời hai lớp bảo vệ: mã PIN (User Verification) và chạm tay (User Presence):
sudo systemd-cryptenroll --fido2-device=auto \
--fido2-with-client-pin=yes \
--fido2-with-user-presence=yes \
/dev/nvme0n1p3
Terminal sẽ yêu cầu ba bước xác thực:
- Nhập passphrase hiện tại của ổ đĩa để cấp quyền ghi slot mới.
- Nhập FIDO2 PIN của YubiKey (mã PIN quản lý trên token).
- Đèn YubiKey nhấp nháy, bạn chạm ngón tay vào cảm biến kim loại để hoàn tất.
Sau lệnh này, một keyslot mới (thường là slot 1) đã gắn với YubiKey.
Bước 2: Cập nhật /etc/crypttab
Tiếp theo, cấu hình tiến trình boot ưu tiên hỏi token FIDO2 trước:
sudo nano /etc/crypttab
Dòng cấu hình cho phân vùng root thường có dạng:
luks-4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID=4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx none discard
Thêm tùy chọn fido2-device=auto vào cột thứ tư:
luks-4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID=4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx none discard,fido2-device=auto
Nên đặt thêm thời gian chờ. Nếu quên cắm YubiKey, hệ thống sẽ đợi 15 giây rồi tự chuyển về hỏi passphrase truyền thống:
luks-4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx UUID=4a1b2c3d-xxxx-xxxx-xxxx-xxxxxxxxxxxx none discard,fido2-device=auto,fido2-device-timeout=15s
Bước 3: Tái tạo Initramfs bằng Dracut
Fedora giải mã phân vùng root ngay trong giai đoạn initramfs. Vì vậy, image khởi động bắt buộc phải chứa driver FIDO2 và binary systemd-cryptsetup. Thiếu hai thành phần này, máy sẽ dừng ngay ở màn hình đen.
Khai báo nạp module FIDO2 cho Dracut:
echo 'add_dracutmodules+=" crypt fido2 "' | sudo tee /etc/dracut.conf.d/fido2.conf
Build lại initramfs cho toàn bộ kernel hiện có:
sudo dracut -f --regenerate-all
Quá trình này mất khoảng 30–60 giây. Đảm bảo lệnh kết thúc mà không xuất hiện thông báo lỗi đỏ nào.
Kiểm tra & Xử lý sự cố
Kiểm tra lại xem keyslot đã nhận token chuẩn xác chưa:
sudo cryptsetup luksDump /dev/nvme0n1p3
Trong output, phần Tokens: sẽ xuất hiện systemd-fido2 kèm keyslot tương ứng. Mật khẩu chữ ở Keyslot 0 vẫn giữ nguyên để làm phương án dự phòng khi bạn không mang theo khóa.
Kịch bản khởi động thực tế
Reboot máy để thử nghiệm:
sudo systemctl reboot
Hai kịch bản sẽ xảy ra:
- Có cắm YubiKey: Prompt hỏi mã PIN hiện lên. Nhập xong, đèn YubiKey nhấp nháy, bạn chạm tay vào khóa là máy nạp vào desktop Fedora sau 2–3 giây.
- Quên cắm YubiKey: Sau 15 giây timeout, màn hình hiện lại dòng quen thuộc:
Please enter passphrase for disk.... Bạn nhập mật khẩu gốc bình thường.
Cứu nguy khi rơi vào Dracut Emergency Shell
Nếu thiếu driver hoặc initramfs tạo lỗi khiến máy văng vào dracut:/#, hãy bình tĩnh xử lý:
- Mở khóa phân vùng thủ công bằng passphrase gốc:
cryptsetup luksOpen /dev/nvme0n1p3 root_crypt exit(Thay
root_cryptbằng tên mapper khai báo ở cột đầu tiên trong file crypttab). - Khi đã vào lại OS, đọc log systemd để tìm lý do FIDO2 không nhận diện:
sudo journalctl -b -u systemd-cryptsetup* - Nếu lỡ làm mất YubiKey hoặc muốn đổi khóa mới, xóa slot FIDO2 cũ bằng lệnh sau:
sudo systemd-cryptenroll --wipe-slot=fido2 /dev/nvme0n1p3
Thiết lập này giúp bạn tiết kiệm thời gian gõ phím mỗi ngày. Quan trọng hơn, bạn không còn lo bị nhìn trộm chuỗi mật khẩu đĩa dài ngoằng khi mở máy nơi công cộng.

