SSD Nodes Learn 🎉 VPS เริ่ม $5.50/เดือน
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-13

วิธีตรวจสอบและเปิดใช้งาน AES-NI บน VPS

ตรวจสอบว่า VPS ของคุณรองรับ AES-NI หรือไม่ พร้อมวิธีวัดผลกระทบต่อความเร็ว AES-GCM และการใช้ OPENSSL_ia32cap เพื่อบังคับเปิดใช้งานชุดคำสั่งฮาร์ดแวร์ให้กลับมาทำงานได้ตามปกติ

ประโยชน์ที่แท้จริงของ AES-NI บน VPS

AES-NI บน VPS คือชุดคำสั่ง x86 จำนวน 6 คำสั่งที่ทำหน้าที่ประมวลผล AES (Advanced Encryption Standard) หนึ่งรอบในระดับฮาร์ดแวร์ หากโมเดล CPU ของผู้ให้บริการซ่อนคำสั่งเหล่านี้ไว้ ตัวฮาร์ดแวร์จริงก็ยังคงมีอยู่ แต่ OpenSSL จะมองไม่เห็นและเปลี่ยนไปใช้การประมวลผลด้วยซอฟต์แวร์แทน ซึ่งใช้รอบการทำงานมากกว่าประมาณ 10 เท่าต่อไบต์ คุณสามารถตรวจสอบฟีเจอร์นี้ได้ด้วยคำสั่งเดียว วัดความแตกต่างได้ด้วยสองคำสั่ง และมักจะบังคับให้กลับมาใช้เส้นทางที่รวดเร็วได้ด้วยตัวแปรสภาพแวดล้อม (environment variable) เพียงตัวเดียว

คำสั่งดังกล่าวคือ AESENC, AESENCLAST, AESDEC, AESDECLAST, AESIMC และ AESKEYGENASSIST Intel เริ่มนำมาใช้ในปี 2010 และ AMD ก็ทำตาม ดังนั้น CPU เซิร์ฟเวอร์ที่คุณเช่าใช้งานส่วนใหญ่จึงมีฮาร์ดแวร์นี้อยู่แล้ว คำสั่งที่ทำงานร่วมกันคือ PCLMULQDQ ซึ่งทำหน้าที่คูณแบบ carry-less ซึ่งเป็นสิ่งที่ GCM (Galois/Counter Mode) จำเป็นต้องใช้ในการสร้าง authentication tag ของตน AES-GCM จะทำงานได้รวดเร็วก็ต่อเมื่อมีทั้งสองอย่างนี้พร้อมใช้งาน เพราะการเข้ารหัส (cipher) และการสร้าง tag เป็นงานที่แยกจากกัน

สี่จุดบน VPS ที่คุณจะเห็นผลกระทบนี้ในการตรวจสอบระบบ (monitoring):

  • การทำ TLS (Transport Layer Security) termination: เว็บเซิร์ฟเวอร์ที่ให้บริการ AES-128-GCM หรือ AES-256-GCM จะใช้เวลาส่วนใหญ่ในการประมวลผล crypto ไปกับการทำงานของ AES
  • การเข้ารหัสวอลุ่ม (Encrypted volumes): LUKS (Linux Unified Key Setup) และ dm-crypt จะรัน aes-xts ในทุกการอ่านและเขียน โดยทำงานในระดับเคอร์เนลบน CPU
  • ทราฟฟิก VPN ที่ใช้ AES: OpenVPN ที่ใช้ AES-256-GCM และ IPsec ที่ใช้ AES-GCM ต่างก็พึ่งพาคำสั่งเหล่านี้
  • การสำรองข้อมูลแบบเข้ารหัส: ทุกสิ่งที่เข้ารหัสสตรีมข้อมูลด้วย AES ก่อนส่งออกจากเครื่องจะต้องแลกด้วยต้นทุนการประมวลผลเดียวกัน

