SSD Nodes Learn Hosting plans →
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-31

התקנת Certbot עבור Nginx ב-Ubuntu 24.04

למדו כיצד להתקין Certbot ב-Ubuntu 24.04 באמצעות apt או snap. המדריך מסביר את הפקודה sudo apt install certbot python3-certbot-nginx, פתרון שגיאות בפורט 80 וחידוש תעודות.

התקנת Certbot: באמצעות apt או snap

בגרסה Ubuntu 24.04, החבילה sudo apt install certbot python3-certbot-nginx מספקת Certbot תקין המנפיק תעודות Let's Encrypt אמיתיות ומהימנות לציבור. התיעוד הרשמי של Certbot מפנה לשימוש ב-snap; ההבדל מצומצם, שכן ה-snap עוקב אחר גרסאות המקור (upstream), בעוד חבילת ה-archive עוקבת אחר הגרסה שהופצה עם ה-LTS ומקבלת עדכוני אבטחה.

בחרו באחת מהאפשרויות. קיום שני עותקים של Certbot משמעו שני טיימרים לחידוש המכוונים לאותו עץ /etc/letsencrypt, והעותק ששכחתם ממנו הוא זה שיגרום לבעיות בלתי צפויות.

נתיב ה-apt:

sudo apt update
sudo apt install certbot python3-certbot-nginx

פעולה זו מתקינה את /usr/bin/certbot, את תוסף ה-nginx, זוג של certbot.service ו-certbot.timer, וערך /etc/cron.d/certbot שאינו מבצע פעולה תחת systemd.

נתיב ה-snap:

sudo apt remove certbot python3-certbot-nginx
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

ה-snap כולל טיימר משלו, snap.certbot.renew.timer. הסירו את חבילת ה-apt לפני התקנת ה-snap.

שתי שיטות ההתקנה מתנהגות באופן זהה לאחר מכן. Certbot בגרסה 2.x משתמש כברירת מחדל במפתחות ECDSA (P-256); העבירו את הדגל --key-type rsa רק עבור לקוח שאינו תומך ב-ECDSA. כל המידע נשמר תחת /etc/letsencrypt: archive/ מכיל את קובצי המפתח והתעודה האמיתיים, live/ מכיל קישורים סימבוליים (symlinks) לקבצים הנוכחיים, renewal/ מכיל קובץ תצורה אחד לכל תעודה, ו-accounts/ מכיל את מפתח חשבון ה-ACME שלכם.

מה HTTP-01 עושה בפועל, ומדוע פורט 80 אינו אופציונלי

אתגר ה-HTTP-01 הוא מנגנון של קריאה חוזרת (callback). אתם מבקשים מ-Let's Encrypt תעודה עבור example.com; השירות מבצע רזולוציה לשם ב-DNS הציבורי, פותח חיבור ל-port 80 בכתובת שנמצאה, ומבקש את http://example.com/.well-known/acme-challenge/<token>. השרת שלכם משיב עם תוכן ה-token המדויק ש-Certbot כתב זה עתה לדיסק. זהו המנגנון כולו. נובעות מכך שלוש השלכות, והן אחראיות לרוב הכשלים בהנפקת תעודות.

  • פורט 80 חייב להיות נגיש מהאינטרנט הציבורי, ולא רק מהמחשב האישי שלכם. חוק ufw, קבוצת אבטחה (security group) של ספק הענן, או firewall בקונסולת ה-VPS שפותח רק את פורט 443, יגרמו לכשל בהנפקה ובכל חידוש עתידי.
  • ה-DNS חייב להצביע כבר עכשיו על השרת הזה. שרת האימות מבצע בדיקה משלו מבחוץ; רשומות ה-/etc/hosts שלכם וזיכרון המטמון של הדפדפן אינם רלוונטיים עבורו.
  • אם פרסמתם רשומת AAAA, תינתן עדיפות ל-IPv6. השירות Let's Encrypt ינסה שוב דרך IPv4 אם חיבור ה-IPv6 נכשל לחלוטין, אך רשומת AAAA מיושנת המצביעה על מארח שמקבל את החיבור ומגיש תוכן אחר, תוביל לכשל מוחלט.

הפניות (redirects) מותרות: תהליך האימות עוקב אחר הפניית HTTP ל-HTTPS ולא משנה לו אם התעודה בצד השני חסרה, פגה או חתומה עצמית. מה שהתהליך לא יעשה, הוא להתחיל בכל פורט שאינו פורט 80. ל-Certbot אין מימוש ל-TLS-ALPN-01, לכן "פשוט להשתמש ב-443" אינו פתרון זמין.

