debian: bind9 + chroot + internal/external

*** ยังเขียนไม่เสร็จ + ยังไม่ได้ตรวจทานซ้ำ ***

เป้า

  • ติดคุกให้ bind (chroot jail)
  • จะทำให้สามารถใช้งานได้ทั้งภายใน และภายนอก (ภายนอกไม่ค่อยจำเป็น แต่ติดตั้งไว้เผื่อจะทำอะไรเพิ่ม) คือโดเมนเดียวกัน แต่มีไอพี 2 กลุ่ม ภายในกลุ่มนึง และภายนอกอีกกลุ่มนึง
  • ติดตั้งเป็นแบบสามารถเปลี่ยนค่าไอพีได้ (allow-update)

สมมุติว่า

  • มีโดเมนภายในเป็น example.com อย่างเดียว มีไอพีเป็น 192.168.1.0/24 โดยจะทำเรื่อง reverse ip ด้วย (คือค้นย้อนกลับจากเลขไอพีได้)
  • โดเมนภายนอกเป็น example.com และ example.org โดยที่เราจะทำให้ทุกบริการมีไอพีเดียวกัน คือเครื่องนี้เครื่องเดียวทำหลายหน้าที่ เพียงเปลี่ยนชื่อ (CNAME) ไปตามบริการนั้น ๆ ติดตั้งเป็นแบบเปลี่ยนค่าได้ เพราะไอพีเราไม่คงที่
    โดเมนภายนอก จะไม่ทำ reverse ip เพราะเรามีหลายโดเมน และถึงแม้จะมีโดเมนเดียว ค่าที่โลกภายนอกค้นได้ก็คงไม่ใช่จากเครื่องเราอยู่ดี (ค้นได้จากชื่อโดเมนอย่างเดียว ค้นย้อนกลับจากเลขไอพีไม่ได้)

ติดตั้งแพกเกจ
# aptitude install bind9 dnsutils

ทำเรื่องติดคุก (chroot jail) จะย้ายคุกไปไว้ที่ /sys1/chroot/bind
# vi /etc/default/bind9

...
# OPTIONS="-u bind"
OPTIONS="-u bindinjail -t /sys1/chroot/bind"
...

สร้างผู้ใช้ชื่อ bindinjail ให้ใช้เชลล์ไม่ได้ อยู่ในกลุ่ม nogroup
# useradd -g nogroup -d /nonexistent -s /bin/false -u 65533 bindinjail
# passwd -l bindinjail

สร้างคุก
# mkdir -p /sys1/chroot/bind/{etc,dev,var/cache/bind,var/log,var/run/bind/run}
# mv /etc/bind /sys1/chroot/bind/etc
# ln -sf /sys1/chroot/bind/etc/bind /etc
# mknod /sys1/chroot/bind/dev/null c 1 3
# mknod /sys1/chroot/bind/dev/random c 1 8
# chmod 666 /sys1/chroot/bind/dev/null /sys1/chroot/bind/dev/random
# chown -R bindinjail:nogroup /sys1/chroot/bind/var/*
# chown -R bindinjail:nogroup /sys1/chroot/bind/etc/bind/

ทำให้ระบบเก็บปูมของ bind (system logging - syslogd)
# vi /etc/default/syslogd

...
# SYSLOGD=""
SYSLOGD="-a /sys1/chroot/bind/dev/log"
...

ปรับตั้งระบบปูมของ bind
# vi /sys1/chroot/bind/etc/bind/named.conf.local

...
logging {
channel "querylog" { file "/var/log/bind9-query.log"; print-time yes; };
category queries { querylog; };
};
...

ปรับตั้งประวัติปูมของ bind
# vi /etc/logrotate.d/bind9-query

/sys1/chroot/bind/var/log/bind9-query.log {
weekly
missingok
rotate 10
postrotate
/etc/init.d/bind9 reload > /dev/null
endscript
compress
notifempty
}

# ln -sf /sys1/chroot/bind/var/log/bind9-query.log /var/log/bind9-query.log

แก้ไข options ให้มาใช้ pid ของคุก
# vi /sys1/chroot/bind/etc/bind/named.conf.options

