SSD Nodes Learn 🎉 VPS vanaf $5.50/mnd
Gidsen Matt ConnorDoor Matt Connor

Eigen CA toevoegen aan Ubuntu trust store

Leer hoe u een eigen CA toevoegt aan Ubuntu met /usr/local/share/ca-certificates en update-ca-certificates. Voorkom HTTPS-fouten door uw root-certificaat correct te vertrouwen.

Uw eigen CA toevoegen aan de trust store van Ubuntu

Om uw eigen CA toe te voegen aan de trust store van Ubuntu, kopieert u het root-certificaat naar /usr/local/share/ca-certificates/ onder een naam die eindigt op .crt, en voert u vervolgens sudo update-ca-certificates uit. Een CA (certificate authority) is een sleutelpaar waarvan het certificaat andere certificaten mag ondertekenen. Zodra de machine uw root vertrouwt, wordt elk certificaat dat door die root is ondertekend geaccepteerd, waardoor HTTPS tussen uw eigen services niet langer verificatiefouten geeft.

Deze handleiding bouwt de volledige keten offline op met openssl. U maakt een root-sleutel en een root-certificaat aan, geeft één leaf-certificaat uit voor een server, installeert vervolgens de root en ziet hoe hetzelfde verificatiecommando een ander resultaat geeft. Die volgorde is essentieel: door vóór en na de installatie te verifiëren, ziet u dat de installatie de oorzaak is van de verandering.

Ubuntu 24.04 wordt geleverd met OpenSSL 3 en het ca-certificates-pakket in een standaard image, dus er hoeft niets vooraf te worden geïnstalleerd (gecontroleerd in augustus 2026).

Wanneer moet u een eigen CA draaien?

Een publieke CA zoals Let's Encrypt vereist een naam in de publieke DNS en een server die bereikbaar is. Interne namen voldoen hier niet aan. Een database op een privénetwerk of een beheerpaneel dat aan een tunnel is gekoppeld, kan geen publiek certificaat verkrijgen, en beide zouden niet aan het internet moeten worden blootgesteld enkel om er een te bemachtigen.

Een self-signed certificate on Ubuntu lost het probleem voor precies één host op. Elke client moet dat ene certificaat vertrouwen, en bij de volgende host begint het werk opnieuw. Een private CA verplaatst deze beslissing naar een hoger niveau. Clients vertrouwen de root één keer, en elk certificaat dat de root daarna ondertekent wordt vertrouwd, inclusief certificaten voor hosts die nog niet bestaan.

De kosten zijn reëel. De root-key kan alles ondertekenen wat de beperkingen toestaan, dus iedereen die ca.key leest, kan certificaten uitgeven die uw machines zullen accepteren. Beveilig deze op dezelfde manier als u een private key beveiligt bij SSH key management. Als een service een publieke DNS-naam heeft, sla dit alles dan over en gebruik een publieke CA: Certbot with nginx and Let's Encrypt kost minder werk en vereist niets op de clientzijde.

De CA-sleutel en het root-certificaat aanmaken

Werk in een map die alleen door uw gebruiker geopend kan worden. De root-sleutel verlaat deze map nooit.

install -d -m 700 ~/ca
cd ~/ca
openssl genrsa -aes256 -out ca.key 4096
chmod 600 ca.key

-aes256 versleutelt de sleutel met een wachtwoordzin naar keuze; elk volgend commando dat met deze sleutel ondertekent, zal hierom vragen. Laat u -aes256 weg, dan staat de sleutel onversleuteld op de schijf. Een back-up of een tweede beheerdersaccount is dan voldoende om iemand anders de mogelijkheid te geven certificaten uit te geven die uw machines vertrouwen.

Maak nu het root-certificaat aan, dat door de CA-sleutel voor zichzelf wordt ondertekend.

openssl req -x509 -new -key ca.key -sha256 -days 3650 \
  -subj "/O=Example Internal/CN=Example Internal Root CA" \
  -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
  -addext "keyUsage=critical,keyCertSign,cRLSign" \
  -addext "subjectKeyIdentifier=hash" \
  -addext "nameConstraints=critical,permitted;DNS:internal.example" \
  -out ca.crt

