จะเอาชนะข้อ จำกัด CNAME ของโดเมนรากได้อย่างไร


117

เรากำลังโฮสต์เว็บแอปพลิเคชันมากมายสำหรับลูกค้าของเรา เห็นได้ชัดว่าพวกเขาต้องการใช้โดเมนของตัวเองเพื่ออ้างถึงแอปพลิเคชันเหล่านั้นโดยปกติแล้วพวกเขาต้องการให้ผู้ใช้ทุกคนพิมพ์http://www.customer1.exampleหรือhttp://customer1.exampleไปที่เว็บแอปพลิเคชันของตน

สถานการณ์ที่เรากำลังเผชิญคือเราจำเป็นต้องมีความยืดหยุ่นในการเปลี่ยนที่อยู่ IP ในอนาคตอันใกล้นี้ และเราไม่ต้องการพึ่งพาลูกค้าที่ทำการเปลี่ยนแปลงบันทึกในโดเมนของพวกเขา ดังนั้นเราจึงคิดว่าการใช้CNAMEระเบียนจะได้ผล แต่เมื่อเราพบว่าCNAMEระเบียนจะใช้ไม่ได้กับโดเมนราก

โดยทั่วไป:

customer1.example IN CNAME customer1.mycompanydomain.example //this is invalid as the RFC
www.customer1.example IN CNAME customer1.mycompanydomain.example //this is valid and will work

เราต้องการที่จะสามารถเปลี่ยนที่อยู่ IP customer1.mycompanydomain.exampleหรือAบันทึกและลูกค้าของเราจะปฏิบัติตามบันทึกนี้ซึ่งเราสามารถควบคุมได้

ใน DNS ของเราจะมีลักษณะดังนี้:

customer1.mycompanydomain.example IN A 192.0.2.1

ความคิดใด ๆ ?


ฉันไม่เข้าใจว่าเหตุใด "customer1.com ใน CNAME customer1.mycompanydomain.com" จึงไม่ถูกต้อง ฉันเชื่อว่ามันควรจะได้ผล คุณช่วยอธิบายได้ไหมว่าปัญหาของโซลูชันนั้นอยู่ที่ใด
sleske

3
ใช่โปรดอ่านคำถามและคำตอบต่อไปนี้ ไม่ถูกต้องตาม DNS RFC stackoverflow.com/questions/655235/…
Geo

2
ฉันไม่เข้าใจชื่อคำถาม "ราก" (.) เกี่ยวข้องตรงไหน?
bortzmeyer

2
เขาหมายถึงรากของโซนไม่ใช่ "ราก"
Alnitak

2
มันไม่ใช่คำศัพท์ DNS ปกติแล้ว "เอเพ็กซ์" เป็นคำที่เหมาะสมไม่ใช่หรือ? หรือ "ระดับบนสุด" สำหรับโปรแกรมเมอร์ Lisp? :-)
bortzmeyer

คำตอบ:


63

สาเหตุที่คำถามนี้ยังคงเกิดขึ้นบ่อยครั้งเป็นเพราะอย่างที่คุณพูดถึงมีบางคนสันนิษฐานว่าสำคัญเขียนว่า RFC ระบุชื่อโดเมนที่ไม่มีโดเมนย่อยไว้ข้างหน้าไม่ถูกต้อง อย่างไรก็ตามหากคุณอ่าน RFC อย่างระมัดระวังคุณจะพบว่านี่ไม่ใช่สิ่งที่กล่าวไว้อย่างแน่นอน ในความเป็นจริงRFC 1912ระบุ:

อย่าลงน้ำด้วย CNAME ใช้เมื่อเปลี่ยนชื่อโฮสต์ แต่วางแผนที่จะกำจัดพวกมัน (และแจ้งให้ผู้ใช้ของคุณทราบ)

โฮสต์ DNS บางตัวมีวิธีรับฟังก์ชันคล้าย CNAME ที่โซนเอเพ็กซ์ (ระดับโดเมนรากสำหรับชื่อโดเมนเปล่า) โดยใช้ประเภทระเบียนที่กำหนดเอง บันทึกดังกล่าว ได้แก่ :

  • ALIAS ที่ DNSimple
  • ANAME ที่ DNS ทำได้ง่าย
  • ANAME ที่ easyDNS
  • CNAME ที่ CloudFlare

