הנפקת תעודת wildcard עם Certbot ואימות DNS-01
למדו כיצד להנפיק תעודת wildcard באמצעות אתגר DNS-01 ב-Certbot. המדריך מסביר כיצד להגדיר רשומות TXT, לבחור את התוסף המתאים ל-API של ספק ה-DNS שלכם ולהבטיח חידוש אוטומטי תקין.
מדוע תעודת wildcard מחייבת שימוש ב-DNS-01
תעודת wildcard מכסה כל תת-דומיין ברמה הראשונה של דומיין: *.example.com תואם ל-app.example.com, ל-blog.example.com, ולכל שם אחר בעל תווית אחת. Let’s Encrypt מנפיקה תעודות wildcard אך ורק באמצעות אתגר DNS-01, ולכן Certbot חייב להוכיח שליטה ב-DNS של הדומיין על ידי פרסום רשומת TXT ב-_acme-challenge.example.com. אתגר HTTP-01 אינו עומד בתנאים, כיוון שהגשת קובץ token מוכיחה שליטה בשם מארח (hostname) בודד – זה שממנו שרת האימות משך את הקובץ. תעודת wildcard היא הצהרה על כל שם אפשרי תחת הדומיין, והרשומה הציבורית היחידה שמייצגת את כל מרחב השמות היא ה-DNS עצמו.
דרישה יחידה זו מכתיבה את כל שאר ההגדרות בדף זה. כדי לעבור את אתגר DNS-01, עליכם להיות מסוגלים ליצור רשומות TXT באזור (zone) של הדומיין, בין אם באופן ידני ובין אם דרך ה-API (ממשק תכנות יישומים) של ספק ה-DNS שלכם. הדרך הידנית עובדת פעם אחת ונכשלת בעת החידוש, מסיבה קונקרטית שמוצגת להלן. הדרך המבוססת על API, באמצעות תוסף DNS של Certbot, מאפשרת חידוש ללא השגחה, וזהו המבנה שאליו עליכם לשאוף.
זהו הפרק העוסק ב-wildcard מתוך מדריכי ה-Certbot שלנו. תעודות רגילות עבור שם מארח בודד, הגדרות שרת האינטרנט וכללי פורט 80 מכוסים ב-Certbot עם nginx על Ubuntu 24.04 וב-Certbot עם Apache על Ubuntu 24.04.
כיצד פועל רשומת ה-TXT מסוג _acme-challenge
כאשר Certbot מבקש את *.example.com, Let's Encrypt משיב עם אסימון אקראי. Certbot משלב את האסימון הזה עם מפתח חשבון ה-ACME (סביבת ניהול תעודות אוטומטית) שלכם, מבצע גיבוב (hashing) לתוצאה באמצעות SHA-256, ומפיק ערך טקסט קצר. ערך זה חייב להופיע כרשומת TXT ב-_acme-challenge.example.com. לאחר מכן, Let's Encrypt שולח שאילתה לשרתי השמות המוסמכים (authoritative name servers) של הדומיין שלכם מתוך התשתית שלו. אם הרשומה שהוא קורא תואמת לערך המצופה, הוכחתם שאתם שולטים באזור (zone), ושליטה באזור מתקבלת כשליטה בכל שם תחתיו.
שני פרטים גורמים לרוב הכשלים:
- בקשת
example.comו-*.example.comבאותה תעודה משמעותה שני אתגרים נפרדים, ושתי רשומות ה-TXT נמצאות תחת אותו שם,_acme-challenge.example.com. שתיהן חייבות להתקיים בו-זמנית. הוספת הרשומה השנייה היא הפעולה הנכונה; החלפת הראשונה בשנייה גורמת לכשל באתגר הראשון. - תהליך האימות קורא את שרתי השמות המוסמכים שלכם, אך לוחות בקרה של ספקי דומיינים עשויים להזדקק לדקה או יותר כדי להפיץ אליהם רשומה חדשה. בדקו מבחוץ לפני שאתם מריצים את האימות:
dig +short TXT _acme-challenge.example.com @1.1.1.1כאשר הפקודה מדפיסה את הערך ש-Certbot ביקש, האימות יכול להצליח. כאשר היא לא מדפיסה דבר, המתינו והריצו אותה שוב.
בדיקת תקינות: מצב ידני
מצב ידני מחייב אותך לבצע את עריכת ה-DNS בעצמך. זו הדרך הטובה ביותר להבין את המנגנון לפני שתעבור לאוטומציה:
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'המרכאות סביב ה-wildcard מונעות מה-shell להתייחס ל-* כאל תבנית של שם קובץ. Certbot יעצור ויציג הנחיות:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com.
with the following value:
Jx9mQ2wLr8vTn5cKp0aYdG3hB7fZs4eN1oiRuXqMk6Eצור את רשומת ה-TXT בלוח הבקרה של ספק ה-DNS שלך, ודא שהיא גלויה באמצעות הפקודה dig לעיל, ורק אז הקש Enter. מכיוון שהרצה זו מבקשת גם את הדומיין הראשי וגם את ה-wildcard, Certbot יציג הנחיות פעמיים; השאר את שתי הרשומות במקומן עד לסיום ההנפקה. הצלחה תסתיים בשורות המוכרות:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pemמדוע מצב ידני אינו יכול להתחדש באופן אוטומטי
כל חידוש מהווה אתגר חדש עם אסימון (token) חדש, ולכן ערך ה-TXT משתנה בכל פעם. הרשומה שהדבקת היום תהיה חסרת תועלת בעוד 60 יום. טיימר החידוש מריץ את Certbot ללא השגחה פעמיים ביום, ואף אחד אינו נמצא ליד המקלדת כדי להדביק את הערך החדש; לכן, תעודה שהונפקה ידנית תיכשל בחידוש עם שגיאה זו בדיוק:
Failed to renew certificate example.com with error: The manual plugin is not
working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with
--manual-auth-hook when using the manual plugin non-interactively.')ניתן לעמוד בדרישה זו על ידי כתיבת סקריפטים מסוג --manual-auth-hook הקוראים ל-API של ספק ה-DNS שלך, אך בשלב זה אתה למעשה בונה מחדש תוסף DNS באופן ידני. השתמש במצב ידני כדי ללמוד את התהליך, או עבור מקרה חד-פעמי אמיתי בדומיין שאת ה-DNS שלו אינך יכול להפוך לאוטומטי עדיין, והגדר תזכורת זמן רב לפני יום 90, כיוון ש-Let's Encrypt אינה שולחת יותר הודעות דוא"ל על פקיעת תוקף. לכל שאר המקרים, השתמש בתוסף.
נתיב התוסף: certbot-dns-cloudflare ב־Ubuntu 24.04
תוסף DNS מחזיק בהרשאות API עבור ספק ה־DNS שלכם ומבצע את כל תהליך ה־TXT record בעצמו, הן בעת ההנפקה והן בכל חידוש. Cloudflare משמשת כאן כדוגמה לעבודה מכיוון שזהו תוסף הספק הנפוץ ביותר, והוא ארוז בתוך Ubuntu.
מדריכי ה־Certbot שלנו ממליצים על חבילות apt ב־Ubuntu 24.04, ועמדה זו תקפה גם עבור Cloudflare:
sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflareהערה כנה לגבי גרסאות. הארכיון של 24.04 מפיץ את התוסף בגרסה 2.0.0 לצד Certbot 2.9.0; הפקודה apt policy python3-certbot-dns-cloudflare תציג את הגרסה שלכם. אי-ההתאמה אינה מזיקה, ושימוש ב-scoped API tokens עובד, מכיוון שספריית ה-python3-cloudflare הבסיסית ב-24.04 היא 2.11.1, שהיא מעל גרסה 2.3.1 הנדרשת על ידי התוסף לתמיכה ב-tokens. בהפצות Ubuntu ישנות יותר, הספרייה הייתה ישנה מדי עבור tokens, ומשם מגיעות האזהרות שניתן למצוא ברשת לגבי כך שתוסף ה-apt מחייב שימוש ב-Global API Key. ב-24.04 אזהרות אלו אינן רלוונטיות עוד.
בלוח הבקרה של Cloudflare צרו scoped API token, ולא Global API Key: עברו ל-My Profile, לאחר מכן ל-API Tokens, ולבסוף ל-Create Token, עם הרשאה בודדת של Zone / DNS / Edit, המוגבלת ל-zone הספציפי עבורו אתם מנפיקים. שמרו את ה-token בקובץ שרק root יכול לקרוא:
sudo mkdir -p /root/.secrets
sudo tee /root/.secrets/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = paste_your_scoped_token_here
EOF
sudo chmod 600 /root/.secrets/cloudflare.iniCertbot בודק את ההרשאות ומציג אזהרה לגבי Unsafe permissions on credentials configuration file אם הקובץ קריא על ידי משתמשים אחרים. כעת בצעו את ההנפקה:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'התוסף יוצר את רשומות ה-TXT דרך ה-API, ממתין השהיה קצרה להפצה, מאפשר לאימות לרוץ, ולאחר מכן מוחק את הרשומות. אם שרתי ה-DNS של ה-zone שלכם איטיים בעדכון שינויים, הגדילו את זמן ההמתנה באמצעות --dns-cloudflare-propagation-seconds 60. התעודה תישמר ב-/etc/letsencrypt/live/example.com/, ועליכם להפנות את Nginx או Apache אל fullchain.pem ו-privkey.pem בדיוק כפי שמוצג במדריכי הבסיס, כולל ה-deploy hook.
אם התוסף של ספק ה-DNS שלכם אינו נמצא ב-apt
המאגר של 24.04 כולל חבילות עבור מספר מצומצם של ספקים בלבד, ביניהם Cloudflare, Route 53, DigitalOcean וממשק ה-RFC 2136 הכללי. הריצו את apt search certbot-dns כדי לראות את הרשימה. אם הספק שלכם חסר, זהו המקרה היחיד שבו אנו חורגים מההמלצה להשתמש ב-apt: התקינו את Certbot ואת התוסף מ-snap, והסירו תחילה את ה-Certbot שהותקן דרך apt כדי למנוע התנגשות בין שני תזמוני חידוש על /etc/letsencrypt:
sudo apt remove certbot python3-certbot-dns-cloudflare
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-yourproviderתוסף snap מתחבר אך ורק ל-Certbot שהותקן כ-snap; הוא אינו יכול להרחיב את הגרסה של apt, וזו הסיבה שאסור לשתי ההתקנות להתקיים במקביל. אם ספק ה-DNS שלכם אינו מציע API כלל, האפשרויות הריאליות שלכם הן העברת ה-DNS של הדומיין לספק שכן מציע API, או הרצת שרת שמות (name server) עצמאי והפניית התוסף rfc2136 אליו.
חידוש: בצעו זאת כעת, אל תחכו 60 יום
Certbot מתעד את אופן ההנפקה של כל תעודה בתוך /etc/letsencrypt/renewal/example.com.conf, כולל authenticator = dns-cloudflare ונתיב פרטי הגישה, כך שהטיימר הסטנדרטי שרץ פעמיים ביום יבצע את החידוש ללא צורך בהתערבותכם. בצעו הרצה של התהליך המלא מול סביבת ה-staging:
sudo certbot renew --dry-runמעבר בהצלחה של הבדיקה מעיד על כך שפרטי הגישה תקינים ושהאימות הושלם מקצה לקצה; החידוש האמיתי בעוד 60 יום ילך באותו הנתיב. כדאי לבצע היום שני צעדי המשך. ראשית, תעודה מחודשת על הדיסק אינה משנה דבר עד ששרת ה-web יטען אותה מחדש, לכן הגדירו את ה-deploy hook המתואר במדריכי Nginx ו-Apache. שנית, התייחסו לקובץ פרטי הגישה בזהירות: כל מי שיכול לקרוא אותו יכול לערוך את אזור ה-DNS שלכם, מה שמספיק כדי להפנות את הדואר שלכם או לעבור אתגרי DNS-01 משלו. שמרו עליו במצב 600 תחת /root, הגבילו את ה-token לאזור אחד בלבד, ובצעו החלפה (rotate) אם עולה חשד לדליפה.
מתי אין צורך ב-wildcard
Wildcard הוא הכלי המתאים עבור תתי-דומיינים רבים, או עבור תתי-דומיינים שלא ניתן לחזות מראש. עבור כל מקרה אחר, זו אינה ברירת המחדל המומלצת.
- עבור תת-דומיין בודד או מספר מצומצם של שמות ידועים: תעודת SAN (Subject Alternative Name) רגילה היא פשוטה יותר.
certbot --nginx -d example.com -d www.example.com -d app.example.comמכסה עד 100 שמות באמצעות HTTP-01 רגיל, ואין צורך לשמור הרשאות API של DNS על השרת. - Wildcard תואם בדיוק לתווית (label) אחת.
*.example.comאינו מכסה את ה-example.comהחשוף, וזו הסיבה שהפקודות לעיל מבקשות את שניהם; הוא גם אינו מכסה אתa.b.example.com, שעבורו נדרש*.b.example.com. - מפתח פרטי אחד עומד מאחורי כל תת-דומיין. אם המכונה שמחזיקה אותו נפרצת, כל השמות שה-wildcard מכסה מושפעים בו-זמנית.
- אם Traefik מבצע TLS termination עבור המכולות שלכם, אין צורך ב-Certbot כלל: Traefik מבקש תעודות wildcard בעצמו באמצעות DNS-01, תוך שימוש באותו סוג של אסימון ספק (provider token).
המקרים שבהם ה-wildcard באמת נחוץ: תתי-דומיינים לכל לקוח או לכל יישום שנוצרים בקצב מהיר מכדי להנפיק עבורם תעודות מחדש, ומארחים פנימיים ללא פורט 80 ציבורי, כגון שירותים שניתן להגיע אליהם רק דרך רשת WireGuard VPN. פרוטוקול DNS-01 לעולם אינו מתחבר למארח שעבורו מונפקת התעודה, כך שגם מכונה פרטית לחלוטין יכולה להחזיק בתעודה מהימנה ציבורית.
FAQ
האם Certbot יכול להנפיק תעודת wildcard באמצעות HTTP-01?
לא. אתגר HTTP-01 מוכיח שליטה על שם מארח (hostname) בודד, כיוון ששרת האימות מושך קובץ token מכתובת ספציפית זו. תעודת wildcard מכסה את כל השמות תחת הדומיין, לכן Let's Encrypt מחייבת עבורה את אתגר DNS-01, בעוד ש־--nginx, --apache, --webroot ו־--standalone הם מאמתים (authenticators) מבוססי HTTP. הדרך היחידה היא יצירת רשומת TXT ב־_acme-challenge.example.com, באופן ידני או באמצעות תוסף DNS.
האם תעודת wildcard מכסה את דומיין השורש?
לא. ה-wildcard תואם בדיוק לתווית (label) אחת, לכן *.example.com מכסה את www.example.com אך לא את example.com החשוף, וגם לא את a.b.example.com. בקשו את שני השמות בתעודה אחת באמצעות -d example.com -d '*.example.com'. פעולה זו יוצרת שני אתגרים, ושתי רשומות ה-TXT יושבות תחת אותו שם _acme-challenge.example.com, לכן יש להוסיף את הרשומה השנייה מבלי למחוק את הראשונה.
מדוע תעודת ה-wildcard שלי לא מתחדשת אוטומטית?
מכיוון שהיא הונפקה באמצעות --manual. כל חידוש דורש ערך TXT חדש לחלוטין, ולטיימר האוטומטי אין דרך להזין אותו, לכן החידוש נעצר עם השגיאה An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively. הנפיקו מחדש את התעודה בעזרת תוסף DNS כגון certbot-dns-cloudflare, או ספקו סקריפטים מסוג --manual-auth-hook ו־--manual-cleanup-hook שמעדכנים את הרשומה דרך ה-API של ספק ה-DNS שלכם.
כמה זמן לוקח לרשומת ה-TXT מסוג _acme-challenge להופיע?
הדבר תלוי בספק ה-DNS שלכם: החל משניות בודדות ועד מספר דקות. תהליך האימות קורא את שרתי ה-DNS הסמכותיים (authoritative) של האזור שלכם, לכן בדקו עם dig +short TXT _acme-challenge.example.com @1.1.1.1 והמתינו עד להופעת הערך הצפוי לפני שתמשיכו בהרצה ידנית. בשימוש בתוסף, הגדילו את זמן ההמתנה המובנה באמצעות אפשרות ה-propagation של התוסף, למשל --dns-cloudflare-propagation-seconds 60, אם האימות מדווח שהרשומה לא נמצאה.
האם תעודת wildcard פחות מאובטחת מתעודה רגילה?
הקריפטוגרפיה זהה לחלוטין. ההבדלים הם תפעוליים: מפתח פרטי אחד מכסה את כל תת-הדומיינים, לכן פריצה לשרת משפיעה על היקף רחב יותר, ופרטי הגישה ל-API של ה-DNS הנדרשים לאוטומציה הם בעצמם סוד רגיש המאוחסן על השרת. אם אתם מנהלים רק מספר קטן של תת-דומיינים ידועים, תעודת SAN מונעת את שני החששות הללו, וזהו בדיוק המקרה שבו מדריך זה ממליץ לוותר על wildcard.