SSD Nodes Learn
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-07-24

יצירת תעודת TLS חתומה עצמית ב-Ubuntu

מדריך ליצירת תעודת TLS עם SAN ב-Ubuntu 24.04 שתתקבל ב-Chrome. נלמד להגדיר nginx או Apache ולגרום למערכת לסמוך עליה ללא שימוש ב-curl -k.

מה אתם בונים

תעודת TLS חתומה עצמית (self-signed) שדפדפנים ולקוחות מודרניים אכן מקבלים — עם subjectAltName תקין, הרשאות מפתח תקינות, וקישור ל-nginx או Apache — בנוסף לחלק שרוב המדריכים מדלגים עליו: גרימת הלקוחות שלכם לסמוך עליה כראוי, במקום ללחוץ על אזהרות ולהטמיע את curl -k בתוך סקריפטים לצמיתות. בסיום, תקבלו CA פרטי בן חמש פקודות עבור מצב שבו שירות פנימי אחד הופך לששה.

ראשית, יש לקבל החלטה, מכיוון שתעודה חתומה עצמית היא הכלי המתאים לעיתים רבות פחות ממה שמקובל להשתמש בה. אם השירות נגיש מהאינטרנט הציבורי תחת שם DNS אמיתי, הפסיקו לקרוא והשתמשו ב-Let's Encrypt חינם באמצעות certbot ב-nginx או ב-המקביל ל-Apache במקום זאת. זה לא עולה דבר, התעודה מתחדשת מעצמה, וכל דפדפן בעולם כבר סומך עליה. תעודה חתומה עצמית באתר ציבורי מרגילה את המשתמשים שלכם ללחוץ על אזהרות אבטחה, הרגל גרוע יותר מאשר שימוש ב-HTTP רגיל.

חתימה עצמית היא הכלי המתאים כאשר אין אינטרנט ציבורי בתמונה: פאנל ניהול המקושר ל-כתובת WireGuard tunnel ב-VPS שלכם, שרת staging ברשת פרטית, תעבורת service-to-service בין backends, מכשיר home-lab, או החלפת תעודת ברירת המחדל ש-Webmin מייצר לעצמו בפורט 10000. Let's Encrypt לא יכולה להנפיק תעודה עבור 10.8.0.1 או git.internal.lan בכל מקרה — אף CA ציבורי לא יכניס כתובת IP פרטית או TLD מומצא לתעודה. עבור שמות אלו, אתם ה-CA.

כל מה שמופיע להלן רץ על מכונת Ubuntu 24.04 חדשה, המגיעה עם OpenSSL 3.0.x (השתמשו ב-openssl version כדי לאמת). שום דבר כאן אינו דורש גישה לאינטרנט; הכל עובד במצב air-gapped.

מדוע פקודת ה-one-liner הישנה מייצרת תעודות ש-Chrome דוחה

הפקודה שכל מדריך לפני שנת 2017 מציע נראית כך:

# Do not run this — shown so you recognise it in old guides
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout selfsigned.key -out selfsigned.crt

היא מציגה סדרת שאלות אינטראקטיביות, מכניסה את ה-hostname שלכם בשדה ה-Common Name, ומייצרת תעודה ללא הרחבת subjectAltName. התעודה הזו אינה תקפה. Chrome הפסיקה לקרוא את ה-Common Name בגרסה 58, באפריל 2017 — תקן RFC 2818 כבר הפסיק להשתמש ב-CN matching בשנת 2000 — וגם Firefox, Safari, curl ו-Python מתנהגים באותו אופן. תעודה מזהה את השרת שלה באמצעות הרחבת SAN, או שלא מזהה אותו בכלל. הדפדפן יציג לכם את השגיאה הבאה:

NET::ERR_CERT_COMMON_NAME_INVALID

This server could not prove that it is git.internal.lan; its security
certificate does not specify Subject Alternative Names.

שום שינוי ב-trust-store לא יפתור את השגיאה, מכיוון שהתעודה אינה מציינת שם כלשהו. אם אתם רואים את NET::ERR_CERT_COMMON_NAME_INVALID כעת, לתעודה שלכם אין SAN (או שיש לה SAN שגוי) ועליכם להנפיק תעודה חדשה. למרבה המזל, הפתרון הוא פקודה אחת.