มีภาระงานทั่วไปหนึ่งประเภทที่ไม่ได้รับผลกระทบเลย นั่นคือ WireGuard ซึ่งใช้ ChaCha20-Poly1305 สำหรับข้อมูลและไม่เคยเรียกใช้ AES ดังนั้น การทำ self-hosted WireGuard VPN จึงทำงานได้ด้วยความเร็วเท่าเดิมแม้บนโฮสต์ที่ถูกปิดบัง flag นี้ไว้ ความแตกต่างดังกล่าวเป็นเหตุผลเชิงปฏิบัติในการพิจารณา เปรียบเทียบ WireGuard กับ OpenVPN ก่อนที่คุณจะเลือกใช้ tunnel สำหรับ VPS ราคาประหยัด

วิธีตรวจสอบว่า VPS ของคุณรองรับ AES-NI หรือไม่

Kernel จะคัดลอกบิตคุณสมบัติของ CPUID ไปไว้ใน /proc/cpuinfo ดังนั้นการใช้ grep เพียงคำสั่งเดียวก็สามารถตอบคำถามนี้ได้

grep -m1 -o '\baes\b' /proc/cpuinfo
lscpu | grep -i -o '\baes\b'

หากคำสั่งใดคำสั่งหนึ่งแสดงผลเป็น aes หมายความว่า CPU แจ้งว่ารองรับ AES-NI สำหรับ guest นี้ หากไม่แสดงผลใดๆ หมายความว่าไม่รองรับ lscpu จะอ่านค่า flag เดียวกัน ดังนั้นทั้งสองคำสั่งจะให้ผลลัพธ์ที่ตรงกันเสมอ ให้ใช้คำสั่งใดก็ได้ที่มีติดตั้งอยู่

จากนั้นให้ตรวจสอบว่า host ระบุว่าคุณกำลังใช้งาน CPU รุ่นใด

grep -m1 'model name' /proc/cpuinfo

หากแสดงชื่อรุ่นจริง เช่น Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz หรือ AMD EPYC 7443P 24-Core Processor หมายความว่า host ส่งผ่านข้อมูลรุ่น CPU จริงมาให้คุณ หากแสดงเป็น QEMU Virtual CPU version 2.5+ หรือ Common KVM processor หมายความว่ามีสถานการณ์อื่นเกิดขึ้น ซึ่งกรณีนี้เป็นกรณีที่ควรทำความเข้าใจให้ชัดเจน

เหตุใดแฟล็กจึงหายไปทั้งที่ฮาร์ดแวร์รองรับ

CPUID คือคำสั่งที่โปรแกรมใช้เพื่อสอบถาม CPU ว่ารองรับฟีเจอร์ใดบ้าง ภายในเครื่องเสมือน (virtual machine) คำสั่ง CPUID จะถูกดักจับโดยไฮเปอร์ไวเซอร์ (hypervisor) เสมอ ดังนั้นไฮเปอร์ไวเซอร์จะเป็นผู้ตัดสินใจว่าจะแจ้งข้อมูลใดแก่แขก (guest) แผงควบคุมส่วนใหญ่จะแสดงการตัดสินใจนั้นในรูปแบบโมเดล CPU ของแขก qemu64 และ kvm64 เป็นโมเดลพื้นฐานทั่วไป ซึ่งไม่มี AES-NI หรือ SSSE3 รวมอยู่ในชุดฟีเจอร์ ดังนั้นแขกจึงไม่เห็นแฟล็ก aes แม้ว่าโฮสต์ทางกายภาพจะเป็น EPYC รุ่นปัจจุบันก็ตาม VPS คือแขกที่อยู่บนฮาร์ดแวร์ของผู้อื่น ดังนั้นฟีเจอร์ทุกอย่างที่รายงานออกมาจึงเป็นการตัดสินใจจากระดับที่สูงกว่า หากการแบ่งชั้นนี้เป็นเรื่องใหม่สำหรับคุณ ให้เริ่มต้นที่ VPS คืออะไร

