ThaiCERT: Thai Computer Emergency Response Team
ศูนย์ประสานงานการรักษาความปลอดภัยคอมพิวเตอร์ ประเทศไทย 
 
 
 


Linux 2.4 Stateful Firewall : IPTABLES
เรียบเรียงโดย :
ภูวดล ด่านระหาญ
เผยแพร่เมื่อ : 3 ธันวาคม 2544

เอกสารฉบับนี้จะอธิบายถึงการนำ Linux 2.4 มาใช้เป็นไฟร์วอลล์ เพื่อควบคุมการผ่านเข้าออกของ network traffic และเพิ่มความปลอดภัยให้กับระบบ หากยังไม่เข้าใจในเรื่องไฟร์วอลล์ ก็ขอแนะนำให้อ่านบทความเรื่องความรู้พื้นฐานเกี่ยวกับไฟร์วอลล์ หรือหากต้องการทำความรู้จักแบบลึกๆ กับ stateful firewall แล้ว ก็สามารถศึกษาได้จาก http://thaicert.nectec.or.th/paper/firewall/stateful.php เช่นเดียวกัน

ใครควรอ่านบทความฉบับนี้
เหมาะสำหรับผู้ที่มีเครื่องคอมพิวเตอร์จำนวนมากในความดูแล และ/หรือมีการเชื่อมต่อกับอินเทอร์เน็ต มีเครื่องเซิร์ฟเวอร์เปิดให้บริการกับสาธารณชน เช่น web service, ftp service, mail service เป็นต้น และต้องการเพิ่มความปลอดภัยให้กับระบบ เนื่องจากไฟร์วอลล์ทำหน้าที่ควบคุมการเข้าออกของข้อมูลใน port ที่ได้รับอนุญาตเท่านั้น ดังนั้นผู้ที่จะเขียน rule ของไฟร์วอลล์ได้ต้องมีความรู้เกี่ยวกับ TCP/IP พอสมควร และขอย้ำตรงนี้อีกว่า ไฟร์วอลล์ไม่ใช่อุปกรณ์ป้องกันการบุกรุกระบบที่สมบูรณ์ 100% เพราะการโจมตีที่เกิดขึ้นในปัจจุบันนั้นมักจะโจมตีผ่าน port ที่เป็นที่รู้จัก เช่น 21, 22, 25, 53, 80 ซึ่งไฟร์วอลล์มักจะอนุญาตให้ข้อมูลเข้าออกผ่านทาง port เหล่านี้เสมอ ดังนั้นควรใช้เครื่องมืออื่นๆ ช่วย เช่น การตั้งนโยบายความปลอดภัยที่รัดกุม การนำระบบ network intrusion detection มาใช้ หรือแม้แต่มีการจัดการระดับ host based ที่ดี เช่น มีการทำ hardening OS. ใน NOS(network operating system) ทุกๆ เครื่องที่เปิดให้บริการแก่สาธารณะ ก็จะช่วยเพิ่มความปลอดภัยให้กับระบบมากยิ่งขึ้น

กล่าวนำ
จากความรู้พื้นฐานเรื่องไฟร์วอลล์ ก็พอจะทราบว่าไฟร์วอลล์ในปัจจุบันนั้นแบ่งเป็นสองชนิดหลักๆ คือ stateful packet filtering firewall และ proxy server ซึ่งจะมีการตรวจสอบข้อมูลที่ไหลผ่านเข้าออกที่คนละเลเยอร์กัน โดย packet filtering นั้นจะตรวจสอบข้อมูลที่ network layer และ session layer ในขณะที่ proxy นั้นสามารถตรวจสอบข้อมูลที่ application layer ได้ด้วย

Linux สามารถใช้งานเป็นไฟร์วอลล์ได้ตั้งแต่เคอร์เนล 1.1 ซึ่งเป็นเวอร์ชันแรก โดย Alan Cox ใช้ชื่อว่า ipfw (จาก BSD) ต่อมา Linux 2.0 ได้ถูกพัฒนาและปรับปรุงได้เครื่องมือที่มีชื่อว่า ipfwadm โดยเครื่องมือชิ้นนี้อนุญาตให้ผู้ใช้สามารถควบคุม filtering rule ได้ และต่อมา Linux 2.2 ก็ได้สร้างเครื่องมือตัวใหม่ชื่อ ipchains ซึ่งเผยแพร่ในปี 1998 โดย Rusty Russel และทีมงาน ทั้งนี้ ipchains นี้ถือได้ว่าเป็นพัฒนาการขั้นที่สามของ Linux Firewall จวบจนกระทั่งในปัจจุบัน ก็มี netfilter และ iptables ซึ่งถือว่าเป็นพัฒนาการขั้นที่สี่ของ Linux Firewall

