วันศุกร์ที่ 29 มิถุนายน พ.ศ. 2555

iptable


Firewall คือ อุปกรณ์ที่ใช้เพิ่มระดับความปลอดภัยให้กับ network โดยเป้นตัวกันระหว่าง network ภายในหน่วยงานกับ networkภายนอกหน่วยงาน เช่น Internet และคอยป้องกันแพ็กเก็ตอันตรายไม่ให้วิ่งเข้ามายังเน็ตเว็คภายในได้ เราสามารถใช้ Linux ทำเป็นFirewall IPTABLES ได้โดยการติดตั้ง IPTABLES


ไอพีเทเบิล เป็นคำลั่งบนลีนุกซ์ ที่ใช้ปรับแต่งให้กับระบบ เพื่อให้สามารถกรองแพ็กเก็ต (filter)และสามารถทำการแปลงแอดเดรสได้อีกด้วยโดยคำสั่งนี้มีมาพร้อมกับลี นุกซ์ เคอร์เนลเวอร์ชั่น 2.4 ขึ้นไป สามารถใช้งานได้โดยไม่ต้องคอมไพล์เคอร์เนลใหม่


ประวัติความเป็นมา/ทฤษฏีพื้นฐานที่เกี่ยวข้อง


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)


รูปแบบการใช้งาน iptables เบื้องต้น จะมีรูปแบบการใช้งานดังนี้คือiptables <command> <match> <target/jump> โดยกฎ (rule)ที่เขียนขึ้นจะเป็นเป็นตัวบอกเคอร์เนลว่าให้กระทำอย่างไรในกรณีที่พบ แพ็กเก็ตตรงตามที่ระบุไว้ หมายถึง ตาราง ที่ต้องการระบุ มี 3 ตาราง คือ ฟิลเตอร์เทเบิล (Filter table) แนตเทเบิล (Nat table) และ แมงเกิล (Mangle table) เช่น iptables -t nat หมายถึงให้ทำงานกับแนตเทเบิล ในกรณีที่ไม่ได้ระบุตาราง ไอพีเทเบิล จะถือว่าคำสั่งดังกล่าวระบุถึงฟิลเตอร์เทเบิล โดยอัตโนมัติ
<command> จะเป็นตัวสั่งให้ไอพีเทเบิลทำในสิ่งที่ต้องการ เช่น iptables -A INPUT ซึ่งหมายถึงให้สร้างกฎต่อท้ายอินพุตเชน (INPUT chain) ในฟิลเตอร์เทเบิล
<match> เป็นส่วนที่ใช้ตรวจสอบว่าแพ็กเก็ต มีข้อมูลตรง (match) กับที่ระบุไว้หรือไม่ เช่น มีไอพีแอดเดรสต้นทาง (source ip address) เป็น 1.2.3.4 
<target/jump> เป็นตัวระบุว่าเมื่อเจอแพ็กเก็ต ที่ตรง (match) ก็จะกระทำ (action) ตามที่ระบุไว้ เช่น ถ้าแพ็กเก็ตใดมีไอพีแอดเดรสต้นทาง (source ip address) เป็น 1.2.3.4 ให้ทิ้งแพ็กเก็ตนั้น (DROP packet )


ตัวอย่างคำสั่งไอพีแอดเดรส




• -A เพิ่มกฎใหม่ ต่อท้ายเชน (chain) (Append rule) เช่น 


iptables -A INPUT -p ALL -i eth0 -j ACCEPT


• -D ลบกฎ (Delete rule) เช่น 


iptables -D INPUT --dport 80 -j DROP


• -I เพิ่มกฎใหม่ ในเชน (Insert rule) เช่น 


iptables -I OUTPUT -p ALL -s 127.0.0.1/32 -j ACCEPT


• -R แทนที่กฎเดิม ด้วยกฎใหม่ (Replace rule)


• -L แสดงกฎทั้งหมดในเชน (ถ้าไม่ระบุเชนจะแสดงกฎ ทั้งหมดในฟิลเตอร์เทเบิลทั้งสาม built-in chain) เช่น 


iptables -L
iptables -L -t nat
iptables -L INPUT


• -F ลบกฎทั้งหมดในเชน ทิ้ง เช่น 


iptables -F INPUT
iptables -F mychain


• -Z ใช้ reset byte counter สำหรับทุกกฎ ในเชน ที่กำหนด เช่น 


iptables -Z INPUT


• -N ใช้สร้างเชน ใหม่ เช่น 


iptables -N mychain