โฮสต์เลือกใช้โมเดลทั่วไปโดยเจตนา เพราะการย้ายเครื่องแบบสด (live migration) ระหว่างเครื่องที่มีโปรเซสเซอร์ต่างกันจะทำได้ก็ต่อเมื่อแขกไม่เคยได้รับแจ้งเกี่ยวกับฟีเจอร์ที่ปลายทางไม่มี ผลกระทบจึงตกอยู่ที่คุณ เคอร์เนลและ OpenSSL ของคุณต่างอ่านค่า CPUID ที่ถูกปิดบังไว้ตั้งแต่ตอนเริ่มต้น และเลือกใช้เส้นทางการทำงานที่ช้ากว่าตลอดอายุของโพรเซส

การแก้ไขที่ต้นทางคือการตั้งค่าฝั่งโฮสต์: -cpu host ในบริบทของ QEMU คือการใช้โมเดลที่มีชื่อซึ่งรวม AES-NI ไว้ด้วย หรือการเพิ่ม +aes เข้าไปในโมเดลอย่างชัดเจน คุณไม่สามารถตั้งค่าเหล่านี้จากภายในแขกได้ การเปิดตั๋วสนับสนุน (support ticket) หรือการเลือกแผนบริการที่ไฮเปอร์ไวเซอร์ส่งผ่านโมเดล CPU มาให้โดยตรง คือคำตอบที่ยั่งยืนที่สุด

วัดช่องว่างประสิทธิภาพด้วย openssl speed

อย่าเชื่อผลการทดสอบมาตรฐานที่เผยแพร่ทั่วไป ให้รันการทดสอบ cipher ที่เซิร์ฟเวอร์ของคุณใช้งานจริง

openssl version
openssl speed -evp aes-128-gcm

แถวผลลัพธ์จะระบุด้วยป้ายกำกับ AES-128-GCM ซึ่งแสดงปริมาณงาน (throughput) ที่ขนาดบล็อก 6 ระดับ ในหน่วย 1000 ไบต์ต่อวินาที ให้อ่านค่าในคอลัมน์ 8192 ไบต์สำหรับการถ่ายโอนข้อมูลขนาดใหญ่ เนื่องจากคอลัมน์ 16 ไบต์นั้นได้รับผลกระทบจาก overhead ต่อการเรียกใช้งานเป็นหลัก จึงไม่สามารถใช้ประเมินความเร็วในการดาวน์โหลดไฟล์ได้

จากนั้นให้รันคำสั่งเดิมโดยปิดการใช้งาน AES-NI และ PCLMULQDQ ในซอฟต์แวร์:

OPENSSL_ia32cap="~0x200000200000000" openssl speed -evp aes-128-gcm

ค่าดังกล่าวมาจากเอกสารประกอบเวกเตอร์ความสามารถของ OpenSSL โดยเครื่องหมาย ~ นำหน้าหมายถึง "ให้ล้างบิตเหล่านี้ออก" บิตที่ 57 คือ AES-NI และบิตที่ 33 คือ PCLMULQDQ ดังนั้น 0x200000200000000 จึงระบุเฉพาะสองรายการนี้เท่านั้น หากตัวเลขที่สองต่ำกว่าตัวเลขแรกมาก แสดงว่าเซิร์ฟเวอร์ของคุณมีการใช้งาน AES-NI ได้ตามปกติและคุณดำเนินการเสร็จสิ้นแล้ว แต่หากตัวเลขทั้งสองเท่ากัน แสดงว่า OpenSSL ทำงานผ่านเส้นทางซอฟต์แวร์อยู่ก่อนแล้ว เนื่องจากไม่มี flag ดังกล่าวให้ล้างออกตั้งแต่แรก

ChartAES-128-GCM throughput, one core, 8192-byte blocks (representative published figures)
The data behind this chart
[
  {
    "label": "AES-NI and PCLMULQDQ",
    "mb_per_sec": "4,850",
    "cycles_per_byte": 0.7
  },
  {
    "label": "Software fallback",
    "mb_per_sec": 310,
    "cycles_per_byte": 11.0
  }
]

