SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-08-13

AES-NI op een VPS controleren en activeren

Controleer of uw VPS AES-NI ondersteunt en meet het prestatieverlies bij een gemaskeerde CPUID. Forceer de hardwareversnelling direct met de variabele OPENSSL_ia32cap.

Wat AES-NI op een VPS u daadwerkelijk oplevert

AES-NI op een VPS is een set van zes x86-instructies die één ronde van AES (Advanced Encryption Standard) in hardware uitvoeren. Als het CPU-model van uw provider deze verbergt, beschikt de hardware er nog steeds over, maar kan OpenSSL ze niet zien. Het systeem valt dan terug op een software-implementatie die ongeveer tien keer zoveel cycli per byte kost. U kunt de aanwezigheid van deze functie met één commando controleren, het verschil met twee commando's meten en vaak het snelle pad forceren met één omgevingsvariabele.

De instructies zijn AESENC, AESENCLAST, AESDEC, AESDECLAST, AESIMC en AESKEYGENASSIST. Intel bracht ze in 2010 uit en AMD volgde, dus elke server-CPU die u waarschijnlijk huurt, beschikt over deze hardware. Een bijbehorende instructie, PCLMULQDQ, voert carry-less multiplication uit; dit is wat GCM (Galois/Counter Mode) nodig heeft om zijn authenticatietag op te bouwen. AES-GCM is alleen snel wanneer beide beschikbaar zijn, omdat de cijfertekst en de tag afzonderlijke bewerkingen zijn.

Vier gebieden op een VPS waar dit zichtbaar is in uw monitoring:

  • TLS (Transport Layer Security) termination. Een webserver die AES-128-GCM of AES-256-GCM aanbiedt, besteedt het grootste deel van zijn bulk-cryptografietijd aan AES.
  • Versleutelde volumes. LUKS (Linux Unified Key Setup) en dm-crypt voeren aes-xts uit bij elke lees- en schrijfactie, in de kernel, op de CPU.
  • AES-gebaseerd VPN-verkeer. OpenVPN met AES-256-GCM en IPsec met AES-GCM leunen beide op deze instructies.
  • Versleutelde back-ups. Alles wat een stream met AES versleutelt voordat deze de server verlaat, brengt dezelfde kosten met zich mee.

Eén veelvoorkomende workload wordt helemaal niet beïnvloed. WireGuard gebruikt ChaCha20-Poly1305 voor zijn data en raakt AES nooit aan, waardoor een self-hosted WireGuard VPN op dezelfde snelheid draait, zelfs als de vlag op de host is gemaskeerd. Dat verschil is een praktische reden om WireGuard tegenover OpenVPN af te wegen voordat u een tunnel kiest voor een goedkope VPS.

Controleren of uw VPS over AES-NI beschikt

De kernel kopieert de CPUID-featurebits naar /proc/cpuinfo, dus één grep-opdracht beantwoordt de vraag.

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

Als een van beide opdrachten aes weergeeft, betekent dit dat de CPU AES-NI aan deze guest adverteert. Als er niets wordt weergegeven, is dit niet het geval. lscpu leest dezelfde vlaggen, dus de twee komen altijd overeen. Gebruik de opdracht die op uw systeem is geïnstalleerd.

Bekijk nu op welke CPU de host aangeeft dat u draait.

grep -m1 'model name' /proc/cpuinfo

Een echte modelnaam zoals Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz of AMD EPYC 7443P 24-Core Processor betekent dat de host het fysieke CPU-model aan u doorgeeft. QEMU Virtual CPU version 2.5+ of Common KVM processor betekent dat er iets anders aan de hand is, en dat is het scenario dat de moeite waard is om te begrijpen.

Waarom de vlag ontbreekt terwijl de processor deze ondersteunt

CPUID is de instructie die een programma gebruikt om aan de CPU te vragen welke functies deze ondersteunt. Binnen een virtuele machine wordt CPUID altijd opgevangen door de hypervisor, waardoor de hypervisor bepaalt wat de gastmachine te zien krijgt. De meeste beheerpanelen presenteren die beslissing als een gast-CPU-model. qemu64 en kvm64 zijn generieke basismodellen en geen van beide bevat AES-NI of SSSE3 in de functieset, waardoor de gastmachine geen aes-vlag ziet, zelfs niet als de fysieke host een moderne EPYC-processor is. Een VPS is een gast op de hardware van een ander, dus elke functie die wordt gerapporteerd is een beslissing die één niveau hoger is genomen. Als deze gelaagdheid nieuw voor u is, begin dan bij wat een VPS is.