בחירת מאמת (authenticator): --nginx, --webroot, --standalone

--nginx היא ברירת המחדל המתאימה כאשר Nginx כבר פועל ומגיש את הדומיין. Certbot מנתח את התצורה שלכם, מזריק מיקום זמני לאימות (challenge), טוען מחדש את Nginx, מבצע אימות, ואז כותב את הוראות ה-TLS לתוך בלוק ה-server שלכם. ללא זמן השבתה.

sudo certbot --nginx -d example.com -d www.example.com

סקריפט, עבור שרת חדש:

sudo certbot --nginx \
  -d example.com -d www.example.com \
  --agree-tos -m ops@example.com --no-eff-email \
  --redirect --non-interactive

--webroot מתאימה כאשר אינכם רוצים ש-Certbot יתערב בתצורת ה-Nginx שלכם, למשל אם אתם מייצרים אותה מתבנית, שומרים אותה ב-git, או פורסים אותה באמצעות Ansible. Certbot כותב רק את קובץ האימות לתוך תיקייה שאתם כבר מגישים.

sudo certbot certonly --webroot -w /var/www/example.com \
  -d example.com -d www.example.com \
  --deploy-hook "systemctl reload nginx"

--standalone מתאימה כאשר שום דבר לא מאזין בפורט 80: שרת דואר, API שדובר רק 443, או סקריפט עלייה ראשונית שרץ לפני ש-Nginx קיים. Certbot קושר את פורט 80 בעצמו למשך מספר שניות. אם Nginx כן פועל, פעולה זו תיכשל; עצרו אותו סביב זמן ההרצה:

sudo certbot certonly --standalone -d mail.example.com \
  --pre-hook "systemctl stop nginx" \
  --post-hook "systemctl start nginx"

הוקים (hooks) אלו נרשמים בתצורת החידוש של התעודה, כך שאותה עצירה/הפעלה תתרחש ללא התערבות בעת החידוש.

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

בעיית הביצה והתרנגולת: Nginx מסרב לעלות כאשר ssl_certificate מצביע על קובץ שאינו קיים, ו-Certbot אינו יכול לבצע אימות בזמן ש-Nginx מושבת. יש להעלות את האתר בפורט 80 תחילה.

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com;
    index index.html;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example.com;
        default_type "text/plain";
        try_files $uri =404;
    }

    location / {
        try_files $uri $uri/ =404;
    }
}

הריצו את sudo nginx -t && sudo systemctl reload nginx, ודאו ש-curl -I http://example.com/ מגיב ממחוץ לשרת, ולאחר מכן בצעו את ההנפקה. לאחר מכן:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    location ^~ /.well-known/acme-challenge/ {
        root /var/www/example.com;
        default_type "text/plain";
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

התחילית ^~ במיקום ה-ACME מוכיחה את חשיבותה: היא מונעת מבלוק ה-return 301 לבלוע את בקשת האימות. שמירת המיקום הזה בפורט 80 מבטיחה שחידושים ימשיכו לעבוד גם לאחר ששאר האתר יעבור ל-HTTPS בלבד.

שני הבלוקים לעיל מגישים קבצים מהדיסק; אם Nginx משמש כ-front עבור יישום, ה-location / הופך לבלוק proxy_pass, והמדריך בלוק ה-reverse proxy, שורה אחר שורה מכסה את ה-headers שהיישום דורש, בעוד שמיקום ה-ACME והנחיות ה-TLS נשארים בדיוק כפי שהם.

תחביר HTTP/2 תלוי בגרסת ה-Nginx שלכם, וערבוב בין שתי הצורות יגרום לשגיאת עלייה. Ubuntu 24.04 מגיעה עם Nginx 1.24, שדורש את התחביר המוטמע, listen 443 ssl http2;. Debian 13 מגיעה עם גרסת Nginx חדשה יותר, שדורשת את ההנחיה הנפרדת http2 on;. בדקו תחילה את nginx -v.

הצביעו עם Nginx על live/, לעולם לא על archive/. הקישורים הסימבוליים ב-live/ מתעדכנים בכל חידוש; נתיב קשיח לתוך archive/ יקבע אתכם לתעודה שתפוג ותשאיר אתכם ללא הגנה.

תווים כלליים (Wildcards) מחייבים DNS-01, ו-DNS-01 מחייב תוסף