ตัวเลขเหล่านี้เป็นตัวเลขตัวแทนที่เผยแพร่สำหรับ x86 core สมัยใหม่ที่ความเร็วประมาณ 3.4 GHz ไม่ใช่การวัดจากโฮสต์ใดโฮสต์หนึ่งโดยเฉพาะ ให้มองตัวเลขเหล่านี้เป็นแนวโน้ม เส้นทางฮาร์ดแวร์ทำงานที่ประมาณ 0.7 รอบต่อไบต์ และเส้นทางซอฟต์แวร์สำรองทำงานที่ประมาณ 11.0 ซึ่งคำนวณได้ประมาณ 4,850 MB/s เทียบกับ 310 MB/s ต่อหนึ่ง core คำสั่งทั้งสองข้างต้นจะให้ตัวเลขเดียวที่อธิบายประสิทธิภาพเซิร์ฟเวอร์ของคุณได้แม่นยำที่สุด หลักการเดียวกันนี้ใช้กับส่วนอื่นๆ ของเครื่อง ดังนั้นควรใช้ควบคู่ไปกับ วิธีการทดสอบประสิทธิภาพ VPS ที่ทำซ้ำได้ ก่อนที่คุณจะสรุปผลเกี่ยวกับแผนการใช้งานใดๆ

บังคับเปิดใช้งานบิตกลับคืนด้วย OPENSSL_ia32cap

นี่คือส่วนที่ทำให้หลายคนประหลาดใจ คำสั่ง AES-NI เป็นคำสั่งระดับ unprivileged และ hypervisor ไม่ได้ดักจับคำสั่งเหล่านี้ มีเพียง CPUID เท่านั้นที่ถูกดักจับ ดังนั้นโฮสต์สามารถแจ้ง guest ของคุณว่าไม่มี AES-NI ในขณะที่ AESENC ยังคงทำงานที่ความเร็วเต็มประสิทธิภาพตามปกติ ซอฟต์แวร์ข้ามเส้นทางที่รวดเร็วไปเพราะได้รับคำตอบที่ผิดจากการสอบถาม CPUID แต่ตัวคำสั่งเองไม่เคยหยุดทำงาน

OpenSSL อนุญาตให้คุณตอบกลับแทน CPU ได้ โดยการใช้ค่าเลขฐานสิบหกใน OPENSSL_ia32cap เพื่อเขียนทับเวกเตอร์ความสามารถ (capability vector) แทนการปิดบังค่าเดิม

OPENSSL_ia32cap="0x0200020207000000" openssl speed -evp aes-128-gcm

หากการทดสอบนั้นเร็วกว่าการรันแบบปกติหลายเท่า แสดงว่าฮาร์ดแวร์มี AES-NI และโฮสต์ของคุณกำลังซ่อนมันอยู่ นี่คือการวินิจฉัยเบื้องต้น และสำหรับ OpenSSL นี่ถือเป็นการแก้ไขปัญหาด้วยเช่นกัน

วิธีการสร้างค่าเลขฐานสิบหกนั้น

เวกเตอร์เชิงตรรกะชุดแรกจะรวมค่า CPUID leaf 1 EDX ไว้ใน 32 บิตล่าง และ leaf 1 ECX ไว้ใน 32 บิตบน ในส่วนครึ่งล่าง บิตที่ 24 คือ FXSR, บิตที่ 25 คือ SSE และบิตที่ 26 คือ SSE2 ซึ่งจะได้ค่า 0x07000000 ในส่วนครึ่งบน บิตที่ 33 คือ PCLMULQDQ, บิตที่ 41 คือ SSSE3 และบิตที่ 57 คือ AES-NI ซึ่งจะได้ค่า 0x02000202 เมื่อรวมกันจะได้ค่า 0x0200020207000000 ที่ต้องรวม SSSE3 ไว้ในรายการเพราะ GHASH ของ OpenSSL ที่ใช้ PCLMULQDQ จำเป็นต้องใช้ pshufb ในการสลับไบต์ และโมเดล CPU แบบทั่วไปของ guest มักจะซ่อน SSSE3 ไปพร้อมกับ AES-NI