Vervang internal.example door het naamsuffix dat u daadwerkelijk gebruikt en lees de volgende sectie voordat u deze laatste extensie behoudt.

Elke extensie vervult één taak.

  • basicConstraints met CA:TRUE maakt dit tot een CA-certificaat. Zonder dit zal een client elk certificaat dat door deze sleutel is ondertekend afwijzen, zelfs als de handtekening zelf correct is.
  • pathlen:0 geeft aan dat de CA leaf-certificaten mag ondertekenen, maar geen verdere CA's daaronder mag aanmaken.
  • keyUsage beperkt de sleutel tot het ondertekenen van certificaten en revocation lists, zodat dezelfde sleutel niet per ongeluk als TLS-serversleutel kan worden gebruikt.
  • subjectKeyIdentifier geeft de root een identificatiecode waar leaf-certificaten naar verwijzen. Hiermee vindt een client de juiste uitgever in een opslagplaats die honderden certificaten bevat.
  • nameConstraints beperkt de namen waarvoor deze CA garant mag staan.

Controleer wat u heeft gemaakt in plaats van aan te nemen dat het commando deed wat u bedoelde.

openssl x509 -noout -subject -issuer -serial -dates -in ca.crt
openssl x509 -noout -text -in ca.crt

Subject en issuer tonen dezelfde reeks, omdat een root-certificaat zichzelf ondertekent. Het serienummer en de twee datums zijn afkomstig uit het bestand dat u zojuist heeft aangemaakt; neem deze gegevens daarom over uit die uitvoer in plaats van uit de handleiding van iemand anders.

Beperk waarvoor uw CA mag ondertekenen

Een root-certificaat in de systeemopslag wordt vertrouwd voor elke naam op het internet, tenzij u anders aangeeft. Dat is een aanzienlijke hoeveelheid autoriteit in één bestand op één server. nameConstraints vermindert dit. Met permitted;DNS:internal.example in de root wordt een keten van deze CA voor een naam buiten internal.example geweigerd, zelfs als de handtekening geldig is.

Test dit in plaats van het zomaar te vertrouwen.

openssl req -new -newkey rsa:2048 -nodes -keyout /tmp/outside.key -out /tmp/outside.csr \
  -subj "/CN=www.example.com"
openssl x509 -req -in /tmp/outside.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 30 -sha256 \
  -extfile <(printf 'subjectAltName=DNS:www.example.com\n') -out /tmp/outside.crt
openssl verify -CAfile ca.crt /tmp/outside.crt
echo $?

Het certificaat wordt uitgegeven, omdat uw CA alles ondertekent waar u om vraagt. Bij de verificatie gaat het mis: de exit-status is ongelijk aan nul en OpenSSL benoemt de beperking die werd overschreden. Dat is de waarde van de extensie. Een gestolen CA-sleutel kan nog steeds geen werkend certificaat produceren voor een naam buiten de subtree. Verwijder de restanten met rm /tmp/outside.* wanneer u klaar bent.

Vier zaken om te weten voordat u een beperking vastlegt. Deze is gemarkeerd als critical, waardoor een client die de extensie niet begrijpt de keten moet weigeren in plaats van deze te negeren; dit is de veilige methode, maar kan een verouderde TLS-bibliotheek verrassen. Een toegestane subtree voor DNS-namen beperkt geen IP-adres SAN's, omdat een naamtype zonder vermelde subtree onbeperkt blijft. Voeg daarom permitted;IP:10.0.0.0/255.255.0.0 toe in dezelfde extensie als uw certificaten IP-adressen bevatten. De subtree moet elke naam dekken waarvoor u ooit zult uitgeven, inclusief korte hostnamen; een certificaat voor de kale naam app zou dus falen tegenover het bovenstaande voorbeeld. De beperking is bovendien verankerd in de root, wat betekent dat van gedachten veranderen een nieuw root-certificaat en een nieuwe installatie op elke client vereist.

Geef een leaf-certificaat uit dat is ondertekend door uw CA

Een leaf-certificaat is het certificaat dat een server aan clients presenteert. Begin met een eigen sleutel en een CSR (certificate signing request). Deze bevat de publieke sleutel en de aangevraagde naam, ondertekend door de leaf-sleutel om aan te tonen dat de aanvrager de private helft bezit.