לא ניתן לאמת תעודת Wildcard (*.example.com) באמצעות HTTP-01, שכן אין שם מארח יחיד שממנו ניתן למשוך קובץ. DNS-01 הוא הנתיב היחיד: עליך להוכיח שליטה על ידי פרסום רשומת TXT מסוג _acme-challenge.example.com. כדי לבצע זאת ללא התערבות ידנית, Certbot זקוק לפרטי גישה (API credentials) לספק ה-DNS שלך, וזהו בדיוק התפקיד של תוספי הספק. המדריך המלא לתעודות Wildcard מכסה את המכניקה של רשומות TXT ואת המלכודות בחידוש ידני; להלן הגרסה המקוצרת עבור Cloudflare.

sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-cloudflare

בנתיב ה-apt, השתמש ב-sudo apt install python3-certbot-dns-cloudflare במקום זאת. פרטי הגישה נשמרים בקובץ שנגיש ל-root בלבד:

# /root/.secrets/cloudflare.ini
# then: sudo chmod 600 /root/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_scoped_token_here

הגבל את ה-token להרשאות עריכת DNS עבור אזור (zone) זה בלבד. זהו מפתח ל-DNS שלך; התייחס אליו בהתאם.

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

השתמש במירכאות עבור ה-Wildcard כדי שה-shell לא יבצע לו globbing. DNS-01 פותר גם בעיות ש-HTTP-01 אינו יכול לפתור: תעודות עבור מארחים ללא פורט 80 ציבורי, שירות פנימי, שרת שניתן להגיע אליו רק דרך WireGuard VPN בניהול עצמי על גבי VPS, או פאנל ניהול בממשק פרטי.

חידוש: 90 הימים, הטיימר ו־deploy hook

תעודות Let’s Encrypt תקפות ל-90 ימים. Certbot מבצע חידוש כאשר נותרו פחות מ-30 ימים, מה שמעניק לכם חלון של 30 יום שבו חידוש כושל הוא מטרד שניתן לתיקון ולא השבתת שירות. Let’s Encrypt אינה שולחת יותר הודעות דוא"ל על פקיעת תוקף, אף אחד לא יתריע בפניכם, ולכן הניטור הוא באחריותכם בלבד.

בדקו את הטיימר שהותקן במערכת שלכם:

systemctl list-timers 'certbot*' 'snap.certbot*'
sudo certbot certificates

certbot renew עובר על כל קובץ הגדרה ב-/etc/letsencrypt/renewal/, מדלג על כל מה שנמצא מחוץ לחלון 30 הימים, ומחדש את השאר תוך שימוש מדויק בדגלים של ההרצה המקורית. זו הסיבה שההרצה הראשונה חשובה: היא זו שנשמרת בתיעוד.

חידוש הקובץ בדיסק אינו משנה דבר כשלעצמו; Nginx ממשיך להגיש את התעודה הישנה מהזיכרון עד שפקודה כלשהי תורה לו לבצע טעינה מחדש (reload). הגדירו deploy hook פעם אחת:

sudo tee /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh >/dev/null <<'EOF'
#!/bin/sh
set -e
nginx -t && systemctl reload nginx
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

כל קובץ בר-הרצה ב-renewal-hooks/deploy/ יופעל לאחר כל חידוש מוצלח. הדגל --deploy-hook מבצע את אותה פעולה עבור תעודה בודדת, ושומר את renew_hook = ... בקובץ ההגדרות של החידוש. certbot --nginx מבצע טעינה מחדש עבורכם; הגדרות --webroot ו---standalone אינן עושות זאת. hook חסר הוא בדיוק הסיבה לכך שאתר מגיש תעודה שפג תוקפה בעוד certbot certificates מדווח בשמחה על תעודה חדשה. כל שירות אחר שקורא את התעודה בעת העלייה זקוק לאותו hook; יישום במכולה (container) כגון התקנת Nextcloud על VPS עם Docker, TLS וגיבויים זקוק לשלב restart או reload משלו שיוגדר כאן גם כן.

בדיקת חידוש בסביבה אמיתית

sudo certbot renew --dry-run

פקודה זו מריצה את תהליך ה-challenge המלא מול סביבת ה-staging של Let's Encrypt: אותו נתיב קוד, אותם חוקי firewall, אותה הגדרת DNS, ללא עלות של rate-limit, וללא כתיבה לדיסק. אם הבדיקה עוברת בהצלחה היום, גם החידוש האוטומטי בעוד 60 יום יעבור, בהנחה שלא חלו שינויים בתשתית השרת.

הרצה במצב dry run אינה מוכיחה שפקודת ה-reload hook תופעל, שכן התנהגות זו משתנה בין גרסאות Certbot. יש לבדוק חלק זה ידנית: הריצו את סקריפט ה-hook ישירות, ודאו ש-systemctl reload nginx מסתיים בהצלחה, ובדקו את sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.