มีคำเตือน 2 ประการที่ควรทราบ และคุณสามารถทำให้เกิดปัญหาทั้งสองอย่างได้หากตั้งค่าโดยเจตนา

การตั้งค่าเพียงเวกเตอร์แรกจะทำให้เวกเตอร์ลำดับถัดไปเป็นศูนย์ ซึ่งจะปิดการทำงานของเส้นทางโค้ด AVX2 และ AVX-512 ซึ่งเป็นความตั้งใจในกรณีนี้ อย่าพยายามบังคับเปิดบิต AVX บน guest ที่ถูกปิดบังไว้ เพราะรีจิสเตอร์ AVX จำเป็นต้องให้ระบบปฏิบัติการเปิดใช้งานสถานะขยาย (extended state) ใน XCR0 และ kernel ของคุณได้ปฏิเสธการดำเนินการนั้นตามข้อมูล CPUID ที่ถูกปิดบังไว้ ส่งผลให้คำสั่ง VEX-encoded ทำให้เกิดข้อผิดพลาด undefined-opcode และ process จะหยุดทำงานทันที

การบังคับใช้ AES-NI บนคอร์ที่ไม่มีความสามารถนี้จริงๆ จะทำให้ process หยุดทำงานทันที:

Illegal instruction (core dumped)

นั่นคือ AESENC ที่ทำให้เกิดข้อผิดพลาด undefined-opcode เนื่องจากบนคอร์นั้นไม่มีคำสั่งดังกล่าวให้ประมวลผล เฟิร์มแวร์ของเซิร์ฟเวอร์บางรุ่นอาจปิดการใช้งาน AES-NI ในระดับฮาร์ดแวร์จนกว่าจะมีการรีเซ็ตครั้งถัดไป ซึ่งจะมีอาการเดียวกัน ไม่ว่ากรณีใดก็ตาม ทางออกคือการเปลี่ยนโฮสต์ ไม่ใช่การเปลี่ยน environment variable

หากต้องการคงค่าที่กำหนดไว้สำหรับบริการที่รันต่อเนื่อง ให้ใช้ systemd drop-in

sudo systemctl edit nginx
[Service]
Environment="OPENSSL_ia32cap=0x0200020207000000"
sudo systemctl daemon-reload
sudo systemctl restart nginx
sudo systemctl show nginx -p Environment

คำสั่งสุดท้ายควรแสดงค่าตัวแปรกลับมาให้คุณเห็น โปรดเข้าใจสิ่งที่คุณกำลังทำ: หากเซิร์ฟเวอร์นั้นถูกย้ายไปยังโฮสต์ที่ CPU ไม่มี AES-NI จริงๆ nginx จะหยุดทำงานด้วยข้อผิดพลาด illegal instruction ทันทีที่มีการเชื่อมต่อ TLS ครั้งแรก ให้บันทึกเรื่องนี้ไว้ใน runbook ของคุณ หรือหลีกเลี่ยงการใช้การตั้งค่านี้ในระบบ production และใช้เพื่อพิสูจน์ปัญหาเฉพาะตอนเปิด ticket เท่านั้น

สิ่งที่การ override แก้ไขไม่ได้

OPENSSL_ia32cap ส่งผลต่อ OpenSSL เท่านั้น ซอฟต์แวร์ตัวอื่นทั้งหมดจะทำการตรวจสอบคุณสมบัติด้วยตนเองและไม่อ่านค่าตัวแปรดังกล่าว

กรณีที่สำคัญคือ kernel โดย dm-crypt และ LUKS จะใช้ kernel crypto API และโมดูล aesni_intel จะปฏิเสธการโหลดเมื่อไม่พบ CPU feature bit:

modprobe: ERROR: could not insert 'aesni_intel': No such device

ไม่มีตัวแปรในระดับ user-space สำหรับเรื่องนี้ kernel จะอ่านค่า CPUID เพียงครั้งเดียวตอนบูตและจะใช้การตัดสินใจนั้นจนกว่าคุณจะรีบูตบนโฮสต์อื่น ดังนั้น encrypted volume ของคุณจะยังคงใช้ software cipher ไม่ว่า OpenSSL จะทำงานอย่างไรก็ตาม ให้วัดผลสิ่งที่คุณได้รับจริง:

