Chuyển tới nội dung chính
Version: 4.1

Dựng và ký bản vá nóng

Trang này dành cho chủ sở hữu của một hệ thống HiTechCloud đã quyết định tự tạo bản vá nóng, cho những nhân mà bản phân phối không phát hành bản vá nào (AlmaLinux, Rocky Linux, Debian, hoặc máy chủ Ubuntu hay RHEL không dùng dịch vụ của nhà cung cấp). Đây là quy trình vận hành của một đường ống mà phần mềm đã được dựng và kiểm thử, còn việc vận hành thì chưa: chưa có gì trên trang này được chạy trên nhân thật, máy dựng thật hay kho phản chiếu thật. Hãy coi mọi lệnh là chưa được chứng minh cho đến khi làm xong danh sách kiểm tra trong phòng thí nghiệm, và đối chiếu các tùy chọn của kpatch-build, sign-file và mokutil với phiên bản bạn đang dùng.

Bản vá nóng là mã chạy trong nhân, có quyền thay thế bất kỳ hàm nào của nhân. Ai nạp được một bản vá là chiếm được máy, và mọi khách hàng trên đó. Vì vậy phần lớn trang này nói về khóa, việc rà soát và những gì bị từ chối.

Chỉ chủ sở hữu mới làm được​

Phần mềm được phát hành làm việc kiểm tra và đóng gói. Nó không thể, và không được phép, làm bất kỳ việc nào sau đây. Đó là việc của bạn.

Chỉ chủ sở hữuVì sao không thể tự động hóa
Tạo và giữ các khóa ký, tốt nhất trên khóa phần cứng, tách khỏi khóa phát hànhKhóa ký mã nhân cho mọi máy chủ có giá trị với kẻ tấn công hơn mọi khóa khác. Không tác tử, tác vụ CI hay máy dựng nào được giữ nó.
Đăng ký khóa công khai tin cậy trên từng máy chủMáy chủ không tin gì cho đến khi chủ của nó đặt khóa vào /etc/hitechcloud/livepatch/trusted-keys.
Đăng ký chứng chỉ ký mô-đun (MOK) trên máy chủ chạy Secure Bootmokutil --import cần màn hình điều khiển và khởi động lại trên từng máy, và không thể làm trên nhiều nền tảng VPS.
Vận hành các máy dựng, và bố trí người rà soát từng CVEMỗi bản dựng cần một máy riêng cho đúng một bản dựng nhân, với mã nguồn, ký hiệu gỡ lỗi và trình biên dịch của chính bản dựng đó.
Phát hành kho phản chiếu, và đặt địa chỉ của nó trên máy chủKho là một trang tĩnh do bạn lưu trữ. Máy chủ không tải gì cho đến khi chạy server-livepatch mirror set.
Quyết định các vấn đề hỗ trợ và trách nhiệm D1 đến D8 của tài liệu thiết kếAi ký, cam kết gì với khách hàng, trách nhiệm khi một bản vá làm sập máy chủ. Cần luật sư trước khi lưu trữ bất kỳ bản vá nào.

Bản vá đến máy chủ như thế nào​

  1. Một máy dựng (một máy cho mỗi bản dựng nhân đích, không bao giờ là máy chủ của khách, không có khóa trên đó) dựng mô-đun vá nóng từ mã nguồn của chính bản phân phối.
  2. Hai người rà soát từng CVE trong đó. Kết quả là review.json.
  3. hitechcloud-livepatch-tool bundle ghi một gói chưa ký, và từ chối nếu bản rà soát chưa đầy đủ.
  4. Trên một máy ngoại tuyến, khóa (hoặc khóa phần cứng) ký manifest. Manifest nêu SHA-256 của mô-đun, bản phát hành nhân, mã bản dựng nhân, kiến trúc, các CVE, số thứ tự, thời hạn và mã băm của bản rà soát, nên chữ ký bao trùm tất cả.
  5. Gói đã ký được phát hành vào cây kho, một chỉ mục của cây được ghi và ký, rồi cây được tải lên máy chủ kho.
  6. Trên máy chủ, quản trị viên yêu cầu bản vá. Máy chủ kiểm tra chữ ký, bản dựng nhân và bản rà soát, rồi nạp nó.