השגיאות שתיתקל בהן בפועל

Could not bind to IPv4 or IPv6., --standalone מתרחשת כאשר Nginx כבר תופס את פורט 80. השתמש ב---nginx או ב---webroot, או עצור את Nginx לפני ההרצה. ודא מי מחזיק בפורט באמצעות sudo ss -lntp | grep ':80'.

Timeout during connect (likely firewall problem), Let's Encrypt לא הצליח להגיע לפורט 80. בדוק החוצה: sudo ufw status (פתח אותו באמצעות sudo ufw allow 'Nginx Full'), לאחר מכן את ה-firewall של ספק ה-VPS, ולבסוף את ה-DNS. בצע בדיקה ממקור שאינו השרת שלך: curl -sSv http://example.com/.well-known/acme-challenge/test. רשומת AAAA מיושנת מפיקה את אותה הודעת שגיאה.

unauthorized :: Invalid response from http://example.com/.well-known/acme-challenge/xyz: 404, פורט 80 נגיש, אך ה-token לא מוגש. הבקשה הגיעה ל-server block אחר (בדוק איזה מהם מחזיק ב-default_server), או שהספרייה שהועברה ל--w אינה זו ש-Nginx מגיש ממנה. הנח קובץ ב-/var/www/example.com/.well-known/acme-challenge/test ונסה לגשת אליו מבחוץ; אם מתקבלת שגיאת 404, הבעיה מעולם לא הייתה בתעודה.

DNS problem: NXDOMAIN looking up A for example.com, השם אינו מתרגם לכתובת IP באופן ציבורי. מדובר ברשומות חדשות שטרם עברו הפצה (propagation), או ברשומה באזור (zone) שהרשם (registrar) שלך אינו משרת.

too many certificates already issued for: example.com, מגבלת קצב (rate limit), השגיאה הנפוצה ביותר בזמן ניפוי שגיאות בלולאה. Let's Encrypt מגביל הנפקת תעודות כפולות, עם אותה קבוצת שמות בדיוק, לחמש בשבוע, ומאפשר בנפרד 50 תעודות חדשות לכל דומיין רשום בשבוע; שום דבר לא יסיר את החסימה מלבד המתנה. בצע ניפוי שגיאות מול סביבת ה-staging באמצעות --dry-run.

nginx: [emerg] cannot load certificate "/etc/letsencrypt/live/example.com/fullchain.pem": No such file or directory, Nginx מוגדר עבור תעודה שמעולם לא הונפקה, או כזו שהוסרה באמצעות certbot delete. הוסף הערה ל-server block של ה-TLS, הפעל את Nginx, הנפק את התעודה, ושחזר את הבלוק.

open() "/etc/letsencrypt/options-ssl-nginx.conf" failed, קובץ זה מגיע עם חבילת ה-plugin של Nginx. במערכת certonly ללא python3-certbot-nginx, הוסף את ה-plugin או החלף את השורה include בהגדרות ssl_protocols ו-ssl_ciphers משלך.

ניהול בקנה מידה רחב

תעודה אחת יכולה להכיל עד 100 שמות, ושימוש ב-certbot --nginx -d a.example.com -d b.example.com ... יחיד עשוי להיראות מפתה, עד שרשומת DNS אחת שאינה מעודכנת נכשלת באימות וגוררת אחריה את כל שאר השמות בתעודה. תעודות נפרדות לכל אתר נכשלות באופן בלתי תלוי, וזהו המצב הרצוי בשרת המארח יותר ממספר מצומצם של שירותים. מעבר למספר קטן של אתרים, שער כניסה התומך ב-ACME מצדיק את עצמו: Traefik reverse proxy המריץ יישומים מרובים תחת Docker Compose מבקש ומחדש את התעודות בעצמו, ו-Certbot יוצא מהתמונה לחלוטין. ההחלטה איזה proxy להציב בשער הכניסה היא אישית, ו-השוואה בין Nginx לבין Caddy ו-Traefik מסתכמת בעיקרה בשאלה כמה מעבודת התעודות והגדרות היישומים תרצו שה-proxy יבצע עבורכם.

גבו את /etc/letsencrypt במלואו, עם sudo tar -czf letsencrypt-$(date +%F).tar.gz -C /etc letsencrypt, תוך שמירה על ה-symlinks. עץ זה מכיל את accounts/, מפתח חשבון ה-ACME שלכם, שלא ניתן לשחזר באופן זהה. מעבר ל-VPS חדש מסתכם ב: ביצוע rsync לעץ עם -a, התקנת Certbot, עדכון ה-DNS, והרצת certbot renew --dry-run לפני ביצוע המעבר.