Hosts kiezen bewust voor een generiek model, omdat live migratie tussen machines met verschillende processors alleen werkt als de gastmachine nooit is geïnformeerd over een functie die de doelmachine mist. De gevolgen zijn voor u. Uw kernel en uw exemplaar van OpenSSL lezen die gemaskeerde CPUID eenmaal bij het opstarten en kiezen vervolgens voor de rest van de levensduur van het proces het trage codepad.

De oplossing bij de bron is een instelling aan de hostzijde: -cpu host in QEMU-termen, een benoemd model dat AES-NI bevat, of een expliciete +aes toegevoegd aan het model. U kunt dit niet instellen vanuit de gastmachine. Het openen van een supportticket of het kiezen van een abonnement waarbij de hypervisor het CPU-model direct doorgeeft, is de duurzame oplossing.

Meet het verschil met openssl speed

Vertrouw niet blindelings op gepubliceerde benchmarks. Voer de cipher uit die uw eigen server daadwerkelijk onderhandelt.

openssl version
openssl speed -evp aes-128-gcm

De resultaatrij is gelabeld AES-128-GCM en geeft de doorvoer weer bij zes blokgroottes, in eenheden van 1000 bytes per seconde. Lees de kolom van 8192 bytes voor bulkoverdracht, aangezien de kolom van 16 bytes wordt gedomineerd door overhead per aanroep en niets zegt over een bestanddownload.

Voer nu hetzelfde commando uit met AES-NI en PCLMULQDQ uitgeschakeld in software:

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

Die waarde is afkomstig uit de documentatie van de capability-vector van OpenSSL. Een leidende ~ betekent "wis deze bits". Bit 57 is AES-NI en bit 33 is PCLMULQDQ, dus 0x200000200000000 benoemt precies die twee en niets anders. Een tweede getal dat ver onder het eerste ligt, betekent dat uw machine over werkende AES-NI beschikt en u klaar bent. Twee getallen die overeenkomen betekenen dat OpenSSL al het softwarepad gebruikte, omdat de vlag nooit aanwezig was om te wissen.

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
  }
]

Dit zijn representatieve gepubliceerde cijfers voor een moderne x86-core rond 3,4 GHz, geen meting van een specifieke host. Lees ze als een verhouding. Het hardwarepad draait op ongeveer 0.7 cycli per byte en de software-fallback op ongeveer 11.0, wat neerkomt op ongeveer 4,850 MB/s tegenover 310 MB/s op één core. Uw twee bovenstaande commando's produceren het enige getal dat uw server beschrijft. Dezelfde discipline geldt voor de rest van de machine, dus combineer dit met een reproduceerbare manier om een VPS te benchmarken voordat u conclusies trekt over een plan.

Forceer de bits weer aan met OPENSSL_ia32cap

Dit is het deel dat mensen vaak verrast. De AES-NI-instructies zijn niet-geprivilegieerd en de hypervisor onderschept deze niet. Alleen CPUID wordt onderschept. Een host kan uw guest dus vertellen dat AES-NI afwezig is, terwijl AESENC op volle snelheid native blijft uitvoeren. Software slaat het snelle pad over omdat het CPUID heeft bevraagd en een onjuist antwoord kreeg. De instructie zelf is nooit gestopt met werken.

OpenSSL staat u toe om namens de CPU te antwoorden. Een eenvoudige hexadecimale waarde in OPENSSL_ia32cap overschrijft de capability-vector in plaats van deze te maskeren.

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

Als die run aanzienlijk sneller is dan de standaard run, beschikt de hardware over AES-NI en verbergt uw host dit. Dit is in de eerste plaats een diagnose. Voor OpenSSL is het toevallig ook een oplossing.

Hoe die hex-waarde wordt opgebouwd

De eerste logische vector verpakt CPUID leaf 1 EDX in de onderste 32 bits en leaf 1 ECX in de bovenste 32 bits. In de onderste helft is bit 24 FXSR, bit 25 SSE en bit 26 SSE2, wat 0x07000000 oplevert. In de bovenste helft is bit 33 PCLMULQDQ, bit 41 SSSE3 en bit 57 AES-NI, wat 0x02000202 oplevert. Samen vormt dit 0x0200020207000000. SSSE3 staat in de lijst omdat de PCLMULQDQ-gebaseerde GHASH van OpenSSL pshufb gebruikt om bytes te wisselen, en een generiek guest CPU-model verbergt SSSE3 samen met AES-NI.

Er zijn twee waarschuwingen van toepassing, en u kunt beide bewust triggeren.

Het instellen van alleen de eerste vector laat de latere vectoren op nul staan, wat de AVX2- en AVX-512-codepaden uitschakelt. Dat is hier een bewuste keuze. Probeer geen AVX-bits te forceren op een gemaskeerde guest, omdat AVX-registers vereisen dat het besturingssysteem de uitgebreide status in XCR0 inschakelt, en uw kernel heeft dat geweigerd op basis van hetzelfde gemaskeerde CPUID. Een VEX-gecodeerde instructie veroorzaakt dan een undefined-opcode fault en het proces stopt.