Khóa​

  • Một khóa ed25519 ký manifest và chỉ mục. Nó không phải khóa phát hành. Máy chủ từ chối tin một khóa là khóa phát hành hoặc khóa mô-đun chính thức, dù tệp được đặt ở đâu.
  • Khóa không bao giờ nằm trong kho mã, trong secret của CI, trên máy dựng hay trên dòng lệnh. Công cụ nhận nó dưới dạng một dòng trên đầu vào chuẩn, hoặc từ một tệp mà chỉ chủ của nó đọc được.
  • Khóa phần cứng không bao giờ để khóa ra ngoài là cách được khuyến nghị. Nếu khóa hỗ trợ chữ ký ed25519, công cụ in ra đúng các byte cần ký và nhận câu trả lời; xem Ký bằng khóa phần cứng.
  • Chữ ký mô-đun nhân (cho Secure Boot) là một khóa và chứng chỉ thứ hai, khác hẳn; xem Secure Boot và MOK.
  • Hãy tạo khóa trên máy ngoại tuyến của chính bạn. Cùng định dạng với khóa phát hành, với tên riêng:
umask 077
openssl genpkey -algorithm ed25519 -out hitechcloud-livepatch.pem
printf 'htc-ed25519-private %s\n' "$(openssl pkey -in hitechcloud-livepatch.pem -outform DER | tail -c 32 | base64 -w0)" > hitechcloud-livepatch.key
printf 'htc-ed25519 %s hitechcloud-livepatch-%s\n' "$(openssl pkey -in hitechcloud-livepatch.pem -pubout -outform DER | tail -c 32 | base64 -w0)" "$(date +%Y)" > hitechcloud-livepatch.pub
hitechcloud-livepatch-tool public-id --public hitechcloud-livepatch.pub
  • Dòng công khai được đặt trên từng máy chủ thành /etc/hitechcloud/livepatch/trusted-keys/<key id>.pub, trong thư mục thuộc root và không ai khác ghi được. Máy chủ bỏ qua tệp có tên không phải mã của khóa trong đó.
  • Để xoay khóa, hãy tin cậy khóa công khai mới trên các máy chủ trước, ký bằng khóa mới, rồi xóa tệp của khóa cũ. Nếu khóa riêng có thể đã bị lộ, hãy xóa tệp công khai của nó khỏi mọi máy chủ ngay: chỉ mục đã lưu và mọi gói nó đã ký không còn được chấp nhận.

Công cụ​

hitechcloud-livepatch-tool được dựng từ thư mục cli/livepatch-tool của kho hitechcloudcli (cargo build --release). Nó chạy trên máy của chính chủ sở hữu và không bao giờ được cài trên máy chủ. Nó dùng chung một tệp với server-livepatch trên máy chủ, nên gói nó ghi ra được đánh giá bằng đúng mã đánh giá nó trên máy chủ.

hitechcloud-livepatch-tool help
hitechcloud-livepatch-tool review-guide
hitechcloud-livepatch-tool recipe rhel --kernel-release <uname -r of the target>

Việc rà soát của con người​

Một gói cần review.json đầy đủ và đã ký duyệt. Công cụ ghi một mẫu trong đó mọi CVE đang chờ, mọi kiểm tra là false và chưa ai ký duyệt:

hitechcloud-livepatch-tool review-template --module <module>.ko --id <patch id> --kernel-release <release> --build-id <build id> --arch <arch> --cve CVE-YYYY-NNNN --out review.json

Tác giả và một người rà soát khác điền vào. Công cụ và mọi máy chủ từ chối gói trừ khi:

  • mọi CVE trong manifest đều có trong bản rà soát, và chỉ những CVE đó, mỗi CVE có quyết định patched và một phân tích bằng văn bản
  • chín kiểm tra trong review-guide đều là true: mã nguồn là đúng mã nguồn của bản phân phối cho bản dựng đích, trình biên dịch và cấu hình là của bản dựng đó, thay đổi là bản sửa của CVE và không gì khác, nó ở mức hàm hoặc các thay đổi dữ liệu đã được rà soát, không hàm nào được vá nằm trong đường khởi tạo hay đường luôn chạy, và mô-đun đã được khởi động, nạp, gỡ rồi nạp lại, kiểm thử hồi quy và hoàn tác trên bản dựng đích
  • bản rà soát nêu SHA-256 của mô-đun này, bản phát hành nhân, mã bản dựng và kiến trúc này
  • một tác giả và một người rà soát không phải tác giả đã ký duyệt, mỗi người với một thời điểm UTC

