سایت بعد از تغییر DNS بالا نمیآید یا با www باز نمیشود؟ راهنمای کامل انتشار DNS
دامنه را به هاست جدید وصل کردهاید و حالا example.com باز میشود اما www.example.com خطا میدهد؛ یا خودتان هنوز سایت قدیمی را میبینید و مشتری میگوید سایت جدید بالا آمده است. این وضعیت بعد از هر تغییر DNS طبیعی است، ولی «صبر کن خودش درست میشود» همیشه جواب درستی نیست. بخشی از این خطاها با گذشت زمان و منقضیشدن کش برطرف میشوند و بخش دیگری یک رکورد جاافتاده یا یک تنظیم اشتباه است که تا دستی اصلاحش نکنید، هیچوقت خودبهخود درست نمیشود. در ادامه کل چرخه را به همان ترتیبی که در عمل انجام میدهید مرور میکنیم: قبل از سوییچ چطور سایت را روی سرور جدید تست کنید، بعد از سوییچ چطور بفهمید DNS واقعاً چه میگوید، و در پایان چطور یکبار برای همیشه تکلیف www را روشن کنید.
وقتی DNS را عوض میکنید دقیقاً چه اتفاقی میافتد
مرورگر شما مستقیم از نیمسرور (Nameserver) دامنه سؤال نمیکند. اول کش سیستمعامل بررسی میشود، بعد سراغ resolver مربوط به سرویس اینترنت شما یا یک resolver عمومی مثل 8.8.8.8 میرود. آن resolver اگر جواب این دامنه را از قبل در حافظه داشته باشد، همان جواب قدیمی را تحویل میدهد و اصلاً به نیمسرور شما سر نمیزند. مدت زمانی که هر رکورد اجازه دارد در این حافظهها بماند، همان TTL است که برحسب ثانیه در کنار رکورد ذخیره میشود.
نتیجهاش این است که بلافاصله بعد از تغییر، دنیا دو دسته میشود: کسانی که تازه اولین بار سراغ دامنه میآیند و IP جدید را میگیرند، و کسانی که resolverشان هنوز جواب قدیمی را نگه داشته است. تا وقتی TTL قدیمی تمام نشده، دستهٔ دوم سایت قبلی را میبینند و هیچ کاری از سمت شما این را عوض نمیکند.
دو نوع تغییر، دو زمانبندی متفاوت
- تغییر نیمسرور نزد ثبتکنندهٔ دامنه: این تغییر در سطح رجیستری دامنه ثبت میشود و TTL آن در اختیار شما نیست. معمولاً چند ساعت تا ۴۸ ساعت طول میکشد تا همهجا اعمال شود.
- تغییر رکورد داخل زون (مثلاً بردن رکورد A روی IP جدید): اینجا TTL همان رکورد تعیینکننده است. اگر TTL روی ۳۰۰ ثانیه باشد، ظرف چند دقیقه تمام میشود.
عدد معروف «۲۴ تا ۴۸ ساعت» یک قاعدهٔ سرانگشتی است، نه یک قانون. بعضی شبکهها TTL را رعایت نمیکنند و جواب را بیشتر از مقدار اعلامشده نگه میدارند، و در مقابل خیلی وقتها انتقال ظرف کمتر از یک ساعت کامل میشود.
نکتهٔ مهمی که معمولاً گفته نمیشود: اگر بیش از ۴۸ ساعت گذشته و هنوز آدرس با www بالا نمیآید، ماجرا دیگر ربطی به کش ندارد. آن موقع تقریباً همیشه یا رکورد www روی نیمسرورهای جدید ساخته نشده، یا وبسرور آن نام را نمیشناسد. در بخشهای بعد هر دو را دقیق بررسی میکنیم.
قبل از انتقال: TTL را پایین بیاورید
سادهترین کاری که کل دردسر انتشار را کوتاه میکند این است که ۲۴ تا ۴۸ ساعت قبل از انتقال، TTL رکوردهای مهم زون (A، www، MX) را روی ۳۰۰ ثانیه بگذارید. دلیل اینکه باید زودتر انجام شود این است که خود این تغییر هم تابع TTL قبلی است؛ اگر TTL فعلی ۸۶۴۰۰ باشد، مقدار جدید تا یک شبانهروز بعد در همهجا شناخته نمیشود.
بعد از اینکه انتقال پایدار شد، TTL را به مقدار عادی (مثلاً ۳۶۰۰) برگردانید؛ TTL خیلی پایین بهصورت دائمی فقط تعداد کوئریها را بیدلیل بالا میبرد.
اگر قرار است نیمسرور را عوض کنید، پایینآوردن TTL روی زون قدیمی کمک چندانی نمیکند. در این حالت مهمتر این است که پیش از سوییچ، زون کامل و درست را روی نیمسرور جدید بسازید تا هر resolverی که زودتر به آنجا رسید، جواب صحیح بگیرد.
پیشنمایش سایت روی سرور جدید، قبل از تغییر DNS
قبل از اینکه DNS را جابهجا کنید باید مطمئن شوید سایت روی هاست جدید واقعاً کار میکند. روش قدیمی این کار mod_userdir بود که اجازه میداد سایت را با آدرسی شبیه server-ip/~username ببینید. این قابلیت به دلیل مشکلات امنیتی روی بیشتر سرورهای اشتراکی غیرفعال شده است و حتی اگر فعال باشد، برای سایتهای CMS به درد نمیخورد؛ چون وردپرس و مشابه آن مسیر فایلهای css، تصاویر و لینکها را بر اساس دامنهٔ ثبتشده در تنظیماتشان میسازند و صفحه بههمریخته بالا میآید.
روش درست و همیشهکار، تغییر فایل hosts روی کامپیوتر خودتان است. با این کار فقط سیستم شما دامنه را به IP سرور جدید میفرستد و بقیهٔ دنیا همچنان سایت قدیمی را میبینند. یعنی میتوانید سایت را روی هاست جدید کامل تست کنید و بعد DNS را عوض کنید.
در ویندوز
- Notepad را با راستکلیک و «Run as administrator» باز کنید. بدون دسترسی مدیر، فایل ذخیره نمیشود.
- از منوی File مسیر زیر را باز کنید (در کادر نام فایل، حالت را روی All Files بگذارید):
C:WindowsSystem32driversetchosts
- در انتهای فایل، IP سرور جدید و دامنه را اضافه کنید. حتماً هم دامنهٔ اصلی و هم نسخهٔ www را بنویسید، وگرنه فقط یکی از آنها تست میشود:
203.0.113.10 example.com www.example.com
- ذخیره کنید و کش DNS ویندوز را خالی کنید:
ipconfig /flushdns
در لینوکس و مک
sudo nano /etc/hosts
همان خط را اضافه و ذخیره کنید. در مک بعد از ذخیره، کش را هم خالی کنید:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
بهجای 203.0.113.10 آیپی سرور جدید و بهجای example.com دامنهٔ خودتان را بگذارید. آیپی هاست را از ناحیهٔ کاربری یا از ایمیل اطلاعات سرویس میگیرید.
دو نکته هنگام تست
- مرورگرها کش DNS جداگانه دارند. اگر تغییر را ندیدید، مرورگر را کامل ببندید و دوباره باز کنید یا از پنجرهٔ ناشناس استفاده کنید.
- در این مرحله معمولاً گواهی SSL دامنه هنوز روی سرور جدید صادر نشده، پس مرورگر هشدار امنیتی میدهد. این طبیعی است. صدور گواهی رایگان با اعتبارسنجی HTTP تا وقتی دامنه واقعاً به سرور جدید اشاره نکند انجام نمیشود؛ آن را برای بعد از سوییچ بگذارید.
بعد از اتمام تست، خط را پاک کنید
حتماً همان خط را از فایل hosts حذف کنید. اگر یادتان برود، بعد از تغییر واقعی DNS هم سیستم شما بهجای مسیر درست سراغ همان IP ثابت میرود و ممکن است ساعتها دنبال مشکلی بگردید که اصلاً وجود ندارد. این یکی از رایجترین دلایل تیکتهای «سایت برای من بالا نمیآید ولی برای بقیه میآید» است.
بعد از سوییچ: ببینید DNS واقعاً چه جوابی میدهد
بهجای حدس زدن، مستقیم از resolver بپرسید. روی لینوکس و مک:
dig example.com A +short dig www.example.com A +short dig example.com NS +short
برای اینکه ببینید یک resolver عمومی چه جوابی میدهد (یعنی خارج از شبکهٔ خودتان وضع چطور است):
dig @8.8.8.8 www.example.com A +short dig @1.1.1.1 www.example.com A +short
و برای اینکه کش را کامل دور بزنید و ببینید نیمسرورهای خود دامنه چه میگویند:
dig +trace example.com
اگر dig را بدون +short اجرا کنید، در بخش ANSWER کنار هر رکورد یک عدد میبینید؛ آن عدد TTL باقیمانده به ثانیه است و دقیقاً میگوید چقدر دیگر باید صبر کنید تا این resolver جواب را دور بریزد.
روی ویندوز dig بهصورت پیشفرض نصب نیست؛ معادلها:
nslookup www.example.com nslookup www.example.com 8.8.8.8
یا در PowerShell:
Resolve-DnsName www.example.com -Server 8.8.8.8
برای دیدن وضعیت انتشار در نقاط مختلف دنیا هم ابزارهای آنلاین بررسی propagation مثل whatsmydns.net یا dnschecker.org کار را راه میاندازند؛ همان دامنه را وارد میکنید و میبینید کدام resolverها IP جدید و کدام هنوز IP قدیمی را برمیگردانند.
جواب را چطور بخوانیم
- IP قدیمی برمیگردد: مشکل کش و TTL است. کاری جز صبر کردن (و خالی کردن کش محلی خودتان) ندارید.
- جواب NXDOMAIN یا پیام
server can't findاست: یعنی این نام روی نیمسرورهای فعلی اصلاً وجود ندارد. اول باdig +traceیا با پرسیدن مستقیم از نیمسرور جدید مطمئن شوید رکورد واقعاً ساخته نشده؛ اگر رکورد را همین الان ساختهاید، جواب منفی قبلی هم برای مدت کوتاهی کش میشود. اگر رکورد نبود، باید بسازیدش — این با صبر کردن حل نمیشود. - IP جدید برمیگردد ولی سایت باز نمیشود: DNS کارش را کرده و مشکل سمت وبسرور، گواهی SSL یا تنظیمات خود سایت است.
چرا سایت بدون www باز میشود ولی با www نه
این پرتکرارترین حالت بعد از انتقال است و دو ریشهٔ کاملاً متفاوت دارد.
ریشهٔ اول، کش: resolver سرویسدهندهٔ اینترنت شما نام www.example.com را جداگانه کش میکند. کاملاً ممکن است TTL رکورد ریشه تمام شده باشد ولی رکورد www هنوز از حافظه پاک نشده باشد. در این حالت دامنه بدون www به سرور جدید میرود و با www هنوز روی مسیر قدیمی است. این خودش با گذشت زمان درست میشود.
ریشهٔ دوم، نبودن رکورد: وقتی زون را روی نیمسرور جدید میسازید، ممکن است فقط رکورد دامنهٔ اصلی ساخته شود و www جا بماند. آنوقت سایت بدون www بالا میآید و با www تا ابد خطای «آدرس پیدا نشد» میدهد. برای تشخیص، خروجی dig www.example.com را نگاه کنید؛ اگر خالی یا NXDOMAIN بود، مسئله همین است.
رکورد درست چه شکلی است
- دامنهٔ اصلی (
example.com) باید رکورد A با IP سرور باشد. طبق استاندارد، روی ریشهٔ دامنه نمیتوان CNAME گذاشت؛ بعضی ارائهدهندههای DNS برای این کار نوع اختصاصی ALIAS یا ANAME دارند. wwwمیتواند یا رکورد A با همان IP باشد، یا رکورد CNAME بهexample.com. هر دو درست است؛ مزیت CNAME این است که با تعویض بعدی IP، فقط یک رکورد را عوض میکنید.- هر دو باید به یک سرور برسند. با
digهر دو را بگیرید و IP خروجی را با هم مقایسه کنید.
اگر DNS درست است ولی www همچنان مشکل دارد
- وبسرور نام www را نمیشناسد: در Apache این نام باید در
ServerAliasو در Nginx درserver_nameآمده باشد. کنترلپنلهای هاست این کار را خودکار انجام میدهند، اما اگر دامنه دستی روی سرور اضافه شده باشد ممکن است جا افتاده باشد. نشانهاش این است که با www بهجای سایت شما، صفحهٔ پیشفرض سرور یا سایت دیگری بالا میآید. - گواهی SSL فقط یک نام را پوشش میدهد: اگر گواهی برای
example.comصادر شده وwww.example.comدر آن نیست، با www خطای گواهی میگیرید. هنگام صدور، هر دو نام را انتخاب کنید.
خالی کردن کش محلی
قبل از اینکه نتیجه بگیرید مشکل از سرور است، کش سمت خودتان را پاک کنید:
- ویندوز:
ipconfig /flushdns - مک:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder - لینوکس با systemd-resolved:
sudo resolvectl flush-caches(روی نسخههای قدیمیترsudo systemd-resolve --flush-caches) - لینوکس با nscd: در راهنماهای قدیمی
service nscd restartیا/etc/init.d/nscd restartنوشته شده؛ روی توزیعهای امروزی شکل درستsudo systemctl restart nscdاست. توجه کنید nscd روی بیشتر توزیعهای امروزی اصلاً نصب نیست و اگر نصب نباشد این دستور خطا میدهد — در آن حالت کش DNSی هم وجود ندارد که پاک شود.
مرورگرها هم کش جدا دارند. در کروم آدرس chrome://net-internals/#dns و گزینهٔ Clear host cache، و در فایرفاکس about:networking#dns و گزینهٔ Clear DNS Cache این کار را انجام میدهند. سادهترین راه هم بستن کامل مرورگر یا استفاده از پنجرهٔ ناشناس است.
یک آدرس را انتخاب کنید: با www یا بدون www
وقتی هر دو نسخه به سرور میرسند، سایت شما عملاً روی دو آدرس در دسترس است و این از نظر سئو مطلوب نیست. یکی را بهعنوان آدرس اصلی انتخاب کنید و دیگری را با ریدایرکت دائمی ۳۰۱ به آن بفرستید. کدام؟ تفاوت فنی مهمی ندارد؛ همانی را نگه دارید که لینکهای موجود و نتایج گوگل به آن اشاره میکنند.
ریدایرکت ۳۰۱ در htaccess
قبل از دستزدن به .htaccess یک نسخهٔ پشتیبان از فایل فعلی بگیرید. یک خطای نگارشی در این فایل کل سایت را با خطای ۵۰۰ از کار میاندازد و اگر نسخهٔ سالم را نداشته باشید، برگرداندن اوضاع وقت میبرد.
برای هدایت به نسخهٔ www، این را در ابتدای فایل .htaccess در ریشهٔ سایت بگذارید:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
و برای هدایت به نسخهٔ بدون www:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.example.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
چند نکته که نداشتنشان معمولاً باعث دردسر میشود:
- فقط یکی از این دو بلوک را بگذارید. اگر هر دو با هم باشند، مرورگر بین دو آدرس گیر میکند و خطای حلقهٔ ریدایرکت میگیرید.
- در نمونههای قدیمی مقصد با
http://نوشته شده است. اگر سایت SSL دارد، حتماًhttps://بنویسید؛ وگرنه هر بازدید یک پرش اضافی از https به http و دوباره به https میخورد و در کنار افزونههای «انتقال به https» به حلقه میرسد. - نقطه در نام دامنه باید با بکاسلش escape شود (
example.com)، وگرنه الگو دامنههای مشابه را هم میگیرد. - در وردپرس این بلوک را بالای بخش
# BEGIN WordPressبگذارید. هر چیزی داخل آن بخش با ذخیرهٔ دوبارهٔ تنظیمات پیوند یکتا بازنویسی میشود. - هنگام تست اول
R=302بگذارید و بعد از اطمینان بهR=301تغییر دهید. ریدایرکت ۳۰۱ در مرورگر کش میشود و اگر اشتباه بنویسید، اصلاح آن روی سیستم خودتان دردسر دارد. - اگر سرور Nginx است، فایل
.htaccessاصلاً خوانده نمیشود و باید در کانفیگ سرور انجام شود؛ شکل کار یک server block جدا برای نام اضافی است (بقیهٔ تنظیمات مثلlistenو گواهی SSL باید مطابق کانفیگ فعلی خودتان تکمیل شود):server { server_name www.example.com; return 301 https://example.com$request_uri; }بعد از هر تغییر، اول با
sudo nginx -tصحت کانفیگ را بررسی کنید و تنها در صورت تأیید باsudo systemctl reload nginxاعمالش کنید. LiteSpeed برخلاف Nginx فایل htaccess را میخواند و همان قواعد Apache روی آن کار میکند.
هشدار مهم برای وردپرس و سایر CMSها
سیستمهای مدیریت محتوا آدرس اصلی سایت را در تنظیمات خودشان نگه میدارند و مستقل از htaccess بازدیدکننده را به آن آدرس میفرستند. اگر htaccess به www ببرد ولی وردپرس آدرس بدون www را ذخیره کرده باشد، دو ریدایرکت مخالف هم به جان هم میافتند و سایت با خطای حلقه از کار میافتد.
پس هر تصمیمی گرفتید، در «تنظیمات ← همگانی» وردپرس هم همان را در دو فیلد WordPress Address و Site Address بنویسید. اگر به پیشخوان دسترسی ندارید (که در حالت حلقه معمولاً همینطور است) میتوانید موقتاً در wp-config.php این دو خط را بالای خط /* That's all, stop editing! */ اضافه کنید:
define('WP_HOME','https://example.com');
define('WP_SITEURL','https://example.com');
با این کار مقدار قفل میشود و همان فیلدها در پیشخوان غیرقابل ویرایش میشوند. بعد از اینکه سایت بالا آمد، مقدار درست را از خود پیشخوان (یا در دیتابیس) اصلاح کنید و این خطوط را بردارید.
توجه کنید که عوض کردن این دو فیلد، آدرسهای داخل مطالب و مسیر تصاویر را اصلاح نمیکند. برای آنها باید روی دیتابیس جستوجو و جایگزینی انجام دهید؛ با WP-CLI به این شکل و حتماً بعد از تهیهٔ نسخهٔ پشتیبان کامل از دیتابیس:
wp db export backup-before-replace.sql wp search-replace 'http://www.example.com' 'https://example.com' --dry-run
اول با --dry-run ببینید چند مورد تغییر میکند، بعد همان دستور را بدون --dry-run اجرا کنید. این تغییر روی دیتابیس برگشتپذیر نیست و تنها راه بازگشت، همان فایل پشتیبان است. در جوملا هم مقدار $live_site در فایل configuration.php را بررسی کنید؛ این مقدار معمولاً خالی است و اگر پر شده باشد باید دقیقاً با آدرس نهایی یکی باشد. سایر CMSها هم تنظیم معادلی دارند.
چند نکته برای روزهای اول بعد از انتقال
- هاست قدیمی را بلافاصله حذف یا لغو نکنید. تا وقتی کشها منقضی نشدهاند، بخشی از بازدیدکنندگان هنوز به سرور قدیمی میرسند. چند روز نگهداشتن آن هزینهٔ کمی دارد و جلوی از دست رفتن اطلاعات را میگیرد.
- اگر نیمسرور را عوض کردهاید، رکوردهای MX هم با آن جابهجا میشوند. قبل از سوییچ، رکوردهای MX فعلی را یادداشت کنید و عیناً روی زون جدید بسازید؛ وگرنه ایمیل دامنه بعد از انتقال قطع میشود. در بازهٔ انتشار هم ایمیلهای ورودی ممکن است روی هر دو سرور بنشیند؛ صندوق قدیمی را چند روز چک کنید.
- در تمام مدت، ملاک قضاوت شما باید خروجی
digباشد نه چیزی که در مرورگر خودتان میبینید. مرورگر شما لایههای کش زیادی دارد و بدترین ابزار ممکن برای عیبیابی DNS است.
چکلیست عیبیابی
- سایت بدون www باز میشود، با www خطای «آدرس پیدا نشد» میدهد و
dig www.example.comخالی برمیگردد ← رکورد www روی نیمسرور جدید ساخته نشده است. - هر دو باز میشوند ولی www سایت قدیمی را نشان میدهد ← کش resolver؛ TTL را با
digببینید و صبر کنید. - هر دو به IP جدید اشاره میکنند ولی با www صفحهٔ دیگری بالا میآید ← نام www به vhost سایت اضافه نشده است.
- با www خطای گواهی میگیرید ← گواهی SSL شامل نام www نیست، باید دوباره برای هر دو نام صادر شود.
- سایت با خطای حلقهٔ ریدایرکت از کار افتاده ← قواعد htaccess با آدرس ذخیرهشده در CMS در تضادند.
- فقط برای شما سایت قدیمی بالا میآید و برای بقیه جدید ← خط تست را از فایل hosts پاک نکردهاید.
- همهچیز درست است اما تغییر را نمیبینید ← کش DNS سیستم و مرورگر را خالی کنید و با پنجرهٔ ناشناس امتحان کنید.
جمعبندی عملی: قبل از سوییچ TTL را کم کنید و سایت را با فایل hosts تست کنید، بعد از سوییچ بهجای حدس زدن با dig جواب واقعی را بگیرید، و در پایان با یک ریدایرکت ۳۰۱ درست و هماهنگ با تنظیمات CMS، تکلیف www را برای همیشه روشن کنید.
