پژمان مقدم
پژمان مقدم
خواندن ۸ دقیقه·۳ سال پیش

چرا در DNS ، نمی‌توان ریشهٔ یک دامنه را CNAME کرد؟

Using CNAME Record for Domain apex
Using CNAME Record for Domain apex


قبل از جواب دادن به این سوال، باید CNAME را دقیق‌تر بشناسیم. با یک مثال در زیردامنه (sub-domain) آغاز میکنیم و در پایان موضوع را به ریشه‌ٔ دامنه بسط میدهیم.

فرض کنید شرکتِ example ، صاحبِ دامنهٔ example.com ، دو name server با IP های 192.168.1.11 به عنوان master و 192.168.1.12 به عنوان slave ، دارد. (در این مقاله صرفاً به تنظیماتِ master خواهیم پرداخت).
این شرکت، یک web server با آدرس 192.168.1.20 و یک mail server با آدرس 192.168.1.30 نیز در اختیار دارد. در سرورِ master ، فایلِ مربوط به zone ِ دامنهٔ example.com با نام example.com.zone ساخته شده و چنین محتوایی خواهد داشت:

$TTL 1D $ORIGIN example.com. @ SOA ns1 hostmaster ( 2021101201 ;serial 1H ;refresh 10M ;retry 1W ;expiry 3H ;minimum ) NS ns1 NS ns2 MX 10 mail ns1 A 192.168.1.11 ns2 A 192.168.1.12 www A 192.168.1.20 @ A 192.168.1.20 mail A 192.168.1.30

همانطور که مشاهده میکنید، هم www.example.com و هم example.com ، به کمکِ @ ، به آدرس 192.168.1.20 ترجمه شده اند، تا اگر کسی www را هم ننوشت، باز به سمت web server راهی شود. در نمونهٔ فوق، اگر کسی بخواهد یک ایمیل به آدرس info@example.com ارسال کند به این شکل باید آدرس mail server را پیدا کند (پاسخِ سرور مختصر شده است) :

$ dig example.com MX ... ;; ANSWER SECTION: example.com. 86400 IN MX 10 mail.example.com. ;; ADDITIONAL SECTION: mail.example.com. 86400 IN A 192.168.1.30 ...

در ادامه فرض کنید این شرکت یک نمایندگی در شهرِ دیگری تأسیس میکند و زیردامنهٔ city.example.com را به آن اختصاص میدهد. در شهرِ مذکور یک web server با آدرس 172.16.1.20 و یک mail server با آدرس 172.16.1.30 راه اندازی میشود و رکورد های زیر به فایل example.com.zone اضافه می شوند:

city A 172.16.1.20 city MX 10 mail.city mail.city A 172.16.1.30

با کمک رکورد های فوق ، هر کسی برای رسیدن به صفحهٔ وبِ نمایندگی می تواند از آدرس city.example.com استفاده کند و همینطور، آدرس ایمیل نمایندگی info@city.example.com خواهد بود. برای به دست آوردن آدرس mail server نمایندگی (به طور مختصر) :

$ dig city.example.com MX ... ;; ANSWER SECTION: city.example.com. 86400 IN MX 10 mail.city.example.com. ;; ADDITIONAL SECTION: mail.city.example.com. 86400 IN A 172.16.1.30 ...

تا اینجا مشکلی نیست. بعد از مدتی، نمایندگی تصمیم میگیرد از یک سرویس CDN برای افزایشِ سرعتِ دسترسی به سرویس وب، استفاده کند و در خواست دارد که city.example.com به آدرس cloud.cdnprovider.com که مربوط به شرکت دیگری است که سرویس CDN ارائه میکند، CNAME شود. دلیل درخواستِ CNAME هم این است که اگر روزی IP ِسرویسِ cloud.cdnprovider.com تغییر کرد مجبور به آپدیتِ رکوردِ DNS نباشیم. در ادامه میبینید که امکان ساختن CNAME در کنار رکورد های دیگر مثل MX و A و TXT و ... وجود ندارد.

آیا می‌توان برای زیردامنهٔ city.example.com یک رکوردِ CNAME ساخت ، بدون آنکه مشکلی برای MX رکورداَش ایجاد شود؟ خیر.

ببینیم اگر CNAME ِ مذکور را بسازیم،‌با چه errorی مواجه می‌شویم:

city CNAME cloud.cdnprovider.com. city MX 10 mail.city mail.city A 172.16.1.30

و حالا بررسی صحتِ zone file :

$ named-checkzone example.com example.com.zone dns_master_load: example.com.zone:20: city.example.com: CNAME and other data zone example.com/IN: loading from master file example.com.zone failed: CNAME and other data zone example.com/IN: not loaded due to errors.