สำหรับผู้ให้บริการแต่ละรายการตั้งค่าจะคล้ายกัน: ชี้รายการ ALIAS หรือ ANAME สำหรับโดเมน apex ของคุณไปที่ example.domain.com เช่นเดียวกับที่คุณทำกับระเบียน CNAME ขึ้นอยู่กับผู้ให้บริการ DNS ค่าว่างหรือ @ ชื่อระบุโซน apex

ALIAS หรือ ANAME หรือ @ example.domain.com

หากผู้ให้บริการ DNS ของคุณไม่รองรับประเภทระเบียนดังกล่าวและคุณไม่สามารถเปลี่ยนไปใช้ประเภทดังกล่าวได้คุณจะต้องใช้การเปลี่ยนเส้นทางโดเมนย่อยซึ่งไม่ยากนักทั้งนี้ขึ้นอยู่กับโปรโตคอลหรือซอฟต์แวร์เซิร์ฟเวอร์ที่ต้องดำเนินการ .

ฉันไม่เห็นด้วยอย่างยิ่งกับข้อความที่ระบุว่าทำโดย "ผู้ดูแลระบบมือสมัครเล่น" หรือแนวคิดดังกล่าวเท่านั้น ง่ายๆคือ "ชื่อและบริการต้องทำอย่างไร" จัดการแล้วปรับการกำหนดค่า DNS ของคุณเพื่อตอบสนองความปรารถนาเหล่านั้น หากบริการหลักของคุณคือเว็บและอีเมลฉันไม่เห็นเหตุผลที่ถูกต้องว่าทำไมการทิ้ง CNAME เพื่อความเป็นประโยชน์จะเป็นปัญหา ท้ายที่สุดใครจะชอบ @ subdomain.domain.org มากกว่า @ domain.org ใครต้องการ "www" ถ้าคุณตั้งค่าด้วยโปรโตคอลเอง เป็นเรื่องที่สมเหตุสมผลที่จะสันนิษฐานว่าการใช้ชื่อโดเมนรากจะไม่ถูกต้อง


1
คำตอบนี้มีประโยชน์มากสำหรับฉันเนื่องจากฉันต้องการชี้โดเมนระดับรากที่ CDN CDN ส่วนใหญ่จำเป็นต้องมี FQDN เนื่องจากสามารถแก้ไขเป็น IP ที่แตกต่างกันในสถานที่หรือเวลาที่ต่างกัน ฉันใช้ DNS Made Easy และสามารถใช้ประเภทระเบียน ANAME ได้
Rubix

3
ฉันไม่เห็นด้วยมากกว่านี้ การต้องการโฮสต์ไซต์จากชื่อโดเมน "เปล่า" เป็นเรื่องธรรมดาและมีเหตุผลที่ต้องทำ มันใช้อักขระน้อยลงดูดีขึ้นเป็นต้นตัวระบุโปรโตคอล (www) ของ url เป็นส่วนร่องรอยของ url หากจำเป็นในตอนแรก (ไม่ใช่)
Ed Bishop

3
ANAME เป็นสิ่งที่ดีหรือคุณสามารถเพียง 301 ทั้งหมดที่ไม่ใช่ www เป็น www ผ่านบริการเปลี่ยนเส้นทาง 301 ฟรี 198.251.86.133
Jacob Evans

51

CNAME 'การบันทึกรูทในทางเทคนิคไม่ได้ต่อต้าน RFC แต่มีข้อ จำกัด ซึ่งหมายความว่าเป็นการปฏิบัติที่ไม่แนะนำ

โดยปกติบันทึกรากของคุณจะมีหลายรายการ พูดว่า 3 สำหรับเนมเซิร์ฟเวอร์ของคุณและอีกอันสำหรับที่อยู่ IP

ต่อ RFC:

หาก CNAME RR อยู่ที่โหนดไม่ควรมีข้อมูลอื่น

และเอกสาร 'Common DNS Operational and Configuration Errors' ตาม IETF:

ผู้ดูแลระบบที่ไม่มีประสบการณ์มักพยายามทำเช่นนี้เป็นวิธีที่ชัดเจนในการอนุญาตให้ชื่อโดเมนของคุณเป็นโฮสต์ อย่างไรก็ตามเซิร์ฟเวอร์ DNS เช่น BIND จะเห็น CNAME และปฏิเสธที่จะเพิ่มทรัพยากรอื่น ๆ สำหรับชื่อนั้น เนื่องจากไม่อนุญาตให้บันทึกอื่น ๆ อยู่ร่วมกับ CNAME รายการ NS จึงถูกละเว้น ดังนั้นโฮสต์ทั้งหมดในโดเมน podunk.xx จึงถูกละเว้นเช่นกัน!