Đây là một bản ghi, không phải bằng chứng. Phần mềm kiểm tra rằng bản ghi đầy đủ và gắn với mô-đun; nó không thể kiểm tra rằng những người đó đã làm việc. Chữ ký là lời xác nhận của chủ sở hữu rằng họ đã làm. Chữ ký mật mã riêng của từng người rà soát chưa được xây dựng (xem Các quyết định còn mở).

Một CVE không thể vá nóng thì không được đưa vào gói. Câu trả lời cho nó là khởi động lại.

Công thức dựng​

In công thức và danh sách kiểm tra cho máy đích, với bản phát hành nhân đã điền sẵn:

hitechcloud-livepatch-tool recipe rhel --kernel-release <release>
hitechcloud-livepatch-tool recipe ubuntu --kernel-release <release>
hitechcloud-livepatch-tool recipe debian --kernel-release <release>

Tóm tắt nội dung:

  • Mọi họ. Một máy dựng cho mỗi bản dựng nhân chính xác: mã nguồn của bản dựng đó (kèm các bản vá của bản phân phối), cấu hình của nó, vmlinux có ký hiệu gỡ lỗi tương ứng (vài GB), và cùng trình biên dịch và binutils mà bản phân phối đã dùng. Trình biên dịch khác cho mã khác. Máy dựng được cô lập, không giữ khóa, và chỉ nạp mô-đun thử trên một VM dùng một lần của bản dựng đích.
  • RHEL, AlmaLinux, Rocky. SRPM của đúng nhân đó, kernel-debuginfo tương ứng, và kpatch-build. RHEL chính hãng có các gói kpatch-patch riêng của Red Hat cho một số CVE, đó là lý do không nên dựng ở đó. Nhân EL được backport rất nhiều, nên bản vá được cắt từ nhân kế tiếp của bản phân phối, không phải từ upstream.
  • Ubuntu. Gói mã nguồn đã dựng đúng loại và phiên bản nhân đó, gói -dbgsym tương ứng, và kpatch-build. Canonical có dịch vụ Livepatch riêng, là một dịch vụ của nhà cung cấp (quyết định D5). Nhân Ubuntu được Canonical ký cho Secure Boot, nên mô-đun của ta cần chữ ký mô-đun riêng và việc đăng ký MOK.
  • Debian. Gói mã nguồn và gói -dbg tương ứng. Debian không phát hành bản vá nóng, và dự án của chính họ báo rằng kpatch không còn hỗ trợ nhân của Debian 13. Với Debian 11 và 12, hãy thử trong phòng thí nghiệm trước. Với Debian 13, con đường thực tế là klp-build của Linux upstream 6.19 được backport cùng công cụ của nó, đó là một dự án và chưa làm.

Danh sách kiểm tra theo từng bản dựng nhân trong mỗi công thức có cùng một hình dạng: máy dựng, mã nguồn, ký hiệu, trình biên dịch, dựng, thông tin máy đích (đọc từ chính nhân đích, không bao giờ từ máy dựng), rà soát, thử trên bản dựng đích, đóng gói, ký, phát hành. Làm lại cho mỗi bản cập nhật nhân của bản phân phối, cho mọi nhân mà khách hàng của bạn chạy.

Ghi một gói​

Trên máy dựng (không có khóa), với mô-đun từ bản dựng và thông tin máy đích từ server-livepatch status --json trên một máy chạy nhân đó:

hitechcloud-livepatch-tool next-serial --tree <mirror tree>
hitechcloud-livepatch-tool bundle --module <module>.ko --review review.json --out <bundle dir> --id <patch id> --kernel-release <release> --build-id <build id> --arch <arch> --cve CVE-YYYY-NNNN --serial <serial>

Một gói gồm đúng bốn tệp: manifest.json, manifest.sig (chưa có), review.json và mô-đun. Số thứ tự là một dãy chung cho mọi gói: máy chủ từ chối bản vá có số thứ tự thấp hơn bản vá nó đã áp dụng gần nhất, nên hãy lấy số kế tiếp từ next-serial. Manifest có hiệu lực 30 ngày theo mặc định và tối đa 90 ngày.

Ký ngoại tuyến​

Sao chép thư mục gói sang máy ngoại tuyến và ký ở đó. Công cụ kiểm tra lại mọi thứ mà máy chủ sẽ kiểm tra trước khi ký.