יצירת תעודה שדפדפנים מקבלים: פקודה אחת

בגרסה 1.1.1 נוסף דגל -addext ל-OpenSSL. המשמעות היא שאין צורך בשימוש בקובצי הגדרה (config-files) מורכבים כפי שנדרש במדריכים ישנים כדי להוסיף SAN. ב-Ubuntu 24.04:

sudo openssl req -x509 -newkey rsa:4096 -sha256 -days 730 -noenc \
  -keyout /etc/ssl/private/git.internal.key \
  -out /etc/ssl/certs/git.internal.crt \
  -subj "/CN=git.internal.lan" \
  -addext "subjectAltName=DNS:git.internal.lan,IP:10.8.0.1"

תפקיד כל דגל:

  • -x509 יוצר תעודה בעלת חתימה עצמית (self-signed) ישירות, במקום לבקשת חתימה (CSR).
  • -newkey rsa:4096 מייצר מפתח חדש באותו שלב. מפתח RSA 4096 תואם לכל הלקוחות הישנים; אם כל הלקוחות מודרניים, -newkey ec -pkeyopt ec_paramgen_curve:P-256 קטן ומהיר יותר.
  • -noenc הוא הכתיב של OpenSSL 3.x עבור -nodes הישן: ללא סיסמה על המפתח. שתי דרכי הכתיב עובדות. מפתח עם סיסמה יגרום ל-nginx להיתקע בהמתנה לקלט בכל עלייה של המערכת, לכן עבור מפתח שרת יש להשתמש בדגל זה.
  • -days 730 — שנתיים; פירוט נוסף על מספר זה מופיע בסעיף תוקף התעודה.
  • -subj עונה על השאלות האינטראקטיביות באופן אוטומטי. ה-CN הוא כעת רק לצורך תצוגה, אך מומלץ להגדיר אותו כשם העיקרי; חלק מהכלים מציגים אותו.
  • -addext "subjectAltName=..." הוא הדגל החשוב ביותר. יש לציין כל שם וכל כתובת IP שהלקוחות יקישו: רשומות DNS: עבור שמות מארחים (גם wildcards כמו DNS:*.internal.lan תקינים), ורשומות IP: עבור כתובות IP. אם מישהו יגלוש ל-https://10.8.0.1, הרשומה IP:10.8.0.1 חייבת להופיע — SAN המכיל DNS בלבד יגרום לשגיאת NET::ERR_CERT_COMMON_NAME_INVALID שוב ושוב.

יש לוודא שה-SAN נוסף בהצלחה לפני הגדרת המערכת:

openssl x509 -in /etc/ssl/certs/git.internal.crt -noout -ext subjectAltName

פלט תקין:

X509v3 Subject Alternative Name:
    DNS:git.internal.lan, IP Address:10.8.0.1

אם הפלט מציג No extensions in certificate, לתעודה אין SAN והדפדפנים יdeny אותה — יש ליצור אותה מחדש במקום להמשיך.

הגדרת הרשאות למפתח

מפתח פרטי שניתן לקריאה על ידי כל משתמש במערכת אינו מפתח פרטי. ב-Ubuntu, /etc/ssl/private מוגדר כבר כ-710 root:ssl-cert, מה שמונע גישה של משתמשים רגילים, אך יש להגדיר את ההרשאות של הקובץ באופן מפורש:

sudo chown root:root /etc/ssl/private/git.internal.key
sudo chmod 600 /etc/ssl/private/git.internal.key

גם nginx וגם Apache קוראים את התעודות כ-root לפני הורדת ההרשאות, לכן מצב root:root 600 מתאים להם. אם המפתח מיועד לשירות שרץ תחת משתמש ייעודי וטוען את המפתח בעצמו — כגון אפליקציית Node, Gitea, או Python daemon — הגדר את הבעלות על chown למשתמש השירות, ועדיין השתמש במצב 600. דברים שאסור לעשות: להשתמש במצב 644, לשמור עותק בתוך git repository, או לשמור עותק בתוך /tmp.

Wire it into nginx

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name git.internal.lan;

    ssl_certificate     /etc/ssl/certs/git.internal.crt;
    ssl_certificate_key /etc/ssl/private/git.internal.key;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}