Netfilter นั้นเป็นชื่อใหม่ของโค้ดที่ทำหน้าที่เป็น packet handler(stateful inspection) ใน Linux kernel 2.4 (จริงคือเวอร์ชัน 2.3.15 และเวอร์ชันต่อๆ มา) ซึ่งได้ถูกออกแบบและปรับปรุงใหม่จากเวอร์ชันก่อนหน้านี้ เป็นเรื่องที่น่ายินดีคือ netfilter นั้นสามารถทำงานย้อนหลังร่วมกับ ipchains และ ipfwadm ได้ และคำสั่งในการเรียกใช้งานคือ iptables

ความแตกต่างระหว่าง iptables และ ipchains

ดาวน์โหลด
ก่อนที่ใช้งานไฟร์วอลล์ตัวใหม่นี้ได้ ให้ล็อกอินเป็น root และทดลองพิมพ์คำว่า iptables ดูว่าคำสั่งนี้มีอยู่หรือไม่ ถ้าไม่มี ต้องดาวน์โหลดจาก http://netfilter.samba.org โดยให้ดาวน์โหลดเวอร์ชันล่าสุดมา ในที่นี้คือ iptables-1.2.4.tar.bz2 จากนั้นให้ขยายไฟล์และติดตั้งดังคำสั่งด้านล่าง

tar -jxvf iptables-1.2.4.tar.bz2
cd iptables-1.2.4
make
make install

ปรับแต่งเคอร์เนล
หลังจากที่มีคำสั่ง iptables อยู่ในระบบแล้ว บางระบบที่มีเคอร์เนลต่ำกว่า 2.4 จำเป็นต้องคอมไพล์เคอร์เนลใหม่ เพื่อให้ใช้งาน iptables ได้ ทั้งนี้ขอแนะนำให้ใช้เคอร์เนลเวอร์ชันล่าสุด ปัจจุบันคือ 2.4.14 ซึ่งสามารถดาวน์โหลดได้จาก http://www.kernel.org

หลังจากที่ดาวน์โหลดมาแล้วให้ขยายไฟล์ไปไว้ที่ /usr/src/linux จากนั้นใช้คำสั่ง make menuconfig หรืออาจใช้ make xconfig ในกรณีที่ได้ติดตั้ง XWindows ไว้แล้ว โดยต้องมั่นใจว่าได้ enable option ต่างๆ ด้านล่างนี้ ภายใต้ Networking options

<*> Packet socket
[*] Network packet filtering (replaces ipchains)
<*> Unix domain sockets
[*] TCP/IP networking
[*] IP: advanced router
[*] IP: policy routing
[*] IP: use netfilter MARK value as routing key
[*] IP: fast network address translation
[*] IP: use TOS value as routing key

และภายใต้เมนู "IP: Netfilter Configuration -- >" ให้ enable ทุกออปชันเพื่อให้ใช้งาน netfilter ได้เต็มประสิทธิภาพ

แต่มีอีกจุดหนึ่งที่ห้าม enable ภายใต้ "Networking options" คือ

[ ] IP: TCP Explicit Congestion Notification support

เพราะออปชันนี้ จะทำให้บาง packet ที่ออกจาก linux ถูกเซ็ตบิต ECN ไปด้วย ซึ่งจะทำให้ไม่สามารถสื่อสารกับ internet router บางตัวได้

จากนั้นก็ให้คอมไพล์และติดตั้งเคอร์เนลโดยใช้คำสั่งดังตัวอย่างใน Appendix A


รูปแบบการใช้งาน iptables เบื้องต้น
iptables จะมีรูปแบบการใช้งานดังนี้คือ

iptables [table] <command> <match> <target/jump>

โดย rule ที่เขียนขึ้นจะเป็นเป็นตัวบอกเคอร์เนลว่าให้กระทำ action อย่างไร ในกรณีที่พบ packet ตรงตามที่ระบุไว้

Table
iptables สามารถทำงานได้กับตาราง(table) 3 ตารางหลัก สามารถระบุตารางได้โดยใช้ออปชัน -t ตามด้วยชื่อ table คือ

  1. Filter table ใช้สำหรับกรอง packet มี 3 built-in chain คือ INPUT, OUTPUT, FORWARD ซึ่งจะได้อธิบายรายละเอียดต่อไป
  2. Nat table ใช้สำหรับการแปลงแอดเดรส (Network Address Translation) มี 3 built-in chain คือ PREROUTING, POSTROUTING, OUTPUT ซึ่งรายละเอียดจะได้อธิบายต่อไป
  3. Mangle table เป็นตารางที่ใช้เปลี่ยนแปลงหรือแก้ไข packet เช่น เปลี่ยนค่า TTL, MARK ซึ่งปกติจะใช้ในการทำ routing ที่มีความซับซ้อนสูง มี 2 built-in chain คือ PREROUTING chain (ใช้แก้ไข packet ก่อนที่จะเข้าสู่ไฟร์วอลล์และก่อนเข้าสู่ routing decision) และ OUTPUT chain (ใช้แก้ไข packet ที่ถูกสร้างโดยไฟร์วอลล์ก่อนที่มันจะถูกส่งไปยัง routing decision) ทั้งนี้ไม่สามารถทำ network address translation หรือ masquerading ที่ table นี้ได้ และในเอกสารฉบับนี้จะไม่กล่าวถึง mangle อีก เนื่องจากเป็นส่วนที่ไม่นิยมนำไปใช้งาน