متاسفانه پیغام CNAME and other data واضح نیست و کمکی به حل مشکل نمی‌کند. برای روشن شدن موضوع، توجه تان رابه بخش 2.4 از RFC 1912 با عنوان Common DNS Operational and Configuration Errors جلب میکنم ( البته در متن اصلی اشتباها suzy.podunk.edu نوشته شده، که اصلاح کردم) :

A CNAME record is not allowed to coexist with any other data. In other words, if suzy.podunk.xx is an alias for sue.podunk.xx, you can't also have an MX record for suzy.podunk.xx, or an A record, or even a TXT record.

پس براساس توضیح فوق، CNAME به همراه رکورد های دیگر قابل استفاده نیست (به جز چند استثنا که خارج از بحث حاضر است). در مثالی که پی گیری میکنیم، با حذف MX رکورد، ( با کمک ; ) امکان ست کردن CNAME ایجاد میشود:

city CNAME cloud.cdnprovider.com. ;city MX 10 mail.city mail.city A 172.16.1.30

بررسی صحت zone file :

$ named-checkzone example.com example.com.zone zone example.com/IN: loaded serial 2021101201 OK

ببینیم بعد از load کردن zone file فوق، سرور به query های مختلفِ مربوط به city.example.com چگونه جواب میدهد:

$ rndc reload server reload successful $ dig city.example.com ... ;; ANSWER SECTION: city.example.com. 86400 IN CNAME cloud.cdnprovider.com. ... $ dig city.example.com MX ... ;; ANSWER SECTION: city.example.com. 86400 IN CNAME cloud.cdnprovider.com. ... $ dig city.example.com TXT ... ;; ANSWER SECTION: city.example.com. 86400 IN CNAME cloud.cdnprovider.com. ...

همانطور که میبینید در جوابِ همهٔ query های A و MX و TXT و ... تنها جواب، CNAME خواهد بود.

در واقع CNAME جایگزین همه رکورد های دیگر (به جز چند استثنأ) می شود.

حالا که با مشخصهٔ اصلیِ CNAME آشنا شدیم، وقت آن رسیده به سوال اصلی بپردازیم:

در مثال فوق، آیا "عملا" امکان تعریف CNAME برای example.com وجو دارد؟ خیر.

توجه کنید که روی کلمه "عملا" تاکید کردم. بعدا با تغییر این کلمه جواب را تغییر خواهم داد.

فعلاً برای روشن شدن موضوع، به بخش 6.1 از RFC 2181 با عنوان Clarifications to the DNS Specification توجه بفرمایید:

The authoritative servers for a zone are enumerated in the NS records for the origin of the zone, which, along with a Start of Authority (SOA) record are the mandatory records in every zone.

بر اساس توضیح فوق، وجود NS و SOA رکورد در هر zone file اجباری است. با در نظر داشتنِ اینکه CNAME به همراهِ رکورد های دیگر قابل استفاده نیست، پس اگر تعریف CNAME برای example.com ممکن بود، باعثِ از بین رفتن NS و SOA رکورد های example.com میشد، که وجودشان اجباری است.

توجه کنید که در توضیح فوق از مفهوم zone file استفاده کردم نه ریشهٔ دامنه. برای عمیق تر بررسی کردن موضوع، به این سوال بپردازیم:

آیا ممکن است در شرایطی قرار بگیریم که ساختن CNAME برای city.example.com هم ( مانند example.com ) غیر ممکن باشد؟ بله.

در مثالی که پی گیری می کردیم، اگر نماینگیِ شرکت تصمیم بگیرد که DNS سرورِ خود را راه اندازی کند و بخواهد که city.example.com به سرورِ ایشان delegate شود، مجبور خواهد بود در سرورِ خود، zone file ِمربوط به city.example.com را بسازد و اجباراً باید NS و SOA رکورد های این زیردامنه را هم داشته باشد. در این وضعیت ساختن یک CNAME برای city.example.com غیر ممکن میشود، چون داشتنِ چنین CNAMEی مستلزمِ از بین رفتن NS و SOA رکوردِ این زیردامنه خواهد بود.

حال سوال اصلی را دوباره بررسی کنیم:

آیا "در تئوری" امکان تعریف CNAME برای example.com وجود دارد؟

جواب:

در سروری که example.com به آن delegate شده : نه. چون NS و SOA رکورد دامنه example.com از بین میرود.

در سرور های یک لایه بالاتر، یعنی سرور های com. : بله. چون آنجا NS و SOA رکوردِ com. اجباری است نه example.com

چرا گفتم "تئوری" ؟ چون عملاً سرور های top level وظایف مهمتری دارند و از این کارها انجام نمیدهند.




dnsbind
شاید از این پست‌ها خوشتان بیاید