sudo nginx -t && sudo systemctl reload nginx

nginx -t חייב להדפיס את syntax is ok ו-test is successful לפני שהפעולה reload תתבצע. אם הוא מדפיס SSL_CTX_use_PrivateKey_file() failed ... key values mismatch במקום זאת, התעודה והמפתח נוצרו בריצות שונות — ראה את סעיף failure-modes.

Wire it into Apache

sudo a2enmod ssl proxy proxy_http

ssl לבדה אינה מספיקה במקרה זה: ה-vhost להלן משתמש ב-ProxyPass, וללא mod_proxy ו-mod_proxy_http בדיקת הקונפיגורציה תיכשל עם השגיאה Invalid command 'ProxyPass', perhaps misspelled or defined by a module not included in the server configuration. שמרו את ה-vhost כ-/etc/apache2/sites-available/git-internal.conf:

<VirtualHost *:443>
    ServerName git.internal.lan
    SSLEngine on
    SSLCertificateFile      /etc/ssl/certs/git.internal.crt
    SSLCertificateKeyFile   /etc/ssl/private/git.internal.key

    ProxyPass        / http://127.0.0.1:3000/
    ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>
sudo a2ensite git-internal
sudo apache2ctl configtest && sudo systemctl reload apache2

configtest אמור להשיב את Syntax OK. כעת בצעו בדיקה ממכונת לקוח:

curl -v https://git.internal.lan/

ותקבלו שגיאה:

curl: (60) SSL certificate problem: self-signed certificate

זו אינה תקלה. זהו מנגנון TLS שעובד: ל-curl אין היכרות עם התעודה שלכם, ולכן הוא מסרב לתקשר עם שרת שאינו יכול לאמת. הסעיף הבא מציג את הפתרון האמיתי — והוא שונה ממה שחצי מהאינטרנט עושה ברגע זה ממש.

גרום ללקוחות לבטוח בו — ודפוסי עבודה שגוויים שיש לסרב להם

פתרונות שגויים תחילה, כפי שהם: curl -k (או --insecure) מוטמע בתוך script, verify=False בתוך Python requests, NODE_TLS_REJECT_UNAUTHORIZED=0 בתוך Node — אף אחד מהפתרונות הללו לא יגרום לתעודה שלכם להיות מהימנה. הם מכבים את אימות התעודה (certificate verification), מה שאומר שהלקוח יתקשר ללא בעיה עם כל שרת שמציג כל תעודה, כולל תעודה שתוקף הציב בנתיב. אתם נשארים עם העומס של TLS אך מאבדים את האימות שהיה מטרתו. גרוע מכך, דגלים אלו מתפשטים: הם מודבקים ב-cron job אחד, לאחר מכן ב-deploy script, ואז בקוד הייצור, עד שאף אחד לא זוכר אילו חיבורים היו אמורים להיות זמניים בלבד. אם verify=False שורד מעבר לסשן ה-debugging שיצר אותו, התכנון שגוי.

הפתרון הנכון הוא ללמד כל מערכת הפעלה של לקוח שתעודה זו היא root מהימן. בלקוחות Ubuntu ו-Debian:

sudo cp git.internal.crt /usr/local/share/ca-certificates/git.internal.crt
sudo update-ca-certificates

השורה החשובה בפלט (אחריה מופיע בלוק Running hooks in /etc/ca-certificates/update.d...):

Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.

שתי מלכודות מסתתרות בשורות אלו. הקובץ חייב להסתיים ב-.crt — סיומת .pem תתעלם בשקט ותקבלו 0 added ללא הודעת שגיאה. והתוכן חייב להיות בפורמט PEM — הקובץ מתחיל ב------BEGIN CERTIFICATE-----; יש להמיר קודם כל קובץ DER בינארי באמצעות openssl x509 -inform der -in file.der -out file.crt. הוספת התעודה עצמה (self-signed) כ-root עובדת מכיוון שתעודה self-signed היא ה-root של עצמה.