sudo cryptsetup benchmark -c aes-xts -s 256

แถว aes-xts 256b จะแสดงค่าเป็นหลักพัน MiB/s หากใช้ hardware AES และเหลือเพียงหลักร้อยต้นๆ หากไม่มี ภาษาที่รันไทม์มีระบบตรวจสอบของตนเอง เช่น Go และ Java ก็อยู่นอกเหนือการควบคุมเช่นกัน crypto/aes ของ Go จะตรวจสอบ CPUID โดยตรงและเลือกใช้ implementation แบบ software ที่เป็น constant-time อย่างเงียบๆ เมื่อไม่พบ bit ดังกล่าว หากบริการที่ทำ TLS termination เป็น Go binary ตัวแปรของ OpenSSL จะไม่มีผลใดๆ ต่อบริการนั้น

หากคุณไม่สามารถใช้งาน AES-NI ได้ ให้เลือกใช้ ChaCha20

ChaCha20-Poly1305 ถูกออกแบบมาให้ทำงานได้อย่างรวดเร็วด้วยซอฟต์แวร์ล้วน บนหน่วยประมวลผลที่ไม่มี AES-NI ให้ใช้งาน อัลกอริทึมนี้มักจะทำงานได้เร็วกว่า AES-GCM อย่างเห็นได้ชัด ดังนั้นสิ่งที่ควรทำบนโฮสต์ดังกล่าวคือการเลิกตั้งค่าให้ AES เป็นลำดับความสำคัญแรก

สำหรับ nginx เวอร์ชัน 1.19.4 ขึ้นไป ที่คอมไพล์ร่วมกับ OpenSSL เวอร์ชัน 1.1.1 ขึ้นไป:

ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_conf_command Ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384;

ssl_ciphers ครอบคลุมการตั้งค่าสำหรับ TLS 1.2 ส่วน ssl_conf_command Ciphersuites ครอบคลุม TLS 1.3 ซึ่ง nginx ไม่มี directive เฉพาะสำหรับส่วนนี้และจะส่งสตริงไปยัง OpenSSL โดยตรงโดยไม่มีการตรวจสอบ ดังนั้นหากพิมพ์ผิดระบบจะยอมรับค่าดังกล่าวโดยไม่แจ้งเตือน ให้ทำการ reload และตรวจสอบสิ่งที่เซิร์ฟเวอร์เสนอให้กับไคลเอนต์:

sudo nginx -t && sudo systemctl reload nginx
openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>/dev/null | grep -i cipher

ผลลัพธ์ที่ถูกต้องควรระบุชื่อ TLS_CHACHA20_POLY1305_SHA256 ก่อนที่คุณจะยืนยันการเปลี่ยนแปลง ให้รันคำสั่ง openssl speed -evp chacha20-poly1305 เปรียบเทียบกับการรัน AES บนเครื่องเดียวกัน แล้วใช้ตัวเลขผลลัพธ์ทั้งสองค่าเป็นตัวตัดสินใจ

โฮสต์ ARM ใช้ส่วนขยายที่แตกต่างกัน

AES-NI มีเฉพาะบน x86 เท่านั้น VPS ที่ใช้สถาปัตยกรรม ARM จะใช้ส่วนขยายด้านการเข้ารหัสลับของ ARMv8 ซึ่งเป็นชุดคำสั่งแยกต่างหากที่ทำหน้าที่เดียวกัน บน aarch64 แฟล็กต่างๆ จะอยู่ใน Features แทนที่จะเป็น flags:

grep -m1 Features /proc/cpuinfo