במקרה של בנייה מחדש של השרת או מעבר לגרסת LTS חדשה, טיימר החידוש לא יעבור איתכם. לאחר כל הגירה, שחזור snapshot או שדרוג הפצה, הריצו את systemctl list-timers 'certbot*' ואת --dry-run. דילוג על כך יוביל להחשכת האתר כעבור 89 ימים, בשעה 3 לפנות בוקר, עבור תעודה שכולם הניחו שמתחדשת מעצמה.

כל האמור לעיל מניח שאתם שולטים במכונה בעלת כתובת IP ציבורית ופורט 80 פתוח לעולם, כלומר, VPS. המנגנונים לעיל זהים בכל אחד מהם.

אותם שלבי תעודה תקפים עבור Apache במקום nginx, וכאשר תעודה ציבורית אינה אפשרות, תעודה בחתימה עצמית ב-Ubuntu מכסה שירותים פנימיים.

FAQ

האם עליי להשאיר את פורט 80 פתוח אם האתר שלי מגיש רק HTTPS?

כן, עבור ה-challenge מסוג HTTP-01. ‏Let’s Encrypt תמיד מתחילה את בקשת האימות שלה בפורט 80, ול-Certbot אין מימוש ל-TLS-ALPN-01. לכן, firewall שפתוח רק בפורט 443 יחסום גם את ההנפקה הראשונית וגם כל חידוש אוטומטי לאחריה. הפניה (redirect) מפורט 80 ל-HTTPS היא תקינה, שכן תהליך האימות עוקב אחריה. הדרך היחידה לדלג לחלוטין על פורט 80 היא שימוש ב-DNS-01 עם תוסף (plugin) של ספק ה-DNS.

apt או snap, איזה Certbot עליי להתקין עבור nginx ב-Ubuntu 24.04?

השתמשו ב-apt. ‏sudo apt install certbot python3-certbot-nginx מספק לכם את Certbot 2.9.0 ב-Ubuntu 24.04, גרסה עדכנית מספיק לכל מה שמופיע במדריך זה. היא מקבלת עדכוני אבטחה דרך unattended-upgrades ואינה דורשת את snapd. בחרו ב-snap רק אם אתם זקוקים לגרסה החדשה ביותר באופן מיידי או לתוסף DNS שמופץ אך ורק כ-snap. כך או כך, בחרו באפשרות אחת בלבד: שתי התקנות משמעותן שני טיימרים לחידוש המצביעים על אותו עץ /etc/letsencrypt, וההתקנה שנשכחה היא זו שתגרום לתקלה.

האם Certbot יכול להנפיק תעודת wildcard עבור nginx?

רק באמצעות DNS-01. בתעודת wildcard כמו *.example.com אין שם מארח (hostname) יחיד שאפשר למשוך ממנו קובץ אימות, ולכן --nginx, --webroot ו---standalone אינם רלוונטיים. התקינו את התוסף עבור ספק ה-DNS שלכם, הניחו token של API עם הרשאות מוגבלות בקובץ הרשאות שנגיש ל-root בלבד, והריצו את certbot certonly --dns-cloudflare -d example.com -d '*.example.com', תוך שימוש במירכאות סביב ה-wildcard כדי למנוע מה-shell לבצע globbing.

מדוע nginx עדיין מגיש את התעודה הישנה לאחר חידוש מוצלח?

‏nginx שומר את התעודה בזיכרון ואינו מבחין בקובץ החדש בדיסק עד לביצוע reload. ‏certbot --nginx מבצע reload עבורכם, אך הרצות של --webroot ו---standalone אינן עושות זאת. לכן, חידוש יכול להצליח בעוד הדפדפן עדיין מציג תעודה שתוקפה פג. הניחו סקריפט בר-הרצה ב-/etc/letsencrypt/renewal-hooks/deploy/ שמריץ את nginx -t && systemctl reload nginx, והוא יופעל לאחר כל חידוש מוצלח.

האם certbot renew --dry-run מוכיח שהחידוש יעבוד?

במידה רבה. הוא מריץ את ה-challenge האמיתי מול סביבת ה-staging, עם אותו firewall, אותו DNS ואותו נתיב קוד, ללא עלות של rate-limit וללא כתיבה לדיסק. לכן, מעבר מוצלח מעיד על כך שחלק הרשת תקין. עם זאת, הוא לא מוכיח באופן אמין שה-deploy hook שלכם יופעל. בדקו זאת בנפרד: הריצו את סקריפט ה-hook ידנית ובדקו את sudo grep renew_hook /etc/letsencrypt/renewal/example.com.conf.