Command

การใช้ command ด้านบนนั้นสามารถใช้ร่วมกับออปชันบางอย่างได้ คือ

Match
การตั้งเงื่อนไขของการ match นั้นจะต้องอาศัยความเข้าใจในเรื่อง IP, TCP, UDP, และ ICMP มาบ้างพอสมควร จึงจะสามารถตั้งเงื่อนไขที่เหมาะสมและตรงตามความต้องการได้ ซึ่งมีรายละเอียดดังนี้

การระบุ target
เมื่อมี packet ที่ match กับ rule แล้ว ต้องกำหนด target สำหรับ packet ไว้ด้วย โดยปกติจะใช้กัน 2 target คือ DROP และ ACCEPT นอกจากนี้ยังมี target แบบอื่นได้คือ


Packet เดินทางในระบบอย่างไร
เมื่อ packet เข้ามาถึงไฟร์วอลล์ มันจะผ่านฮาร์ดแวร์เข้ามายัง device ที่เหมาะสมในเคอร์เนล จากนั้น packet จะเดินทางไปเป็นทอดๆ ก่อนที่จะถูกส่งไปยังปลายทางที่แท้จริง เช่น แอพลิเคชันในเครื่องไฟร์วอลล์ หรือ forward ต่อไปยังเครื่องอื่น ซึ่งจะยกตัวอย่างเพื่อให้เห็นภาพอย่างชัดเจนดังนี้

Table 1. Forwarded packet
Step Table Chain Comment
1     ข้อมูลอยู่ในระหว่างการเดินทาง เช่น กำลังมาจากอินเทอร์เน็ต
2     ข้อมูลเข้ามายังเครื่องไฟร์วอลล์ผ่านทาง incoming interface (เช่น eth0)
3 mangle PREROUTING ใช้สำหรับการทำ mangling packet เท่านั้น เช่น เปลี่ยนค่า TOS ของ packet ซึ่งในกรณีปกติแล้วแทบไม่ได้ใช้งาน
4 nat PREROUTING chain นี้ใช้สำหรับทำ Destination Network Address Translation ไม่ควรสร้าง rule เพื่อกรอง packet ที่ chain นี้ เพราะอาจจะมีบาง packet ที่ไม่เข้าสู่ chain นี้ (มีแค่ packet แรกเท่านั้นที่ผ่านเข้าสู่ chain ส่วน packet ถัดไปใน connection เดียวกันนั้น จะถูกกระทำเหมือนกับที่ packet แรกได้รับ)
5     เข้าสู่ Routing decision เพื่อตัดสินใจว่า packet จะถูกส่งไปที่ใด
6 filter FORWARD เนื่องจากในตัวอย่างนี้ packet จะถูกส่งไปยังเครื่องอื่นในเครือข่าย ดังนั้น packet จึงต้องเข้า FORWARD chain ของ filter table ซึ่งสามารถเขียน rule สำหรับควบคุมการผ่านเข้าออกของ packet สำหรับ forwarded packet ได้ที่นี่
7 nat POSTROUTING และก่อนที่ packet จะออกไปจากเครื่องไฟร์วอลล์ โดยส่วนใหญ่(ไม่ใช่ทั้งหมด) จะผ่าน chain นี้ ซึ่งใช้ทำ Source Network Address Translation ไม่ควรสร้าง rule เพื่อกรอง packet ที่ chain นี้ เพราะอาจจะมีบาง packet ที่ไม่เข้าสู่ chain นี้ (มีแค่ packet แรกเท่านั้นที่ผ่านเข้าสู่ chain ส่วน packet ถัดไปใน connection เดียวกันนั้น จะถูกกระทำเหมือนกับที่ packet แรกได้รับ)
8     packet ออกไปทาง outgoing interface (เช่น eth1)
9     packet เดินทางไปสู่เป้าหมาย (เช่น ผ่านทาง LAN)
อย่างที่เห็นจากตาราง forwarded packet คือ packet ที่มีปลายทางที่ไม่ใช่เครื่องไฟร์วอลล์ อาจจะเป็น packet ที่มาจากอินเทอร์เน็ต หรืออาจจะเป็น packet ที่มาจากเครื่องลูกในเครือข่ายที่ต้องการส่งออกไปอินเทอร์เน็ต ซึ่งไม่ว่าจะส่งในทิศทางใด packet ก็จะต้องผ่าน chain ในลักษณะด้านบนนี้เสมอ


