Држите коренски CA VPN-а ван мреже и ипак издајте сертификате
Држите коренски кључ ван мреже, потписујте листове сертификате посредничким CA, објављујте CRL на време и тестирајте ланац пре него што се повеже први клијент.
Ваш VPN одговара на везе у 3 сата ујутру, док машина која потписује његове сертификате стоји искључена у фиоци. Клијент који проверава сертификат сервера никада не контактира ваш CA, тако да CA не мора бити доступан ни за једну везу. Део који захтева планирање је дан када сертификат треба издати, обновити или опозвати док кључ остаје закључан.
Шта веза заиста проверава
Када се OpenVPN клијент повеже, пролази ланац потписа од листовног сертификата сервера навише до CA сертификата ком већ верује, проверава период важења и, ако профил тако каже, консултује листу опозива. Никада не тражи ваш коренски CA. Сервер чини огледалску радњу за клијентске сертификате. У тренутку повезивања присутни су само лист, посреднички и пакет поверења који сте раније поделили.
Оно што заиста не успева је једна од три ствари: кључ за потпис није доступан при издавању, листа опозива је застарела или је пакет поверења клијента старији од ланца који сервер представља. Прво је проблем процеса; остала два су проблеми дистрибуције. Ниједно не захтева да кључ буде на мрежи, а управљана VPN услуга која за аутентификацију тунела захтева приватни сертификат само премешта овлашћење потписа на добављача. Azure тачка-сајт ради обрнуто: отпремите коренски сертификат и сертификати потписани под њим сматрају се поузданим, па питајте ко потписује, ко проверава и како се сертификат повлачи раније.
Изградите корен на хосту који никада не добија адресу
Офлајн корен се користи ретко: за потпис сертификата посредничког CA и касније за његово обнављање или опозив. Све остало се дешава ниво ниже. Обавите посао с кореном на машини која се држи ван мреже, ако је могуће из живе системе, и запишите ко је био у соби. Команде претпостављају OpenSSL 1.1.1 или новији, јер -addext не постоји у старијим градњама.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out root.key
openssl req -x509 -new -key root.key -sha256 -days 7300 \
-subj "/CN=Example VPN Root CA" -out root.crt \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
Направите посреднички сертификат на хосту за потписивање и однесите само његов захтев на офлајн машину. Корен потписује тај захтев са нултом дужином пута, тако да посреднички CA може потписивати сертификате крајњих тачака, али не може створити други CA под собом. То једно проширење спречава компромитовани хост за потписивање да створи овлашћење једнако корену. Користите ECDSA само ако сваки клијент ради на OpenVPN 2.4 или новијем; у супротном генеришите RSA кључеве и задржите исти ток.
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out intermediate.key
openssl req -new -key intermediate.key -subj "/CN=Example VPN Intermediate CA" -out intermediate.csr
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
-CAcreateserial -days 3650 -sha256 -extfile intermediate.ext -out intermediate.crt
intermediate.ext садржи basicConstraints=critical,CA:TRUE,pathlen:0, keyUsage=critical,keyCertSign,cRLSign и authorityKeyIdentifier=keyid:always. Вратите коренски кључ у његов сеф пре поновног повезивања хоста за потписивање. Ако корен мора моћи да опозове посреднички сертификат, потпишите га помоћу openssl ca -config root.cnf -extensions intermediate_ca против index.txt коренског нивоа уместо openssl x509 -req, да би серијски број био забележен; затим пошаљите добијену коренску листу у профилу клијента, где је датотечни crl-verify чита при покретању. Шаљите клијентима пакет са оба CA сертификата; сам лист се неће проверити против корена.
Издајте листове из посредничког CA, са базом података
Потписивање помоћу openssl x509 -req ради док не буде потребан опозив, јер ништа не бележи серијски број. Користите openssl ca од првог сертификата да серијски број, рок и стање опозива живе у једној бази података. Направите датотеке базе једном, затим усмерите конфигурацију на њих:
mkdir -p /etc/vpn-ca/intermediate/newcerts
touch /etc/vpn-ca/intermediate/index.txt
echo 1000 > /etc/vpn-ca/intermediate/serial
echo 1000 > /etc/vpn-ca/intermediate/crlnumber
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /etc/vpn-ca/intermediate
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
certificate = $dir/intermediate.crt
private_key = $dir/intermediate.key
default_md = sha256
default_days = 365
default_crl_days = 30
unique_subject = no
policy = policy_any
[ policy_any ]
commonName = supplied
[ server_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @server_names
[ client_cert ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature
extendedKeyUsage = clientAuth
[ server_names ]
DNS.1 = vpn.example.com
Линија употребе кључа претпоставља ECDSA кључ; додајте keyEncipherment за RSA. Дајте сваком клијенту сопствено уобичајено име, јер OpenVPN идентификује везу по том пољу, и два лаптопа која деле CN=vpn-client не могу се разликовати у логовима, у правилима client-config-dir или у било ком притиску по кориснику, и губите приписивање које чини одлуку о опозиву одбрањивом. Издајте и проверите лист овако:
openssl req -new -key alice.key -subj "/CN=alice-laptop" -out alice.csr
openssl ca -config intermediate.cnf -extensions client_cert -in alice.csr -out alice.crt -batch
openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt alice.crt
Држите кључ за потписивање иза границе политике уместо да га копирате на VPN хост: мала услуга која проверава захтев, упоређује уобичајено име са листом дозвољених и враћа само сертификат. Бележите сваки серијски број; лог је једина веза између сертификата и особе која га је затражила.
Објавите опозив без буђења корена
Клијентске сертификате опозива посреднички CA, никада корен. Коренска листа је важна само када је посреднички CA спаљен. Усмерите сервер на посредничку листу помоћу crl-verify. Датотечни CRL се учитава при покретању услуге, па га поново учитајте после сваке регенерације; директоријумска форма чита стање у тренутку повезивања и кошта једну датотеку по серијском броју.
Опозовите и регенеришите са две команде из исте базе:
openssl ca -config intermediate.cnf -revoke /etc/vpn-ca/intermediate/newcerts/1001.pem
openssl ca -config intermediate.cnf -gencrl -out /etc/openvpn/crl.pem
Затим пратите сат. CRL носи поље следећег ажурирања, и када тај датум прође, страна која проверава одбија листу уместо да је игнорише. Месечна регенерација са default_crl_days = 30 оставља простор; годишња не. Краћи животни век листова је поузданија контрола, јер се опозив примењује само тамо где се листа проверава.
Тестирајте ланац, затим запишите церемонију
Репродукујте четири неуспеха пре него што поверујете дизајну. Проверите ланац помоћу openssl verify -CAfile ca-bundle.crt -untrusted intermediate.crt server.crt. Повежите се са истеклим клијентским сертификатом и потврдите да га сервер одбија. Опозовите тест клијента, поново учитајте и потврдите да листа ступа на снагу. Померите сат хоста дан унапред, јер погрешан сат може издати и одбити сертификате који другде изгледају важећи.
Офлајн корен је контрола само ако постоје папири: две именоване особе за церемонију, евиденција сваког потписаног серијског броја, шифрована резервна копија чувана одвојено од машине и тест опоравка на изолованом хосту. Потпишите резервни посреднички CA током исте церемоније, да вас мртав хост за потписивање не примора да откључате корен у поноћ.
Пре него што то назовете готовим, потврдите пет ствари: коренски кључ није на умреженом хосту, посреднички кључ живи само на хосту за потписивање, пакет клијента носи оба CA сертификата, CRL има будуће следеће ажурирање и неко поседује календарски унос за сваки рок у ланцу. Ако једно недостаје, подешавање које изгледа офлајн је само недокументовано.