openssl req -new -newkey rsa:2048 -nodes \
  -keyout app.key -out app.csr \
  -subj "/CN=app.internal.example"
chmod 600 app.key

De relevante namen worden in een extensiebestand geplaatst, niet in de CSR. Clients vergelijken de hostnaam met de subjectAltName (SAN) en negeren de common name volledig. Een certificaat met alleen een CN en zonder SAN faalt daarom bij de hostnaamverificatie op elke moderne client, ongeacht wat er in de CN staat.

basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:app.internal.example, DNS:api.internal.example
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always

Sla dit op als app.ext en onderteken vervolgens het verzoek met de CA.

openssl x509 -req -in app.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -days 397 -sha256 -extfile app.ext -out app.crt

-CAcreateserial schrijft ca.srl naast de CA. Dit bestand bevat het volgende serienummer, zodat geen twee certificaten van deze CA hetzelfde nummer hebben. Bewaar dit bestand in de CA-directory. -days 397 is een keuze, geen beperking van de tool. Korte geldigheidsduur is hier belangrijker dan bij een publieke CA, omdat een private CA geen infrastructuur voor intrekking heeft: er is geen CRL en geen OCSP-responder tenzij u deze zelf bouwt. Een gelekte leaf-sleutel blijft dus bruikbaar totdat het certificaat verloopt.

Controleer het resultaat voordat u wijzigingen aanbrengt in de trust store.

openssl x509 -noout -subject -issuer -serial -dates -in app.crt
openssl x509 -noout -ext subjectAltName -in app.crt

De issuer-regel vermeldt nu de CA in plaats van het leaf-certificaat zelf. De SAN-regel bevat de namen waarvoor dit certificaat geldig is; een client vergelijkt de hostnaam uitsluitend met deze lijst.

Verifiëren met een expliciet -CAfile, voordat u iets installeert

openssl verify -CAfile ca.crt app.crt
echo $?

Dit stelt één specifieke vraag: vormt app.crt een keten naar het certificaat in ca.crt? Dit zegt niets over wat deze machine vertrouwt, omdat u OpenSSL de root via de opdrachtregel hebt meegegeven. Een foutmelding hier wijst op een probleem met de certificaten zelf; los dit dus op voordat u verdergaat.

Vraag het nu aan de machine.

openssl verify app.crt
echo $?

Zonder -CAfile valt OpenSSL terug op de ingebouwde certificaatdirectory. openssl version -d toont de basisdirectory die uw build gebruikt, en op Ubuntu verwijst de certs-directory daaronder naar /etc/ssl/certs. Uw root staat daar nog niet in, dus de verificatie mislukt: de keten bereikt een uitgever die niet in de opslag staat en er is geen andere plek om te zoeken. Let op de exit-status. Dit is de waarde die over twee stappen zal veranderen.

Een echte client is een betere test dan openssl verify, omdat deze naast de keten ook de hostnaam controleert. Serveer het certificaat en haal het op.

openssl s_server -accept 8443 -cert app.crt -key app.key -www &
curl --resolve app.internal.example:8443:127.0.0.1 https://app.internal.example:8443/

--resolve stuurt de verbinding naar 127.0.0.1 terwijl er nog steeds om app.internal.example wordt gevraagd, dus de SAN komt overeen en de enige openstaande vraag is het vertrouwen. curl faalt en toont de reden waarom de keten niet kon worden geverifieerd. Voeg -v toe voor meer details. Laat de testserver draaien.

Installeer de root in /usr/local/share/ca-certificates

sudo cp ca.crt /usr/local/share/ca-certificates/example-internal-root.crt
sudo chmod 644 /usr/local/share/ca-certificates/example-internal-root.crt
sudo update-ca-certificates