Het forceren van AES-NI op een core die er daadwerkelijk niet over beschikt, beëindigt het proces onmiddellijk:

Illegal instruction (core dumped)

Dit is AESENC die een undefined-opcode fault veroorzaakt, omdat die instructie op die core niet bestaat om uit te voeren. Sommige serverfirmware kan AES-NI ook in hardware uitschakelen tot de volgende reset; het symptoom is identiek. Hoe dan ook is de oplossing een andere host, niet een andere omgevingsvariabele.

Gebruik een systemd drop-in om de override voor een langlopende service te behouden.

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

Het laatste commando hoort de variabele aan u terug te geven. Begrijp waar u aan begint: als die server ooit wordt gemigreerd naar een host waarvan de CPU echt geen AES-NI heeft, crasht nginx met een illegal instruction bij de eerste TLS-verbinding. Noteer dit in uw runbook, of houd de override volledig uit productie en gebruik deze alleen om uw punt te bewijzen wanneer u een ticket opent.

Wat de override niet oplost

OPENSSL_ia32cap bereikt alleen OpenSSL en niets anders. Elke andere software voert zijn eigen feature-detectie uit en leest die variabele nooit.

De kernel is hier het belangrijke geval. dm-crypt en LUKS gebruiken de kernel crypto API, en de aesni_intel-module weigert te laden wanneer de CPU-featurebit ontbreekt:

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

Er is geen user-space variabele hiervoor. De kernel leest CPUID eenmalig bij het opstarten en die beslissing blijft staan totdat u op een andere host opstart, dus uw versleutelde volume blijft de software-cipher gebruiken, ongeacht wat OpenSSL doet. Meet wat u daadwerkelijk behaalt:

sudo cryptsetup benchmark -c aes-xts -s 256

De aes-xts 256b-rij komt in de duizenden MiB/s uit met hardware-AES en in de lage honderden zonder. Runtime-omgevingen voor programmeertalen met hun eigen detectie, waaronder Go en Java, zijn eveneens onbereikbaar. De crypto/aes van Go controleert CPUID direct en gebruikt geruisloos zijn constant-time software-implementatie wanneer de bit niet is gezet. Als de service die uw TLS beëindigt een Go-binary is, verandert de OpenSSL-variabele niets voor die service.

Als u niet over AES-NI beschikt, heeft ChaCha20 de voorkeur

ChaCha20-Poly1305 is ontworpen om snel te presteren in softwarematige implementaties. Op een processor zonder bruikbare AES-NI is dit algoritme doorgaans aanzienlijk sneller dan AES-GCM. De logische keuze op een dergelijke host is daarom om AES niet langer de voorkeur te geven.

Voor nginx 1.19.4 en nieuwer, gecompileerd met OpenSSL 1.1.1 of nieuwer:

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 heeft betrekking op TLS 1.2. ssl_conf_command Ciphersuites heeft betrekking op TLS 1.3, waarbij nginx geen specifieke richtlijn heeft en de string direct doorgeeft aan OpenSSL zonder deze te valideren; een typefout wordt hier dus stilzwijgend geaccepteerd. Herlaad de configuratie en controleer wat aan een client wordt aangeboden:

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

Een correct resultaat vermeldt TLS_CHACHA20_POLY1305_SHA256. Voordat u de wijziging definitief doorvoert, voert u openssl speed -evp chacha20-poly1305 uit naast de AES-test op dezelfde machine en laat u de twee getallen de doorslag geven.

ARM-hosts gebruiken andere extensies

AES-NI is uitsluitend voor x86. Een ARM-VPS gebruikt de ARMv8-cryptografische extensies; dit is een afzonderlijke instructieset die dezelfde taak uitvoert. Op aarch64 bevinden de vlaggen zich onder Features in plaats van flags:

grep -m1 Features /proc/cpuinfo

Zoek naar aes en pmull. pmull is de ARM-tegenhanger van PCLMULQDQ, en GCM heeft dit om dezelfde reden nodig. De override-variabele van OpenSSL op ARM is OPENSSL_armcap, met een eigen bit-indeling die is gedefinieerd in crypto/arm_arch.h in de OpenSSL-broncode; de hexadecimale x86-waarde in deze handleiding is daar dus niet van toepassing. In de praktijk stellen de ARM-servercores die als VPS-hosts worden verkocht deze extensies bloot, waardoor het probleem met gemaskeerde functies grotendeels een x86-aangelegenheid is.

Foutmodi en de bijbehorende meldingen