ให้มองหา aes และ pmull โดย pmull คือส่วนที่เทียบเท่ากับ PCLMULQDQ บน ARM และ GCM จำเป็นต้องใช้มันด้วยเหตุผลเดียวกัน ตัวแปรสำหรับ override ของ OpenSSL บน ARM คือ OPENSSL_armcap ซึ่งมีรูปแบบบิตของตัวเองที่กำหนดไว้ใน crypto/arm_arch.h ในซอร์สโค้ดของ OpenSSL ดังนั้นค่าเลขฐานสิบหกของ x86 ในคู่มือนี้จึงไม่มีความหมายในบริบทดังกล่าว ในทางปฏิบัติแล้ว ARM server core ที่ขายเป็น VPS โฮสต์มักจะเปิดเผยส่วนขยายเหล่านี้อยู่แล้ว ดังนั้นปัญหาเรื่องฟีเจอร์ที่ถูกปิดกั้น (masked-feature) จึงเป็นเรื่องที่พบได้เฉพาะบน x86 เป็นหลัก

รูปแบบความล้มเหลวและข้อความที่คุณจะพบ

ไม่มี aes ใน /proc/cpuinfo และการรันแบบบังคับทำงานเร็วขึ้นมาก โฮสต์กำลังปกปิด CPUID ให้ตรวจสอบว่าชื่อรุ่นเป็นแบบทั่วไป จากนั้นสอบถามผู้ให้บริการว่า hypervisor ของพวกเขานำเสนอ CPU รุ่นใดให้กับ guest

ไม่มี aes ใน /proc/cpuinfo และการรันแบบบังคับแสดงผล Illegal instruction ชุดคำสั่งไม่มีอยู่จริง หรือเฟิร์มแวร์ได้ปิดการใช้งานไว้ ให้ย้ายภาระงานไปยังโฮสต์อื่น

aes มีอยู่แต่ปริมาณงานยังคงต่ำ ตรวจสอบว่าคุณกำลังอ่านคอลัมน์ขนาด 8192-byte และไม่มีกระบวนการอื่นใช้งาน core นั้นอยู่ ในแผนการใช้งานแบบแชร์ทรัพยากร เพื่อนบ้านที่ส่งเสียงดัง (noisy neighbour) จะแสดงอาการเหมือนฟีเจอร์ CPU หายไป จนกว่าคุณจะรันการทดสอบซ้ำในช่วงเวลาที่ต่างกันของวัน

การรันแบบปกปิดและการรันปกติให้ตัวเลขเท่ากัน OpenSSL อยู่บนเส้นทางการประมวลผลด้วยซอฟต์แวร์อยู่แล้ว ผลลัพธ์นั้นคือข้อสรุป ไม่ใช่ความผิดพลาดในการทดสอบ

Nested virtualisation เปลี่ยนคำตอบในระดับถัดลงไป guest ที่อยู่ภายใน guest จะได้รับ CPUID ตามที่เลเยอร์กลางเลือกส่งต่อให้ ซึ่ง AES-NI มักจะสูญหายในระดับนี้โดยไม่ทันสังเกต หากคุณรัน nested virtual machines on a VPS ให้ตรวจสอบ flag ภายใน guest ชั้นในควบคู่ไปกับเครื่องที่คุณเช่ามา

FAQ

ทำไม VPS ของฉันถึงไม่มี flag aes ใน /proc/cpuinfo

เนื่องจาก hypervisor แสดงผล CPU รุ่นทั่วไปให้ guest เห็น qemu64 และ kvm64 ไม่ได้รวม AES-NI ไว้ในชุดฟีเจอร์ ดังนั้น CPUID จึงรายงานว่าไม่มีฟีเจอร์นี้ไม่ว่าโปรเซสเซอร์จริงจะเป็นรุ่นใดก็ตาม โฮสต์ทำเช่นนี้เพื่อให้สามารถย้าย guest ที่กำลังทำงานอยู่ระหว่างเครื่องที่มี CPU ต่างรุ่นกันได้ ให้รัน grep -m1 'model name' /proc/cpuinfo หากพบสตริงเช่น QEMU Virtual CPU version 2.5+ หรือ Common KVM processor นั่นคือสัญญาณบ่งบอก แต่ถ้าเป็นสตริงรุ่น Xeon หรือ EPYC จริง แสดงว่ามีการส่งผ่านรุ่น CPU มาโดยตรงและไม่มี flag นี้ในฮาร์ดแวร์จริง