• -X ลบเชน ที่ไม่มีกฎ ซึ่งสามารถลบ user-defined chain ที่ไม่มีกฎ ได้ แต่ไม่สามารถลบ built-in chain ได้ เช่น 


iptables -X emptychain


• -P เปลี่ยน default policy ของเชน ค่าที่ใช้ได้คือ ACCEPT, DROP ทั้งนี้ค่านี้มีความสำคัญอย่างมากเพราะหากแพ็กเก็ตถูกส่งเข้ามาในเชน แล้ว และไม่ตรงกับกฎ ใดๆ เลย แพ็กเก็ตนั้นก็ต้องถูกตัดสินใจโดย policy ของเชน นั้นๆ เช่น 


iptables -P FORWARD DROP


ซึ่งหากแพ็ก เก็ตถูกส่งเข้ามายังฟอร์เวิร์ดเชน (FORWARD chain) และไม่ตรงกับกฎใดๆใน ฟอร์เวิร์ดเชน นี้เลย แพ็กเก็ตนั้นถูกทิ้งทันที • -E ใช้เปลี่ยนชื่อ chain ใหม่ เช่น 


iptables -E myoldchain mynewchain 


การ ใช้คำสั่ง ด้านบนนั้นสามารถใช้ร่วมกับออปชันบางอย่างได้ คือ • -V, --verbose ใช้ร่วมกับ -L, -A, -I, -D, -R เพื่อให้แสดงจำนวนไบต์ ที่ ตรงกับกฎ ออกมาด้วย (หน่วยเป็นได้ทั้ง K(x1,000),M(x1,000,000),G(x1,000,000,000)) เช่น 


iptables -L –v


• -x, --exact ใช้ร่วมกับ -L และ -v เพื่อให้แสดงจำนวนแพ็กเก็ต และจำนวนของไบต์ ข้อมูลที่ตรงกับกฎ โดยไม่ให้แสดงผลในหน่วยของ K,M,G เช่น 


iptables -L OUTPUT -v –x


• -n, --numeric ใช้ร่วมกับ -L เพื่อสั่งให้ไอพีเทเบิล แสดงข้อมูลไอพีแอดเดรสและพอร์ต เป็นตัวเลขเท่านั้น เช่น 


iptables -L OUTPUT -n 


• --line-numbers ใช้ร่วมกับ -L เพื่อแสดงเลขบรรทัดของกฎ ซึ่งตัวเลขที่แสดงนี้จะสามารถใช้ได้กับคำสั่งเพิ่มกฎใหม่ในเชน ( insert rule) ที่ระบุเป็นลำดับที่ของกฎ เช่น 


iptables -L --line-numbers


• --modprobe=command เพื่อโหลดโมดูล (module) ที่เกี่ยวข้อง




Match


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


สามารถระบุไอพีแอดเดรสต้นทาง (source ip address) ของแพ็กเก็ต โดยใช้ -s หรือ --source หรือ --src และสำหรับไอพีแอดเดรสปลายทาง (destination ip address) ก็ใช้ -d หรือ --destination หรือ –dst
การทำ Inversion


ในบางกรณีนั้นหากต้องการระบุเป็นอินเวิร์ส (inverse) เช่น อนุญาตให้ทุกไอพียกเว้นไอพีที่ระบุไว้ ซึ่งการใช้คำสั่งดังกล่าวสามารถทำได้โดยใช้เครื่องหมาย ! นำหน้า argument ที่ต้องการ (เครื่องหมาย ! หมายถึง NOT) เช่น -p ! TCP ซึ่งจะตรง กับโพรโตคอลทุกๆ ตัวที่ไม่ใช่ทีซีพี หรือ -s ! localhost ซึ่งหมายถึงแพ็กเก็ต ที่มีไอพีแอดเดรสต้นทาง อื่นๆ ยกเว้น localhost (127.0.0.1)
การระบุโพรโตคอล


สามารถระบุโพรโตคอลที่ต้องการได้ดังนี้คือ ทีซีพี (TCP), ยูดีพี (UDP), ไอซีเอ็มพี (ICMP) หรือสามารถใช้ตัวเลขแทนได้ (สำหรับ *NIX อ้างอิงได้จาก /etc/protocols) และยังสามารถใช้ได้ทั้งตัวอักษรเล็กหรือใหญ่ (ใช้ได้ทั้ง tcp และ TCP) เช่น -p TCP หรือ -p ! tcp
การระบุ interface