Table 2. Destination localhost

Step Table Chain Comment
1     ข้อมูลอยู่ในระหว่างการเดินทาง เช่น กำลังมาจากอินเทอร์เน็ต
2     ข้อมูลเข้ามายังเครื่องไฟร์วอลล์ผ่านทาง incoming interface (เช่น eth0)
3 mangle PREROUTING ใช้สำหรับการทำ mangling packet เท่านั้น เช่น เปลี่ยนค่า TOS ของ packet ซึ่งในกรณีปกติแล้วแทบไม่ได้ใช้งาน
4 nat PREROUTING chain นี้ใช้สำหรับทำ Destination Network Address Translation ไม่ควรสร้าง rule เพื่อกรอง packet ที่ chain นี้ เพราะอาจจะมีบาง packet ที่ไม่เข้าสู่ chain นี้ (มีแค่ packet แรกเท่านั้นที่ผ่านเข้าสู่ chain ส่วน packet ถัดไปใน connection เดียวกันนั้น จะถูกกระทำเหมือนกับที่ packet แรกได้รับ)
5     เข้าสู่ Routing decision เพื่อตัดสินใจว่า packet จะถูกส่งไปที่ใด
6 filter INPUT ทุก packet ที่มีเป้าหมายเป็นเครื่องไฟร์วอลล์จะต้องเข้าสู่ chain นี้เสมอ ไม่ว่าจะมาจาก interface ใดก็ตาม
7     Local process/application (เช่น server/client program)
packet ที่มีปลายทางเป็นเครื่องไฟร์วอลล์นั้น จะต้องผ่าน INPUT chain เสมอ


Table 3. Source localhost

Step Table Chain Comment
1     Local process/application (เช่น server/client program)
2 Mangle OUTPUT ใช้สำหรับการทำ mangling packet เท่านั้น การกรอง packet ที่ chain นี้จะไม่มีผลใดๆ ต่อ packet
3 Nat OUTPUT ไม่ได้ใช้งาน
4 Filter OUTPUT ใช้สำหรับกรอง packet ที่ออกมาจาก localhost หรือเครื่องไฟร์วอลล์เอง
5     เข้าสู่ Routing decision เพื่อตัดสินใจว่า packet จะถูกส่งไปที่ใด
6 Nat POSTROUTING และก่อนที่ packet จะออกไปจากเครื่องไฟร์วอลล์ โดยส่วนใหญ่(ไม่ใช่ทั้งหมด) จะผ่าน chain นี้ ซึ่งใช้ทำ Source Network Address Translation ไม่ควรสร้าง rule เพื่อกรอง packet ที่ chain นี้ เพราะอาจจะมีบาง packet ที่ไม่เข้าสู่ chain นี้ (มีแค่ packet แรกเท่านั้นที่ผ่านเข้าสู่ chain ส่วน packet ถัดไปใน connection เดียวกันนั้น จะถูกกระทำเหมือนกับที่ packet แรกได้รับ)
7     packet ออกไปทาง outgoing interface (เช่น eth1)
8     Local process/application (เช่น server/client program)

จากสามตัวอย่างด้านบน คงพอจะมองเห็นภาพออกแล้วว่า packet เดินทางเข้าออกในระบบอย่างไร อย่างไรก็ตาม จะสรุปความสำคัญของแต่ละตาราง (table) อีกครั้ง ดังนี้

I. Filter Table
เป็นตารางที่ใช้งานมากที่สุด เป็นจุดที่ใช้ในการตรวจสอบและควบคุมการผ่านเข้าออกของ packet ถ้าหากจะพิจารณาการไหลเวียนของ packet เฉพาะในส่วนของ filter table โดยไม่สนใจ table อื่นๆ นั้น ก็พอจะแสดงให้เห็นได้ดังภาพที่ 1 โดยเมื่อ packet เข้ามาในระบบ มันจะเข้าไปยัง routing decision เพื่อตัดสินใจว่า packet จะถูกส่งไปที่ใด


รูปที่ 1 แสดงให้เห็นว่า packet มีเส้นทางการเดินทางอย่างไรเมื่อเข้ามาในระบบ (filter table)

