
مقدمه
Let’s Encrypt یک مرجع صدور گواهی (CA) رایگان و خودکار است که توسط گروه تحقیقاتی امنیت اینترنت (ISRG) — یک سازمان غیرانتفاعی — اداره میشود. حالت Standalone در Certbot، یک وبسرور داخلیِ موقت روی پورت 80 اجرا میکند تا چالش HTTP-01 مربوط به ACME را که از سوی API مربوط به Let’s Encrypt صادر شده تکمیل کند. از حالت Standalone استفاده کنید وقتی هیچ وبسروری روی ماشین شما در حال اجرا نیست، یا وقتی که در حال امنسازی یک سرویس غیر HTTP — مانند یک سرور ایمیل، یک بروکر MQTT یا یک اپلیکیشن TCP سفارشی — هستید. اگر وبسروری مانند Nginx یا Apache از قبل در حال اجراست، بهجای آن از پلاگین webroot یا پلاگین Nginx/Apache استفاده کنید؛ که چالش را بدون توقفِ یک سرویس زنده کامل میکنند.
در این آموزش، از Certbot مربوط به EFF استفاده میکنید تا یک گواهی معتبر ۹۰ روزه صادرشده از Let’s Encrypt — که در /etc/letsencrypt/live/your_domain/ ذخیره میشود — دریافت کنید. همچنین تمدید خودکار را با استفاده از تایمر systemd مربوط به Certbot و اسکریپتهای Pre/Post Hook — که در هر تلاش تمدید، هر سرویسی را که پورت 80 را اشغال کرده متوقف و مجدداً راهاندازی میکنند — پیکربندی میکنید.
توجه: این آموزش روی اوبونتو 22.04 LTS و 24.04 LTS اعتبارسنجی شده است و دستورات روی هر دو نسخه بهدرستی کار میکنند. اگر هنوز از اوبونتو 20.04 یا نسخههای قدیمیتر استفاده میکنید، توصیه میکنیم ابتدا سیستمعامل خود را ارتقا دهید؛ چرا که این نسخهها دیگر پشتیبانی نمیشوند.
نکات کلیدی
- حالت Standalone در Certbot یک وبسرور داخلیِ موقت اجرا میکند تا به چالش ACME مربوط به Let’s Encrypt پاسخ دهد. این حالت نیاز دارد پورت TCP 80 برای چالش پیشفرض HTTP-01 آزاد باشد.
- از حالت Standalone وقتی استفاده کنید که هیچ وبسروری در حال اجرا نیست، یا وقتی در حال امنسازی یک سرویس غیر HTTP — مانند سرور ایمیل، بروکر پیام یا اپلیکیشن TCP سفارشی — هستید. وقتی یک وبسرور از قبل در حال سرو کردن ترافیک است، از webroot یا پلاگین Nginx/Apache استفاده کنید.
- روی اوبونتو 22.04 و نسخههای جدیدتر، Certbot را از طریق snap نصب کنید. EFF دیگر پکیج مبتنی بر apt را برای نسخههای فعلی اوبونتو بهطور فعال نگهداری نمیکند.
- گواهیهای Let’s Encrypt ۹۰ روز اعتبار دارند. Certbot نصبشده از طریق snap، یک تایمر systemd در اختیار دارد که روزی دو بار تمدید را امتحان کرده و هنگامی که گواهی کمتر از ۳۰ روز تا انقضا داشته باشد، آن را تمدید میکند.
- در حالت Standalone، پورت 80 باید در زمان تمدید آزاد باشد. از اسکریپتهای Pre-Hook و Post-Hook برای متوقفکردن و راهاندازی مجدد هر سرویسی که قبل و بعد از هر تلاش تمدید، پورت را در اختیار دارد استفاده کنید.
- فایلهای گواهی در /etc/letsencrypt/live/your_domain/ ذخیره میشوند. بیشتر سرویسها به دو فایل نیاز دارند: fullchain.pem (زنجیره گواهی) و privkey.pem (کلید خصوصی).
پیشنیازها
قبل از شروع این آموزش به موارد زیر نیاز دارید:
- یک سرور اوبونتو 22.04 یا 24.04 همراه با یک کاربر غیر root با دسترسی sudo و فایروال پایه؛ همانطور که در راهنمای «راهاندازی اولیه سرور با اوبونتو» توضیح داده شده.
- یک نام دامنه که به سرور شما اشاره کند. اگر از سرور مجازی پارمین کلود استفاده میکنید، میتوانید این کار را با دنبالکردن مستندات «دامنهها و DNS» ما انجام دهید. این آموزش در سراسر متن از your_domain استفاده میکند.
- پورت 80 باید در زمان صدور گواهی و هر تمدید بعدی، روی سرور شما در دسترس باشد. اگر یک وبسرور در حال حاضر پورت 80 را اشغال کرده، باید قبل از اجرای Certbot در حالت Standalone آن را متوقف کرده و بعداً دوباره راهاندازی کنید. اگر سرویسی که میخواهید امن کنید هر دو پورت 80 و 443 را اشغال کرده و نمیتوانید بهصورت موقت آن را متوقف کنید، بهجای آن از حالت webroot مربوط به Certbot استفاده کنید. برای راهاندازی فایروال UFW، مقاله «راهاندازی فایروال با UFW روی اوبونتو» را ببینید.
مرحله ۱ — نصب Certbot
با رفرشکردن هسته snapd شروع کنید. اوبونتو 22.04 و 24.04 بهصورت پیشفرض شامل snapd هستند:
sudo snap install core; sudo snap refresh core
اگر روی سروری کار میکنید که قبلاً نسخه قدیمیتری از certbot روی آن نصب بوده، باید قبل از ادامه آن را حذف کنید:
sudo apt remove certbot
بعد از آن، میتوانید پکیج certbot را نصب کنید:
sudo snap install --classic certbot
در نهایت، میتوانید دستور certbot را از دایرکتوری نصب snap به PATH خود لینک کنید تا بتوانید فقط با تایپ certbot آن را اجرا کنید. این کار برای همه پکیجها لازم نیست؛ اما snapها بهصورت پیشفرض کمتر مداخلهگر هستند تا بهطور تصادفی با هیچ پکیج سیستمی دیگری تداخل نکنند:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
نصب را با بررسی نسخه Certbot تأیید کنید:
certbot --version
خروجی:
certbot 2.11.0
نسخه نمایشدادهشده، کانال snap فعلی را در زمان نصب منعکس میکند و با انتشار بهروزرسانیهای Certbot تغییر خواهد کرد.
مرحله ۲ — پیکربندی فایروال
حالت Standalone در Certbot به چالش HTTP-01 مربوط به ACME پاسخ میدهد؛ که نیازمند دسترسپذیری پورت TCP 80 از اینترنت است. پورت 80 را در فایروال خود باز کنید:
sudo ufw allow 80
خروجی:
Rule added
Rule added (v6)
سپس پورت 443 را برای سرو کردن ترافیک HTTPS پس از صدور گواهی باز کنید:
sudo ufw allow 443
خروجی:
Rule added
Rule added (v6)
حالت Standalone بهصورت پیشفرض از چالش HTTP-01 روی پورت 80 استفاده میکند؛ اگر بهجای آن از –preferred-challenges tls-alpn-01 استفاده میکنید، پورت 443 را باز کنید. اگر پورت 80 فقط در زمان صدور گواهی لازم است و اپلیکیشن شما HTTP سرو نمیکند، پس از آن را با sudo ufw delete allow 80 ببندید.
مرحله ۳ — دریافت گواهی با حالت Standalone
توجه: قبل از صدور از طریق API زنده Let’s Encrypt، با –dry-run اجرا کنید تا پیکربندی خود را تأیید کنید. اگر لازم است کل جریان صدور را در طول تست تکرار کنید، –staging (یا –test-cert) را اضافه کنید تا به محدودیتهای نرخ نخورید. گواهیهای استیجینگ توسط مرورگرها معتبر شناخته نمیشوند؛ اما فرایند صدور یکسان است. برای مقادیر فعلی محدودیتهای نرخ، مستندات محدودیتهای نرخ Let’s Encrypt را ببینید.
هشدار: حالت Standalone به پورت 80 متصل (Bind) میشود. اگر Nginx، Apache یا هر سرویس دیگری در حال حاضر روی پورت 80 گوش میدهد، قبل از اجرای دستور زیر آن را متوقف کرده و پس از صدور گواهی دوباره راهاندازی کنید. اگر پورت از قبل در حال استفاده باشد، Certbot با خطای Binding شکست خواهد خورد.
از گزینه –standalone استفاده کنید تا به Certbot بگویید چالش را با وبسرور داخلی خودش هندل کند. فلگ d- دامنهای را که برایش گواهی درخواست میکنید مشخص میکند. میتوانید چند گزینه d- اضافه کنید تا چند دامنه در یک گواهی پوشش داده شوند.
sudo certbot certonly --standalone -d your_domain
هنگام اجرای دستور، از شما خواسته میشود یک آدرس ایمیل وارد کرده و با شرایط سرویس موافقت کنید. پس از انجام این کار، باید پیامی ببینید که به شما میگوید فرایند موفق بوده و گواهیهای شما کجا ذخیره شدهاند:
خروجی:
IMPORTANT NOTES:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
This certificate expires on 2026-09-06.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
خودکارسازی صدور گواهی
برای محیطهای خودکار یا اسکریپتی که درخواستهای تعاملی در دسترس نیستند، گزینههای ثبتنام را بهصورت Inline پاس بدهید:
sudo certbot certonly --standalone \
--non-interactive \
--agree-tos \
--no-eff-email \
-m your_email@example.com \
-d your_domain
گزینه –agree-tos توافقنامه مشترکین Let’s Encrypt را میپذیرد؛ گزینه –no-eff-email درخواست عضویت در خبرنامه EFF را رد میکند و m- آدرسی را تنظیم میکند که Let’s Encrypt برای هشدارهای انقضا و اطلاعرسانی شکست تمدید از آن استفاده میکند. از یک آدرس واقعی استفاده کنید: اطلاعرسانیهای شکست تمدید، تنها هشدار زودهنگاماند اگر تایمر systemd از کار بیفتد.
اکنون باید گواهیهای خود را داشته باشید. با ls دایرکتوریای که کلیدها و گواهیهای شما را در خود دارد فهرست کنید:
sudo ls /etc/letsencrypt/live/your_domain
خروجی:
cert.pem chain.pem fullchain.pem privkey.pem README
جزئیات گواهی را با openssl تأیید کنید:
sudo openssl x509 -in /etc/letsencrypt/live/your_domain/cert.pem -noout -subject -issuer -dates -ext subjectAltName
خروجی:
subject=CN = your_domain
issuer=C = US, O = Let's Encrypt, CN = E5
notBefore=Mon Jun 8 00:00:00 2026 GMT
notAfter=Sun Sep 6 00:00:00 2026 GMT
X509v3 Subject Alternative Name:
DNS:your_domain
مقدار notAfter پنجره اعتبار ۹۰ روزه را تأیید میکند. مقدار issuer تأیید میکند که Let’s Encrypt گواهی را امضا کرده است. اگر با فلگهای d- مکرر برای چند دامنه گواهی صادر کرده باشید، همه دامنهها اینجا بهصورت ورودیهای جداگانه DNS: ظاهر میشوند. دامنهای که در این فهرست نباشد، توسط گواهی پوشش داده نمیشود.
برای فهرستکردن همه گواهیهایی که در حال حاضر توسط Certbot مدیریت میشوند — شامل دامنهها و تاریخهای انقضایشان — اجرا کنید:
sudo certbot certificates
خروجی:
Found the following certs:
Certificate Name: your_domain
Serial Number: ...
Key Type: ECDSA
Domains: your_domain
Expiry Date: 2026-09-06 00:00:00+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/your_domain/fullchain.pem
Private Key Path: /etc/letsencrypt/live/your_domain/privkey.pem
این دستورِ اصلی برای بررسی وضعیت گواهی روی هر سروری است که توسط Certbot مدیریت میشود.
پیکربندی یک سرویس برای استفاده از گواهی
بیشتر سرویسها به دو فایل از این دایرکتوری نیاز دارند: fullchain.pem بهعنوان گواهی و privkey.pem بهعنوان کلید خصوصی. مثال زیر Directiveهای مربوط به TLS را برای Postfix در /etc/postfix/main.cf نشان میدهد:
/etc/postfix/main.cf
smtpd_tls_cert_file = /etc/letsencrypt/live/your_domain/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/your_domain/privkey.pem
smtpd_tls_security_level = may
توجه: دایرکتوری /etc/letsencrypt/live/ فقط توسط root قابلخواندن است. سرویسهایی که با کاربر غیر root اجرا میشوند (مانند کاربر postfix) به یک Deploy Hook نیاز دارند که فایلهای گواهی را به مکانی قابلخواندن برای همه کپی کند؛ یا به اعطای دسترسی صریح روی دایرکتوری گواهی. برای راهاندازی کامل Postfix، مقاله «نصب و پیکربندی Postfix روی اوبونتو» را ببینید.
برای یک بروکر MQTT مانند Mosquitto، موارد زیر را به /etc/mosquitto/conf.d/tls.conf اضافه کنید:
/etc/mosquitto/conf.d/tls.conf
listener 8883
cafile /etc/ssl/certs/ca-certificates.crt
certfile /etc/letsencrypt/live/your_domain/fullchain.pem
keyfile /etc/letsencrypt/live/your_domain/privkey.pem
پورت 8883 پورت استاندارد MQTT-over-TLS است. همان هشدارِ دسترسیِ فقط-root اعمال میشود: کاربر mosquitto به یک Deploy Hook یا دسترسی خواندن صریح به privkey.pem نیاز دارد.
فایل README در این دایرکتوری اطلاعات بیشتری درباره هر یک از این فایلها دارد. اغلب فقط به دو مورد از این فایلها نیاز خواهید داشت:
- privkey.pem: کلید خصوصی. آن را محرمانه نگه دارید. دایرکتوری /etc/letsencrypt به همین دلیل فقط برای root است. بیشتر سرویسها در پیکربندی به آن با عنوان ssl-certificate-key یا ssl-certificate-key-file اشاره میکنند.
- fullchain.pem: زنجیره کامل گواهی. بیشتر سرویسها به آن با عنوان ssl-certificate اشاره میکنند.
برای اطلاعات بیشتر درباره سایر فایلهای موجود، به بخش «Where are my certificates?» از مستندات Certbot مراجعه کنید.
بعضی نرمافزارها گواهیهایشان را با فرمتهای دیگر، در مکانهای دیگر یا با دسترسیهای کاربری متفاوت لازم دارند. بهتر است همهچیز را در دایرکتوری letsencrypt رها کنید و هیچ دسترسیای را در آن تغییر ندهید (دسترسیها بههرحال هنگام تمدید بازنویسی میشوند)؛ اما گاهی این گزینهای نیست. در این حالت، باید اسکریپتی بنویسید که فایلها را جابهجا کرده و در صورت نیاز دسترسیها را تغییر دهد. این اسکریپت باید هر بار که Certbot گواهیها را تمدید میکند اجرا شود؛ که مرحله بعد آن را پوشش میدهد.
مرحله ۴ — پیکربندی تمدید خودکار
گواهیهای Let’s Encrypt ۹۰ روز اعتبار دارند. Certbot نصبشده از طریق snap یک تایمر systemd (snap.certbot.renew.timer) ثبت میکند که روزی دو بار certbot renew را اجرا کرده و هر گواهیِ در فاصله ۳۰ روزی از انقضا را تمدید میکند. هیچ راهاندازی دستیِ cron لازم نیست.
پس از تمدید، Certbot باید هر سرویسِ استفادهکننده از گواهی را Reload یا ریاستارت کند تا فایلهای جدید را بردارد. در حالت Standalone، همچنین باید قبل از تلاش تمدید هر سرویسِ در اختیاردارنده پورت 80 را متوقف کرده و بعداً دوباره راهاندازی کند. Certbot دو مکانیزم برای این کار فراهم میکند: گزینه renew_hook در فایل پیکربندی تمدید، و اسکریپتهای Pre/Post Hook در دایرکتوریهای renewal-hooks.
برای افزودن یک renew_hook، فایل پیکربندی تمدید Certbot برای دامنه خود را باز کنید:
sudo nano /etc/letsencrypt/renewal/your_domain.conf
یک فایل متنی با چند گزینه پیکربندی باز میشود. میتوانید در خط آخر، هوکی اضافه کنید که هر سرویس روبهوب را Reload کرده و آنها را وادار به استفاده از گواهی تمدیدشده کند:
/etc/letsencrypt/renewal/your_domain.conf
renew_hook = systemctl reload your_service
دستور بالا را به هر چیزی که لازم است برای Reload کردن سرورتان یا اجرای هر اسکریپت پس از تمدید بهروزرسانی کنید. معمولاً روی اوبونتو، بیشتر از systemctl برای Reload کردن یک سرویس استفاده میکنید.
استفاده از اسکریپتهای Pre-Hook و Post-Hook برای ریاستارت سرویسها
در حالت Standalone، هر تلاش تمدید باید برای تکمیل چالش ACME دوباره به پورت 80 متصل شود. اگر سرویسی در زمان تمدید پورت 80 را اشغال کرده باشد، تمدید شکست میخورد و گواهی در نهایت منقضی میشود. Pre-Hookها سرویس را قبل از تلاش تمدید متوقف میکنند؛ Post-Hookها آن را بعد از آن راهاندازی مجدد میکنند.
قبل از انتخاب رویکرد، به توافق Downtime توجه کنید: در حالت Standalone، Certbot باید برای چند ثانیه در طول چالش ACME به پورت 80 متصل شود. هر سرویسی که توسط Pre-Hook متوقف شده، برای آن بازه بهعلاوه زمان توقف و راهاندازی مجدد، در دسترس نیست. برای بیشتر سرویسهای غیر HTTP (ایمیل، MQTT و TCP سفارشی) این قابلقبول است. اگر تمدید بدون Downtime لازم است، از یک پروکسی معکوس استفاده کنید که /.well-known/acme-challenge/ را به –http-01-port مربوط به Certbot فوروارد کند، درحالیکه سرویس شما به کار خود ادامه میدهد؛ اما آن پیکربندی خارج از محدوده این آموزش است.
هنگام انتخاب بین دو رویکرد هوک زیر: از رویکرد دایرکتوری renewal-hooks (رویکرد ۱) استفاده کنید اگر میخواهید هوکها فارغ از اینکه تمدید چطور فعال شود اجرا شوند. از رویکرد فلگهای Inline (رویکرد ۲) استفاده کنید اگر میخواهید هوک در فایل پیکربندی تمدید ذخیره شود و گواهی را بهصورت تعاملی صادر میکنید. برای حالت Standaloneای که یک سرویس غیر HTTP را امن میکند، رویکرد ۱ انتخاب مطمئنتری است.
رویکرد ۱: اسکریپتهای هوک در دایرکتوریهای renewal-hooks (پیشنهادی برای حالت Standalone).
اسکریپت Pre-Hook را بسازید:
sudo tee /etc/letsencrypt/renewal-hooks/pre/stop-service.sh <<'EOF'
#!/bin/sh
systemctl stop your_service
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/pre/stop-service.sh
اسکریپت Post-Hook را بسازید:
sudo tee /etc/letsencrypt/renewal-hooks/post/start-service.sh <<'EOF'
#!/bin/sh
systemctl start your_service
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/start-service.sh
Certbot اسکریپتهای این دایرکتوریها را بر اساس زمان اجرایشان نسبت به یک تلاش تمدید پردازش میکند:
/etc/letsencrypt/renewal-hooks/pre/: قبل از هر تلاش تمدید اجرا میشود؛ چه گواهی عملاً تمدید شود و چه نشود./etc/letsencrypt/renewal-hooks/deploy/: فقط زمانی اجرا میشود که یک گواهی با موفقیت تمدید و مستقر شده باشد./etc/letsencrypt/renewal-hooks/post/: بعد از هر تلاش تمدید اجرا میشود؛ فارغ از نتیجه.
توجه: مقدار your_service را با نام یونیت systemd اپلیکیشن خود جایگزین کنید. مثلاً برای یک سرور ایمیل Postfix از postfix استفاده کنید. با systemctl list-units --type=service سرویسهای فعال را فهرست کرده و نام یونیت درست را تأیید کنید.
رویکرد ۲: فلگهای Inline هنگام صدور گواهی (ذخیرهشده در پیکربندی تمدید).
sudo certbot certonly --standalone \
--pre-hook "systemctl stop your_service" \
--post-hook "systemctl start your_service" \
-d your_domain
Certbot این فلگها را بهطور خودکار در /etc/letsencrypt/renewal/your_domain.conf مینویسد؛ پس در هر اجرای بعدی certbot renew اعمال میشوند.
تأیید تایمر تمدید
بررسی کنید که تایمر systemd فعال است و اجرای بعدیِ برنامهریزیشدهاش را تأیید کنید:
sudo systemctl list-timers | grep certbot
خروجی:
NEXT LEFT LAST PASSED UNIT ACTIVATES
Tue 2026-06-09 12:00:00 UTC 5h left Mon 2026-06-08 00:00:00 UTC 6h ago snap.certbot.renew.timer snap.certbot.renew.service
یک تمدید Dry-Run را اجرا کنید تا مطمئن شوید پیکربندی بدون صدور گواهی جدید کار میکند:
sudo certbot renew --dry-run
خروجی:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)
اگر خطایی ندیدید، Certbot طوری تنظیم شده که در صورت لزوم تمدید کند و هر دستورِ لازم برای استفاده سرویس شما از فایلهای گواهی جدید را اجرا کند. توجه کنید که –dry-run هوکهای Pre و Post را اجرا میکند اما هوکهای Deploy را رد میکند. اگر بهجای اسکریپتهای Pre/Post، یک renew_hook در فایل پیکربندی تمدید تنظیم کردهاید، در طول Dry-Run اجرا نخواهد شد؛ چون عملاً هیچ گواهیای صادر نمیشود.
حالت Standalone در برابر سایر حالتهای Certbot
حالتی را انتخاب کنید که با این دو مورد مطابقت داشته باشد: آیا روی ماشین شما از قبل وبسروری در حال اجراست و آیا به بهروزرسانی خودکار پیکربندی وبسرور نیاز دارید؟
| حالت | پورت مورد استفاده | نیاز به وبسرور | مناسب برای |
|---|---|---|---|
| –standalone | 80 (HTTP-01) یا 443 (TLS-ALPN-01) | خیر (از سرور داخلی استفاده میکند) | نبودِ وبسرور در حال اجرا؛ سرویسهای غیر HTTP مانند ایمیل، MQTT یا TCP سفارشی |
| –webroot | 80 (توسط وبسرور شما سرو میشود) | بله، از قبل در حال اجرا | سایتهایی که توسط وبسروری در حال اجرا سرو میشوند و نمیخواهید آن را متوقف کنید |
| –nginx | 80/443 | بله (Nginx) | سایتهای Nginx؛ همچنین پیکربندی Nginx را بهطور خودکار تغییر میدهد |
| –apache | 80/443 | بله (Apache) | سایتهای Apache؛ همچنین پیکربندی Apache را بهطور خودکار تغییر میدهد |
| DNS-01 (–manual یا پلاگین DNS) | هیچ (رکورد TXT مربوط به DNS) | خیر | گواهیهای وایلدکارت؛ سرورهایی بدون دسترسی ورودی HTTP/HTTPS |
اگر روی ماشین شما از قبل وبسروری در حال اجراست، برای جلوگیری از توقف یک سرویس زنده در طول تمدید، webroot یا پلاگین Nginx/Apache را به standalone ترجیح بدهید. برای Nginx، مقاله «امنسازی Nginx با Let’s Encrypt روی اوبونتو» را ببینید. برای Apache، مقاله «امنسازی Apache با Let’s Encrypt روی اوبونتو» را ببینید.
عیبیابی مشکلات رایج حالت Standalone
اشغال بودن از قبلِ پورت 80 (EADDRINUSE)
اگر پروسه دیگری به پورت 80 متصل باشد، Certbot با خطای OSError: [Errno 98] Address already in use شکست میخورد. پروسه در اختیاردارنده پورت را شناسایی کنید:
sudo ss -tlnp 'sport = :80'
خروجی:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
سرویس مزاحم را متوقف کنید (مثال: Nginx):
sudo systemctl stop nginx
سپس دستور certbot certonly --standalone را دوباره اجرا کنید. پس از صدور گواهی، سرویس را راهاندازی مجدد کنید:
sudo systemctl start nginx
مسدود بودن پورت 80 توسط فایروال
چالش HTTP-01 مربوط به ACME شکست میخورد اگر سرورهای Let’s Encrypt نتوانند به پورت 80 روی IP عمومی دامنه شما برسند. وضعیت فعلی UFW را بررسی کنید:
sudo ufw status
خروجی:
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
443 ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
اگر پورت 80 در فهرست مجازها نیست، آن را باز کنید:
sudo ufw allow 80
خروجی:
Rule added
Rule added (v6)
پس از صدور گواهی، اگر اپلیکیشن شما HTTP سرو نمیکند، قانون را حذف کنید:
sudo ufw delete allow 80
خروجی:
Rule deleted
Rule deleted (v6)
خطاهای Binding دو-Stackی IPv4/IPv6
در برخی محیطهای Docker و پیکربندیهای VPS، ممکن است Certbot به دلیل تداخلهای Dual-Stack مربوط به IPv4/IPv6 نتواند به پورت 80 متصل شود. خطا معمولاً به این شکل است: «Problem binding to port 80: Could not bind to IPv4 or IPv6». از فلگ –preferred-challenges برای تحمیل صریح چالش HTTP-01 استفاده کنید:
sudo certbot certonly --standalone --preferred-challenges http-01 -d your_domain
اگر داخل یک کانتینر Docker اجرا میکنید، مطمئن شوید پورت 80 از کانتینر به هاست نگاشت شده و هیچ پروسهای در سطح هاست هم به پورت 80 متصل نیست.
شکست چالش با باز بودن پورت 80 (عدم تطابق DNS/IPv6)
اگر Certbot خطایی مانند Connection refused یا Timeout during connect برگرداند — درحالیکه UFW پورت 80 را مجاز نشان میدهد — علت اغلب یک رکورد AAAA مربوط به DNS است. Let’s Encrypt ترجیح میدهد از IPv6 استفاده کند و ابتدا تلاش میکند از طریق IPv6 به دامنه شما برسد. اگر دامنه شما رکورد AAAAای دارد که به آدرسی اشاره میکند که عملاً روی پورت 80 سرو نمیدهد، چالش فارغ از قوانین فایروال IPv4 شما شکست میخورد.
بررسی کنید که آیا دامنه شما رکورد AAAA دارد:
dig AAAA your_domain
خروجی:
;; ANSWER SECTION:
your_domain. 300 IN AAAA 2001:db8::1
اگر رکورد AAAA وجود دارد اما سرور شما IPv6 پیکربندینشده دارد، یا رکورد AAAA را از ارائهدهنده DNS خود حذف کنید یا مطمئن شوید آدرس IPv6 سرور هم روی پورت 80 گوش میدهد. برای تأیید دسترسپذیری پورت 80 روی IPv6:
sudo ss -tlnp 'sport = :80'
خروجی:
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1234,fd=6))
LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=1234,fd=6))
اگر سرور شما Dual-Stack است، باید هم ورودی IPv4 (0.0.0.0:80) و هم ورودی IPv6 ([::]:80) ظاهر شوند. اگر فقط ورودی IPv4 وجود دارد و رکورد AAAA هم موجود است، چالش Let’s Encrypt شکست خواهد خورد.
سوالات متداول
حالت Standalone در Certbot چیست و چه زمانی باید از آن استفاده کنم؟
در حالت Standalone، Certbot بهصورت موقت پورت 80 را اشغال کرده و یک توکن تأیید را در یک URL شناختهشده قرار میدهد. Let’s Encrypt آن توکن را برای تأیید کنترل شما روی دامنه دریافت کرده و سپس گواهی را صادر میکند. از حالت Standalone استفاده کنید وقتی هیچ وبسروری روی سیستم شما در حال اجرا نیست، یا وقتی در حال امنسازی یک سرویس غیر HTTP — مانند سرور ایمیل، بروکر MQTT یا اپلیکیشن TCP سفارشی — هستید.
آیا قبل از اجرای Certbot در حالت Standalone باید وبسرور خود را متوقف کنم؟
بله. حالت Standalone در Certbot برای هندل چالش ACME به پورت 80 متصل میشود. اگر Nginx یا Apache از قبل به پورت 80 متصل باشد، Certbot با خطای Binding شکست میخورد. قبل از اجرای sudo certbot certonly --standalone وبسرور را متوقف کرده و پس از صدور گواهی دوباره راهاندازی کنید.
چطور یک گواهی Let’s Encrypt دریافتشده با حالت Standalone را تمدید کنم؟
Certbot نصبشده از طریق snap روی اوبونتو یک تایمر systemd (snap.certbot.renew.timer) ثبت میکند که روزی دو بار certbot renew را اجرا میکند. برای حالت Standalone، اسکریپتهای Pre-Hook و Post-Hook را طوری پیکربندی کنید که هر سرویسِ در اختیاردارنده پورت 80 را متوقف و مجدداً راهاندازی کنند؛ با استفاده از فلگهای –pre-hook و –post-hook یا اسکریپتهایی که در /etc/letsencrypt/renewal-hooks/ قرار میگیرند. فرایند را با sudo certbot renew --dry-run تست کنید.
فایلهای گواهی بعد از صدور توسط Certbot کجا ذخیره میشوند؟
گواهیها در /etc/letsencrypt/live/your_domain/ ذخیره میشوند. فایلهایی که بیشتر سرویسها لازم دارند عبارتاند از fullchain.pem (زنجیره کامل گواهی که به سرویس بهعنوان گواهی SSL پاس میشود)، privkey.pem (کلید خصوصی)، cert.pem (فقط گواهی End-Entity) و chain.pem (فقط زنجیره میانی).
اگر پورت 80 در طول صدور گواهی توسط فایروال مسدود باشد چه اتفاقی میافتد؟
چالش HTTP-01 مربوط به ACME شکست میخورد؛ چون سرورهای Let’s Encrypt نمیتوانند به پورت 80 روی دامنه شما برسند. پورت 80 را با sudo ufw allow 80 باز کنید، دستور certbot را اجرا کرده و سپس اگر اپلیکیشن شما HTTP سرو نمیکند، دوباره با sudo ufw delete allow 80 ببندید.
آیا میتوانم از حالت Standalone در Certbot داخل یک کانتینر Docker استفاده کنم؟
بله؛ اما پورت 80 باید از کانتینر به هاست نگاشت شده باشد و هیچ پروسهای در سطح هاست نمیتواند همزمان به پورت 80 متصل باشد. مشکلات Dual-Stack مربوط به IPv4/IPv6 میتوانند در محیطهای Docker باعث شکست Binding شوند. اگر با خطای Dual-Stack روبرو شدید، مطمئن شوید پیکربندی شبکه کانتینر شما نگاشت درست پورت را ممکن میکند؛ یا –preferred-challenges http-01 را برای تحمیل صریح چالش HTTP-01 پاس بدهید.
یک گواهی Let’s Encrypt چقدر اعتبار دارد و هر چند وقت یکبار تمدید میشود؟
گواهیهای Let’s Encrypt ۹۰ روز اعتبار دارند. تایمر systemd مربوط به Certbot وقتی گواهی در فاصله ۳۰ روزی از انقضا باشد، تمدید را امتحان میکند. اگر هوکهای Pre/Post بهدرستی پیکربندی شده باشند و پورت 80 در زمان تمدید در دسترس باشد، هیچ مداخله دستی لازم نیست.
آیا snap روش توصیهشده برای نصب Certbot روی اوبونتو است؟
بله. EFF نصب Certbot از طریق snap را روی اوبونتو 22.04 و نسخههای جدیدتر توصیه میکند. پکیج apt با نام python3-certbot دیگر بالادستی بهطور فعال نگهداری نمیشود. نصب از طریق snap تضمین میکند آخرین نسخههای Certbot را بهطور خودکار از طریق مکانیزم snap refresh دریافت کنید.
جمعبندی
در این آموزش، Certbot را از طریق snap روی اوبونتو نصب کردید؛ فایروال را برای مجاز دانستن چالش HTTP-01 مربوط به ACME روی پورت 80 و ترافیک HTTPS روی پورت 443 پیکربندی کردید؛ با certbot certonly --standalone گواهی دریافت کردید؛ جزئیات گواهی را با openssl تأیید کردید؛ و تمدید خودکار را با استفاده از اسکریپتهای Pre-Hook و Post-Hook در کنار تایمر systemd مربوط به Certbot پیکربندی کردید.
فایلهای گواهی در /etc/letsencrypt/live/your_domain/ اکنون برای پیکربندی TLS برای هر سرویسی که روی سرور شما اجرا میشود در دسترساند. گواهی بدون مداخله دستی بهطور خودکار تمدید میشود؛ به شرطی که هوکهای Pre/Post در هر تلاش تمدید، پورت 80 را آزاد نگه دارند.