-i หรือ --in-interface ตามด้วยชื่ออินเตอร์เฟส ( interface) ใช้เพื่อระบุ incoming interface ซึ่งหมายถึงว่า แพ็กเก็ต ที่จะตรงกับกฎ นี้ต้องเข้ามาจากอินเตอร์เฟส ที่กำหนด เช่น -i eth0 หมายความว่า ทุกแพ็กเก็ต ที่เข้ามาทาง eth0 จะ ตรงกับกฎ นี้ ทั้งนี้ชื่ออินเตอร์เฟส ที่สามารถใช้ได้นั้น สามารถตรวจสอบได้โดยใช้คำสั่ง ifconfig และ -o หรือ --out-interface ตามด้วยชื่อของอินเตอร์เฟส ใช้เพื่อระบุ outgoing interface ซึ่งหมายถึงว่า แพ็กเก็ต ที่จะ ตรงกับกฎ นี้ กำลังจะเดินทางผ่านอินเตอร์เฟส ที่ระบุไว้ เช่น -o eth1 หรือ -o ! eth1
ragment packet


ในการส่งข้อมูลใน ip network นั้นเป็นเรื่องปกติที่จะเกิดการแฟรกเมนต์ (fragment)ของแพ็กเก็ตเนื่องจากขนาดของแพ็กเก็ต มีขนาดใหญ่เกินไปที่จะส่งไปในครั้งเดียว จำเป็นต้องมีการแบ่งแพ็กเก็ต ออกเป็นหลายๆ ชิ้นทยอยส่งไป ซึ่งเรียกกันว่าการทำแฟรกเมนต(fragment)โดยเครื่องปลายทางจะทำหน้าที่ประกอบ แฟรกเมนต์แพ็กเก็ต(fragment packet)รวมกันเป็นแพ็กเก็ต ที่สมบูรณ์ดังเดิม ข้อมูลที่เป็นแฟรกเมนต์แพ็กเก็ต นั้นจะมีเฮดเดอร์ (header)ที่สมบูรณ์แค่แพ็กเก็ต แรกเท่านั้น ส่วนแพ็กเก็ต ที่ตามมาจะมีแค่เฮดเดอร์ บางส่วนคือ ไอพีแอดเดรสเท่านั้น ไม่มีข้อมูลของโพรโตคอลแนบมาด้วย ดังนั้นการตรวจสอบข้อมูลเฮดเดอร์ ของ ทีซีพี ยูดีพี ไอซีเอ็มพี จึงไม่สามารถทำได้ในแพ็กเก็ต ที่สองเป็นต้นมา หากใช้แนต (NAT)แพ็กเก็ตประเภทแฟรกเมนต์แพ็กเก็ต จะถูกประกอบเข้าด้วยกันจนสมบูรณ์ก่อนที่ แพ็กเก็ต จะเข้าไปถึง แพ็กเก็ตฟิลเตอร์ริ่ง (packet filtering) ดังนั้นจึงไม่มีความจำเป็นที่จะต้องกังวลเกี่ยวกับ แฟรก-เมนต์แพ็กเก็ต ในกรณีที่ไม่ได้ใช้แนต (NAT) แพ็กเก็ตประเภทแฟรกเมนต์แพ็กเก็ตก็จะไม่ถูกประกอบเข้าด้วยกัน ไอพีเทเบิล จะมีกระบวนการในการทำงานกับ แฟรกเมนต์แพ็กเก็ตดังนี้ หลังจากที่แฟรกเมนต์แพ็กเก็ตแรกผ่านเข้ามาแล้วไอพีเทเบิล สามารถตรวจสอบได้ว่าจะอนุญาตให้ผ่านหรือไม่ ในขณะที่แฟรกเมนต์แพ็กเก็ต ที่สองและหลังจากนั้นที่ตามมานั้น จะไม่สามารถนำไปตรวจสอบกับกฎ ใดๆ เลย เช่น -p TCP --sport www หรือแม้แต่ -p TCP --sport ! www แต่ยังสามารถเขียนกฎ ให้ตรวจสอบทั้งแฟรกเมนต์แพ็กเก็ต ตัวที่สองและหลังจากนั้นที่ตามมาได้ด้วยการใช้ -f หรือ --fragment ทั้งนี้อาจจะเขียนในทางตรงข้ามคือไม่ต้องตรวจสอบแฟรกเมนต์แพ็กเก็ต ที่สองและหลังจากนั้นโดยใช้ ! -f ก็ได้ โดยปกติแล้วมักจะปล่อยให้แฟรกเมนต์แพ็กเก็ต ผ่านไป เนื่องจากถ้าสามารถทิ้งแฟรกเมนต์แพ็กเก็ตแรกได้แล้ว แพ็กเก็ตทั้งหมดก็จะไม่สามารถถูกประกอบที่เครื่องปลายทางได้ แต่ทั้งนี้แฟรกเมนต์แพ็กเก็ต ที่ถูกปล่อยไปดังกล่าวอาจจะทำให้เครื่องที่ได้รับนั้นเกิดการชะงัก หรือเกิดความเสียหายได้ หรืออาจจะเกิดการโจมตีแบบดีไนอัลออฟเซอร์วิส (Denial of Service) โดยใช้แฟรกเมนต์แพ็กเก็ตได้
การระบุ target