อ้างอิง:


17
แต่ทำไมไม่มีบันทึกอื่นที่อนุญาตให้อยู่ร่วมกับ CNAME นี่เป็นเพียงข้อ จำกัด ที่เพิ่มโดยผู้เขียน RFC หรือมีเหตุผลทางเทคนิคหรือไม่? หากไม่มีเหตุผลทางเทคนิคก็อาจมีส่วนขยาย RFC ได้อย่างง่ายดาย
Sven

ดังนั้นถ้ามันใช้งานได้สำหรับฉัน (ใช้ CNAME สำหรับบันทึกรากโดเมนย่อยอื่น ๆ สำหรับโดเมนนั้นยังคงใช้งานได้) นั่นหมายความว่าฉันโชคดีและการติดตั้ง DNS ของผู้ให้บริการของฉันไม่ได้เพิกเฉยต่อบันทึกเพิ่มเติมที่ควรจะเป็น และยังหมายความว่าฉันไม่จำเป็นต้องกลัวปัญหาใด ๆ ในฝั่งไคลเอ็นต์ตราบใดที่เซิร์ฟเวอร์ DNS จัดการเช่นนี้?
didi_X8

นี่เป็นความพยายามที่จะตอบคำถามอื่น "เหตุใด CNAME จึงไม่ได้รับอนุญาตที่จุดสูงสุด" ในขณะที่คำถามจริงคือ "จะเอาชนะข้อ จำกัด นี้ได้อย่างไร" -1
rustyx

ดูเหตุผลที่serverfault.com/questions/613829/…
rhand

CNAME 'การตั้งค่ารูทเรคคอร์ดนั้นไม่ได้ต่อต้าน RFC ในทางเทคนิค คุณจะต้องอธิบายว่ามันไม่ได้ต่อต้าน RFC1034 ส่วน 3.6.2 อย่างไร: ถ้า CNAME RR อยู่ที่โหนดจะไม่มีข้อมูลอื่นอยู่ เพื่อให้แน่ใจว่าข้อมูลสำหรับชื่อ Canonical และนามแฝงต้องไม่แตกต่างกัน . แน่นอนว่า "ราก" (นั่นคือจุดสูงสุดในบริบทนี้) มีอยู่แล้วNSและSOAบันทึกจึงไม่สามารถมีCNAMEบันทึกได้
Patrick Mevzek

4

ฉันไม่รู้ว่าพวกเขาหลีกเลี่ยงมันได้อย่างไรหรือผลข้างเคียงเชิงลบของพวกเขาอาจเป็นอย่างไร แต่ฉันใช้ Hover.com เพื่อโฮสต์โดเมนบางโดเมนของฉันและเพิ่งตั้งค่าส่วนบนของโดเมนของฉันเป็น CNAME ที่นั่น เครื่องมือแก้ไข DNS ของพวกเขาไม่ได้บ่นอะไรเลยและโดเมนของฉันแก้ไขอย่างมีความสุขผ่าน CNAME ที่กำหนด

นี่คือสิ่งที่ Dig แสดงให้ฉันเห็นสำหรับโดเมนนี้ (โดเมนจริงถูกทำให้สับสนเป็น mydomain.com):

; <<>> DiG 9.8.3-P1 <<>> mydomain.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2056
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;mydomain.com.          IN  A

;; ANSWER SECTION:
mydomain.com.       394 IN  CNAME   myapp.parseapp.com.
myapp.parseapp.com. 300 IN  CNAME   parseapp.com.
parseapp.com.       60  IN  A   54.243.93.102

หากจำเป็นจริงๆ (DNS สาธารณะ .... ) ควรใช้คำแนะนำ RFC2606 และ RFC5737 หรือ 3849 สำหรับที่อยู่ IP
Patrick Mevzek

3

