โดยปกติแล้ว เวลาหาเส้นทางเพื่อการส่งข้อมูล (routing) บนเน็ตเวิร์กไม่ว่าจะบนลีนุกซ์หรือเร้าเตอร์ทั่วไป จะดูจาก IP Address ปลายทาง
(Destination Address) ที่อยู่ใน IP Packet เป็นหลัก
แต่ในบางกรณี เราสามารถคอนฟิกลีนุกซ์หรือเร้าเตอร์ให้ดูข้อมูลอื่นๆ ที่อยูใน IP Packet เพื่อหาเส้นทาง เช่น ดูจาก IP Address ต้นทาง (Source Address) การคอนฟิกเช่นนี้เรียกว่า Policy based routing
ในบทความนี้จะกล่าวถึงวิธีการคอนฟิก Policy based routing บนลีนุกซ์ เพื่อให้ดูข้อมูล IP Address ต้นทาง เวลาหาเส้นทาง (routing) ที่จะส่งข้อมูลไปยังเร้าเตอร์ตัวถัดไป
ความต้องการของระบบ
ลีนุกซ์ที่จะคอนฟิกเป็น Policy based routing ได้ ใน Kernel ต้องเปิดการใช้งาน (enable) คุณสมบัติสองอย่างนี้
Networking -> Networking options -> [*] IP: advanced router (CONFIG_IP_ADVANCED_ROUTER) [*] IP: policy routing (CONFIG_IP_MULTIPLE_TABLES)
โดยทั่วไปจากการติดตั้ง เวอร์ชั่นส่วนใหญ่ของลีนุกซ์จะเปิดการใช้งานคุณสมบัตินี้อยู่แล้ว ตัวอย่างไฟล์คอนฟิกของ Kernel ที่ติดตั้งมากับ Fedora 9
[root@linux-router ~]# cat /boot/config-2.6.25-14.fc9.i686 ... CONFIG_IP_ADVANCED_ROUTER=y ... CONFIG_IP_MULTIPLE_TABLES=y ...
โปรแกรมที่ใช้คอนฟิก Policy คือ iproute ซึ่งส่วนใหญ่ก็ติดตั้งมาให้อยู่แล้ว
ตัวอย่างเวอร์ชั่นของ iproute ที่ติดตั้งมากับ Fedora 9
[root@linux-router ~]# rpm -q iproute iproute-2.6.23-4.fc9.i386
การเชื่อมต่อของเน็ตเวิร์ก
ในบทความนี้จะคอนฟิกบนลีนุกซ์ ที่ทำหน้าที่เป็น router เชื่อมระหว่าง เน็ตเวิร์กภายในองค์กร และ เน็ตเวิร์กที่ต่อเข้ากับ Internet Router เช่น ADSL หรือ Leased-line โดยมีตัวอย่าง IP Address ดังต่อไปนี้
Linux Router
- eth0: 192.168.1.1/24 ต่อกับ Internet ADSL Router ที่มี IP เป็น 192.168.1.254
- eth1: 192.168.2.1/24 ต่อกับ Internet Leased-line Router ที่มี IP เป็น 192.168.2.254
- eth2: 10.1.0.1/24 ทำหน้าที่เป็น Default Gateway ของ Net #1 ภายในองค์กร
- eth3: 10.2.0.1/24 ทำหน้าที่เป็น Default Gateway ของ Net #2 ภายในองค์กร
ต้องการคอนฟิกให้
- เครื่องที่อยู่ใน Net #1: 10.1.0.0/24 เวลาใช้อินเตอร์เน็ต ให้ใช้ ADSL Router
- เครื่องที่อยู่ใน Net #2: 10.2.0.0/24 เวลาใช้อินเตอร์เน็ต ให้ใช้ Leased-line Router
ก่อนที่จะเริ่มคอนฟิก policy ในขั้นต่อไปได้นั้น ต้องตรวจสอบ routing table ของทุกเครื่องว่าสามารถ ping ถึงกันได้หมด เช่น เครื่องที่อยู่ในเน็ตเวิร์ก Net #1 ต้องสามารถ ping ไปยัง ADSL Router ได้ และเครื่องที่อยู่ใน Net #2 ต้องสามารถ ping ไปยัง Leased-line Router ได้
คอนฟิกลีนุกซ์ให้ทำหน้าที่เป็น Router
โดยดีฟอลต์แล้ว ลีนุกซ์ไม่ได้ทำหน้าที่เป็น Router คือจะไม่ส่งต่อข้อมูล (IP packet forwarding) ใดๆ ระหว่างอินเตอร์เฟซ ดังนั้น ถ้าต้องการให้ลีนุกซ์ทำ routing ได้ ต้องเปิดคุณสมบัตินี้ก่อน ซึ่งสามารถทำได้โดยแก้ไขไฟล์ /etc/sysctl.conf เปลี่ยนคอนฟิกของ net.ipv4.ip_forward จากค่า 0 เป็น 1
ตัวอย่างการแก้ไขไฟล์ /etc/sysctl.conf เพื่อคอนฟิกเป็น Router
# Controls IP packet forwarding net.ipv4.ip_forward = 1
หลังจากแก้ไขไฟล์แล้ว ต้องรันคำสั่ง sysctl -p เพื่อให้ค่าที่แก้ไขไปมีผลทันที
ตัวอย่างการรันคำสั่ง sysctl
[root@linux-router ~]# sysctl -p net.ipv4.ip_forward = 1 ...
ตรวจสอบคอนฟิกก่อนทำ Policy
ใช้คำสั่ง ip rule เพื่อตรวจสอบว่าลีนุกซ์ใช้กฎเกณฑ์ (rule) ใดในการทำ routing โดยดีฟอลต์ลีนุกซ์จะตัดสินใจโดยดูจาก 3 ส่วนหลักๆ คือ local, main, default ในการตรวจสอบทุก packet (from all)
[root@linux-router ~]# ip rule list 0: from all lookup local 32766: from all lookup main 32767: from all lookup default
ในที่นี้จะสนใจเฉพาะในส่วน main ซึ่งเป็น routing table ที่ใช้งานตามปกติ เราสามารถดูรายละเอียดของ main ได้ โดยใช้คำสั่ง ip route ดังนี้
[root@linux-router ~]# ip route list table main 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.1 192.168.2.0/24 dev eth1 proto kernel scope link src 192.168.2.1 10.1.0.0/24 dev eth2 proto kernel scope link src 10.1.0.1 10.2.0.0/24 dev eth3 proto kernel scope link src 10.2.0.1
ผลลัพธ์ที่ได้จะเหมือนกับที่ได้จากคำสั่ง netstat -rn ดังนี้
[root@linux-router ~]# netstat -rn Kernel IP routing table Destination Gateway Genmask Flags MSS Window irtt Iface 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.2.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 10.1.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2 10.2.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth3
จะเห็นว่าไม่มีการคอนฟิก default gateway บนลีนุกซ์เลย เราจะคอนฟิกโดยใช้ policy ตามขั้นตอนต่อไป
คอนฟิก Policy สำหรับ Net #1
ต้องการให้ packet ที่มาจากเครื่องที่อยู่ใน Net #1 10.1.0.0/24 เวลาส่งต่อไปยังอินเตอร์เน็ต ให้ส่งไปที่ ADSL Router สามารถคอนฟิกได้ดังนี้
ตัวอย่างการคอนฟิกเพื่อกำหนดกฎเกณฑ์ว่ามาจาก 10.1.0.0/24 ให้จัดเข้าอยู่ Table 10
[root@linux-router ~]# ip rule add from 10.1.0.0/24 table 10
[root@linux-router ~]# ip rule list 0: from all lookup local 32765: from 10.1.0.0/24 lookup 10 32766: from all lookup main 32767: from all lookup default
ตัวอย่างการกำหนดเส้นทางการส่งของ Table 10 ให้ส่งออกทาง eth0 ไปที่ ADSL Router (192.168.1.254)
[root@linux-router ~]# ip route add default via 192.168.1.254 dev eth0 table 10
[root@linux-router ~]# ip route list table 10 default via 192.168.1.254 dev eth0
คอนฟิก Policy สำหรับ Net #2
สำหร้บ Net #2 ต้องการให้ packet ที่มาจากเครื่องที่อยู่ใน Net #2 10.2.0.0/24 เวลาส่งต่อไปยังอินเตอร์เน็ต ให้ส่งไปที่ Leased-line Router สามารถคอนฟิกได้ดังนี
ตัวอย่างการคอนฟิกเพื่อกำหนดกฎเกณฑ์ว่ามาจาก 10.2.0.0/24 ให้จัดเข้าอยู่ Table 20
[root@linux-router ~]# ip rule add from 10.2.0.0/24 table 20
[root@linux-router ~]# ip rule list 0: from all lookup local 32764: from 10.2.0.0/24 lookup 20 32765: from 10.1.0.0/24 lookup 10 32766: from all lookup main 32767: from all lookup default
ตัวอย่างการกำหนดเส้นทางการส่งของ Table 20 ให้ส่งออกทาง eth1 ไปที่ Leased-line Router (192.168.2.254)
[root@linux-router ~]# ip route add default via 192.168.2.254 dev eth1 table 20
[root@linux-router ~]# ip route list table 20 default via 192.168.2.254 dev eth1
การทดสอบ Policy
หลังจากที่คอนฟิกแล้ว สามารถทดสอบได้โดยใช้คำสั่ง ping จากไคลเอนต์ในเน็ตเวิร์กทั้งสองว่าไปตามเส้นทางที่กำหนดไว้หรือไม่