OPENSSL_ia32cap เปิดใช้งาน AES-NI จริงหรือแค่หลอกระบบ

มันเปิดใช้งานคำสั่งจริง คำสั่ง AES-NI เป็นคำสั่งที่ไม่ต้องใช้สิทธิ์พิเศษและ hypervisor ไม่เคยดักจับคำสั่งเหล่านี้ ดังนั้น AESENC จึงทำงานบนฮาร์ดแวร์โดยตรงไม่ว่า CPUID จะรายงานอย่างไร มีเพียงคำสั่ง CPUID เท่านั้นที่ถูกดักจับ การตั้งค่า OPENSSL_ia32cap เป็นค่าเลขฐานสิบหกจะไปแทนที่คำตอบที่ OpenSSL ได้รับจาก CPUID ทำให้ OpenSSL เลือกใช้โค้ดพาธสำหรับฮาร์ดแวร์และฮาร์ดแวร์จะประมวลผลด้วยความเร็วเต็มที่ หากฮาร์ดแวร์ไม่มีคำสั่งเหล่านี้จริง โปรเซสจะหยุดทำงานด้วย Illegal instruction (core dumped) ในการดำเนินการ AES ครั้งแรก

การตั้งค่า override จะช่วยเพิ่มความเร็วให้กับ volume ที่เข้ารหัสด้วย LUKS หรือไม่

ไม่ช่วย OPENSSL_ia32cap ถูกอ่านโดย OpenSSL เท่านั้น LUKS และ dm-crypt ใช้ kernel crypto API ซึ่งโมดูล aesni_intel จะโหลดไม่ผ่านพร้อมข้อผิดพลาด modprobe: ERROR: could not insert 'aesni_intel': No such device เมื่อฟีเจอร์บิตไม่ถูกตั้งค่า เคอร์เนลจะอ่าน CPUID ตอนบูตและไม่มีตัวแปรใน user-space ใดเปลี่ยนค่านี้ได้ ให้วัดค่าจริงด้วย sudo cryptsetup benchmark -c aes-xts -s 256 และเปรียบเทียบแถว aes-xts 256b กับโฮสต์ที่รายงาน flag นี้

การขาด flag AES-NI ทำให้ WireGuard ทำงานช้าลงหรือไม่

ไม่ช้าลง WireGuard ใช้ ChaCha20-Poly1305 สำหรับข้อมูลทั้งหมดและไม่เคยใช้คำสั่ง AES ดังนั้น throughput จึงเท่ากันทั้งบนโฮสต์ที่ปิดบังฟีเจอร์และโฮสต์ที่เปิดเผยฟีเจอร์ ส่วน OpenVPN และ IPsec ที่ตั้งค่าเป็น AES-GCM จะสูญเสีย throughput บนโฮสต์ที่ไม่มี AES-NI ดังนั้น tunnel สองรายการบน VPS เดียวกันอาจมีพฤติกรรมต่างกันมาก ซึ่งเป็นสิ่งที่ควรทราบก่อนที่จะโทษเครือข่าย

ฉันจะตรวจสอบ AES-NI บน ARM VPS ได้อย่างไร

คอร์ ARM ไม่มี AES-NI แต่มี ARMv8 cryptographic extensions ซึ่งทำงานแบบเดียวกันด้วยคำสั่งที่ต่างออกไป ให้รัน grep -m1 Features /proc/cpuinfo และมองหา aes และ pmull เนื่องจาก aarch64 จะแสดงรายการเหล่านี้ภายใต้ Features แทนที่จะเป็น flags ค่า OPENSSL_ia32cap ของ x86 ไม่มีความหมายบน ARM ตัวแปรที่เทียบเท่าของ OpenSSL บน ARM คือ OPENSSL_armcap และรูปแบบบิตถูกกำหนดไว้ใน crypto/arm_arch.h ในซอร์สโค้ดของ OpenSSL