user-defined chain


เนื่องจากไอพีเทเบิล อนุญาตให้ผู้ใช้สามารถสร้างเชน (chain) ขึ้นมาได้ใหม่นอกเหนือจากเชนที่มีมาอยู่แล้ว (built-in chain) ทั้งสามตัว (INPUT, OUTPUT, FORWARD) ทั้งนี้จะต้องใช้ตัวอักษรตัวเล็กทั้งหมดสำหรับเชน ที่ผู้ใช้สร้างขึ้นเอง เมื่อแพ็กเก็ตตรงกับกฎ ที่เป็นเชนที่ผู้ใช้กำหนดขึ้น (user-defined chain) แพ็กเก็ตนั้นจะถูกนำไปตรวจสอบใหม่โดยเชนที่ผู้ใช้กำหนด นั้นๆ และถ้าในเชนนั้นๆ ไม่มีการตัดสินใจใดๆ แพ็กเก็ตนั้นก็สามารถย้อนกลับมายังกฎ ถัดไปในเชนที่เริ่มต้นเดินทางได้


new target


เป็น target ที่สร้างเพิ่มเติมขึ้นมาคือ


LOG เป็น โมดูลที่มีความสามารถในการเก็บข้อมูลลงล็อก (มี syslog facility เป็น kernel) สำหรับแพ็กเก็ตที่ตรงกับกฎที่ระบุปลายทาง เป็น LOG มีออปชันให้เลือกใช้งานดังนี้คือ--log-level เป็นการระบุ priority level ของ log ซึ่งกำหนดได้ตั้งแต่ debug, info ,notice, warning, crit, alert, emerg--log-prefix ตามด้วยชุดของตัวอักษรยาวไม่เกิน 29 ตัว ซึ่งชุดของตัวอักษรดังกล่าวจะปรากฏอยู่บนล็อกไฟล์
ความสำคัญของ 3 ตารางหลัก ในคำสั่งไอพีเทเบิล


1.Filter Table เป็น ตารางที่ใช้งานมากที่สุด เป็นจุดที่ใช้ในการตรวจสอบและควบคุมการผ่านเข้าออกของแพ็กเก็ต ถ้าหากจะพิจารณาการไหลเวียนของแพ็กเก็ต เฉพาะในส่วนของฟิลเตอร์เทเบิล (filter table) โดยไม่สนใจเทเบิล อื่นๆ นั้น ก็พอจะแสดงให้เห็นได้ดังรูปที่ 2.20 โดยเมื่อแพ็กเก็ต เข้ามาในระบบ มันจะเข้าไปยัง routing decision เพื่อตัดสินใจว่า แพ็กเก็ต จะถูกส่งไปที่ใด
2.Mangle Table เป็นตารางที่ใช้สำหรับแก้ไข ข้อมูล TOS, TTL, MARK ของแพ็กเก็ต ซึ่งโดยปกติแล้วแทบจะไม่ได้ใช้งาน และไม่ควรทำ packet filtering หรือกรองแพ็กเก็ต ที่ตารางนี้ รวมทั้งไม่ควรทำ DNAT, SNAT หรือ Masquerading ที่ตารางนี้อย่างเด็ดขาดด้วย
3.Nat Table เป็น ตารางที่ใช้สำหรับทำการแปลงแอดเดรส (network address translation) เช่น เปลี่ยนค่าไอพีแอดเดรสต้นทางและปลายทาง (source ip address, destination ip address) จุดสำคัญอีกอย่างหนึ่งที่ต้องรู้ก็คือ มีเพียงแพ็กเก็ต แรกเท่านั้นที่เข้ามาที่เชน นี้ ส่วนแพ็กเก็ต ถัดไปนั้นจะถูกกระทำเหมือนที่แพ็กเก็ต แรกได้รับ ดังนั้นจึงไม่ควรทำ packet filtering ที่เชน เหล่านี้


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