לאחר מכן, curl, wget, git, apt, וכל דבר אחר שמשתמש ב-OpenSSL מול ה-system bundle יבטחו בשרת ללא צורך בדגלים כלל. מספר קטן של לקוחות מחזיקים מאגרי אמון (trust stores) משלהם ודורשים טיפול נפרד:

  • Chrome/Chromium ב-Linux קורא בבסיס נתונים NSS, לא ב-system store: sudo apt install libnss3-tools, ולאחר מכן certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n "git.internal" -i git.internal.crt לכל משתמש.
  • Firefox בעל מאגר משלו: Settings → Privacy & Security → Certificates → Import, או שינוי security.enterprise_roots.enabled ל-true בתוך about:config כדי שיקרא מה-system store.
  • Python requests כולל חבילת CA משלו (certifi) ומתעלם מה-system store: יש להעביר את verify="/usr/local/share/ca-certificates/git.internal.crt" או לייצא את REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt.
  • Node.js: יש לייצא את NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/git.internal.crt.

בלקוחות Windows, לחצו פעמיים על .crt והתקינו אותו תחת Trusted Root Certification Authorities; ב-macOS, הוסיפו אותו ל-System keychain בתוך Keychain Access וסמנו אותו כ-Always Trust.

שורש אחד עבור שירותים רבים: CA פרטי קטן

אמון מבוסס תעודה בודדת אינו ניתן להרחבה: שישה שירותים על ארבע מכונות לקוח דורשים עשרים וארבע התקנות אמון, וכל שירות חדש מוסיף עומס נוסף. הפתרון הוא CA פרטי — הלקוחות סומכים על שורש אחד, ואתה חותם את התעודה של כל שירות באמצעותו.

האפשרות הנוחה היא mkcert, הזמינה במאגרי Ubuntu 24.04. היא מטפלת בחנויות ה-NSS (Chrome, Firefox) שupdate-ca-certificates מחסירה:

sudo apt install -y mkcert libnss3-tools
mkcert -install
mkcert git.internal.lan "*.internal.lan" 10.8.0.1

mkcert -install יוצרת שורש ורושמת אותו בכל מאגרי האמון במכונה; הפקודה השלישית מפיקה את git.internal.lan+2.pem ו-git.internal.lan+2-key.pem, המוכנים להטמעה בקטעי הקוד של nginx או Apache לעיל. הנחת היסוד של התוכנה היא מכונת פיתוח — מפתח השורש נשמר במכונה שבה רצה -install — לכן היא אידיאלית עבור מחשב פיתוח נייד ואינה מתאימה עבור צבר שרתים.

עבור שרתים, OpenSSL רגיל מבצע את כל תהליך ה-CA בחמש פקודות:

openssl genrsa -out lab-ca.key 4096
openssl req -x509 -new -key lab-ca.key -sha256 -days 3650 \
  -out lab-ca.crt -subj "/CN=Lab Internal CA" \
  -addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"
openssl genrsa -out git.key 2048
openssl req -new -key git.key -out git.csr -subj "/CN=git.internal.lan" \
  -addext "subjectAltName=DNS:git.internal.lan,IP:10.8.0.1"
openssl x509 -req -in git.csr -CA lab-ca.crt -CAkey lab-ca.key \
  -CAcreateserial -days 730 -sha256 -copy_extensions copy -out git.crt

המלכוד נמצא בפקודה האחרונה: openssl x509 -req מסירה את כל ההרחבות (extensions) מה-CSR כברירת מחדל, כולל ה-SAN שהוספת בקפידה. -copy_extensions copy (אופציה של OpenSSL 3.x, ולכן עובדת ב-24.04) מעבירה אותן; אם תשמיט אותה, לתעודה החתומה לא יהיה SAN, ו-Chrome יציג שוב את NET::ERR_CERT_COMMON_NAME_INVALID. ניתן לאמת זאת באמצעות בדיקת openssl x509 -noout -ext subjectAltName שצוינה קודם.

הפץ את lab-ca.crt ללקוחות באמצעות שלבי ה-trust-store לעיל — פעם אחת לכל מכונה, לצמיתות. הגן על lab-ca.key כעל אוצר יקר: הגדר הרשאות 600, ומומלץ לשמור אותו במכונה שאינה אחד השרתים שהוא חותם עבורם, מכיוון שכל מי שמחזיק בו יכול להנפיק תעודה עבור כל שם שהלקוחות יסכימו לו.

Expiry and rotation