hitechcloud-livepatch-tool sign --bundle <bundle dir> --forbid-key-id <release key id> < hitechcloud-livepatch.key
hitechcloud-livepatch-tool verify --bundle <bundle dir> --public hitechcloud-livepatch.pub

Khóa cũng có thể là một tệp truyền bằng --key-file, công cụ từ chối trừ khi chỉ chủ của nó đọc được. Khóa truyền làm đối số bị từ chối.

Ký bằng khóa phần cứng​

hitechcloud-livepatch-tool signing-input --bundle <bundle dir> --out manifest.signing-input
openssl pkeyutl -sign -rawin -inkey <token key URI> -in manifest.signing-input -out manifest.signature
hitechcloud-livepatch-tool attach --bundle <bundle dir> --public hitechcloud-livepatch.pub --signature manifest.signature

Lệnh ở giữa phụ thuộc vào khóa phần cứng và nhà cung cấp PKCS#11 của nó; đó là một ví dụ, không phải công thức đã thử, và nhiều khóa phần cứng không hỗ trợ ed25519. Công cụ kiểm tra chữ ký với khóa công khai trước khi ghi, và không ghi gì khi nó sai.

Kho phản chiếu​

Kho phản chiếu là một trang tĩnh: bất kỳ máy chủ web nào phục vụ tệp qua HTTPS. Nó chỉ phân phối. Nó không thể ký, và một kho bị xâm nhập không thể khiến máy chủ nạp bất cứ thứ gì, vì mọi tệp đều được kiểm tra với chỉ mục đã ký và chữ ký riêng của manifest. Bố cục là một thư mục cho mỗi gói:

livepatch/index.json
livepatch/index.sig
livepatch/<distribution>/<release>/<arch>/<kernel release>/<patch id>/manifest.json
livepatch/<distribution>/<release>/<arch>/<kernel release>/<patch id>/manifest.sig
livepatch/<distribution>/<release>/<arch>/<kernel release>/<patch id>/review.json
livepatch/<distribution>/<release>/<arch>/<kernel release>/<patch id>/<module>.ko
hitechcloud-livepatch-tool publish --tree <tree> --bundle <bundle dir> --distro ubuntu --release 24.04 --public hitechcloud-livepatch.pub
hitechcloud-livepatch-tool index --tree <tree> --public hitechcloud-livepatch.pub
hitechcloud-livepatch-tool sign --index <tree>/index.json < hitechcloud-livepatch.key
hitechcloud-livepatch-tool verify --tree <tree> --public hitechcloud-livepatch.pub
  • Chỉ mục liệt kê mọi gói với kích thước và SHA-256 của từng tệp, bản phát hành nhân, mã bản dựng và kiến trúc của nó, cùng danh sách các bản vá đã bị rút. Nó có số thứ tự riêng, chỉ tăng, và thời hạn (mặc định 14 ngày, tối đa 30): chỉ mục đã cũ hay một bản cũ được phát lại cho máy chủ đều bị từ chối. Hãy ký lại và tải lên lại trước khi nó hết hạn.
  • Để rút một bản vá, chạy revoke --tree <tree> --id <patch id> --reason <text>, rồi chạy lại index và sign --index. Máy chủ hiển thị bản vá là đã bị rút, và bảo quản trị viên hoàn tác nó nếu nó đang được nạp.
  • Tải cây lên máy chủ kho (index.sig mới tải sau cùng). Chuyển hướng không được theo, nên hãy phục vụ tệp trực tiếp. Địa chỉ https://mirrors.hitechcloud.org là kho phản chiếu của chính dự án, đã được liệt kê trong docs-internal/external-downloads.allow; thư mục livepatch/ dưới nó không thêm máy chủ ngoài nào mới. Tác vụ đồng bộ của kho không ghi hay dọn thư mục livepatch/.

Trên máy chủ​

Tất cả những việc này chỉ root làm được, trên dòng lệnh của máy chủ. Bảng quản trị có thể hiển thị kết quả và yêu cầu làm mới hoặc áp dụng, và không thể thay đổi bất cứ điều gì trong số đó.

install -d -m 0755 /etc/hitechcloud/livepatch/trusted-keys
install -m 0644 <key id>.pub /etc/hitechcloud/livepatch/trusted-keys/<key id>.pub
hitechcloudcli server-livepatch mirror set https://<mirror host>/livepatch
hitechcloudcli server-livepatch mirror refresh
hitechcloudcli server-livepatch mirror
hitechcloudcli server-livepatch fetch <patch id> --yes
hitechcloudcli server-livepatch rollback <module> --yes