De details die bepalen of dit überhaupt werkt:

  • De bestandsnaam moet eindigen op .crt. De update-ca-certificates man-pagina stelt dat certificaten met een .crt-extensie die onder /usr/local/share/ca-certificates worden gevonden, worden opgenomen en impliciet worden vertrouwd. Een bestand genaamd root.pem of root.cer wordt overgeslagen zonder enige melding.
  • De inhoud moet PEM zijn, wat het base64-blok is verpakt in BEGIN CERTIFICATE en END CERTIFICATE-regels. Een DER-bestand dat is hernoemd naar .crt blijft binair en wordt niet gelezen. Converteer dit met openssl x509 -inform DER -in ca.der -out ca.crt.
  • Alleen de root hoort hier thuis. De private sleutel van de CA en het leaf-certificaat hebben niets te zoeken in een trust store.

update-ca-certificates geeft aan hoeveel certificaten er zijn toegevoegd en verwijderd. Als er niets is toegevoegd, zijn de extensie of het bestandsformaat de oorzaak.

Bevestig de wijziging vanuit het systeem in plaats van af te gaan op dat bericht.

ls -l /etc/ssl/certs/$(openssl x509 -noout -subject_hash -in /usr/local/share/ca-certificates/example-internal-root.crt).0
grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crt

Het eerste commando bouwt een bestandsnaam op basis van de subject-hash van uw certificaat en toont deze. update-ca-certificates heeft die symlink aangemaakt en deze verwijst terug naar het bestand dat u heeft geïnstalleerd. Het tweede commando telt de certificaten in de single-file bundel. Voer dit ook uit vóór de installatie, zodat u kunt zien dat het aantal met één toeneemt.

Wanneer u deze root naar andere machines kopieert, controleer dan of de kopie intact is aangekomen voordat u deze installeert. Een rootcertificaat is het slechtste bestand op het systeem om fouten in te hebben, dus behandel het zoals elke andere download die u met een checksum zou verifiëren voor gebruik.

Controleer opnieuw tegen de systeemopslag

openssl verify app.crt
echo $?
curl --resolve app.internal.example:8443:127.0.0.1 https://app.internal.example:8443/

Dezelfde commando's, dezelfde certificaatbestanden, een ander resultaat. Er is niets veranderd aan app.crt en de server is degene die u eerder heeft opgestart. Het enige verschil is dat de root zich nu in de opslag bevindt die de clients raadplegen, waardoor de keten wordt voltooid. Dat is het mechanisme dat het onthouden waard is: verificatie is een zoektocht naar een uitgever die de client al vertrouwt, en het installeren van een CA is de manier waarop de uitgever in de opslag terechtkomt die de client doorzoekt.

Stop de testserver met kill %1.

Waarom /etc/ssl/certs niet de juiste plek is voor uw bestanden

/etc/ssl/certs is gegenereerde output. update-ca-certificates vult deze met symbolische koppelingen naar de werkelijke certificaatbestanden en schrijft het samengevoegde bundelbestand /etc/ssl/certs/ca-certificates.crt daarnaast.

Een certificaat dat u handmatig naar die map kopieert, wordt door geen enkel proces gevonden. De directory-lookup van OpenSSL opent alleen bestanden die zijn vernoemd naar de subject-hash van een certificaat; een bestand genaamd myca.crt is voor OpenSSL dus onzichtbaar. curl op Ubuntu leest het bundelbestand, en aangezien de bundel wordt herbouwd vanuit de geregistreerde bronnen, staat uw kopie ook daar niet in. Voer update-ca-certificates --fresh uit en de symbolische koppelingen in de map worden verwijderd en opnieuw opgebouwd, waarbij handmatig aangemaakte koppelingen verloren gaan.

De andere helft van de splitsing is /usr/share/ca-certificates, dat toebehoort aan het ca-certificates-pakket en vermeld staat in /etc/ca-certificates.conf. Pakketupdates overschrijven dit bestand. /usr/local/share/ca-certificates is de map die is gereserveerd voor de lokale beheerder, zodat uw CA-certificaten elke upgrade van het pakket dat de rest beheert, overleven.

Welke programma's negeren de systeem-trust store