บริษัท ของฉันทำสิ่งเดียวกันกับลูกค้าหลายรายที่เราโฮสต์เว็บไซต์ให้พวกเขาแม้ว่าในกรณีของเราจะเป็น xyz.company.com แทนที่จะเป็น www.company.com เราจะให้พวกเขาตั้งค่าระเบียน A บน xyz.company.com เพื่อชี้ไปยังที่อยู่ IP ที่เราจัดสรรให้

เกี่ยวกับวิธีที่คุณสามารถรับมือกับการเปลี่ยนแปลงที่อยู่ IP ฉันไม่คิดว่าจะมีวิธีแก้ปัญหาที่สมบูรณ์แบบ แนวคิดบางประการ ได้แก่ :

  • ใช้ NAT หรือตัวจัดสรรภาระงาน IP และให้ที่อยู่ IP ที่เป็นของลูกค้าของคุณ หากที่อยู่ IP ของเว็บเซิร์ฟเวอร์จำเป็นต้องเปลี่ยนแปลงคุณสามารถอัปเดต NAT หรือตัวโหลดบาลานเซอร์ได้

  • เสนอบริการโฮสต์ DNS ด้วยและให้ลูกค้าของคุณโฮสต์โดเมนกับคุณเพื่อให้คุณสามารถอัปเดตระเบียน A ได้

  • ให้ลูกค้าของคุณตั้งค่าระเบียน A ของพวกเขาบนเว็บเซิร์ฟเวอร์หลักหนึ่งรายการและใช้การเปลี่ยนเส้นทาง HTTP สำหรับคำขอเว็บของลูกค้าแต่ละราย


3

Sipwiz ถูกต้องวิธีเดียวที่จะทำอย่างถูกต้องคือวิธี HTTP และ DNS แบบไฮบริด ผู้รับจดทะเบียนของฉันเป็นผู้ขายต่อให้กับ Tucows และพวกเขาเสนอการส่งต่อโดเมนรากเป็นบริการเสริมฟรี

หากโดเมนของคุณคือ blah.com พวกเขาจะถามคุณว่าคุณต้องการให้โดเมนส่งต่อไปที่ใดและคุณพิมพ์ www.blah.com พวกเขากำหนดระเบียน A ให้กับเซิร์ฟเวอร์ apache และเพิ่ม blah.com เป็น DNS vhost โดยอัตโนมัติ vhost ตอบสนองด้วยข้อผิดพลาด HTTP 302 ที่เปลี่ยนเส้นทางไปยัง URL ที่ถูกต้อง สคริปต์ / การตั้งค่าเป็นเรื่องง่ายและสามารถจัดการได้โดยต่ำสุดมิฉะนั้นจะถูกทิ้งฮาร์ดแวร์

รันคำสั่งต่อไปนี้สำหรับตัวอย่าง: curl -v eclecticengineers.com


3

คุณต้องใส่จุดต่อท้ายโดเมนภายนอกจึงไม่คิดว่าคุณหมายถึง customer1.mycompanydomain.com.localdomain

ดังนั้นเพียงแค่เปลี่ยน:

customer1.com IN CNAME customer1.mycompanydomain.com

ถึง

customer1.com IN CNAME customer1.mycompanydomain.com.

สำหรับผม (ห่วง 9.8.2) หากบันทึกเป็นสำหรับโดเมนของcustomer1.comงานนี้ ... แต่ถูกตีความว่าเป็นการระบุ CNAME customer1.com.customer1.comสำหรับโดเมนย่อย ถ้าฉันเพิ่มจุดในรายการแรกระเบียนจะตีความได้อย่างถูกต้อง แต่ใช้ไม่ได้อีกต่อไป ฉันไม่เห็นวิธีแก้ปัญหาที่นี่
Jussi Hirvi

-2

ฉันเห็นว่า readytocloud.com โฮสต์บน Apache 2.2

มีวิธีที่ง่ายกว่าและมีประสิทธิภาพมากกว่าในการเปลี่ยนเส้นทางไซต์ที่ไม่ใช่ www ไปยังไซต์ www ใน Apache

เพิ่มกฎการเขียนซ้ำต่อไปนี้ในการกำหนดค่า Apache (ไม่ว่าจะภายในโฮสต์เสมือนหรือภายนอกไม่สำคัญ):

RewriteCond %{HTTP_HOST} ^readytocloud.com [NC]
RewriteRule ^/$ http://www.readytocloud.com/ [R=301,L]

