آموزش نصب Mailcow روی VPS و رفع مشکل ارسال ایمیل به Gmail
قبل از نصب mailcow حتما پورت 25 را تست کنید. مسدود بودن این پورت باعث ایجاد صف در خروجی میشود. با تنظیم صحیح DNS از خطای 550 5.7.25 و ریجکت شدن توسط Gmail جلوگیری کنید.
آنچه میسازید
یک سرور ایمیل کامل روی سیستمی که مالک آن هستید: SMTP برای ارسال و دریافت، IMAP برای همگامسازی گوشی و لپتاپ، یک کلاینت وبمیل و یک فیلتر اسپم که تمام پیامها را در هر دو جهت امتیازدهی میکند. mailcow-dockerized شامل Postfix، Dovecot، Rspamd، وبمیل SOGo، MariaDB، Redis و یک کلاینت ACME در قالب یک stack از Docker Compose است، بنابراین بخش نرمافزاری کار دشواری نیست. شما میتوانید آن را در نیم ساعت راهاندازی کنید.
بخش دشوار، تمام موارد پیرامون آن است. ایمیل تنها سرویسی است که بقیه اینترنت بهطور فعال به یک سرور تازهتأسیس اعتماد نمیکند و فاصله بین «کار کردن» و «حذف بیسروصدای پیامها توسط Gmail» عمدتاً به چهار رکورد DNS و یک تنظیم اعتبار IP بستگی دارد که ممکن است کنترل کاملی روی آن نداشته باشید. پیشنیازهای زیر را پیش از اجاره هرگونه سرور مطالعه کنید. اگر پس از خواندن آنها تصمیم گرفتید که چالش کسب اعتبار ارزشش را ندارد، این یک نتیجهگیری منطقی است؛ بررسی ما از آنچه در سال 2026 واقعاً ارزش self-hosting دارد، دقیقاً به همین دلایل، ایمیل را در دسته «فقط اگر واقعاً قصدش را دارید» قرار میدهد.
پیشنیازها خودِ پروژه هستند
اگر حتی یکی از این موارد را نادیده بگیرید، ایمیلهایی ارسال خواهید کرد که هرگز به مقصد نمیرسند. این موارد به ترتیب تقریبیِ میزانِ ایجاد مشکل برای کاربران آورده شدهاند:
پورت خروجی 25 باید باز باشد. سرور شما از طریق پورت TCP 25 به Gmail و Microsoft ایمیل ارسال میکند. بخش بزرگی از ارائهدهندگان VPS و سرویسهای ابری، پورت 25 خروجی را بهصورت پیشفرض برای مقابله با اسپم مسدود میکنند. این مسدودسازی بیسروصدا انجام میشود؛ هیچ خطایی هنگام بوت رخ نمیدهد، همهچیز سالم به نظر میرسد و ایمیلها در صف انتظار باقی میمانند تا زمانی که Postfix تسلیم شده و آنها را بازگشت (bounce) دهد (mailcow حداکثر طول عمر صف را روی پنج روز تنظیم میکند). پیش از نصب هر چیزی، این پورت را تست کنید. اگر مسدود است، تنها راهحل، ارسال تیکت پشتیبانی و درخواست از ارائهدهنده برای باز کردن آن است؛ برخی این کار را برای حسابهای قدیمی انجام میدهند و برخی هرگز انجام نخواهند داد.
یک IP تمیز با اعتبار قابلاستفاده. IPهای بازیافتیِ VPSها اغلب از قبل در لیستهای سیاه (blocklists) مربوط به فعالیتهای اسپمِ مستأجر قبلی قرار دارند. پیش از شروع، IP خود را در سرویسهایی مانند Spamhaus یا mxtoolbox بررسی کنید. قرار داشتن IP در لیست سیاه به معنای رد شدن ایمیلهاست که با هیچ کدنویسیای قابلحل نیست.
کنترل DNS به همراه رکورد PTR صحیح. شما باید رکوردهایی را به zone دامنه خود اضافه کنید و برای IP سرور خود به یک رکورد معکوس DNS (PTR) نیاز دارید که به نام میزبان (hostname) ایمیل شما اشاره کند. رکورد PTR تقریباً هرگز در پنل DNS شما تنظیم نمیشود؛ این رکورد نزد مالکِ IP است، بنابراین باید در پنل کنترل ارائهدهنده VPS یا از طریق تیکت تنظیم شود.
حداقل 6 گیگابایت رم و 2 هسته vCPU. حداقلِ موردنیاز mailcow برای یک نصب شخصی، 6 گیگابایت رم به همراه 1 گیگابایت swap است و توصیه میشود پس از اینکه تعداد کمی کاربر به آن متکی شدند، به 8 گیگابایت ارتقا یابد. در مقادیر کمتر از حدود 2.5 گیگابایت، generate_config.sh پیشنهاد میدهد که اسکنر ویروس ClamAV را غیرفعال کنید تا kernel شروع به کشتن کانتینرها نکند. حداقل فضای دیسک مستندشده برای mailcow قبل از ذخیره هرگونه ایمیل، 20 گیگابایت است؛ بنابراین از ابتدا فضای بیشتری اختصاص دهید تا برای رشد صندوقهای پستی فضا باقی بماند.
یک نام DNS، نه یک IP خام. یک نام میزبان مانند mail.example.com انتخاب کنید. این نام واحد، تبدیل به MAILCOW_HOSTNAME شما، موضوع گواهی TLS، مقصد PTR و بنر SMTP شما میشود. این نام را در همهجا ثابت نگه دارید.
گام 1، اطمینان از باز بودن پورت 25 خروجی
این کار را در ابتدا انجام دهید. اگر این مرحله با شکست مواجه شود، سایر اقدامات بیهوده خواهد بود. از داخل VPS تازه راهاندازی شده، تلاش کنید یک مکالمه SMTP با یک سرور ایمیل واقعی برقرار کنید:
sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25نتیجه موفقیتآمیز بلافاصله ظاهر میشود:
Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!پورت مسدود شده به مدت 5 ثانیه کامل معلق میماند و سپس با خطا مواجه میشود:
nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progressدر یک VPS تازه که هیچ قانون فایروال خروجی برای آن تعریف نکردهاید، این وقفه (timeout) ناشی از مسدودسازی توسط ارائهدهنده سرویس است. این یک فیلتر شبکه در سمت ارائهدهنده است، نه فایروال شما؛ بنابراین هیچ تغییری در تنظیمات محلی آن را رفع نمیکند. یک تیکت پشتیبانی ارسال کنید: "لطفاً پورت 25 TCP خروجی را برای VPS من با آدرس <IP> باز کنید؛ من در حال راهاندازی یک سرور ایمیل قانونی هستم." تا زمانی که این درخواست به نتیجه "succeeded" نرسیده است، mailcow را نصب نکنید. توجه داشته باشید که پورت 25 ورودی (اتصال سایر سرورها به شما) مسیر جداگانهای دارد و معمولاً باز است؛ این سمت خروجی است که ارائهدهندگان آن را محدود میکنند.
گام 2، تنظیم رکوردهای DNS در حال حاضر
اعمال تغییرات DNS زمانبر است، بنابراین پیش از نصب، تمام رکوردهای ممکن را منتشر کنید. فرض کنید دامنه شما example.com، میزبان ایمیل شما mail.example.com و آدرس IP شما 10.0.0.10 است. در ناحیه (zone) خود، موارد زیر را ایجاد کنید:
mail.example.com. A 10.0.0.10
mail.example.com. AAAA 2001:db8::10 ; only if you have IPv6
example.com. MX 10 mail.example.com.
example.com. TXT "v=spf1 mx -all"
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:postmaster@example.com"رکورد SPF بیان میکند که «فقط MX من مجاز به ارسال ایمیل برای این دامنه است و بقیه باید رد شوند». سیاست DMARC را روی p=none قرار دهید تا بتوانید گزارشها را بدون ریجکت شدن ایمیلهای خودتان مانیتور کنید؛ پس از اطمینان از همراستایی (alignment)، آن را به p=quarantine و سپس p=reject تغییر دهید. دو رکورد بهصورت عمدی هنوز در اینجا وجود ندارند: DKIM که mailcow در گام 6 برای شما تولید میکند، و PTR که باید همین حالا در پنل ارائهدهنده خود تنظیم کنید.
رکورد PTR (یا همان reverse DNS) را برای 10.0.0.10 روی mail.example.com تنظیم کنید که مقدار دقیق MAILCOW_HOSTNAME است. این تنها رکوردی است که اکثر افراد فراموش میکنند و ارائهدهندگان بزرگ ایمیل بر اساس آن، پیامها را رد میکنند. اگر پنل شما فیلد rDNS ندارد، یک تیکت پشتیبانی ارسال کنید.
گام 3، نصب Docker
نرمافزار mailcow به Docker Engine نسخه 24.0 یا جدیدتر و Docker Compose نسخه 2.0 یا جدیدتر نیاز دارد. استفاده از افزونه Compose (docker compose) سادهترین روش است، اگرچه mailcow از فایل اجرایی مستقل docker-compose نیز پشتیبانی میکند. از اسکریپت راحتی (convenience script) رسمی Docker استفاده کنید و به سراغ بسته docker.io در Ubuntu نروید، زیرا این بسته هیچ افزونه Composeای را به همراه ندارد:
curl -fsSL https://get.docker.com | sudo sh
sudo docker compose versionشما باید یک خط Docker Compose version مشاهده کنید که نسخه v2.x یا v5.x را گزارش میدهد. نسخه Compose v5 که در سال 2025 منتشر شد، از نظر عملکرد با v2 یکسان است و هر دو نسخه برای mailcow مناسب هستند. اگر docker compose version عبارت docker: 'compose' is not a docker command را چاپ کرد، یعنی Docker Engine نصب شده اما افزونه Compose نصب نیست. افزونه را از مخزن Docker نصب کنید، اسکریپت بالا را دوباره اجرا کنید، یا راهنمای اصول اولیه Docker Compose ما را دنبال کنید که هر دو مورد را از مخزن apt رسمی Docker تنظیم میکند.
گام 4، کلون کردن mailcow و تولید فایل پیکربندی
cd /opt
sudo git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
umask
sudo ./generate_config.shبررسی اینکه umask خروجی 0022 را میدهد، از مراحل نصب خود mailcow پیروی میکند که پیش از کلون کردن، umask 0022 را تنظیم میکند. هیچکدام از تستهای mailcow این مقدار را بررسی نمیکنند و یک shell با دسترسی root در نسخه تازه Ubuntu 24.04 بهطور پیشفرض 0022 را ارائه میدهد. سپس اسکریپت تنها مورد مهم را میپرسد: نام دامنه کامل (FQDN). مقدار mail.example.com را وارد کنید؛ این مقدار باید دقیقاً با رکورد A و رکورد PTR شما مطابقت داشته باشد. این اسکریپت فایل mailcow.conf را میسازد که تنها فایل محیطی (environment file) مورد استفاده کل stack است. اگر نیاز به تغییر پورتهای وب (HTTP_PORT، HTTPS_PORT) یا غیرفعال کردن ClamAV در سرورهای کوچک دارید، این فایل را باز کنید:
MAILCOW_HOSTNAME=mail.example.com
HTTP_PORT=80
HTTPS_PORT=443
SKIP_CLAMD=n # set to y to drop the virus scanner on a <2.5 GiB boxSKIP_FTS=y اهرم دیگری برای سرورهای با RAM کم است: جستجوی متن کامل (full-text search) دومین مصرفکننده حافظه است که در مستندات mailcow ذکر شده و صرفنظر از آن، تنها قابلیت جستجو در متن بدنه ایمیلها در webmail را از شما میگیرد.
مقادیر HTTP_PORT=80 و HTTPS_PORT=443 را تغییر ندهید مگر اینکه سرویس دیگری روی میزبان از آنها استفاده کند. کلاینت ACME داخلی mailcow بهطور پیشفرض از چالش HTTP-01 استفاده میکند که برای دریافت گواهی، نیاز دارد پورت 80 از اینترنت در دسترس باشد. (نسخه mailcow 2026-03 و بعد از آن میتوانند بهجای آن از چالش DNS-01 با ACME_DNS_CHALLENGE=y استفاده کنند که نیازی به پورت 80 ندارد اما به دسترسی API به میزبان DNS شما نیاز دارد.) به همین دلیل است که چیدمان ساده، یک تنظیم جداگانه nginx-plus-Certbot را روی همان سرور اجرا نمیکند؛ mailcow گواهیهای TLS خود را بهصورت داخلی صادر و تمدید میکند و حضور سرویس دومی که پورتهای 80/443 را اشغال کند، باعث اختلال در این فرآیند میشود. mailcow روش جایگزین را مستند کرده است: listenerهای وب خود را با HTTP_BIND=127.0.0.1 HTTP_PORT=8080 HTTPS_BIND=127.0.0.1 HTTPS_PORT=8443 به صورت محلی bind کنید، یک reverse proxy روی پورتهای 80 و 443 قرار دهید و اگر میخواهید Certbot محلی گواهیها را مدیریت کند، mailcow را به مسیر آنها ارجاع داده و یک renewal hook اضافه کنید. این کار قطعات متحرک بیشتری را به سرور ایمیل اضافه میکند، بنابراین همین موازنه برای هر سرویس دیگری که به رابط وب عمومی نیاز دارد صدق میکند: ساختاری مانند تغییر ظاهر Jellyfin به سبک فروشگاه ویدئوی دهه 90 که انتظار دارد reverse proxy اختصاصی خود را روی پورت 443 داشته باشد، باید روی میزبان متفاوتی قرار گیرد مگر اینکه mailcow را به پشت آن proxy منتقل کنید. استثنا مربوط به سرویسی است که هرگز درخواست پورت وب عمومی نمیکند: یک relay خودمیزبان RustDesk که فقط روی محدوده پورتهای 21115 تا 21119 گوش میدهد، بنابراین میتواند در صورت داشتن پهنای باند کافی، روی همان سرور قرار بگیرد.
گام 5، راهاندازی پشته و ورود به سیستم
sudo docker compose pull
sudo docker compose up -d
sudo docker compose psعملیات pull حدود دو دوجین ایمیج را دریافت میکند؛ چند دقیقه به آن زمان بدهید. وقتی docker compose ps نشان داد که تمام کانتینرها running (یا healthy) هستند، https://mail.example.com/admin را در مرورگر باز کنید. نام کاربری پیشفرض برای ورود مدیر admin و رمز عبور moohoo است. بلافاصله این رمز عبور را در رابط کاربری مدیریت در مسیر System → Configuration و سپس Access → Administrators تغییر دهید. اگر مرورگر هشدار NET::ERR_CERT_AUTHORITY_INVALID را نمایش داد، به این معنی است که گواهی ACME هنوز صادر نشده است؛ پیش از آنکه تصور کنید سیستم خراب است، بخش مربوط به خطای ACME در ادامه را مطالعه کنید؛ وجود یک گواهی خودامضا (self-signed) به عنوان جایگیرنده در یکی دو دقیقه اول طبیعی است.
گام 6، افزودن دامنه، صندوق پستی و انتشار DKIM
در رابط کاربری مدیریت، به بخش E-Mail → Configuration بروید و در زبانه Domains روی Add domain کلیک کرده و example.com را وارد کنید. سپس در بخش Mailboxes، گزینه Add mailbox را انتخاب کنید تا you@example.com را با یک رمز عبور بسازید. این یک صندوق پستی فعال است که از همین حالا از طریق IMAP در دسترس است.
حالا نوبت کلید DKIM است. به مسیر System → Configuration و سپس Options → ARC/DKIM keys بروید؛ ممکن است mailcow هنگام افزودن دامنه، کلید را تولید کرده باشد. اگر نه، در همانجا کلید را تولید کنید، دامنه را انتخاب کنید، selector را روی dkim نگه دارید، 2048-bit را انتخاب کرده و روی Add کلیک کنید. مقدار طولانی TXT نمایش داده شده را کپی کرده و آن را به این صورت منتشر کنید:
dkim._domainkey.example.com. TXT "v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqh...long-key...QAB"صفحه Domains در mailcow دارای یک دکمه DNS است که تمام رکوردهای مورد انتظار را فهرست کرده و با تیک سبز یا ضربدر قرمز، وضعیت انتشار واقعی آنها را نشان میدهد. از آن به عنوان چکلیست استفاده کنید و پیش از تست قابلیت ارسال ایمیل، تمام ردیفها را سبز کنید. قرمز بودن ردیف DKIM پس از انتشار، معمولاً به این معنی است که کلید بهدرستی در بخشهای TXT تقسیم نشده است؛ یک کلید 2048-بیتی طولانیتر از حد مجاز 255 کاراکتر برای یک رشته TXT واحد است، بنابراین آن را به عنوان یک مقدار منطقی واحد وارد کنید و اجازه دهید میزبان DNS شما آن را به قطعات مناسب تقسیم کند.
گام 7، تست قابلیت تحویل و کسب امتیاز 10/10
به سایت mail-tester.com بروید، آدرس تصادفی نمایش داده شده را کپی کنید و از صندوق پستی جدید خود پیامی به آن ارسال کنید. برای این کار، به SOGo webmail در https://mail.example.com/SOGo وارد شوید و از آنجا ایمیل بفرستید. سپس روی دکمه "Then check your score" کلیک کنید.
هدف شما کسب امتیاز 10/10 است. کسر امتیازهای رایج و دلایل آنها عبارتند از:
- عدم تطابق SPF: رکورد
MX/SPF شما وجود ندارد یا IP فرستنده در آن لحاظ نشده است. رکورد TXT مربوط به SPF را دوباره بررسی کنید. - عدم تأیید امضای DKIM: رکورد TXT مربوط به
dkim._domainkeyوجود ندارد، هنوز در حال انتشار در شبکه است یا دچار نقص شده است. این رایجترین دلیل کسر امتیاز است. - نبود PTR یا عدم تطابق آن: رکورد reverse DNS به
mail.example.comاشاره نمیکند. این مورد را از طریق پنل ارائهدهنده سرور اصلاح کنید. - قرارگیری در لیست سیاه (Blocklist): به دلیل سابقه IP شما. درخواست خروج از لیست سیاه (delisting) بدهید یا از ارائهدهنده بخواهید IP تمیزتری به شما اختصاص دهد.
تا زمانی که امتیاز شما 10/10 نشده است، ایمیل واقعی به Gmail یا Outlook ارسال نکنید. امتیاز پایین به همراه یک IP جدید، باعث میشود دامنه شما از همان روز اول در لیست سیاه قرار بگیرد.
گام 8، اتصال یک کلاینت ایمیل واقعی
نرمافزار Thunderbird، Apple Mail یا گوشی خود را با تنظیمات زیر به سرور متصل کنید. میزبان سرور برای همه آنها mail.example.com است:
- IMAP: پورت 993، SSL/TLS (یا 143 با STARTTLS)
- SMTP submission: پورت 465، SSL/TLS (یا 587 با STARTTLS)
- نام کاربری: آدرس کامل ایمیل،
you@example.com - رمز عبور: رمز عبوری که برای صندوق پستی تعیین کردهاید
هرگز ایمیل کلاینت را از طریق پورت 25 ارسال نکنید؛ این پورت فقط برای ارتباط سرور به سرور است. mailcow در این پورت امکان ارسال احرازهویتشده را فراهم نمیکند و اتصال کلاینت به آن رد خواهد شد. اگر کلاینت خطای Relay access denied را گزارش میدهد، به این معنی است که سعی دارد از طریق پورت 25 یا بدون احرازهویت ایمیل ارسال کند؛ تنظیمات آن را به پورت 465 یا 587 تغییر دهید و از اعتبارنامههای صندوق پستی خود استفاده کنید.
گام 9، پشتیبانگیری از دادههای حیاتی
نرمافزار mailcow یک اسکریپت پشتیبانگیری ارائه میدهد که از تمام volumeهای دارای وضعیت (stateful) اسنپشات تهیه میکند. آن را روی یک دیسک خارجی یا یک مسیر remote mount شده اجرا کنید:
sudo MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
./helper-scripts/backup_and_restore.sh backup allall شش مورد را ذخیره میکند و از دست دادن هر یک از آنها به معنای از دست رفتن دادههاست: vmail (صندوقهای پستی واقعی)، crypt (کلیدهایی که vmail را رمزگشایی میکنند و بدون آن بیفایده هستند)، mysql (پایگاهداده MariaDB که دامنهها، کاربران، نامهای مستعار و تنظیمات را نگه میدارد)، redis (وضعیت صف و کش)، rspamd (آموزشهای مربوط به spam/ham) و postfix (صف ایمیل). این اسکریپت درون یک کانتینر کمکی اجرا میشود و آرشیوهای فشرده ایجاد میکند، بنابراین پشتیبانها حتی در حالی که stack فعال است، منسجم باقی میمانند. آن را با یک cron job شبانه خودکار کنید و از --delete-days 14 برای حذف مجموعههای قدیمی استفاده کنید. یک cron job که از کار میافتد، بدون اطلاع قبلی متوقف میشود؛ بنابراین وضعیت خروجی اسکریپت را به جایی بفرستید که واقعاً متوجه آن شوید؛ یک سرور ntfy خودمیزبان با یک دستور curl تکخطی در همان cron job، خرابی را در همان شب روی گوشی شما نمایش میدهد. بازیابی با همان اسکریپت و با استفاده از restore انجام میشود که اسنپشاتها را لیست کرده و به شما اجازه میدهد مورد دلخواه برای بازگردانی را انتخاب کنید. پشتیبانی که هرگز بازیابی آن را تست نکردهاید، یک امید است، نه یک پشتیبان؛ حتماً یک بار تست بازیابی را روی یک VPS موقت انجام دهید.
گام 10، بهروزرسانی طبق زمانبندی
نرمافزار mailcow از طریق اسکریپت اختصاصی خود بهروزرسانی میشود. این اسکریپت کدهای جدید را دریافت میکند، mailcow.conf را مهاجرت میدهد، تصاویر را پیشبارگذاری میکند و کانتینرها را به ترتیب زیر راهاندازی مجدد میکند:
cd /opt/mailcow-dockerized
sudo ./update.sh --check # reports whether an update exists, changes nothing
sudo ./update.sh # applies itابتدا نسخه پشتیبان تهیه کنید (گام 9)، زیرا بازگرداندن مهاجرت طرحواره (schema migration) دشوار است. بهروزرسانیها بهطور مکرر منتشر میشوند و شامل اصلاحات امنیتی برای دیمونهایی هستند که در معرض اینترنت قرار دارند؛ بنابراین اجازه ندهید سرور ایمیل برای ماهها بدون بهروزرسانی باقی بماند. اگر بهروزرسانی باعث شد کانتینری در وضعیت ناسالم (unhealthy) قرار گیرد، sudo docker compose logs --tail=50 <service>-mailcow نام دیمونی که در راهاندازی مجدد شکست خورده است را مشخص میکند.
نکتهای در مورد مقاومسازی
نرمافزار mailcow سرویس netfilter اختصاصی خود (netfilter-mailcow) را اجرا میکند که IPهایی را که به پورتهای ایمیل و وبمیل حمله میکنند مسدود میسازد، بنابراین بخش ایمیل بهصورت پیشفرض محافظتشده است. این موضوع شامل SSH روی خود میزبان نمیشود؛ SSH همچنان در معرض دید است و همچنان هدف حملات brute-force قرار میگیرد. این ساختار را با نظارت Fail2ban بر لاگ احراز هویت SSH و ورود فقط با کلید (key-only) ترکیب کنید. رابط کاربری مدیریت mailcow را با یک رمز عبور قوی محافظت کنید و در حالت ایدهآل، آن را از دسترس اینترنت عمومی خارج کرده یا پشت یک VPN قرار دهید.
حالتهای شکست و رشتههای دقیق خطا
صف ایمیل پر میشود و هیچ پیامی ارسال نمیشود. دستور sudo docker compose exec postfix-mailcow postqueue -p را اجرا کنید یا صف ایمیل را در رابط کاربری مدیریت بخوانید؛ ورودیها تا 5 روز در وضعیت deferred باقی میمانند تا Postfix آنها را بازگرداند (bounce)، با این خطا:
status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)این خطا تقریباً همیشه به معنای مسدود بودن پورت خروجی 25 توسط سرویسدهنده شماست (گام 1). یک قانون خروجی در فایروال میزبان نیز همین timeout را ایجاد میکند، پس ابتدا آن را بررسی کنید؛ اگر میزبان مشکلی ندارد، هیچ تغییری در پیکربندی مشکل را حل نمیکند، یک تیکت پشتیبانی باز کنید. این مشکل مربوط به DNS یا TLS نیست؛ نشانه اصلی، عبارت timed out در مقابل یک MX از راه دور روی پورت 25 است.
جیمیل همه چیز را اسپم تشخیص میدهد یا باز میگرداند. پیام را در جیمیل باز کنید، گزینه "Show original" را بزنید و نتایج احراز هویت را بخوانید. dkim=fail یا dkim=none به این معناست که رکورد dkim._domainkey TXT شما گم شده، ناقص است یا هنوز منتشر نشده است؛ دقیقاً همان چیزی که در صفحه ARC/DKIM نمایش داده شده را دوباره منتشر کنید و منتظر پایان TTL بمانید. spf=fail به این معناست که رکوردهای SPF/MX شامل IP شما نمیشوند. همراستایی (Alignment) همه چیز است؛ شکست در یک بررسی برای انتقال به پوشه اسپم کافی است.
رد شدن توسط سرویسدهندههای بزرگ هنگام اتصال. پیامهای بازگشتی یا لاگهای Postfix حاوی خطای رد شدن PTR توسط جیمیل هستند:
550-5.7.25 [10.0.0.10] The IP address sending this message does not have a PTR
550-5.7.25 record setup, or the corresponding forward DNS entry does not match
550 5.7.25 the sending IP. As a policy, Gmail does not accept messages from IPs
550 5.7.25 with missing PTR records.کد 550 5.7.25 به معنای نبودن یا عدم تطابق reverse DNS است. رکورد PTR برای IP خود را در پنل سرویسدهنده روی mail.example.com تنظیم کنید (گام 2). رکوردهای Forward (A) و Reverse (PTR) باید با هم مطابقت داشته باشند و هر دو باید به همان نام میزبانی اشاره کنند که mailcow هنگام معرفی به سایر سرورها استفاده میکند.
مرورگر هشدار گواهی نشان میدهد که برطرف نمیشود. کانتینر acme-mailcow در دریافت گواهی معتبر شکست خورده است. لاگ آن را بررسی کنید:
sudo docker compose logs acme-mailcow | tail -n 40خطی مانند Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. یا شکست در challenge به این معناست که پورت 80 از اینترنت در دسترس نیست، یا رکورد A به این سرور اشاره نمیکند. اگر رکورد AAAA منتشر کردهاید، آن را نیز بررسی کنید: mailcow ابتدا رکورد AAAA را اعتبارسنجی میکند و در صورت وجود، بررسی A را نادیده میگیرد؛ بنابراین یک رکورد AAAA اشتباه یا مسیر IPv6 که به پورت 80 نمیرسد، باعث شکست اعتبارسنجی میشود، حتی اگر رکورد A صحیح باشد. اطمینان حاصل کنید که mail.example.com به این سرور resolve میشود، پورتهای 80 و 443 را در فایروال میزبان باز کنید و مطمئن شوید سرویس دیگری از این پورتها استفاده نمیکند. پس از رفع علت، کلاینت را با sudo docker compose restart acme-mailcow ریاستارت کنید تا نیازی به انتظار برای پایان دوره back-off یکساعته نباشد.
FAQ
آیا میزبانی شخصی ایمیل واقعاً ارزشش را دارد؟
اگر به دنبال مالکیت دادهها، نامهای مستعار نامحدود و کنترل کامل هستید، بله؛ mailcow یک پشته حرفهای را با هزینه یک VPS در اختیار شما میگذارد. اما قابلیت تحویل ایمیل (deliverability) یک وظیفه دائمی است: اعتبار IP، همراستایی DNS و نظارت بر لیستهای سیاه هرگز بهطور کامل پایان نمییابند. برای یک آدرس ایمیل حیاتی کسبوکار که حتی یک روز قرار گرفتن در پوشه اسپم دیگران برایتان هزینه دارد، استفاده از یک سرویسدهنده مدیریتشده انتخاب منطقیتری است. زمانی سراغ میزبانی شخصی بروید که کنترل را به راحتی ترجیح میدهید و واقعاً برای نگهداری آن وقت میگذارید. اگر هدف اصلی شما خارج کردن دادهها از سرورهای دیگران است و نه لزوماً ایمیل، با سرویسی شروع کنید که کسی در آن دخیل نیست: یک کتابخانه عکس هیچ مشکل تحویل ایمیلی ندارد و مقایسه ما بین PhotoPrism و Immich حداقل رم مورد نیاز و دستورات پشتیبانگیری برای آن را روی همان نوع VPS بررسی کرده است.
چگونه بفهمم پورت خروجی 25 مسدود است؟
دستور nc -vz -w 5 gmail-smtp-in.l.google.com 25 را از روی سرور اجرا کنید. عبارت "succeeded!" به معنای باز بودن پورت است؛ یک timed out پس از مکث، نشاندهنده مسدود بودن پورت است و اگر هیچ قانون فایروال خروجی روی سرور خود ندارید، این محدودیت از سمت سرویسدهنده شماست. این رایجترین دلیل برای این است که یک سرور شخصی میتواند ایمیل دریافت کند اما هرگز نمیتواند ارسال کند، و تنها راه حل برای مسدودسازی توسط سرویسدهنده، باز کردن پورت توسط آنهاست و هیچ تنظیمات محلی آن را تغییر نمیدهد.
چرا ایمیلهای من همچنان در پوشه اسپم Gmail قرار میگیرند؟
تقریباً همیشه به دلیل زنجیره احراز هویت ناقص است. در Gmail گزینه "Show original" را بزنید و به دنبال spf=pass، dkim=pass و dmarc=pass بگردید. یک dkim=fail نشاندهنده یک رکورد TXT از نوع dkim._domainkey مفقود یا ناقص است؛ عدم تطابق PTR یا یک IP جدید بدون سابقه ارسال نیز به اعتبار شما لطمه میزند. ابتدا امتیاز mail-tester.com را به 10/10 برسانید، سپس IP را بهآرامی گرم کنید؛ یعنی بهجای ارسال حجم زیاد در روز اول، روزانه چند پیام بفرستید و بهتدریج آن را افزایش دهید.
دقیقاً از چه چیزی باید پشتیبان بگیرم؟
دستور backup_and_restore.sh backup all را اجرا کنید و کل مجموعه را خارج از سرور نگهداری کنید. این دستور vmail (صندوقهای پستی)، crypt (کلیدهایی که آنها را رمزگشایی میکنند)، دیتابیس MariaDB (دامنهها، کاربران، نامهای مستعار، تنظیمات)، Redis، دادههای یادگیریشده Rspamd و صف Postfix را ضبط میکند. حجم crypt همان چیزی است که افراد نادیده میگیرند؛ بدون آن، پشتیبان vmail فقط متن رمزنگاریشده غیرقابل خواندن است. حداقل یک بار بازیابی را روی یک سرور آزمایشی تست کنید.
آیا میتوانم mailcow را روی یک VPS با 2 گیگابایت رم اجرا کنم؟
بهراحتی خیر. generate_config.sh پیشنهاد میدهد که ClamAV را در رمهای زیر 2.5 گیگابایت غیرفعال کنید، و حتی با خاموش بودن ClamAV، سرویسهای Rspamd، Dovecot، MariaDB و بقیه پشته برای حافظه با هم رقابت میکنند؛ بنابراین تحت هر بار کاری واقعی، با مشکل swap و OOM kills مواجه خواهید شد. برای یک نصب پایدار تککاربره، 6 گیگابایت رم به همراه 1 گیگابایت swap را حداقل در نظر بگیرید و به محض اینکه بیش از چند نفر به آن وابسته شدند، به 8 گیگابایت ارتقا دهید.