Het installeren van de root-certificaten lost dit op voor elk programma dat OpenSSL aanroept of /etc/ssl/certs leest. Dit omvat curl, wget, git, de standaard ssl-module van Python en Go-programma's, die op Linux de systeembestanden lezen. Runtimes die hun eigen certificatenlijst meeleveren, worden niet beïnvloed; dit is de voornaamste bron van verwarring na een succesvolle installatie.

  • Node.js gebruikt een ingebouwde lijst. Wijs het programma naar uw root-certificaat met NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/example-internal-root.crt, in te stellen in de omgeving voordat het proces start, aangezien Node de variabele eenmalig bij het opstarten leest. Huidige Node-releases hebben ook een optie om de systeem-store te lezen; voer node --help | grep -i system-ca uit om te zien of uw versie dit ondersteunt.
  • De requests-bibliotheek van Python gebruikt de certifi-bundel. Stel REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt in voor dat proces, of geef verify="/etc/ssl/certs/ca-certificates.crt" mee aan de aanroep. pip gebruikt --cert om dezelfde reden.
  • Java leest een keystore. Op Ubuntu installeert het ca-certificates-java-pakket een hook onder /etc/ca-certificates/update.d/, waardoor update-ca-certificates ook de Java-keystore ververst wanneer dat pakket aanwezig is. Importeer de root anders met keytool -importcert.
  • Firefox beheert een eigen store en kijkt nooit naar /etc/ssl/certs. Importeer certificaten via de instellingen voor certificaten in de browser. Chromium op Linux leest een NSS-database per gebruiker, die u bewerkt met certutil uit het libnss3-tools-pakket.
  • Containers hebben een eigen bestandssysteem, dus de store van de host is niet relevant binnen de container. Kopieer de root naar de image en voer update-ca-certificates uit tijdens de build. Houd hier rekening mee als uw services draaien onder Docker Compose op een VPS.

Wanneer een programma het certificaat na een schone installatie nog steeds weigert, achterhaal dan welke bestanden het opent voordat u andere wijzigingen aanbrengt. strace -f -e trace=openat <command> 2>&1 | grep -i cert is een direct hulpmiddel en beantwoordt deze vraag in één run.

De CA bruikbaar houden op de lange termijn

Het opnieuw uitgeven van een leaf-certificaat bestaat opnieuw uit de CSR-stap en de ondertekeningsstap, met gebruik van hetzelfde app.ext-bestand. Clients hoeven geen actie te ondernemen, omdat de root die zij vertrouwen niet is gewijzigd. Bewaar ca.srl en elk .ext-bestand in de CA-directory, zodat de volgende uitgifte een herhaling is van een commando dat eerder werkte, in plaats van een reconstructie uit het geheugen.

Maak een back-up van ca.key en ca.crt op een locatie buiten de machine, en houd deze versleuteld. Als u de sleutel verliest, kunt u niets nieuws meer uitgeven: u moet dan een tweede CA opbouwen en de bijbehorende root installeren op elke locatie waar de eerste root aanwezig was. Houd een schriftelijke lijst bij van elke machine en elke applicatie-store die de root heeft ontvangen, omdat die lijst essentieel is voor het kunnen uitvoeren van rotatie en verwijdering.

Wanneer de root zelf bijna verloopt, genereert u tijdig de vervanger en installeert u beide roots naast elkaar. Twee roots in de store is toegestaan en een client accepteert beide. Geef de leaf-certificaten opnieuw uit op basis van de nieuwe root en verwijder de oude pas zodra er niets meer van afhankelijk is.

Een CA verwijderen uit de trust store

sudo rm /usr/local/share/ca-certificates/example-internal-root.crt
sudo update-ca-certificates --fresh

--fresh verwijdert de symlinks in /etc/ssl/certs en herbouwt deze op basis van de bronnen die nog aanwezig zijn, waardoor het verwijderde root-certificaat zowel uit de map als uit de bundel verdwijnt. Controleer de verwijdering op dezelfde wijze als u de installatie heeft gecontroleerd.

openssl verify app.crt
echo $?
grep -c 'BEGIN CERTIFICATE' /etc/ssl/certs/ca-certificates.crt
ls -l /etc/ssl/certs/$(openssl x509 -noout -subject_hash -in ~/ca/ca.crt).0

De verificatie mislukt opnieuw, het aantal certificaten keert terug naar de oorspronkelijke waarde en de hash-symlink is verdwenen.