ดังภาพ iptables ประกอบไปด้วย built-in chain จำนวน 3 chain ซึ่งไม่สามารถลบได้คือ INPUT, OUTPUT, FORWARD เมื่อเครื่องคอมพิวเตอร์เริ่มทำงานในครั้งแรก ทั้งสาม chain จะมี default policy เป็น ACCEPT ซึ่งหมายความว่าอนุญาตให้ทุกอย่างผ่านเข้าออกได้หมด และสำหรับ FORWARD chain นั้น ถึงแม้จะได้กำหนดให้ policy เป็น ACCEPT แล้ว packet ก็จะยังไม่สามารถถูก forward ไปยังจุดหมายที่ต้องการได้ ตราบใดที่ยังไม่ได้เซ็ตให้ enable IP forwarding ทั้งนี้โดย default แล้ว forward=0 สามารถกำหนดให้ enable IP forwarding (forward=1) ได้ โดย

ใช้คำสั่ง echo "1" > /proc/sys/net/ip_forward เพื่อกำหนดให้ IP forwarding เป็น enable เพื่อให้ Linux box สามารถ forward ip packet ได้ ในบางครั้งนั้นการใช้คำสั่งดังกล่าวทุกครั้งอาจจะไม่สะดวก สามารถแก้ไขไฟล์ configuration ที่ /etc/sysctl.conf แล้ว set ให้ net.ipv4.ip_forward=1 เพื่อเป็นการแก้ไขแบบถาวร

ในกรณีที่ต้องการให้สนับสนุนการทำงานกับ dynamic IP ด้วย เช่น PPP, SLIP, DHCP ก็สามารถทำได้โดยใช้คำสั่ง echo "1" > /proc/sys/net/ipv4/ip_dynaddr ได้เช่นเดียวกัน

II. Mangle Table
เป็นตารางที่ใช้สำหรับแก้ไขข้อมูล TOS, TTL, MARK ของ packet ซึ่งโดยปกติแล้วแทบจะไม่ได้ใช้งาน และไม่ควรทำ packet filtering หรือกรอง packet ที่ตารางนี้ รวมทั้งไม่ควรทำ DNAT, SNAT หรือ Masquerading ที่ตารางนี้อย่างเด็ดขาดด้วย

III. Nat Table
เป็นตารางที่ใช้สำหรับทำ network address translation เช่น เปลี่ยนค่า source ip address, destination ip address จุดสำคัญอีกอย่างหนึ่งที่ต้องรู้ก็คือ มีเพียง packet แรกเท่านั้นที่เข้ามาที่ chain นี้ ส่วน packet ถัดไปนั้นจะถูกกระทำเหมือนที่ packet แรกได้รับ ดังนั้นจึงไม่ควรทำ packet filtering ที่ chain เหล่านี้

การใช้งาน Nat table นั้นก็เพียงแต่ใช้ออปชัน -t nat เท่านั้น และ target ที่สามารถใช้งานได้คือ SNAT, DNAT, Masquerade, Redirect ซึ่งมีรายละเอียดดังนี้

นอกจากนี้ยังสามารถสร้าง rule ที่ใช้ค่า address ร่วมกันได้ เช่น เปลี่ยน source address ของเครื่อง 192.168.1.1 และ 192.168.1.2 ไปเป็น 1.2.3.4 ร่วมกันได้ เพราะ NAT ฉลาดเพียงพอที่จะแยกแยะและป้องกันการชนกัน และมีตัวอย่างการใช้งานแบบอื่นอีกเช่น

# iptables -t nat -A POSTROUTING -s 192.168.0/24 -o eth1 -j SNAT --to 1.2.3.0/24
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254

และสำหรับการทำ source NAT ต้องมั่นใจว่า เมื่อ packet เดินทางไปถึงเป้าหมายแล้ว packet นั้นๆ สามารถเดินทางกลับมาหาเครื่องที่เป็นเจ้าของ packet นั้นได้จริงๆ เช่น หากทำ SNAT จาก private IP เป็น 1.2.3.4 เมื่อ packet ถูกส่งไปถึงปลายทาง และปลายทางต้องการส่งกลับมา packet นั้นจะต้องเดินทางมาถึง linux box ที่รัน iptables นี้เท่านั้น การสื่อสารจึงจะสมบูรณ์ ซึ่งสามารถทำได้ด้วยวิธีต่างๆ ดังนี้คือ

  1. กรณีที่ทำ SNAT โดยใช้ไอพีแอดเดรสของเครื่อง linux box นั้นเอง และเป็นเครื่องที่ทำ routing เรียบร้อยแล้ว และทุกอย่างสามารถสื่อสารกันได้ ก็ไม่ต้องทำอะไร
  2. ถ้าทำ SNAT โดยใช้ไอพีแอดเดรสที่ไม่ใช่ไอพีของ linux box นั้นๆ แต่เป็นไอพีแอดเดรสที่อยู่ใน network เดียวกันและไม่มีเครื่องใดใช้ เครื่อง linux box นั้นจะต้องสามารถทำ ARP reply ตอบกลับ ARP request ที่ถูกส่งออกมาเพื่อค้นหา MAC address สำหรับไอพีแอดเดรสที่ทำ SNAT นั้นได้ ซึ่งสามารถแก้ไขได้โดยการสร้าง IP alia ดังคำสั่งด้านล่าง
  3. #ip address add 1.2.3.99 dev eth0
    หรืออาจจะเพิ่ม arp record ที่เครื่องที่ทำหน้าที่เป็น gateway ของ linux box

  4. หรือถ้าทำ SNAT โดยใช้ไอพีแอดเดรสที่แตกต่างกันออกไปจาก Linux box โดยสิ้นเชิง (เช่น ไอพีแอดเดรสคนละ network) ก็จำเป็นต้องมีการแก้ไข routing table ที่เครื่องที่ทำหน้าที่เป็น gateway ของ Linux box ที่รัน iptables อยู่

