Cara Cek dan Pulihkan AES-NI di VPS
Periksa AES-NI di VPS, ukur dampak CPUID yang disembunyikan pada throughput AES-GCM, lalu pulihkan jalur cepat OpenSSL dengan OPENSSL_ia32cap.
Manfaat nyata AES-NI pada VPS
AES-NI pada VPS adalah sekumpulan enam instruksi x86 yang menjalankan satu putaran AES (advanced encryption standard) di perangkat keras. Jika model CPU dari provider Anda menyembunyikan instruksi tersebut, silikon di bawahnya tetap memilikinya. Namun, OpenSSL tidak dapat melihatnya dan beralih ke implementasi perangkat lunak yang membutuhkan sekitar sepuluh kali lebih banyak siklus per byte. Anda dapat memeriksa fitur ini dengan satu perintah, mengukur perbedaannya dengan dua perintah, dan sering kali mengaktifkan kembali jalur cepat menggunakan satu variabel lingkungan.
Instruksi tersebut adalah AESENC, AESENCLAST, AESDEC, AESDECLAST, AESIMC, dan AESKEYGENASSIST. Intel merilisnya pada 2010, kemudian AMD mengikutinya. Jadi, CPU server apa pun yang kemungkinan besar Anda sewa sudah memiliki dukungan perangkat keras ini. Instruksi pendamping, PCLMULQDQ, melakukan perkalian tanpa carry. Operasi ini diperlukan oleh GCM (Galois/counter mode) untuk membentuk tag autentikasi. AES-GCM hanya cepat jika keduanya tersedia, karena cipher dan tag merupakan dua pekerjaan yang terpisah.
Berikut empat bagian pada VPS yang menunjukkan dampak fitur ini dalam pemantauan Anda:
- Terminasi TLS (transport layer security). Web server yang menyediakan AES-128-GCM atau AES-256-GCM menghabiskan sebagian besar waktu kriptografi massalnya di dalam AES.
- Volume terenkripsi. LUKS (Linux unified key setup) dan dm-crypt menjalankan
aes-xtspada setiap operasi baca dan tulis, di dalam kernel, pada CPU. - Trafik VPN berbasis AES. OpenVPN dengan
AES-256-GCMdan IPsec dengan AES-GCM sama-sama bergantung pada fitur ini. - Backup terenkripsi. Apa pun yang mengenkripsi aliran data dengan AES sebelum data tersebut meninggalkan server akan menanggung biaya yang sama.
Ada satu workload umum yang sama sekali tidak terpengaruh. WireGuard menggunakan ChaCha20-Poly1305 untuk datanya dan tidak pernah menggunakan AES. Karena itu, VPN WireGuard yang di-host sendiri berjalan pada kecepatan yang sama pada host yang flag tersebut disembunyikan. Perbedaan ini menjadi alasan praktis untuk mempertimbangkan WireGuard dibandingkan OpenVPN sebelum memilih tunnel untuk VPS murah.
Cara memeriksa apakah VPS Anda memiliki AES-NI
Kernel menyalin bit fitur CPUID ke /proc/cpuinfo, sehingga satu perintah grep sudah cukup untuk menjawabnya.
grep -m1 -o '\baes\b' /proc/cpuinfo
lscpu | grep -i -o '\baes\b'Perintah mana pun yang menampilkan aes berarti CPU mengiklankan dukungan AES-NI kepada guest ini. Jika tidak menampilkan apa pun, berarti CPU tidak mengiklankannya. lscpu membaca flag yang sama, sehingga hasil kedua perintah selalu sama. Gunakan perintah yang tersedia.
Sekarang periksa CPU yang menurut host sedang Anda gunakan.
grep -m1 'model name' /proc/cpuinfoString model nyata seperti Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz atau AMD EPYC 7443P 24-Core Processor berarti host meneruskan model CPU fisik kepada Anda. QEMU Virtual CPU version 2.5+ atau Common KVM processor berarti ada mekanisme lain yang digunakan. Kasus inilah yang perlu dipahami.
Mengapa flag tidak ada padahal CPU memilikinya
CPUID adalah instruksi yang digunakan program untuk menanyakan kemampuan CPU. Di dalam mesin virtual, CPUID selalu diteruskan ke hypervisor, sehingga hypervisor menentukan informasi yang diterima guest. Sebagian besar panel mengekspos keputusan tersebut sebagai model CPU guest. qemu64 dan kvm64 adalah model baseline generik. Keduanya tidak menyertakan AES-NI atau SSSE3 dalam set fiturnya, sehingga guest tidak melihat flag aes meskipun host fisiknya menggunakan EPYC generasi terbaru. VPS adalah guest pada perangkat keras milik pihak lain. Karena itu, setiap fitur yang dilaporkan VPS ditentukan satu tingkat di atasnya. Jika konsep pelapisan ini masih baru bagi Anda, mulai dengan apa itu VPS.
Host sengaja memilih model generik karena migrasi langsung antarmesin dengan prosesor berbeda hanya berfungsi jika guest tidak pernah diberi tahu tentang fitur yang tidak tersedia di mesin tujuan. Dampaknya Anda yang menanggung. Kernel dan salinan OpenSSL yang Anda gunakan sama-sama membaca CPUID yang telah difilter tersebut satu kali saat startup. Setelah itu, keduanya memilih jalur kode yang lebih lambat selama proses berjalan.
Perbaikannya harus dilakukan pada sisi host: -cpu host dalam istilah QEMU, model bernama yang menyertakan AES-NI, atau +aes eksplisit yang ditambahkan ke model tersebut. Anda tidak dapat mengatur semua itu dari dalam guest. Membuka tiket dukungan atau memilih paket yang hypervisornya meneruskan model CPU adalah solusi yang bertahan lama.
Ukur perbedaannya dengan openssl speed
Jangan menerima benchmark yang dipublikasikan begitu saja. Jalankan cipher yang benar-benar dinegosiasikan oleh server Anda.
openssl version
openssl speed -evp aes-128-gcmBaris hasil diberi label AES-128-GCM dan menampilkan throughput pada enam ukuran blok, dalam satuan 1000 byte per detik. Baca kolom 8192 byte untuk transfer data dalam jumlah besar, karena kolom 16 byte didominasi overhead per panggilan dan tidak memberi informasi tentang pengunduhan file.
Sekarang jalankan perintah yang sama dengan AES-NI dan PCLMULQDQ dinonaktifkan di perangkat lunak:
OPENSSL_ia32cap="~0x200000200000000" openssl speed -evp aes-128-gcmNilai tersebut berasal dari dokumentasi vektor kapabilitas OpenSSL. Awalan ~ berarti "hapus bit ini". Bit 57 adalah AES-NI dan bit 33 adalah PCLMULQDQ, sehingga 0x200000200000000 hanya menonaktifkan kedua fitur tersebut. Nilai kedua yang jauh lebih rendah daripada nilai pertama berarti AES-NI pada server Anda berfungsi dan pemeriksaan ini selesai. Dua nilai yang sama berarti OpenSSL sejak awal sudah menggunakan jalur perangkat lunak, karena flag tersebut tidak pernah ada untuk dihapus.
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
}
]Angka tersebut adalah angka publik representatif untuk core x86 modern dengan frekuensi sekitar 3.4 GHz, bukan hasil pengukuran dari host tertentu. Gunakan angka tersebut untuk melihat polanya. Jalur perangkat keras berjalan pada sekitar 0.7 siklus per byte, sedangkan fallback perangkat lunak berjalan pada sekitar 11.0, yang setara dengan sekitar 4,850 MB/s dibandingkan 310 MB/s pada satu core. Dua perintah di atas menghasilkan satu-satunya angka yang menggambarkan server Anda. Terapkan metode yang sama pada bagian lain mesin, lalu bandingkan dengan cara yang dapat diulang untuk melakukan benchmark VPS sebelum menarik kesimpulan tentang suatu paket.
Aktifkan kembali fitur tersebut dengan OPENSSL_ia32cap
Berikut bagian yang sering mengejutkan pengguna. Instruksi AES-NI dapat dijalankan tanpa hak istimewa, dan hypervisor tidak mencegatnya. Hanya CPUID yang dicegat. Jadi, host dapat memberi tahu guest bahwa AES-NI tidak tersedia, sementara AESENC tetap dijalankan secara native dengan kecepatan penuh. Software melewati jalur cepat karena meminta informasi melalui CPUID dan menerima jawaban yang salah. Instruksinya sendiri tidak pernah berhenti bekerja.
OpenSSL memungkinkan Anda memberikan jawaban tersebut atas nama CPU. Nilai heksadesimal biasa dalam OPENSSL_ia32cap menimpa vektor kapabilitas, bukan hanya menyamarkannya.
OPENSSL_ia32cap="0x0200020207000000" openssl speed -evp aes-128-gcmJika eksekusi tersebut beberapa kali lebih cepat daripada eksekusi biasa, silicon memiliki AES-NI dan host menyembunyikannya. Ini pertama-tama merupakan diagnosis. Untuk OpenSSL, cara ini juga berfungsi sebagai perbaikan.
Cara membentuk nilai heksadesimal tersebut
Vektor logis pertama memuat CPUID leaf 1 EDX ke dalam 32 bit rendah dan leaf 1 ECX ke dalam 32 bit tinggi. Pada bagian rendah, bit 24 adalah FXSR, bit 25 adalah SSE, dan bit 26 adalah SSE2, sehingga menghasilkan 0x07000000. Pada bagian tinggi, bit 33 adalah PCLMULQDQ, bit 41 adalah SSSE3, dan bit 57 adalah AES-NI, sehingga menghasilkan 0x02000202. Jika digabungkan, hasilnya adalah 0x0200020207000000. SSSE3 disertakan dalam daftar karena GHASH berbasis PCLMULQDQ milik OpenSSL menggunakan pshufb untuk menukar byte, dan model CPU guest generik menyembunyikan SSSE3 bersama AES-NI.
Ada dua peringatan, dan Anda dapat memicu keduanya dengan sengaja.
Menetapkan hanya vektor pertama membuat vektor berikutnya tetap bernilai nol, sehingga jalur kode AVX2 dan AVX-512 dinonaktifkan. Dalam konteks ini, hal tersebut memang disengaja. Jangan mencoba memaksa bit AVX aktif pada guest yang disamarkan, karena register AVX memerlukan sistem operasi untuk mengaktifkan extended state di XCR0, sedangkan kernel Anda menolak melakukannya berdasarkan CPUID yang sama-sama disamarkan. Instruksi berkode VEX kemudian memicu fault undefined-opcode dan proses berhenti.
Memaksa AES-NI aktif pada core yang benar-benar tidak memilikinya akan langsung menghentikan proses:
Illegal instruction (core dumped)Itu adalah AESENC yang memicu fault undefined-opcode, karena pada core tersebut tidak ada instruksi seperti itu untuk dijalankan. Sebagian firmware server juga dapat menonaktifkan AES-NI pada hardware hingga reset berikutnya, dan gejalanya sama. Dalam kedua kasus tersebut, solusinya adalah menggunakan host lain, bukan environment variable lain.
Untuk mempertahankan override pada service yang berjalan lama, gunakan 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 EnvironmentPerintah terakhir seharusnya menampilkan kembali variable tersebut. Pahami konsekuensinya: jika server tersebut kelak dimigrasikan ke host yang CPU-nya benar-benar tidak memiliki AES-NI, nginx akan berhenti dengan illegal instruction pada koneksi TLS pertamanya. Catat hal ini dalam runbook, atau jangan gunakan override tersebut di production dan manfaatkan hanya untuk membuktikan masalah saat membuka ticket.
Hal-hal yang tidak diperbaiki oleh override
OPENSSL_ia32cap hanya dibaca oleh OpenSSL. Perangkat lunak lain menjalankan deteksi fiturnya sendiri dan tidak pernah membaca variabel tersebut.
Kernel adalah kasus yang penting. dm-crypt dan LUKS menggunakan API kriptografi kernel, dan modul aesni_intel menolak dimuat jika bit fitur CPU tidak ada:
modprobe: ERROR: could not insert 'aesni_intel': No such deviceTidak ada variabel ruang pengguna untuk mengubahnya. Kernel membaca CPUID sekali saat boot, dan keputusan tersebut berlaku sampai Anda melakukan reboot pada host yang berbeda. Karena itu, volume terenkripsi Anda tetap menggunakan cipher perangkat lunak, apa pun yang dilakukan OpenSSL. Ukur hasil yang sebenarnya Anda dapatkan:
sudo cryptsetup benchmark -c aes-xts -s 256Baris aes-xts 256b mencapai ribuan MiB/s dengan AES perangkat keras dan hanya ratusan MiB/s tanpa dukungan tersebut. Runtime bahasa pemrograman yang menjalankan deteksinya sendiri, termasuk Go dan Java, juga tidak terpengaruh. crypto/aes milik Go memeriksa CPUID secara langsung dan diam-diam menggunakan implementasi perangkat lunak constant-time saat bit tersebut tidak aktif. Jika service yang menangani terminasi TLS Anda adalah binary Go, variabel OpenSSL tidak mengubah apa pun pada service tersebut.
Jika AES-NI tidak tersedia, prioritaskan ChaCha20
ChaCha20-Poly1305 dirancang agar cepat saat dijalankan sepenuhnya dalam software. Pada core tanpa AES-NI yang dapat digunakan, algoritme ini biasanya jauh lebih cepat daripada AES-GCM. Karena itu, langkah yang tepat pada host tersebut adalah berhenti memprioritaskan AES.
Untuk nginx 1.19.4 dan yang lebih baru, yang dibangun dengan OpenSSL 1.1.1 atau yang lebih baru:
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 mencakup TLS 1.2. ssl_conf_command Ciphersuites mencakup TLS 1.3. Untuk TLS 1.3, nginx tidak memiliki directive khusus dan meneruskan string tersebut langsung ke OpenSSL tanpa memeriksanya. Karena itu, kesalahan pengetikan akan diterima secara diam-diam. Muat ulang konfigurasi, lalu pastikan cipher yang ditawarkan kepada client:
sudo nginx -t && sudo systemctl reload nginx
openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>/dev/null | grep -i cipherHasil yang benar mencantumkan TLS_CHACHA20_POLY1305_SHA256. Sebelum menerapkan perubahan, jalankan openssl speed -evp chacha20-poly1305 di samping pengujian AES pada host yang sama, lalu gunakan kedua angka tersebut sebagai dasar keputusan.
Host ARM menggunakan ekstensi yang berbeda
AES-NI hanya tersedia pada x86. VPS ARM menggunakan ekstensi kriptografi ARMv8, yaitu set instruksi terpisah yang menjalankan fungsi yang sama. Pada aarch64, flag berada di bawah Features, bukan flags:
grep -m1 Features /proc/cpuinfoCari aes dan pmull. pmull adalah padanan ARM untuk PCLMULQDQ, dan GCM memerlukannya karena alasan yang sama. Variabel override OpenSSL pada ARM adalah OPENSSL_armcap, dengan tata letak bitnya sendiri yang ditetapkan dalam crypto/arm_arch.h pada source code OpenSSL. Karena itu, nilai heksadesimal x86 dalam panduan ini tidak berlaku di ARM. Pada praktiknya, core server ARM yang dijual sebagai host VPS mengekspos ekstensi ini, sehingga masalah fitur yang dimaskir terutama terjadi pada x86.
Mode kegagalan dan string yang akan Anda lihat
Tidak ada aes di /proc/cpuinfo, dan eksekusi paksa jauh lebih cepat. Host menyembunyikan CPUID. Pastikan nama modelnya generik, lalu tanyakan kepada penyedia layanan model CPU guest yang disajikan hypervisor mereka.
Tidak ada aes di /proc/cpuinfo, dan eksekusi paksa menampilkan Illegal instruction. Instruksi tersebut memang tidak tersedia, atau telah dinonaktifkan oleh firmware. Pindahkan workload ke host lain.
aes tersedia, tetapi throughput tetap rendah. Pastikan Anda membaca kolom 8192-byte dan tidak ada proses lain yang menggunakan core tersebut. Pada paket shared, noisy neighbour terlihat persis seperti fitur CPU yang hilang sampai Anda menjalankan pengujian dua kali pada waktu yang berbeda dalam sehari.
Eksekusi dengan masking dan eksekusi normal menghasilkan angka yang sama. OpenSSL memang sudah menggunakan jalur software. Hasil tersebut adalah temuan, bukan kesalahan dalam pengujian.
Nested virtualisation mengubah hasil satu tingkat di bawahnya. Guest di dalam guest menerima CPUID yang diteruskan oleh lapisan perantara. AES-NI mudah hilang pada lapisan tersebut tanpa terlihat. Jika Anda menjalankan mesin virtual bertingkat pada VPS, periksa flag tersebut di dalam inner guest dan pada mesin yang Anda sewa.
FAQ
Mengapa VPS saya tidak memiliki flag aes di /proc/cpuinfo?
Karena hypervisor menyajikan model CPU guest generik. qemu64 dan kvm64 tidak menyertakan AES-NI dalam kumpulan fiturnya, sehingga CPUID melaporkannya sebagai tidak tersedia, apa pun prosesor fisiknya. Host melakukan ini agar guest yang sedang berjalan dapat dimigrasikan antar-mesin dengan CPU yang berbeda. Jalankan grep -m1 'model name' /proc/cpuinfo: string seperti QEMU Virtual CPU version 2.5+ atau Common KVM processor menjadi petunjuknya, sedangkan string model Xeon atau EPYC yang sebenarnya berarti model CPU diteruskan langsung dan flag tersebut memang tidak tersedia pada silikon CPU.
Apakah OPENSSL_ia32cap benar-benar mengaktifkan AES-NI, atau hanya berpura-pura?
Variabel ini mengaktifkan instruksi yang sebenarnya. Instruksi AES-NI tidak memerlukan hak istimewa, dan hypervisor tidak pernah mencegatnya, sehingga AESENC dijalankan secara native, apa pun yang dilaporkan CPUID. Hanya instruksi CPUID yang dicegat. Menetapkan OPENSSL_ia32cap ke nilai heksadesimal biasa menggantikan jawaban yang diterima OpenSSL dari CPUID, sehingga OpenSSL memilih jalur kode perangkat keras dan perangkat keras kemudian menjalankannya dengan kecepatan penuh. Jika silikon CPU benar-benar tidak memiliki instruksi tersebut, proses berhenti dengan Illegal instruction (core dumped) pada operasi AES pertama.
Apakah override ini akan mempercepat volume terenkripsi LUKS saya?
Tidak. OPENSSL_ia32cap dibaca oleh OpenSSL dan tidak oleh komponen lain. LUKS dan dm-crypt menggunakan kernel crypto API. Di sana, modul aesni_intel gagal dimuat dengan modprobe: ERROR: could not insert 'aesni_intel': No such device ketika bit fitur tersebut tidak aktif. Kernel membaca CPUID saat boot, dan tidak ada variabel ruang pengguna yang dapat mengubahnya. Ukur hasil sebenarnya dengan sudo cryptsetup benchmark -c aes-xts -s 256, lalu bandingkan baris aes-xts 256b dengan host yang melaporkan flag tersebut.
Apakah flag AES-NI yang tidak tersedia memperlambat WireGuard?
Tidak. WireGuard menggunakan ChaCha20-Poly1305 untuk seluruh data dan tidak pernah menggunakan instruksi AES, sehingga throughput-nya sama pada host yang menyembunyikan flag maupun host yang tidak menyembunyikannya. OpenVPN dan IPsec yang dikonfigurasi dengan AES-GCM mengalami penurunan throughput pada host tanpa AES-NI. Karena itu, dua tunnel pada VPS yang sama dapat berperilaku sangat berbeda. Hal ini perlu diketahui sebelum Anda menyalahkan jaringan.
Bagaimana cara memeriksa AES-NI pada VPS ARM?
Core ARM tidak memiliki AES-NI. Core tersebut memiliki ekstensi kriptografi ARMv8, yang menjalankan fungsi sama dengan instruksi yang berbeda. Jalankan grep -m1 Features /proc/cpuinfo dan cari aes serta pmull, karena aarch64 mencantumkannya di bawah Features, bukan flags. Nilai OPENSSL_ia32cap pada x86 tidak memiliki arti pada ARM. Variabel yang setara pada OpenSSL adalah OPENSSL_armcap, dan tata letak bitnya didefinisikan dalam crypto/arm_arch.h pada source OpenSSL.