หรือกฎการเขียนซ้ำต่อไปนี้หากคุณต้องการการแมป URL แบบ 1 ต่อ 1 จากไซต์ที่ไม่ใช่ www ไปยังไซต์ www:

RewriteCond %{HTTP_HOST} ^readytocloud.com [NC]
RewriteRule (.*) http://www.readytocloud.com$1 [R=301,L]

หมายเหตุโมดูล mod_rewrite ต้องโหลดเพื่อให้ใช้งานได้ โชคดีที่ readytocloud.com ทำงานบนกล่อง CentOS ซึ่งโดยค่าเริ่มต้นจะโหลด mod_rewrite

เรามีเซิร์ฟเวอร์ไคลเอนต์ที่ใช้ Apache 2.2 ซึ่งมีโดเมนต่ำกว่า 3,000 โดเมนและมีการเปลี่ยนเส้นทางเกือบ 4,000 ครั้งอย่างไรก็ตามการโหลดบนเซิร์ฟเวอร์จะอยู่ที่ประมาณ 0.10 - 0.20


คำถามเกี่ยวกับ DNS ไม่เกี่ยวกับเว็บเซิร์ฟเวอร์ Apache
SamTzu

-7

ขอบคุณทั้ง sipwiz และ MrEvil เราได้พัฒนาสคริปต์ PHP ที่จะแยกวิเคราะห์ URL ที่ผู้ใช้ป้อนและวางwwwไว้ที่ด้านบน (เช่นหากลูกค้าเข้าสู่kiragiannis.comระบบจะเปลี่ยนเส้นทางไปที่www.kiragiannis.com ) เพื่อให้ลูกค้าของเราชี้ให้รากของพวกเขา (เช่นcustomer1.comการAบันทึกที่เปลี่ยนเส้นทางเว็บของเราเป็น) และจากนั้นwww CNAMEจะจริงAบันทึกการจัดการโดยเรา

ด้านล่างรหัสในกรณีที่คุณสนใจสำหรับเราในอนาคต

<?php
$url = strtolower($_SERVER["HTTP_HOST"]);

if(strpos($url, "//") !== false) { // remove http://
  $url = substr($url, strpos($url, "//") + 2);
}

$urlPagePath = "";
if(strpos($url, "/") !== false) { // store post-domain page path to append later
  $urlPagePath = substr($url, strpos($url, "/"));
  $url = substr($url, 0, strpos($url,"/"));
}


$urlLast = substr($url, strrpos($url, "."));
$url = substr($url, 0, strrpos($url, "."));


if(strpos($url, ".") !== false) { // get rid of subdomain(s)
  $url = substr($url, strrpos($url, ".") + 1);
}


$url = "http://www." . $url . $urlLast . $urlPagePath;

header( "Location:{$url}");
?>

10
นี่ไม่ได้ตอบคำถามที่คน 69k + เข้ามาในกระทู้นี้กำลังมองหา คำถามคือข้อมูลเพิ่มเติมเกี่ยวกับ DNS และไม่มีส่วนเกี่ยวข้องกับ PHP
Matt Clark

1
คำถามเกี่ยวกับ DNS ไม่เกี่ยวกับการเข้ารหัส PHP
SamTzu

HTTP_HOST เป็นชื่อโฮสต์เช่นเดียวกับชื่อที่บ่งบอกไม่ใช่ URL ดังนั้นจะไม่มีhttp://การลบหรือ/( $urlPagePathจะว่างเปล่าเสมอไป) Cf httpd.apache.org/docs/2.4/expr.html เนื่องจากวิธีที่โค้ดพยายามกำจัดโดเมนย่อยจึงไม่สามารถใช้งานได้กับสิ่งต่างๆเช่นwww.example.co.ukที่ซึ่งco.ukต้องพิจารณาโดยรวม นอกจากนี้ยังไม่รองรับ HTTPS และในที่สุดการใช้ PHP เพียงแค่ทำการเปลี่ยนเส้นทาง HTTP ที่เว็บเซิร์ฟเวอร์ใด ๆ สามารถทำได้ในการกำหนดค่านั้นมีความซับซ้อนมากเกินไป ดังนั้นในระยะสั้นนี้ไม่ควรเป็นคำตอบที่ตรวจสอบได้สำหรับคำถามนี้
Patrick Mevzek

หากกฎนี้ใช้กับโฮสต์ทั้งหมดควรทำเป็น apache config
Svetoslav Marinov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.