...
options {
directory "/var/cache/bind";
pid-file "/var/run/named.pid";
...

เสร็จขั้นต้น ทดสอบระบบครั้งแรก
# /etc/init.d/sysklogd restart
# /etc/init.d/bind9 restart

ต้องไม่มีรายงานข้อผิดพลาด

ต่อไปเป็นเรื่องการอัปเดตไอพี และการทำให้รองรับเครือข่ายภายในและภายนอก ผสมกัน

บอก bind ว่าเราจะใช้งาน dnssec
# vi /etc/bind/named.conf.options

...
options {
...
recursion yes;
dnssec-enable yes;

};
...

สร้างไดเรกทอรี่มารองรับการทำงาน
# mkdir -p /sys1/chroot/bind/etc/bind/{internal,external}

สร้างกฎ acl สำหรับเครือข่ายภายใน ตั้งชื่อว่า internal (นอกจากนั้นจะถือว่าเป็น external ทั้งหมด)
และให้มาอ่านไฟล์คอนฟิกที่เราจะสร้างขึ้นภายหลัง ของโซน example.com และ example.org
# cd /sys1/chroot/bind/etc/bind
# vi named.conf.local

...
acl internal {
127.0.0.0/8;
192.168.0.0/16;
};

include "/etc/bind/example.com.conf";
include "/etc/bind/example.org.conf";
...

สร้างไฟล์เปล่า ๆ กันเหนียวเผื่อทดสอบ จะได้มีไฟล์รองรับ
# touch /etc/bind/{example.com.conf,example.org.conf}

สร้างกุญแจ สำหรับอัปเดตไอพี example.com และ example.org

ของ example.com

สั่งสร้างกุญแจสำหรับลงทะเบียนโซน
# dnssec-keygen -r /dev/urandom -a rsasha1 -b 1024 -n ZONE example.com
ตัวอย่างได้ผลเป็น
Kexample.com.+005+11187

และได้ไฟล์ Kexample.com.+005+11187.key และ Kexample.com.+005+11187.private

และกุญแจสำหรับอัปเดตโซน
# dnssec-keygen -r /dev/urandom -k -a rsasha1 -b 1024 -n ZONE example.com
ตัวอย่างได้ผลเป็น

Kexample.com.+005+09453

และได้ไฟล์ Kexample.com.+005+09453.key และ Kexample.com.+005+09453.private

สร้างไฟล์คอนฟิกของโซน example.com
# vi example.com.conf

view "internal" {
match-clients { internal; };
zone "example.com" IN {
type master;
file "/etc/bind/internal/example.com.zone.signed";
key-directory "/etc/bind";
update-policy {
grant example.com. subdomain example.com any;
};
};
zone "0.168.192.in-addr.arpa" IN {
type master;
file "/etc/bind/internal/example.com.reverse.signed";
key-directory "/etc/bind";
update-policy {
grant example.com. subdomain example.com any;
};
};
};

view "external" {
match-clients { any; };
zone "example.com" IN {
type master;
file "/etc/bind/external/example.com.zone.signed";
key-directory "/etc/bind";
update-policy {
grant example.com. subdomain example.com any;
};

};
};

สร้างโซนไฟล์ของ internal
# vi internal/example.com.zone
อันนี้ลองเปลี่ยนตามจริงนะครับ สมมุติว่าเครื่องนี้เอาชื่อ server1 เป็นหลัก แล้วใช้ชื่ออื่นคือ www, ns1, ftp, mail เป็นชื่อรอง

$TTL    86400
@ IN SOA server1.example.com. root.server1.example.com. (
41 ; serial (d. adams)
3H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum
@ IN NS ns1.example.com. ; primary NS
@ IN NS ns2.example.com. ; secondary NS

www IN CNAME server1
ns1 IN CNAME server1
ftp IN CNAME server1
mail IN CNAME server1
www IN A 192.168.1.1
ns2 IN A 192.168.1.2
work1 IN A 192.168.1.101
work2 IN A 192.168.1.102
work3 IN A 192.168.1.103

$INCLUDE /etc/bind/Kexample.com.+005+11187.key
$INCLUDE /etc/bind/Kexample.com.+005+09453.key

ลงทะเบียนโซน example.com ของ internal
# cd internal
# dnssec-signzone -r /dev/urandom -t -g -o example.com example.com.zone /etc/bind/Kexample.com.+005+11187.private

example.com.zone.signed
Signatures generated: 21
Signatures retained: 0
Signatures dropped: 0
Signatures successfully verified: 0
Signatures unsuccessfully verified: 0
Runtime in seconds: 0.063
Signatures per second: 331.151

# cd ..

เปลี่ยนเจ้าของและกลุ่ม
# chown -R bindinjail:nogroup *

เสร็จโซนไฟล์ของ internal

ทดสอบขั้นต้น
# /etc/init.d/bind9 restart
ต้องไม่มีรายงานข้อผิดพลาด

ทดสอบอัปเดต
# nsupdate -d -v -k Kexample.com.+005+09453.private

Creating key...
> server 192.168.1.1
> zone example.com
> update add testing.example.com. 3600 A 192.168.1.5
> show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; UPDATE SECTION:
testing.example.com. 3600 IN A 192.168.1.5

> send
Sending update to 192.168.1.1#53
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 43656
;; flags: ; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
;; ZONE SECTION:
;example.com. IN SOA

;; UPDATE SECTION:
testing.example.com. 3600 IN A 192.168.1.5

;; SIG0 PSEUDOSECTION:
. 0 ANY SIG 0 5 0 0 20080223084852 20080223083852 9453 example.com. zpGfPIECwJ8V31lm7mlq7zMiKYSuh2TlIyOZgEUJjZUgYTRHYZrwi75Z mDaKAJGb7uG+r4SLmuFDRdjQQ1mvtZcuo8SK2yjHK59QzUoFnGJXz427 vRNj/do4DbMxMkJpJwqDiKU87lGiy+CXvpbQAm+4AeJutpCTsGnfhixx k4c=

Reply from update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 43656
;; flags: qr ra ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0

> quit

ลองค้นดูอีกที
# nslookup testing.example.com localhost

Server:         localhost
Address: 127.0.0.1#53

Name: testing.example.com
Address: 192.168.1.5

เสร็จ forward internal

ยังเขียนไม่เสร็จ หมดแรงก่อน ข้อเขียนข้างบนยังไม่ได้ตรวจทาน
- reverse internal example.com ทำเหมือนเดิม ยกเว้นตอนอัปเดตใช้คำสั่งเป็น
> update add 5.1.168.192.in-addr.arpa. 3600 IN PTR testing.example.com.
โดยอย่าให้มีคำสั่ง zone XXXX มาก่อนหน้า อัปเดตได้เลย

- forward external ทำเหมือนเดิม ---รอเขียนต่อ---

อ้างอิง
http://myrddin.org/howto/debian-bind9-chroot/
http://www.ops.ietf.org/dns/dynupd/secure-ddns-howto.html
http://garnser.blogspot.com/2008/02/how-to-enable-bind-with-dnssec-and.html
http://www.unixwiz.net/techtips/bind9-chroot.html

 

Thai Search

Google Search

Custom Search

Theme

Who's online

There are currently 0 users and 4 guests online.