תקופת התוקף של תעודות CA ציבוריות מתקצרת — ב-March 2026 הגביל ה-CA/Browser Forum תעודות חדשות שניתנו ב-publicly trusted ל-200 ימים (במקום 398), והגבלה זו תרד ל-100 ימים בשנת 2027 ול-47 ימים עד March 2029 — אך כללים אלו מחייבים רק CAs publicly trusted. ה-CA הפרטי שלך אינו כפוף להם, ודפדפנים אינם אוכפים אותם עבור שורשי (roots) שהותקנו ידנית. מגבלה אחת מהעולם האמיתי חלה: פלטפורמות של Apple דוחות כל תעודת TLS server שתוקפה עולה על 825 ימים, ללא קשר למי שהנפק את התעודה. לכן, אם יש צורך בחיבור ממכשירי iPhone או Mac, יש לשמור על תעודות leaf לתקופה של שנתיים או פחות. -days 730 עומד בתקן זה בכל מקום; שילוב של root לתקופה של עשר שנים עם תעודות leaf לתקופה של שנתיים הוא מבנה פנימי נוח.

תעודות בעלות תוקף ארוך נכשלות בדרך אחת בלבד: הן פוקעות בשקט, כולן בבת אחת, בתאריך שאף אחד לא זוכר שקבע. בדקו מה קיים אצלכם:

openssl x509 -in /etc/ssl/certs/git.internal.crt -noout -enddate

רשמו את החידוש ביומן אמיתי, או הגדירו cron שישלח התראה 30 יום מראש — openssl x509 -checkend 2592000 -in cert.crt מחזיר ערך שונה מ-zero ברגע שהפקיעה נמצאת בטווח של מספר שניות זה. אם אתם כבר משתמשים ב-Uptime Kuma לצורך ניטור סטטוס, ה-HTTPS monitors שלו מסמנים פקיעת תעודה קרובה ללא עלות.

ביצוע rotation עם CA פרטי הוא תהליך פשוט: הריצו מחדש את הפקודות של CSR-and-sign, החליפו את הקבצים, ורעננו את ה-web server. ה-root לא השתנה, ולכן אף לקוח לא יבחין בשינוי.

מצבי כשל, עם המחרוזות שיופיעו

NET::ERR_CERT_AUTHORITY_INVALID — המצב הצפוי לפני התקנת ה-trust, לא תקלה בתעודה. אם המצב נמשך לאחר התקנת ה-root: בלינוקס, Chrome קורא את NSS במקום את ה-system store (ראה את שלב certutil); או שהקובץ שהועתק לא הסתיים ב-.crt ו-update-ca-certificates ציינו 0 added; או שהשרת מציג תעודה שונה מזו שבה השתמשת ב-trust — השווה את ה-fingerprints באמצעות openssl s_client -connect git.internal.lan:443 </dev/null 2>/dev/null | openssl x509 -noout -fingerprint -sha256.

NET::ERR_CERT_COMMON_NAME_INVALID — לתעודה אין SAN, או שה-SAN אינו מכסה את השם המופיע בשורת הכתובת. המקרה הקלאסי: ה-SAN מכיל את DNS:git.internal.lan אך המשתמש ניוט ל-https://10.8.0.1. שינויים ב-trust-store לא יפתרו זאת; יש להנפיק מחדש עם הרשומה החסרה.

curl: (60) SSL certificate problem: self-signed certificate — curl אינו סומך על התעודה. המקרה self-signed certificate in certificate chain מציין את אותו הדבר עבור תעודה שנחתמה על ידי ה-private CA שלך. פתרון חד-פעמי: curl --cacert lab-ca.crt https://...; פתרון קבוע: ה-trust store. לא -k.

unable to load certificate ... Expecting: TRUSTED CERTIFICATE (או Expecting: CERTIFICATE REQUEST, או no start line) — בלבול בפורמט PEM. סיפקת ל-OpenSSL סוג קובץ שגוי: key או CSR במקום תעודה, או DER binary במקום PEM. head -1 filename יגיד לך מה קיים בפועל — תעודה מתחילה ב------BEGIN CERTIFICATE-----. עבור DER, בצע המרה באמצעות openssl x509 -inform der -in file.der -out file.crt.