SNAT 


การทำ source NAT จะทำที่ POSTROUTING chain โดย หลักๆ คือทำการเปลี่ยนแอดเดรสต้นทาง (source address) ก่อนที่จะส่งแพ็กเก็ตนั้นออกไป ซึ่งสามารถใช้ออปชัน -o (outgoing interface) ร่วมด้วยได้ นอกจากนี้ยังใช้ -j SNAT และ --to--source หรือ --to เพื่อเปลี่ยนไอพีแอดเดรสหรือ port ไปตามต้องการได้ เช่น


เปลี่ยน source ip address เป็น 1.2.3.4


iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4


เปลี่ยน source address เป็น 1.2.3.4, 1.2.3.5 หรือ 1.2.3.6


iptables -t nat -A POSTROUING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6


เปลี่ยน source address เป็น 1.2.3.4 port 1-1023


iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023


Masquerading 


การ ทำ masquerade นั้นเป็นหนึ่งในรูปแบบของการทำ source NAT แบบพิเศษ ซึ่งใช้สำหรับ กรณีที่ได้รับไอพีแบบไม่ซ้ำ(dynamically-assigned IP address) เช่น ผู้ที่ใช้โมเด็มล็อกอินเข้าไปยัง isp (สำหรับผู้ที่ใช้ static IP address ให้ใช้ SNAT ดังตัวอย่างด้านบน) ซึ่งข้อดีของการทำ masquerading คือไม่จำเป็นต้องระบุค่าของไอพีแอดเดรสที่จะใช้ในการเปลี่ยน เช่น


ทำ masquerade สำหรับทุก packet ที่วิ่งผ่าน ppp0


iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE


DNAT 


การ ทำ Destination NAT จะทำภายใต้ PREROUTING chain หลักๆ คือการเปลี่ยนค่า destination address หรือ port ก่อนที่จะส่งpacket ไปยัง routing decision โดยปกติการใช้งานจะระบุ -j DNAT และใช้ --to-destination หรือ --to และยังสามารถใช้ -i(incoming interface) ร่วมด้วยได้ เช่น


เปลี่ยน destination address เป็น 192.168.1.20


iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 192.168.1.20


เปลี่ยน destination address เป็น 192.168.1.20, 192.168.1.21 หรือ 192.168.1.22


iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 192.168.1.20-192.168.1.22


เปลี่ยน destination address ของ web traffic เป็น 192.168.1.50 port 8080


iptables -t nat -A PREROUING -p tcp --dport 80 -ieth0 -j DNAT --to 192.168.1.50:80


Redirection 


การทำ redirect นั้นเป็นหนึ่งในรูปแบบของการทำ Destination NAT แบบพิเศษ เช่น


เปลี่ยน web traffic ธรรมดาให้ผ่านไปยัง squid proxy (transparent)


ip tables -t nat -A PREROUTING -p tcp -i eth0 --dport 80 -j REDIRECT --to-port 3128


ตัวอย่าง การทำ Masquerading


ตัวอย่าง การใช้งาน masquerading ที่เห็นได้ชัดเจนในประเทศไทยก็คือ ร้านอินเทอร์เน็ตคาเฟ่(แบบประหยัด) ซึ่งนิยมใช้โมเด็ม 1 ตัว ติดต่อ(connect)ไปยัง ไอเอสพี (Internet Service Provider) แล้วใช้ NAT เพื่อให้เครื่องลูกที่มีอยู่หลายๆ เครื่องนั้น สามารถใช้งานอินเทอร์เน็ตผ่านโมเด็มตัวนั้นได้ โดยเครื่องลูกจะต้องใช้ private ip ซึ่งมีให้เลือกหลายคลาส (class) เช่น 10.x.x.x 192.168.x.x เป็นต้น จากนั้นก็ตั้งเกตเวย์ให้ชี้ไปยัง linux box ที่ทำหน้าที่หมุนโมเด็มและรันไอพีเทเบิล ซึ่งสามารถใช้คำสั่งง่ายๆ ดังด้านล่างก็ทำให้เครื่องลูกสามารถใช้งานอินเทอร์เน็ตได้แล้ว คือ
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
echo "1" > /proc/sys/net/ip_forward




เครดิต www.linuxthai.org

ไม่มีความคิดเห็น:

แสดงความคิดเห็น