Dit commando wijzigt uitsluitend de systeem-store. Maak de installatie op de overige locaties handmatig ongedaan: leeg NODE_EXTRA_CA_CERTS, verwijder de alias uit eventuele Java-keystores, verwijder het root-certificaat uit elk browserprofiel en herbouw elke container-image waarin het certificaat was opgenomen. Het verwijderen van het root-certificaat maakt de certificaten die hiermee zijn ondertekend bovendien niet ongeldig. Deze blijven geldig op elke machine die het certificaat nog vertrouwt; dit is de praktische reden waarom een private CA een bijgehouden lijst nodig heeft van locaties waar het root-certificaat is geplaatst. Een CA die u niet volledig kunt intrekken vormt een permanent beveiligingslek. Test de verwijdering daarom op één machine op de dag dat u de CA opzet, terwijl de lijst nog kort is.

FAQ

Waar plaats ik een CA-certificaat op Ubuntu?

In /usr/local/share/ca-certificates/, met een bestandsnaam die eindigt op .crt en PEM-inhoud. Voer daarna sudo update-ca-certificates uit. Die map is gereserveerd voor de lokale beheerder, waardoor pakket-upgrades de bestanden ongemoeid laten. /usr/share/ca-certificates hoort bij het ca-certificates-pakket en /etc/ssl/certs wordt gegenereerd uit beide bronnen; een bestand dat in een van die mappen wordt geplaatst, wordt daarom overschreven of genegeerd.

Waarom weigert curl het certificaat nog steeds na update-ca-certificates?

Doorloop de mogelijke oorzaken in volgorde. Het bestand eindigt mogelijk niet op .crt, of is in DER- in plaats van PEM-formaat; in dat geval heeft update-ca-certificates het overgeslagen en niets toegevoegd. Het certificaat bevat mogelijk geen subjectAltName die overeenkomt met de hostnaam; dit is een hostnaamfout en geen vertrouwensfout. Controleer dit met openssl x509 -noout -ext subjectAltName -in app.crt. De server verstuurt mogelijk alleen het leaf-certificaat terwijl een intermediate-certificaat ook vereist is. curl kan via CURL_CA_BUNDLE of --cacert naar een andere bundel verwijzen. Daarnaast moet een langlopende service worden herstart, omdat de meeste programma's de trust store slechts eenmaal inlezen bij het opstarten.

Omvat de systeem-trust store ook Firefox, Chrome, Node en Java?

Nee. curl, wget, git, de standaard ssl-module van Python en Go-programma's lezen de systeembestanden, dus die werken zodra update-ca-certificates is uitgevoerd. Firefox beheert een eigen store. Chromium op Linux gebruikt een NSS-database per gebruiker, die u bewerkt met certutil uit het libnss3-tools-pakket. Node.js vereist NODE_EXTRA_CA_CERTS dat naar uw root-bestand wijst. Java leest een keystore, die update-ca-certificates alleen ververst wanneer het ca-certificates-java-pakket is geïnstalleerd. De requests-module van Python gebruikt certifi en vereist REQUESTS_CA_BUNDLE.

Hoe verwijder ik een CA uit de trust store van Ubuntu?

Verwijder het bestand uit /usr/local/share/ca-certificates/ en voer sudo update-ca-certificates --fresh uit. De optie --fresh verwijdert de symlinks in /etc/ssl/certs en bouwt deze opnieuw op, waardoor het certificaat tegelijkertijd uit de hash-symlinks en de ca-certificates.crt-bundel verdwijnt. Bevestig dit door openssl verify uit te voeren tegen een certificaat dat door die CA is ondertekend en controleer de exit-status. Herhaal de verwijdering in elke andere store waar u het certificaat aan heeft toegevoegd, aangezien dat commando die stores niet aanpast.

Kan ik een private CA gebruiken in plaats van Let's Encrypt voor een publieke site?

Nee. De browser van een bezoeker heeft uw root-certificaat nooit gezien, waardoor een schermvullende waarschuwing wordt getoond. U kunt uw root-certificaat niet installeren op machines die u niet beheert. Een private CA is bedoeld voor namen die alleen door uw eigen machines worden opgelost en voor clients die u zelf beheert. Voor alles wat door derden wordt bezocht, dient u het certificaat te verkrijgen van een publieke CA.

#tls#certificates#openssl#ubuntu#security#pki