Jinsi ya kuwasha AES-NI kwenye VPS yako
Jifunze jinsi ya kukagua kama VPS yako inatumia AES-NI, pima athari za utendaji wa AES-GCM, na tumia variable ya OPENSSL_ia32cap kulazimisha maagizo ya CPU yafanye kazi kikamilifu.
Faida halisi ya AES-NI kwenye VPS
AES-NI kwenye VPS ni seti ya maagizo sita ya x86 yanayotekeleza raundi moja ya AES (advanced encryption standard) ndani ya maunzi. Ikiwa mfano wa CPU ya mtoa huduma wako inaficha maagizo haya, silicon iliyo chini bado inayo, lakini OpenSSL haiwezi kuyaona na inarudi kwenye utekelezaji wa programu (software implementation) unaotumia takriban mara kumi ya mizunguko (cycles) kwa kila byte. Unaweza kukagua kipengele hiki kwa amri moja, kupima tofauti hiyo kwa amri mbili, na mara nyingi kulazimisha njia ya haraka (fast path) kurejea kwa kutumia variable moja ya mazingira.
Maagizo hayo ni AESENC, AESENCLAST, AESDEC, AESDECLAST, AESIMC na AESKEYGENASSIST. Intel ilianza kuyatumia mwaka 2010 na AMD ikafuata, kwa hivyo CPU yoyote ya seva unayoweza kukodisha ina silicon hiyo. Agizo la ziada, PCLMULQDQ, hufanya carry-less multiplication, ambayo ndiyo kitu ambacho GCM (Galois/counter mode) inahitaji ili kutengeneza authentication tag yake. AES-GCM huwa ya haraka tu pale zote mbili zinapopatikana, kwa sababu cipher na tag ni kazi mbili tofauti.
Maeneo manne kwenye VPS ambapo hii huonekana katika ufuatiliaji wako:
- TLS (transport layer security) termination. Seva ya wavuti inayotoa AES-128-GCM au AES-256-GCM hutumia muda wake mwingi wa bulk-crypto ndani ya AES.
- Encrypted volumes. LUKS (Linux unified key setup) na dm-crypt huendesha
aes-xtskatika kila usomaji na uandikaji, ndani ya kernel, kwenye CPU. - Trafiki ya VPN inayotumia AES. OpenVPN yenye
AES-256-GCMna IPsec yenye AES-GCM zote hutegemea maagizo haya. - Backup zilizosimbwa. Kitu chochote kinachosimba mtiririko wa data (stream) kwa AES kabla ya kuondoka kwenye seva hulipa gharama hiyo hiyo.
Kazi moja ya kawaida haiathiriwi hata kidogo. WireGuard hutumia ChaCha20-Poly1305 kwa data yake na haigusi AES kamwe, kwa hivyo WireGuard VPN inayojiendesha yenyewe huenda kwa kasi ile ile kwenye seva hata kama flag hiyo imefichwa. Tofauti hiyo ni sababu ya kivitendo ya kupima WireGuard dhidi ya OpenVPN kabla ya kuchagua tunnel kwa ajili ya VPS ya bei nafuu.
Jinsi ya kuangalia kama VPS yako ina AES-NI
Kernel hunakili bits za vipengele vya CPUID kwenye /proc/cpuinfo, kwa hivyo amri moja ya grep inajibu swali hili.
grep -m1 -o '\baes\b' /proc/cpuinfo
lscpu | grep -i -o '\baes\b'Amri yoyote kati ya hizi ikichapisha aes inamaanisha CPU inatangaza AES-NI kwa mgeni (guest) huyu. Kutochapisha chochote inamaanisha haina kipengele hicho. lscpu husoma flags zilezile, kwa hivyo zote mbili hutoa matokeo yanayolingana. Tumia ile iliyopo kwenye mfumo wako.
Sasa angalia ni CPU ipi ambayo mwenyeji (host) anadai unatumia.
grep -m1 'model name' /proc/cpuinfoJina halisi la mfano wa CPU kama Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz au AMD EPYC 7443P 24-Core Processor inamaanisha mwenyeji anapitisha mfano halisi wa CPU ya kimwili kwako. QEMU Virtual CPU version 2.5+ au Common KVM processor inamaanisha kuna kitu kingine kinaendelea, na hali hiyo ndiyo inayostahili kueleweka.
Kwa nini flag haionekani wakati silicon inayo
CPUID ni maelekezo ambayo programu hutumia kuuliza CPU ni nini inachokikubali. Ndani ya virtual machine, CPUID daima hupitishwa kwa hypervisor, kwa hivyo hypervisor ndiyo huamua kile ambacho guest huambiwa. Paneli nyingi huonyesha uamuzi huo kama CPU model ya guest. qemu64 na kvm64 ni mifano ya kawaida ya msingi, na hakuna hata mmoja anayejumuisha AES-NI au SSSE3 katika seti yake ya vipengele, kwa hivyo guest haioni flag ya aes hata wakati host halisi ni EPYC ya sasa. VPS ni guest kwenye maunzi ya mtu mwingine, kwa hivyo kila kipengele inachoripoti ni uamuzi uliofanywa ngazi moja juu. Ikiwa mpangilio huo wa matabaka ni mpya kwako, anza na nini maana ya VPS.
Host huchagua mfano wa kawaida kwa makusudi, kwa sababu live migration kati ya mashine zenye processor tofauti hufanya kazi tu ikiwa guest haikuwahi kuambiwa kuhusu kipengele ambacho mashine ya mwisho (destination) haina. Gharama huangukia kwako. Kernel yako na nakala yako ya OpenSSL zote husoma CPUID hiyo iliyofichwa mara moja wakati wa kuanza, na zote huchagua njia ya polepole ya msimbo kwa muda wote wa mchakato huo.
Suluhisho kwenye chanzo ni mpangilio wa upande wa host: -cpu host katika istilahi za QEMU, mfano wenye jina unaojumuisha AES-NI, au +aes ya wazi iliyoongezwa kwenye mfano huo. Huwezi kuweka yoyote ya hayo ukiwa ndani ya guest. Kufungua tiketi ya usaidizi, au kuchagua mpango ambao hypervisor yake hupitisha CPU model moja kwa moja, ndiyo jibu la kudumu.
Pima tofauti kwa kutumia openssl speed
Usiweke imani yako kwenye benchmark iliyochapishwa. Endesha cipher ambayo seva yako inaitumia katika mazungumzo yake.
openssl version
openssl speed -evp aes-128-gcmMstari wa matokeo umepewa lebo ya AES-128-GCM na unaonyesha uwezo wa kupitisha data (throughput) katika ukubwa wa block sita, kwa vipimo vya baiti 1000 kwa sekunde. Soma safu ya baiti 8192 kwa ajili ya uhamishaji wa data nyingi, kwa sababu safu ya baiti 16 huathiriwa zaidi na gharama ya kila wito (per-call overhead) na haikupi taarifa yoyote kuhusu upakuaji wa faili.
Sasa endesha amri hiyo hiyo huku AES-NI na PCLMULQDQ zikiwa zimezimwa kwenye programu:
OPENSSL_ia32cap="~0x200000200000000" openssl speed -evp aes-128-gcmThamani hiyo inatokana na nyaraka za vekta ya uwezo wa OpenSSL. ~ ya mwanzo inamaanisha "futa biti hizi". Biti 57 ni AES-NI na biti 33 ni PCLMULQDQ, kwa hivyo 0x200000200000000 inataja hizo mbili pekee na si kingine. Namba ya pili iliyo chini sana kuliko ya kwanza inamaanisha kuwa seva yako ina AES-NI inayofanya kazi na umemaliza. Namba mbili zinazolingana zinamaanisha kuwa OpenSSL ilikuwa tayari kwenye njia ya programu (software path), kwa sababu flag hiyo haikuwepo ili ifutwe.
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
}
]Hizo ni takwimu zilizochapishwa zinazowakilisha core ya kisasa ya x86 inayokaribia 3.4 GHz, si kipimo kilichochukuliwa kutoka kwa mwenyeji mmoja. Zisome kama muundo. Njia ya maunzi (hardware path) inafanya kazi kwa takriban 0.7 cycles kwa kila baiti na njia ya programu (software fallback) kwa takriban 11.0, ambayo inafikia takriban 4,850 MB/s dhidi ya 310 MB/s kwenye core moja. Amri zako mbili hapo juu zinazalisha namba pekee inayoelezea seva yako. Nidhamu hiyo hiyo inatumika kwa sehemu nyingine za mashine, kwa hivyo unganisha hii na njia inayoweza kurudiwa ya kupima VPS kabla ya kufikia hitimisho kuhusu mpango.
Lazimisha bits zirejee kwa kutumia OPENSSL_ia32cap
Hapa ndipo sehemu inayowashangaza watu. Maelekezo ya AES-NI hayahitaji upendeleo (unprivileged), na hypervisor haiyazuilii. CPUID pekee ndiyo inayozuiwa. Kwa hivyo, host inaweza kuambia guest yako kuwa AES-NI haipo wakati AESENC inaendelea kutekelezwa kiasili kwa kasi kamili. Programu huruka njia ya haraka kwa sababu iliuliza CPUID na kupata jibu lisilo sahihi. Maelekezo yenyewe hayakuacha kufanya kazi.
OpenSSL hukuruhusu kujibu kwa niaba ya CPU. Thamani ya hexadecimal katika OPENSSL_ia32cap huandika juu ya vector ya uwezo badala ya kuificha.
OPENSSL_ia32cap="0x0200020207000000" openssl speed -evp aes-128-gcmIkiwa uendeshaji huo ni wa haraka mara kadhaa kuliko uendeshaji wa kawaida, basi silicon ina AES-NI na host yako inaficha hilo. Hiyo ni hatua ya kwanza ya utambuzi. Kwa OpenSSL, pia inatokea kuwa ni suluhisho.
Jinsi thamani hiyo ya hex inavyoundwa
Vector ya kwanza ya kimantiki huweka CPUID leaf 1 EDX kwenye bits 32 za chini na leaf 1 ECX kwenye bits 32 za juu. Katika nusu ya chini, bit 24 ni FXSR, bit 25 ni SSE na bit 26 ni SSE2, ikitoa 0x07000000. Katika nusu ya juu, bit 33 ni PCLMULQDQ, bit 41 ni SSSE3 na bit 57 ni AES-NI, ikitoa 0x02000202. Ukiziunganisha unapata 0x0200020207000000. SSSE3 imo kwenye orodha kwa sababu GHASH inayotegemea PCLMULQDQ ya OpenSSL hutumia pshufb kubadilisha bytes, na mfano wa jumla wa CPU ya guest huficha SSSE3 pamoja na AES-NI.
Maonyo mawili yanatumika, na unaweza kusababisha yote mawili kwa makusudi.
Kuweka vector ya kwanza pekee huziacha vectors zinazofuata zikiwa sifuri, jambo linalozima njia za msimbo za AVX2 na AVX-512. Hilo ni la makusudi hapa. Usijaribu kulazimisha bits za AVX kwenye guest iliyofichwa, kwa sababu registers za AVX zinahitaji mfumo wa uendeshaji kuwezesha extended state katika XCR0, na kernel yako ilikataa kufanya hivyo kulingana na CPUID hiyo hiyo iliyofichwa. Maelekezo yaliyosimbwa kwa VEX kisha huibua hitilafu ya undefined-opcode na mchakato hufa.
Kulazimisha AES-NI kwenye core ambayo haina uwezo huo huua mchakato mara moja:
Illegal instruction (core dumped)Hiyo ni AESENC inayoibua hitilafu ya undefined-opcode, kwa sababu kwenye core hiyo hakuna maelekezo kama hayo ya kutekeleza. Firmware nyingine za seva zinaweza pia kuzima AES-NI kwenye hardware hadi reset inayofuata, na dalili ni sawa. Kwa vyovyote vile, jibu ni host tofauti, si variable tofauti ya mazingira.
Ili kuhifadhi override kwa huduma inayodumu kwa muda mrefu, tumia 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 EnvironmentAmri ya mwisho inapaswa kukuonyesha variable hiyo. Elewa unachojitolea kufanya: ikiwa seva hiyo itahamishiwa kwenye host ambayo CPU yake haina AES-NI, nginx itakufa kwa hitilafu ya illegal instruction kwenye muunganisho wake wa kwanza wa TLS. Iweke kwenye runbook yako, au uweke override hiyo nje ya production kabisa na uitumie tu kuthibitisha hoja unapofungua ticket.
Mambo ambayo override hairekebishi
OPENSSL_ia32cap inafika kwenye OpenSSL pekee na si kwingine. Kila programu nyingine hufanya ugunduzi wake wa vipengele (feature detection) na haisomi kigezo hicho.
Kernel ndilo suala muhimu. dm-crypt na LUKS hutumia kernel crypto API, na moduli ya aesni_intel hukataa kupakia wakati bit ya kipengele cha CPU haipo:
modprobe: ERROR: could not insert 'aesni_intel': No such deviceHakuna kigezo cha user-space kwa ajili ya hili. Kernel husoma CPUID mara moja wakati wa boot na uamuzi huo hubaki hivyo hadi utakapofanya reboot kwenye host nyingine, kwa hivyo encrypted volume yako hubaki kwenye software cipher bila kujali OpenSSL inafanya nini. Pima kile unachopata kihalisi:
sudo cryptsetup benchmark -c aes-xts -s 256Safu ya aes-xts 256b hufikia maelfu ya MiB/s ukiwa na hardware AES na mamia machache ukiwa huna. Lugha za runtime zenye ugunduzi wake, ikiwemo Go na Java, pia haziwezi kufikiwa. crypto/aes ya Go hukagua CPUID moja kwa moja na hutumia kimyakimya utekelezaji wake wa software wa constant-time wakati bit hiyo haipo. Ikiwa huduma inayomalizia TLS yako ni binary ya Go, kigezo cha OpenSSL hakibadilishi chochote kwa ajili yake.
Ikiwa huwezi kutumia AES-NI, pendelea ChaCha20
ChaCha20-Poly1305 iliundwa ili kuwa na kasi katika programu tumizi (software). Kwenye processor isiyo na AES-NI inayoweza kutumika, kwa kawaida inashinda AES-GCM kwa kiasi kikubwa, kwa hivyo hatua ya busara kwenye seva kama hiyo ni kuacha kupendelea AES.
Kwa nginx 1.19.4 na matoleo mapya zaidi, yaliyojengwa kwa kutumia OpenSSL 1.1.1 au matoleo mapya zaidi:
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 inashughulikia TLS 1.2. ssl_conf_command Ciphersuites inashughulikia TLS 1.3, ambapo nginx haina maelekezo (directive) maalum na hupitisha mfuatano wa herufi moja kwa moja kwa OpenSSL bila kuukagua, kwa hivyo kosa la uchapaji hapo hukubaliwa kimya kimya. Pakia upya (reload) na uthibitishe kile ambacho mteja anapewa:
sudo nginx -t && sudo systemctl reload nginx
openssl s_client -connect example.com:443 -tls1_3 </dev/null 2>/dev/null | grep -i cipherMatokeo mazuri yanataja TLS_CHACHA20_POLY1305_SHA256. Kabla ya kutekeleza mabadiliko haya, endesha openssl speed -evp chacha20-poly1305 kando ya jaribio la AES kwenye seva hiyo hiyo na uache namba hizo mbili zitoe uamuzi.
Seva za ARM hutumia viendelezi tofauti
AES-NI ni kwa ajili ya x86 pekee. VPS ya ARM hutumia viendelezi vya kriptografia vya ARMv8, seti tofauti ya maagizo inayotekeleza kazi hiyo hiyo. Kwenye aarch64, flag hizi hupatikana chini ya Features badala ya flags:
grep -m1 Features /proc/cpuinfoTafuta aes na pmull. pmull ndiyo inayolingana na PCLMULQDQ katika ARM, na GCM inaihitaji kwa sababu hiyo hiyo. Variable ya override ya OpenSSL kwenye ARM ni OPENSSL_armcap, ikiwa na mpangilio wake wa bit uliotajwa katika crypto/arm_arch.h ndani ya source code ya OpenSSL, kwa hivyo thamani ya hex ya x86 katika mwongozo huu haina maana huko. Kwa vitendo, cores za seva za ARM zinazouzwa kama VPS hosts hufichua viendelezi hivi, kwa hivyo tatizo la masked-feature ni la x86 zaidi.
Njia za kufeli, pamoja na maandishi utakayoyaona
Hakuna aes katika /proc/cpuinfo, na uendeshaji wa kulazimishwa ni wa haraka zaidi. Host inaficha CPUID. Thibitisha kuwa jina la model ni la kawaida, kisha uulize mtoa huduma wako ni model ipi ya CPU ya guest ambayo hypervisor yao inaitoa.
Hakuna aes katika /proc/cpuinfo, na uendeshaji wa kulazimishwa unachapisha Illegal instruction. Maelekezo hayapo kabisa, au firmware imeyazima. Hamishia mzigo wa kazi kwenye host nyingine.
aes ipo lakini throughput bado ni ndogo. Hakikisha unasoma safu ya 8192-byte, na hakuna kitu kingine kinachotumia core hiyo. Kwenye mpango wa pamoja (shared plan), jirani mwenye kelele (noisy neighbour) huonekana kama kipengele cha CPU kinachokosekana hadi utakapofanya jaribio mara mbili kwa nyakati tofauti za siku.
Uendeshaji uliofichwa na uendeshaji wa kawaida vinatoa namba sawa. OpenSSL ilikuwa tayari kwenye njia ya programu (software path). Matokeo hayo ndiyo hitimisho, si kosa katika jaribio.
Nested virtualisation inabadilisha jibu ngazi moja chini. Guest iliyo ndani ya guest nyingine hupata chochote CPUID ambacho safu ya kati ilichagua kupitisha, na AES-NI ni rahisi kupotea hapo bila kutambua. Ikiwa unaendesha nested virtual machines on a VPS, angalia flag ndani ya guest ya ndani pamoja na ile ya mashine uliyokodisha.
FAQ
Kwa nini VPS yangu haina flag ya aes katika /proc/cpuinfo?
Hii ni kwa sababu hypervisor inatoa mfano wa CPU wa jumla kwa mgeni (guest). qemu64 na kvm64 hazijumuishi AES-NI katika seti zao za vipengele, kwa hivyo CPUID inaripoti kuwa haipo bila kujali processor halisi ni ipi. Wenyeji (hosts) hufanya hivi ili mgeni anayeendesha aweze kuhamishwa kati ya mashine zenye CPU tofauti. Endesha grep -m1 'model name' /proc/cpuinfo: kamba kama QEMU Virtual CPU version 2.5+ au Common KVM processor ni ishara ya hili, wakati kamba halisi ya mfano wa Xeon au EPYC inamaanisha kuwa mfano wa CPU umepitishwa moja kwa moja na flag hiyo kwa kweli haipo kwenye silicon.
Je, OPENSSL_ia32cap inawasha AES-NI kweli, au inajifanya tu?
Inawasha maelekezo halisi. Maelekezo ya AES-NI hayana upendeleo na hypervisor haiwazuii kamwe, kwa hivyo AESENC inatekeleza kwa asili bila kujali kile CPUID inaripoti. Maelekezo ya CPUID pekee ndiyo yanayozuiwa. Kuweka OPENSSL_ia32cap kwa thamani ya hexadecimal ya kawaida kunachukua nafasi ya jibu ambalo OpenSSL ilipata kutoka kwa CPUID, kwa hivyo OpenSSL inachagua njia yake ya msimbo wa maunzi na maunzi huyaendesha kwa kasi kamili. Ikiwa silicon haina maelekezo hayo kweli, mchakato hufa na Illegal instruction (core dumped) kwenye operesheni ya kwanza ya AES.
Je, kubadilisha mipangilio hii kutaongeza kasi ya volume yangu iliyosimbwa kwa LUKS?
Hapana. OPENSSL_ia32cap inasomwa na OpenSSL pekee na si kitu kingine chochote. LUKS na dm-crypt hutumia API ya crypto ya kernel, ambapo moduli ya aesni_intel inashindwa kupakia na modprobe: ERROR: could not insert 'aesni_intel': No such device wakati bit ya kipengele haijawashwa. Kernel inasoma CPUID wakati wa boot na hakuna variable ya user-space inayoweza kubadilisha hilo. Pima takwimu halisi na sudo cryptsetup benchmark -c aes-xts -s 256 na ulinganishe safu ya aes-xts 256b dhidi ya mwenyeji anayeripoti flag hiyo.
Je, kukosekana kwa flag ya AES-NI kunapunguza kasi ya WireGuard?
Hapana. WireGuard hutumia ChaCha20-Poly1305 kwa data yote na haitumii maelekezo ya AES kamwe, kwa hivyo throughput yake ni sawa kwenye mwenyeji aliyefichwa na yule ambaye hajafichwa. OpenVPN na IPsec zilizosanidiwa na AES-GCM hupoteza throughput kwenye mwenyeji asiye na AES-NI. Kwa hivyo, tunnels mbili kwenye VPS moja zinaweza kufanya kazi kwa njia tofauti sana, jambo ambalo ni muhimu kujua kabla ya kulaumu mtandao.
Ninawezaje kuangalia AES-NI kwenye ARM VPS?
Core za ARM hazina AES-NI. Zina viendelezi vya cryptographic vya ARMv8, ambavyo hufanya kazi sawa na maelekezo tofauti. Endesha grep -m1 Features /proc/cpuinfo na utafute aes na pmull, kwa kuwa aarch64 inaziainisha chini ya Features badala ya flags. Thamani ya OPENSSL_ia32cap ya x86 haina maana kwenye ARM. Variable inayolingana ya OpenSSL huko ni OPENSSL_armcap, na mpangilio wake wa bit umefafanuliwa katika crypto/arm_arch.h kwenye chanzo cha OpenSSL.