มีเอกสารอธิบายเกี่ยวกับความปลอดภัยในการใช้ NAT ที่ http://thaicert.nectec.or.th/paper/firewall/nat.php ซึ่งหลังจากอ่านแล้วจะช่วยให้มองเห็นภาพได้ชัดเจนว่า ต้องทำ NAT หรือไม่อย่างไร


ตัวอย่างที่ 1 การใช้งาน iptables แบบง่าย
ในการใช้งาน iptables ในระบบที่ใช้งานจริงนั้น โดยส่วนใหญ่จะเขียนเป็น script ขึ้นมา ซึ่งมีความซับซ้อนพอสมควร ซึ่งก่อนจะไปถึงขั้นนั้นมีวิธีทดลองใช้คำสั่งง่ายๆ เพื่อทำความเข้าใจหลักการทำงานเบื้องต้นของ iptables

เช่น ต้องการ drop packet ที่เป็น ICMP ทั้งหมด ที่ออกจากเครื่องนี้ ซึ่งในกรณีนี้ไม่จำเป็นต้องระบุ source ip address เพราะทุก packet ที่ออกจากเครื่องนี้จะต้องผ่านการตรวจสอบจาก OUTPUT chain

เริ่มการทดสอบโดยทดลอง ping ไปยัง www.nectec.or.th ซึ่งจะได้ผลลัพธ์คล้ายด้านล่างนี้

# ping -c 1 www.nectec.or.th
PING www.nectec.or.th (202.44.204.33) from 203.154.207.22 : 56(84) bytes of data.
64 bytes from www.nectec.or.th (202.44.204.33): icmp_seq=0 ttl=61 time=3.710 msec

--- www.nectec.or.th ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/mdev = 3.710/3.710/3.710/0.000 ms

ซึ่ง option -c 1 ระบุให้ส่ง packet ออกไปแค่ packet เดียว จากนั้นให้ใช้คำสั่งดังด้านล่างนี้ เพื่อ block ICMP packet ที่จะออกจากเครื่องนี้

# iptables -A OUTPUT -p icmp -j DROP

จากนั้นทดลอง ping อีกครั้ง เพื่อตรวจสอบผลลัพธ์ที่ได้

# ping -c 1 www.nectec.or.th
PING www.nectec.or.th (202.44.204.33) from 203.154.207.22 : 56(84) bytes of data.
ping: sendto: Operation not permitted

--- www.nectec.or.th ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

ซึ่งผลลัพธ์แสดงให้เห็นว่า ICMP echo-request packet ดังกล่าวไม่ได้รับอนุญาตให้ผ่าน OUTPUT chain ไปได้ และถ้าหากต้องการลบ rule ดังกล่าวก็สามารถทำได้หลายวิธีคือ

# iptables -F OUTPUT (ซึ่งจะลบทุก rule ใน chain OUTPUT นี้)
# iptables -D OUTPUT 1 (เนื่องจากรู้ว่ามี rule เดียวจึงสามารถสั่งลบ rule ลำดับที่ 1 ได้เลย) หรือ
# iptables -D OUTPUT -p icmp -j DROP (ลบ rule โดยการระบุออปชันของ rule ที่ต้องการได้โดยตรง)