Geen aes in /proc/cpuinfo, en de geforceerde run is aanzienlijk sneller. De host maskeert CPUID. Controleer of de modelnaam generiek is en vraag uw provider welk guest CPU-model hun hypervisor presenteert.

Geen aes in /proc/cpuinfo, en de geforceerde run geeft Illegal instruction weer. De instructies ontbreken daadwerkelijk of zijn uitgeschakeld in de firmware. Verplaats de workload naar een andere host.

aes is aanwezig, maar de doorvoer is nog steeds laag. Controleer of u de kolom van 8192-byte leest en of er geen andere processen gebruikmaken van de core. Op een gedeeld abonnement lijkt een 'noisy neighbour' precies op een ontbrekende CPU-functie, totdat u de test op verschillende tijdstippen opnieuw uitvoert.

De gemaskeerde run en de normale run geven hetzelfde resultaat. OpenSSL gebruikte al het softwarepad. Dat resultaat is de bevinding, geen fout in de test.

Geneste virtualisatie verandert het antwoord één niveau lager. Een guest binnen een guest krijgt de CPUID die de tussenlaag heeft doorgegeven; AES-NI gaat daar gemakkelijk verloren zonder dat dit opvalt. Als u nested virtual machines on a VPS gebruikt, controleer de vlag dan zowel in de inner guest als op de machine die u heeft gehuurd.

FAQ

Waarom heeft mijn VPS geen aes-vlag in /proc/cpuinfo?

Omdat de hypervisor een generiek gast-CPU-model presenteert. qemu64 en kvm64 bevatten geen AES-NI in hun functiesets, waardoor CPUID dit als afwezig rapporteert, ongeacht de fysieke processor. Hosts doen dit zodat een draaiende gastmachine kan worden gemigreerd tussen machines met verschillende CPU's. Voer grep -m1 'model name' /proc/cpuinfo uit: een tekenreeks zoals QEMU Virtual CPU version 2.5+ of Common KVM processor is de aanwijzing, terwijl een echte Xeon- of EPYC-modelnaam betekent dat het CPU-model wordt doorgegeven en de vlag daadwerkelijk ontbreekt in de hardware.

Schakelt OPENSSL_ia32cap AES-NI echt in, of doet het alleen alsof?

Het schakelt de echte instructies in. AES-NI-instructies zijn niet-geprivilegieerd en de hypervisor onderschept deze nooit, dus AESENC voert ze native uit, ongeacht wat CPUID rapporteert. Alleen het CPUID-instructie wordt onderschept. Het instellen van OPENSSL_ia32cap op een hexadecimale waarde vervangt het antwoord dat OpenSSL van CPUID kreeg, waardoor OpenSSL zijn hardware-codepad kiest en de hardware dit vervolgens op volledige snelheid uitvoert. Als de hardware de instructies daadwerkelijk mist, crasht het proces met Illegal instruction (core dumped) bij de eerste AES-operatie.

Zal de override mijn LUKS-versleutelde volume versnellen?

Nee. OPENSSL_ia32cap wordt alleen door OpenSSL gelezen en door niets anders. LUKS en dm-crypt gebruiken de kernel crypto API, waarbij de aesni_intel-module niet laadt met modprobe: ERROR: could not insert 'aesni_intel': No such device wanneer de feature-bit niet is gezet. De kernel leest CPUID bij het opstarten en geen enkele user-space variabele verandert dat. Meet de werkelijke waarde met sudo cryptsetup benchmark -c aes-xts -s 256 en vergelijk de aes-xts 256b-rij met een host die de vlag wel rapporteert.

Vertraagt een ontbrekende AES-NI-vlag WireGuard?

Nee. WireGuard gebruikt ChaCha20-Poly1305 voor alle data en gebruikt nooit AES-instructies, dus de doorvoer is gelijk op een gemaskeerde host en een niet-gemaskeerde host. OpenVPN en IPsec die zijn geconfigureerd met AES-GCM verliezen wel doorvoer op een host zonder AES-NI. Twee tunnels op dezelfde VPS kunnen zich daarom heel verschillend gedragen; dit is nuttig om te weten voordat u het netwerk de schuld geeft.

Hoe controleer ik op AES-NI op een ARM-VPS?

ARM-cores hebben geen AES-NI. Ze beschikken over de ARMv8 cryptografische extensies, die hetzelfde werk doen met andere instructies. Voer grep -m1 Features /proc/cpuinfo uit en zoek naar aes en pmull, aangezien aarch64 deze vermeldt onder Features in plaats van flags. De x86 OPENSSL_ia32cap-waarde heeft geen betekenis op ARM. De equivalente variabele van OpenSSL is daar OPENSSL_armcap, en de bit-indeling daarvan is gedefinieerd in crypto/arm_arch.h in de OpenSSL-broncode.