nginx: [emerg] SSL_CTX_use_PrivateKey_file(...) failed (SSL: error ... key values mismatch) — התעודה וה-key אינם תואמים, בדרך כלל משום שפקודת היצירה הורצה פעמיים והקבצים התערבבו. ודא באמצעות השוואה בין openssl x509 -in git.internal.crt -noout -pubkey | sha256sum ל-openssl pkey -in git.internal.key -pubout | sha256sum; hashes זהים מעידים על זוג תואם. אם הם שונים, צור מחדש את שניהם יחד.

FAQ

מדוע Chrome עדיין מציג "Not secure" לאחר שיצרתי תעודה חתומה עצמית (self-signed)?

אם השגיאה היא NET::ERR_CERT_AUTHORITY_INVALID, התעודה תקינה — ל-Chrome פשוט אין עדיין סיבה לבטוח בה. יש להתקין אותה (או את ה-CA root הפרטי שלך) במאגר האמון (trust store) של הלקוח. זכור כי ב-Linux, Chrome משתמש ב-NSS database באמצעות certutil ולא במאגר המערכת. אם השגיאה היא NET::ERR_CERT_COMMON_NAME_INVALID, בתעודה חסר Subject Alternative Name התואם ל-URL, ויש להנפיק אותה מחדש עם -addext "subjectAltName=...".

כיצד גורמים ל-curl לבטוח בתעודה חתומה עצמית ללא הדגל -k?

העתק את התעודה (בפורמט PEM, עם סיומת .crt) אל תוך /usr/local/share/ca-certificates/ והרץ את sudo update-ca-certificates — הפלט חייב להיות 1 added. מרגע זה, curl יאמת אותה כמו כל תעודה ציבורית. עבור בקשה חד-פעמית ללא שינוי המערכת, ניתן להשתמש ב-curl --cacert /path/to/cert.crt לאימות מול הקובץ בלבד; השימוש ב--k מבטל את האימות לחלוטין ואינו מומלץ לשום סקריפט.

לכמה זמן תעודה חתומה עצמית יכולה להיות תקפה?

מבחינה טכנית, לכל פרק זמן שתבחר — המגבלות של CA/Browser Forum (כיום 200 ימים, ו-47 ימים עד שנת 2029) מחייבות CA שזוכה אמון ציבורי בלבד, לא אמון פרטי. בפועל, הגבל את תעודות השרת ל-825 ימים, מכיוון שמכשירים של Apple דוחים כל תעודה ארוכה יותר ללא קשר למנפיק. הגדרה הגיונה היא שורש (root) פרטי ל-10 שנים עם תעודות קצה (leaf) ל-2 שנים (-days 730); יש לתזמן את החידוש בלוח השנה, מכיוון שתעודה פנימית שפגה תפיל את כל השירותים בשקט בתאריך שאף אחד לא יזכור.

האם כדאי להשתמש בתעודה חתומה עצמית או ב-Let's Encrypt?

אם לשירות יש שם DNS ציבורי והוא נגיש מהאינטרנט, השתמש תמיד ב-Let's Encrypt — זהו שירות חינמי, אוטומטי, ונתמך על ידי כל לקוח. תעודה חתומה עצמית (או CA פרטי) מיועדת למקרים שבהם Let's Encrypt אינו יכול להנפיק תעודה: כתובות IP פרטיות, שמות מארחים פנימיים בלבד כמו .lan, רשתות מנותקות (air-gapped), ושירותים המוסתרים במכוון מאחורי VPN. ההחלטה תלויה בנגישות ובשיום (naming), לא בעוצמת ההצפנה — הקריפטוגרפיה זהה.

מדוע התעודה שלי נדחית גם לאחר שהוספתי אותה ל- /usr/local/share/ca-certificates?

בדוק שלושה דברים. הקובץ חייב להסתיים ב-.crt — סיומת .pem תתעלם על ידי המערכת ו-update-ca-certificates ידווח על 0 added. התוכן חייב להיות טקסט PEM המתחיל ב------BEGIN CERTIFICATE-----, ולא פורמט DER בינארי. כמו כן, האפליקציה חייבת להשתמש במאגר המערכת — ל-Chrome ב-Linux, ל-Firefox, ל-Python requests, ל-Node.js ול-Java יש מאגר אמון פרטי משלהן, ויש להוסיף להן את התעודה בנפרד.

#openssl#tls#self-signed#ubuntu#security