แม้จะมีเซิร์ฟเวอร์ DNS ที่เราสามารถใช้งานได้ฟรี เช่น DNS ของ Google (8.8.8.8, 8.8.4.4) แต่ในบางครั้ง เราก็จำเป็นต้องติดตั้งและคอนฟิกเซิร์ฟเวอร์ DNS ขึ้นมาใช้งานเอง เช่นใช้งานภายในองค์กร (Intranet) หรือตั้ง DNS เพื่อเก็บข้อมูลโดเมนเนมของเราเอง
ลองมาดูวิธีการติดตั้งและคอนฟิก BIND บน CentOS 7 เพื่อทำหน้าที่เป็นเซิร์ฟเวอร์ DNS กัน
โดยในตอนแรกเราจะเริ่มติดตั้ง BIND และคอนฟิกเป็นแบบ Caching Only ความหมายคือ คอนฟิกให้ทำหน้าที่เป็น DNS เซิร์ฟเวอร์ที่ให้บริการเครื่องไคลเอนต์ (Client) ในการถามข้อมูล เช่น ถามชื่อ (Hostname) แล้วตอบเป็น IP Address ให้ โดยเซิร์ฟเวอร์ที่คอนฟิกในโหมด caching only นี้ จะทำหน้าที่ไปค้นหาข้อมูล (recursion) โดยการถาม DNS เซิร์ฟเวอร์ตัวอื่นๆ ที่อยู่บนอินเทอร์เน็ตไปเรื่อยๆ จนกว่าจะเจอเซิร์ฟเวอร์ที่เก็บข้อมูลของโดเมน (Authoritative Server) และได้คำตอบว่า ชื่อที่ไคลเอ้นต์ถามมา มี IP Address เป็นค่าอะไร
เริ่มต้นใช้คำสั่ง yum install ติดตั้งแพ็กเกจ bind (DNS Server) และ bind-utils (DNS Client)
[root@cent7 ~]# yum install bind [root@cent7 ~]# yum install bind-utils
ชื่อเซอร์วิสของ BIND บนลีนุกซ์ตระกูล Red Hat หรือ CentOS คือ named
ใช้คำสั่ง systemctl start เพื่อรันเซอร์วิส named
[root@cent7 ~]# systemctl start named
ดีฟอลต์คอนฟิกจากการติดตั้ง เซิร์ฟเวอร์จะทำหน้าที่ DNS แบบ Caching Only ให้บริการเฉพาะตัวเครื่องเซิร์ฟเวอร์เอง (localhost)
ใช้คำสั่ง dig เพื่อทดสอบเซิร์ฟเวอร์ DNS เครื่องตัวเอง (localhost) เพื่อถามข้อมูลชื่อ www.google.com
[alice@cent7 ~]$ dig @localhost www.google.com ; <<>> DiG 9.9.4-RedHat-9.9.4-18.el7_1.3 <<>> @localhost www.google.com ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41857 ;; flags: qr rd ra; QUERY: 1, ANSWER: 16, AUTHORITY: 4, ADDITIONAL: 5 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.google.com. IN A ;; ANSWER SECTION: www.google.com. 300 IN A 61.91.8.20 www.google.com. 300 IN A 61.91.8.39 www.google.com. 300 IN A 61.91.8.25 ... ;; AUTHORITY SECTION: google.com. 172797 IN NS ns2.google.com. google.com. 172797 IN NS ns4.google.com. google.com. 172797 IN NS ns1.google.com. google.com. 172797 IN NS ns3.google.com. ;; ADDITIONAL SECTION: ns2.google.com. 172797 IN A 216.239.34.10 ns1.google.com. 172797 IN A 216.239.32.10 ns3.google.com. 172797 IN A 216.239.36.10 ns4.google.com. 172797 IN A 216.239.38.10 ;; Query time: 3270 msec ;; SERVER: ::1#53(::1) ;; WHEN: Fri Aug 07 22:50:25 ICT 2015 ;; MSG SIZE rcvd: 435
หากคอนฟิกถูกต้อง จะมีข้อมูลตอบกลับมาตามตัวอย่างข้างบน วิธีการดูผลลัพธ์ที่ได้
QUESTION SECTION คือข้อมูลที่เราถามไป ดีฟอลต์หากไม่ได้ระบุออปชัน type เวลาใช้คำสั่ง dig จะเป็นการถามข้อมูล A เพื่อเปลี่ยนชื่อเป็น IP Address
;; QUESTION SECTION:
;www.google.com. IN A
ANSWER SECTION คือผลลัพธ์ที่เซิร์ฟเวอร์ DNS ตอบกลับมา
;; ANSWER SECTION: www.google.com. 300 IN A 61.91.8.20 www.google.com. 300 IN A 61.91.8.39 www.google.com. 300 IN A 61.91.8.25 ...
คำอธิบาย
- ตัวเลข 300 คือค่า TTL (Time to Live) หรือจำนวนวินาทีที่เซิร์ฟเวอร์จะเก็บค่าตอบนี้ไว้ในแคช (cache) จะได้ไม่ต้องไปถามเซิร์ฟเวอร์ DNS เครื่องที่เก็บข้อมูลจริงไว้ (AUTHORITY)
- IN ย่อมาจาก Internet
- A คือการเปลี่ยนชื่อเป็น IP Address
จากตัวอย่างจะเห็นว่าชื่อ www.google.com. มีหลาย IP Address มาก เพราะทาง google ต้องการให้ผู้ใช้งานเว็บไซต์กระจายการใช้งานไปยังเซิร์ฟเวอร์ IP ต่างๆ
AUTHORITY SECTION คือข้อมูลเซิร์ฟเวอร์ที่ให้คำตอบจริงๆ เซิร์ฟเวอร์ DNS ที่เราเพิ่งติดตั้งและคอนฟิกไป ไม่มีข้อมูลของชื่อ www.google.com ต้องไปถามเซิร์ฟเวอร์ DNS ตัวอื่นๆ (การทำงานแบบนี้เรียกว่า recursive) เช่นในตัวอย่างนี้เซิร์ฟเวอร์ที่ให้คำตอบ (Authoritative Server) สำหรับโดเมนชื่อ google.com ประกอบด้วย NS (Name Server) จำนวน 4 เครื่อง
;; AUTHORITY SECTION:
google.com. 172797 IN NS ns2.google.com.
google.com. 172797 IN NS ns4.google.com.
google.com. 172797 IN NS ns1.google.com.
google.com. 172797 IN NS ns3.google.com.
;; ADDITIONAL SECTION: เป็นการแสดงค่า IP Address ของเซิร์ฟเวอร์ NS อีกที
ถ้าลองรันคำสั่ง dig อีกครั้ง
[alice@cent7 ~]$ dig @localhost www.google.com ; <<>> DiG 9.9.4-RedHat-9.9.4-18.el7_1.3 <<>> @localhost www.google.com ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39248 ;; flags: qr rd ra; QUERY: 1, ANSWER: 16, AUTHORITY: 4, ADDITIONAL: 5 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;www.google.com. IN A ;; ANSWER SECTION: www.google.com. 244 IN A 61.91.8.50 www.google.com. 244 IN A 61.91.8.35 www.google.com. 244 IN A 61.91.8.20 ... ;; AUTHORITY SECTION: google.com. 172741 IN NS ns1.google.com. google.com. 172741 IN NS ns4.google.com. google.com. 172741 IN NS ns2.google.com. google.com. 172741 IN NS ns3.google.com. ;; ADDITIONAL SECTION: ns2.google.com. 172741 IN A 216.239.34.10 ns1.google.com. 172741 IN A 216.239.32.10 ns3.google.com. 172741 IN A 216.239.36.10 ns4.google.com. 172741 IN A 216.239.38.10 ;; Query time: 0 msec ;; SERVER: ::1#53(::1) ;; WHEN: Fri Aug 07 22:51:21 ICT 2015 ;; MSG SIZE rcvd: 435
สังเกตว่าค่า TTL จะลดลงจาก 300 เป็น 244 และ 172797 ลดเหลือ 172741
การถามข้อมูลจากเซิร์ฟเวอร์ 127.0.0.1 ครั้งนี้ ตัวเซิร์ฟเวอร์จะตอบจากค่าที่อยู่ในแคชเลย ไม่ต้องไปถาม (recursive) เซิร์ฟเวอร์ DNS ของ google.com อีกครั้ง ทำให้ประหยัดเวลา แบนด์วิดธ์ของอินเทอร์เน็ต และลดโหลดของเซิร์ฟเวอร์ DNS ที่เก็บข้อมูลจริงๆ อยู่ด้วย สังเกตเวลาที่ใช้ (Query time) เป็น 0 msec
คอนฟิกให้เครื่องไคลเอนต์อื่นเข้ามาเรียกใช้เซอร์วิส DNS ได้
ดีฟอลต์คอนฟิกจะอนุญาตให้จากตัวเครื่องเซิร์ฟเวอร์เอง (localhost) ใช้ได้เท่านั้น ถ้าต้องการให้เครื่องอื่น สามารถเข้ามาใช้เซอร์วิส DNS ที่เรารันขึ้นมาได้ ต้องแก้คอนฟิกเพิ่มเติม
- แก้คอนฟิก firewall โดยอนุญาตให้เครื่องอื่นเข้ามาใช้พอร์ตที่รันเซอร์วิส DNS ได้ (UDP 53)
สามารถแก้ไขได้โดยใช้คำสั่ง firewall-cmd เพิ่มเซอร์วิสชื่อ dns
[root@cent7 ~]# firewall-cmd --zone=public --add-service=dns
success
- แก้ไขไฟล์ /etc/named.conf ซึ่งเป็นคอนฟิกของเซิร์ฟเวอร์ BIND DNS
[root@cent7 ~]# vi /etc/named.conf ... options { listen-on port 53 { any; }; listen-on-v6 port 53 { ::1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { localhost; }; allow-query-cache { localhost; 192.168.1.0/24; }; ...
ภายใต้ส่วนคอนฟิก options ให้แก้ไขไฟล์คอนฟิกบรรทัดที่มีคำว่า listen-on port 53 โดยแก้ค่าจาก 127.0.0.1 ให้เป็น any ซึ่งจะทำให้เซอร์วิส DNS รันบนทุกพอร์ตแลนของเซิร์ฟเวอร์ เพื่อรอรับการเรียกจากเครื่องอื่นๆ
แล้วก็เพิ่มคอนฟิก allow-query-cache ต่อท้ายจากบรรทัดที่มีคำว่า allow-query เพื่อกำหนดไคลเอนต์ที่สามารถเข้ามาเรียกใช้เซอร์วิส DNS ได้ เช่นในตัวอย่างคอนฟิกจะอนุญาตให้เครื่องอื่นๆ ที่มาจาก localhost (ตัวเครื่องเซิร์ฟเวอร์เอง) และเครื่องอื่นๆ ที่มี IP Address อยู่ในเน็ตเวิร์ก 192.168.1.0/24 สามารถเข้ามาเรียกใช้เซอร์วิสได้
สิ่งที่ผิดพลาดกันบ่อย เวลาแก้ไขไฟล์คอนฟิก named.conf คือหลังเครื่องหมายวงเล็บ } ต้องมีเครื่องหมาย ; ด้วย ดังนั้นหลังการแก้ไขคอนฟิกทุกครั้ง ก่อนที่จะรีสตาร์ตเซอร์วิส แนะนำให้ใช้คำสั่ง named-checkconf เพื่อตรวจสอบความถูกต้องของการแก้ไขไฟล์คอนฟิก
ตัวอย่างการรันคำสั่ง named-checkconf แล้วเจอไฟล์คอนฟิกที่ไม่ถูกต้อง
[root@cent7 ~]# named-checkconf
/etc/named.conf:31: missing ';' before 'recursion'
ถ้าถูกต้อง คำสั่ง named-checkconf จะไม่ฟ้องข้อความใดๆ ขึ้นมา
[root@cent7 ~]# named-checkconf [root@cent7 ~]#
รีสตาร์ตเซอร์วิส named หลังการแก้ไขไฟล์คอนฟิก เพื่อให้คอนฟิกมีผล
[root@cent7 ~]# systemctl restart named
ลองใช้เครื่องไคลเอนต์อื่นๆ ชี้มาที่ IP ของเซิร์ฟเวอร์ DNS ตัวนี้ แล้วใช้คำสั่งเพื่อทดสอบการเปลี่ยนชื่อเป็น IP Address เช่นบน Windows สามารถใช้คำสั่ง nslookup ได้
รูปแบบการใช้คำสั่ง nslookup บน Windows
C:\Users\alice>nslookup /?
Usage:
nslookup [-opt ...] # interactive mode using default server
nslookup [-opt ...] - server # interactive mode using 'server'
nslookup [-opt ...] host # just look up 'host' using default server
nslookup [-opt ...] host server # just look up 'host' using 'server'
ตัวอย่างการใช้คำสั่ง nslookup จากเครื่อง Windows เพื่อถามชื่อ www.mydomain.com จากเซิร์ฟเวอร์ DNS 192.168.1.1
C:\Users\alice>nslookup www.mydomain.com 192.168.1.1 Server: UnKnown Address: 192.168.1.1 Non-authoritative answer: Name: mydomain.com Address: 65.254.242.180 Aliases: www.mydomain.com
คำเตือน! เพื่อความปลอดภัยของตัวเซิร์ฟเวอร์ DNS เอง โดยเฉพาะเครื่องที่ต่ออินเทอร์เน็ต (Public IP) โดยตรง ห้ามแก้ไขไฟล์คอนฟิก named.conf เพื่อให้เครื่องอื่นๆ ที่ไม่ใช่ของเรา มาใช้บริการถามชื่อจากเซิร์ฟเวอร์ DNS ที่คอนฟิกแบบ Caching Only ได้โดยเด็ดขาด คอนฟิกอนุญาต (allow-query-cache) เฉพาะให้เครื่องที่เราดูแลหรืออยู่ในเน็ตเวิร์กของเราเท่านั้นที่สามารถใช้งานได้