ตัวอย่างที่ 2 การทำ Masquerading
ตัวอย่างการใช้งาน masquerading ที่เห็นได้ชัดเจนในประเทศไทยก็คือ ร้านอินเทอร์เน็ตคาเฟ่(แบบประหยัด) ซึ่งนิยมใช้โมเด็ม 1 ตัว connect ไปยัง ISP แล้วใช้ NAT เพื่อให้เครื่องลูกที่มีอยู่หลายๆ เครื่องนั้น สามารถใช้งานอินเทอร์เน็ตผ่านโมเด็มตัวนั้นได้ โดยเครื่องลูกจะต้องใช้ private ip ซึ่งมีให้เลือกหลาย class เช่น 10.x.x.x 192.168.x.x เป็นต้น จากนั้นก็ตั้ง gateway ให้ชี้ไปยัง linux box ที่ทำหน้าที่หมุนโมเด็มและรัน iptables ซึ่งสามารถใช้คำสั่งง่ายๆ ดังด้านล่างก็ทำให้เครื่องลูกสามารถใช้งานอินเทอร์เน็ตได้แล้ว คือ

# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
#
echo "1" > /proc/sys/net/ip_forward


ตัวอย่างที่ 3 การเขียน rule จากเครือข่ายตัวอย่าง rc.firewall (ตัวอย่างเครือข่ายและ script นี้คัดลอกมาจากเว็บไซต์ www.boingworld.com)

จากภาพแสดงเครือข่ายที่มีการเชื่อมต่อกับอินเทอร์เน็ตแบบถาวร โดยไม่ได้ใช้ DHCP, PPP, SLIP ซึ่งสามารถใช้ script จากไฟล์ rc.firewall.txt


ตัวอย่างที่ 4 การเขียน rule จากเครือข่ายตัวอย่าง rc.DMZ.firewall (ตัวอย่างเครือข่ายและ script นี้คัดลอกมาจากเว็บไซต์ www.boingworld.com)

สำหรับ script ของเครือข่ายด้านบนนี้ ดูได้ที่ rc.DMZ.firewall.txt ซึ่งเขียนขึ้นสำหรับผู้ที่มีการใช้งานเครือข่ายดังรูปด้านบน ซึ่งประกอบไปด้วย trusted internal network หรือเครือข่ายภายในที่ไว้ใจได้ และ DMZ (De-Militarized Zone) และมีการเชื่อมต่ออินเทอร์เน็ต ในกรณีนี้ไอพีปลอมที่ใช้ภายใน DMZ จะถูกทำ NAT แบบ 1 ต่อ 1 ซึ่งจำเป็นต้องทำ IP alias ที่ eth0 ของเครื่องไฟร์วอลล์ เพื่อให้ packet สามารถเดินทางกลับมาถึงเครื่องไฟร์วอลล์ได้

ส่วนของ trusted internal network นั้น จะใช้ไอพี 192.168.0.0/24 และส่วนของ DMZ นั้นใช้ 192.168.1.0/24 ซึ่งจะถูกทำ NAT แบบ 1ต่อ 1 กับไอพีที่ได้รับจัดสรรมาจาก ISP ตัวอย่าง ถ้ามี packet จากอินเทอร์เน็ตส่งมายัง DNS_IP ก็จะถูกทำ DNAT (destination network address translation) ที่เครื่องไฟร์วอลล์ ซึ่งจะส่ง packet ไปยัง DNS ใน DMZ โดยใช้ไอพีภายใน (คือ 192.168.1.3) มีโค้ดตัวอย่างการทำ DNAT คือ

$IPTABLES -t nat -A PREROUTING -p TCP -i $INET_IFACE -d $DNS_IP --dport 53 -j DNAT --to-destination $DMZ_DNS_IP


ตัวอย่างที่ 5 การเขียน rule จากเครือข่ายตัวอย่าง rc.DHCP.firewall (ตัวอย่างเครือข่ายและ script นี้คัดลอกมาจากเว็บไซต์ www.boingworld.com)

script สำหรับเครือข่ายนี้ดูได้ที่ rc.DHCP.firewall.txt ซึ่งเหมาะสำหรับเครือข่ายที่ได้รับไอพีมาแบบไม่คงที่ โดยใช้งานได้ทั้งกับ DHCP, PPP และ SLIP ซึ่ง script นี้มีความปลอดภัยน้อยกว่า rc.firewall.txt เพราะมีการเปิดกว้างมากกว่า


ตัวอย่างที่ 6 การเขียน rule จากเครือข่ายตัวอย่าง rc.UTIN.firewal (ตัวอย่างเครือข่ายและ script นี้คัดลอกมาจากเว็บไซต์ www.boingworld.com)

script สำหรับเครือข่ายนี้ดูได้ที่ rc.UTIN.firewall.txt ซึ่งเหมาะสำหรับเครือข่ายที่ที่ต้องการความปลอดภัยสูง เพราะเป็นเครือข่ายที่ไม่ไว้ใจแม้กระทั่งเครือข่ายภายใน


ตัวอย่างที่ 7 rc.flush-iptables.txt (script นี้คัดลอกมาจากเว็บไซต์ www.boingworld.com)