Địa chỉ chỉ là https (http thường chỉ cho chính máy này, trong phòng thí nghiệm), không có tên người dùng hay truy vấn. Nó được giữ trong một tệp chỉ root ghi được. Mặc định là không có, và không có gì được tải cho đến khi nó được đặt. Máy chủ không bao giờ tự tải hay tự áp dụng: không bộ hẹn giờ nào làm việc đó. Bản vá không được giữ lại sau khi khởi động lại.

Secure Boot và MOK​

Dưới Secure Boot, khóa nhân (lockdown) hoặc sig_enforce, nhân chỉ nạp mô-đun được ký bằng khóa mà nó tin cậy. Chữ ký ed25519 của manifest không làm nhân hài lòng. Vì vậy chủ sở hữu cần thêm:

  • một khóa ký mô-đun và chứng chỉ X.509, giữ ngoại tuyến như khóa manifest
  • mọi mô-đun được ký bằng sign-file của chính nhân trước khi đóng gói (công cụ nhận ra chữ ký mà nhân gắn thêm và ghi nó vào manifest)
  • chứng chỉ được đăng ký trên mọi máy chủ Secure Boot bằng mokutil --import, xác nhận trên màn hình điều khiển ở lần khởi động kế tiếp

Máy chủ bắt buộc chữ ký sẽ từ chối mô-đun chưa ký trước khi nạp, và nêu lý do. Không có Secure Boot và không có sig_enforce, chữ ký của manifest là cổng duy nhất, đó là lý do việc rà soát và khóa quan trọng đến vậy.

Danh sách kiểm tra trong phòng thí nghiệm​

Chưa ai làm việc này. Hãy làm trên các VM dùng một lần và ghi kết quả vào tài liệu thiết kế.

  1. Dựng hitechcloud-livepatch-tool, chạy các bài kiểm thử của nó, và tạo một khóa dùng thử.
  2. Trên một VM có nhân của bản phân phối thật, dựng một bản vá đơn giản bằng kpatch-build trên một máy dựng riêng, rà soát, đóng gói, ký bằng khóa dùng thử, và tin cậy khóa đó trên VM.
  3. apply --bundle nó. Kiểm tra /sys/kernel/livepatch/<name>/enabled và transition, dấu taint của nhân, rollback, và việc khởi động lại gỡ nó đi.
  4. Kiểm tra rằng từng trường hợp sau bị từ chối: mã bản dựng khác, một byte bị đổi trong mô-đun, manifest chưa ký, manifest hết hạn, số thứ tự thấp hơn, bản rà soát bị đổi.
  5. Phát hành nó vào một cây, lập chỉ mục và ký, phục vụ cây qua HTTPS, rồi mirror set, mirror refresh và fetch. Kiểm tra rằng chỉ mục đã cũ, số thứ tự chỉ mục thấp hơn, một tệp bị tráo và một bản vá bị rút đều bị từ chối.
  6. Trên một VM Secure Boot: mô-đun chưa ký bị từ chối kèm lý do, và mô-đun được ký bằng chứng chỉ đã đăng ký thì nạp được.
  7. Một luồng nhân bị giữ trong hàm được vá: apply hoàn tác sau giới hạn và thoát với mã khác 0; rollback báo là bị kẹt và không bao giờ ghi force.
  8. Đặt khóa công khai thật lên một máy chủ dự phòng và lặp lại bước 3 với khóa phần cứng thật.

Các quyết định còn mở​

Các quyết định D1 đến D8 của chủ sở hữu nằm trong tài liệu thiết kế. Những quyết định mà đường ống này làm cho cụ thể:

  • D1: ai giữ khóa ký và khóa ký mô-đun, và ở đâu. Khuyến nghị là khóa phần cứng do chủ sở hữu giữ.
  • D2: có vận hành việc dựng bản vá hay không, cho những nhân nào, với những người rà soát nào, và cam kết gì với khách hàng. Hãy bắt đầu với một dòng nhân và "nỗ lực tốt nhất, nếu không thì khởi động lại".
  • D4: có hỗ trợ đăng ký MOK hay không.
  • D8: trách nhiệm khi một bản vá làm sập máy chủ của khách hàng.
  • Liệu từng người rà soát có nên ký review.json bằng khóa của riêng họ, thay vì chữ ký của chủ sở hữu xác nhận bản ghi. Chưa xây dựng.