script สำหรับตัวอย่างนี้ดูได้ที่ rc.flushiptables.txt ซึ่ง script นี้มีไว้เพื่อ reset และลบ rule ทั้งหมดในทุก table และทุก chain ทิ้งไป


คำอธิบายเพิ่มเติม
เนื่องจากในตัวอย่างที่ 3 - 6 นั้น มีการสร้าง rule ที่ค่อนข้างซับซ้อน จึงจะยกมาขยายความเพิ่มเติมคือ

คำแนะนำเพิ่มเติม

แต่ script ดังกล่าวนี้ไม่ได้ป้องกันการปลอมไอพีสำหรับทั้งเครือข่าย ดังนั้นจึงต้องสร้าง rule ไว้ที่ PREROUTING chain เพื่อป้องกันปัญหานี้อีกครั้ง เช่น

การป้องกันการปลอมไอพีดัง rule ด้านบนนี้ สามารถลดปัญหาที่จะเกิดขึ้นจากการโจมตีแบบ Denial of Service เช่น Land attack ได้เป็นอย่างดี


การนำไปใช้งาน
การนำ iptables ไปใช้งานจริงนั้น จะต้องสร้าง rule ขึ้นมาให้สอดคล้องกับเครือข่ายที่มีอยู่ และระดับความปลอดภัยที่ต้องการ ทั้งนี้มีข้อแนะนำมากมายเกี่ยวกับการเขียน rule ของ iptables และเนื่องจากมีรายละเอียดและตัวอย่างค่อนข้างเยอะ รวมทั้งวิธีการ audit firewall ที่ implement ไปแล้วว่าตรงกับความต้องการหรือไม่ ดังนั้นจึงจำเป็นต้องแยกเอกสารออกเป็นอีกฉบับหนึ่ง เพื่อไม่ให้เอกสารนี้มีความยาวมากเกินไป ซึ่งจะนำเสนอในโอกาสต่อไป


Appendix A

คำสั่งที่ใช้ในการคอมไพล์เคอร์เนล

make dep
make clean
make bzImage
make modules

#รันคำสั่งนี้ในกรณีที่คอมไพล์เคอร์เนลแบบเลือก module ด้วย
make modules_install
#รันคำสั่งนี้ในกรณีที่คอมไพล์เคอร์เนลแบบเลือก module ด้วย
cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz-2.4.14
#การ copy bzImage นั้น ขึ้นอยู่กับสถาปัตยกรรมของเครื่องคอมพิวเตอร์นั้นๆ ซึ่งในที่นี้ใช้ i386
cp /usr/src/linux/System.map /boot/System.map-2.4.14
ln -s /boot/System.map-2.4.14 .boot/System.map
#ถ้าได้รับ error ให้ลบไฟล์ /boot/System.map ทิ้งก่อน

จากนั้นให้แก้ไข /etc/lilo.conf เพื่อเพิ่ม configuration ใหม่ ตัวอย่างด้านล่างแสดง Red Hat Linux ที่มีเคอร์เนลเดิมเป็น 2.4.3-12 และเคอร์เนลใหม่เป็น 2.4.14

boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
message=/boot/message
default=linux-2.4.14

image=/boot/vmlinuz-2.4.14
label=linux-2.4.14
read-only
root=/dev/hda1

image=/boot/vmlinuz-2.4.3-12
label=linux-2.4.3-12
read-only
root=/dev/hda1

หลังจากนั้นรันคำสั่ง lilo -v และรีบูตใหม่ ถ้าไม่มีข้อผิดพลาดใดๆ ก็จะได้เคอร์เนลของ Linux เวอร์ชันล่าสุดที่สนับสนุนการทำงานของ iptables อย่างเต็มที่ ทั้งนี้ขอแนะนำให้ใช้เวอร์ชันล่าสุดที่สูงกว่า 2.4.3 เพราะเวอร์ชัน 2.4.3 (และต่ำกว่า) นั้นมีข้อผิดพลาด (bug) ของ ftp port รายละเอียดของข้อผิดพลาดนี้อ่านได้ที่ http://netfilter.samba.org/security-fix/index.html#desc-ftp-160401 และสำหรับผู้ที่มีปัญหากับการคอมไพล์และติดตั้งเคอร์เนลนั้น สามารถศึกษาเพิ่มเติมได้จาก The Linux Kernel HOWTO
หมายเหตุ คำสั่งทั้งหมดที่ใช้ในการอัพเกรดเคอร์เนลด้านบนนั้น ได้ผ่านการทดลองใช้บน Red Hat Linux 7.1 เท่านั้น


ข้อมูลอ้างอิง



Home || เอกสารเผยแพร่ || Firewall

ThaiCERT Disclaimer | Copyright © 2001 ThaiCERT(NECTEC). All rights reserved.