บนลีนุกซ์มีคุณสมบัติ firewall ติดตั้งมาให้สามารถเลือกอนุญาต หรือปฏิเสธการ รับ/ส่ง packet เข้า/ออกเครื่องได้
จุดมุ่งหมายหลักๆ ของ firewall ก็เพื่อเพิ่มความปลอดภัยให้กับเครื่องเซิร์ฟเวอร์
หลายคนมักจะปิดคุณสมบัตินี้ไป ด้วยเหตุผลบอกว่ายากต่อการทำความเข้าใจ และแก้ไข
ในบทความนี้จะอธิบายการใช้คำสั่ง iptables เพื่อแสดงสถานะ firewall ที่เปิดใช้งาน การเพิ่ม rule เพื่ออนุญาตการเชื่อมต่อ การลบ rule ที่ไม่ได้ใช้แล้ว
ลองทำตามดู ในหลายเซอร์วิส เพียงแค่แก้ไข rule นิดเดียวเท่านั้น ก็จะใช้งานได้แล้ว ไม่จำเป็นต้องปิดคุณสมบัติ firewall แต่อย่างได้
แสดง (list) rule ที่เปิดใช้งานอยู่
ใช้คำสั่ง iptables ออปชั่น “-L” เพื่อแสดงคอนฟิก firewall ที่เปิดใช้งานอยู่
ออปชั่นเพิ่มเติม ที่มักจะใช้ร่วมกับออปชั่น “-L”
- ออปชั่น “-v” เพื่อแสดงรายละเอียดเพิ่มเติมของ rule เช่นผลรวมสะสมของจำนวน packets (pkts) ขนาด (bytes)
- ออปชั่น “-n” เพื่อแสดง IP (source และ destination) และพอร์ตให้เป็นตัวเลข
- ออปชั่น “–line-numbers” เพื่อแสดงตัวเลขกำกับ rule ในแต่ละบรรทัด เพื่อสะดวกต่อการแก้ไข rule
ตัวอย่างการใช้คำสั่ง iptables ออปชั่น “-L” เพื่อแสดงค่าคอนฟิก firewall ที่ใช้งานอยู่
[root@cent6 ~]# iptables -L -v -n --line-numbers Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 630 49714 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 3 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 4 2 128 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT 349 packets, 55278 bytes) num pkts bytes target prot opt in out source destination
คอนฟิก rule ที่แสดงนี้ เป็นคอนฟิกดีฟอลต์จากติดตั้ง CentOS 6 (หากไม่ได้มีการเลือกแก้ไข firewall ระหว่างการติดตั้ง)
ในที่นี้ขออธิบาย rule คร่าวๆ ในส่วนของ Chain INPUT ที่เปิดใช้งานอยู่ดังนี้
- num 1 : อนุญาต (ACCEPT) ให้ทุก packet ที่ผ่านขั้นตอนการเชื่อมต่อเรียบร้อยแล้ว (RELATED, ESTABLISHED) เข้าสู่เครื่องได้
- num 2 : อนุญาต (ACCEPT) ให้ packet ประเภท (icmp) เช่น ping เข้าสู่เครื่องได้
- num 3 : อนุญาต (ACCEPT) ให้ทุก packet ที่ส่งภายในของเครื่องเองได้ (lo หรือ loopback)
- num 4 : อนุญาต (ACCEPT) ให้ packet แรก (NEW) ที่พยายามเชื่อมต่อเข้าพอร์ตปลายทาง tcp dpt:22 (secure shell) สามารถเข้าสู่เครื่องได้ หรือสรุปง่ายๆ คืออนุญาตให้สามารถ ssh เข้าสู่เครื่องนี้ได้นั่นเอง
- num 5 : packet อื่นๆ นอกจากนี้ จะถูกปฏิเสธ (REJECT) การเข้าถึงเครื่อง และจะมีการตอบ icmp-host-prohibited กลับไปยังเครื่องต้นทางที่พยายามส่ง packet เข้ามา
การทำงาน firewall ของลีนุกซ์จะตรวจสอบ (match) ตามลำดับ rule num ที่คอนฟิกไว้ เช่นเมื่อมี packet พยายามส่งเข้า (INPUT) ก็จะตรวจสอบเรียงตาม num 1, 2, 3, 4, 5
เพิ่ม (insert) rule ใหม่
หากเราติดตั้งเซอร์วิสใหม่ คอนฟิกและรันได้เรียบร้อยแล้ว เช่นเว็บเซิร์ฟเวอร์ เปิดใช้งานพอร์ต tcp 80
ตัวอย่างการใช้คำสั่ง netstat -an เพื่อดูพอร์ตที่เปิดอยู่ ในที่นี้จะใช้คำสั่ง grep เพื่อเลือกแสดงเฉพาะบรรทัดที่มีตัวเลข 80
[root@cent6 ~]# netstat -an | grep 80 tcp 0 0 :::80 :::* LISTEN
เราสามารถทดสอบจากเครื่องที่รันเว็บเซิร์ฟเวอร์เองได้ เพราะ rule ของ firewall โดยดีฟอลต์อนุญาตให้การส่งข้อมูลภายใน (lo) สามารถทำได้ (rule num 3)
ตัวอย่างการใช้คำสั่ง telnet เพื่อทดสอบการเชื่อมต่อเข้าพอร์ต 80 ของเว็บเซิร์ฟเวอร์ 192.168.5.62 (ทดสอบบนเครื่องเดียวกัน กับที่รันเว็บเซิรฟ์เวอร์)
[root@cent6 ~]# telnet 192.168.5.62 80 Trying 192.168.5.62... Connected to 192.168.5.62. Escape character is '^]'. HEAD / HTTP/1.0 HTTP/1.1 403 Forbidden Date: Sun, 08 Apr 2012 08:53:11 GMT Server: Apache/2.2.15 (CentOS) Accept-Ranges: bytes Content-Length: 5039 Connection: close Content-Type: text/html; charset=UTF-8 Connection closed by foreign host.
คำอธิบายการใช้คำสั่ง telnet เข้าพอร์ต
- หากใช้คำสั่ง telnet แล้วขึ้น “command not found” ต้องติดตั้งไฟล์ rpm ของโปรแกรม telnet เพิ่ม ซึ่งอยู่ในแผ่นดีวีดีติดตั้ง CentOS อยู่แล้ว
[root@cent6 Packages]# rpm -i telnet-0.17-47.el6.x86_64.rpm
- เราสามารถใช้คำสั่ง telnet เพื่อทดสอบเข้าพอร์ตเว็บ (tcp 80) ได้ โดยพิมพ์คำสั่ง telnet ตามด้วย IP ของเว็บเซิร์ฟเวอร์ แล้วตามด้วยพอร์ตที่รันเว็บ
- ในคำสั่ง telnet เมื่อขึ้น Connected แปลว่าสามารถเชื่อมต่อเข้าพอร์ตที่ระบะไว้ได้
- กดปุ่ม [Enter] หนึ่งครั้ง แล้วพิมพ์คำสั่ง HEAD / HTTP/1.0 เพื่อเป็นการส่งคำสั่งขอดูข้อมูลเบื้องต้นของเว็บเซิร์ฟเวอร์ได้
- หากต้องการออกจากคำสั่ง telnet ให้กดปุ่ม [Ctrl] และ ] พร้อมกัน จะมีพร้อมพต์ telnet> ขึ้นมาให้พิมพ์คำสั่ง quit เพื่อออจาก telnet
[root@cent6 ~]# telnet 192.168.5.62 80 Trying 192.168.5.62... Connected to 192.168.5.62. Escape character is '^]'. ^] telnet> quit Connection closed.
แต่ถ้าใช้ browser หรือทดสอบด้วยคำสั่ง telnet เข้าพอร์ต 80 จากเครื่องอื่นๆ เปิดเว็บเข้ามา จะเข้าไม่ได้
$ telnet 192.168.5.62 80 Trying 192.168.5.62... telnet: connect to address 192.168.5.62: No route to host
ต้องเพิ่ม rule ใหม่ เข้าไปเพื่ออนุญาตการเชื่อมต่อเข้ามา โดย rule ที่เพิ่มใหม่ ต้องเพิ่มก่อน rule สุดท้ายที่มีการปฏิเสธการเข้าถึง (REJECT) ทุก packet
ใช้คำสั่ง iptables ออปชั่น “-L” เพื่อแสดงคอนฟิก firewall ที่ใช้งานอยู่
[root@cent6 ~]# iptables -L -v -n --line-numbers Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 2363 182K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 2 168 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 3 11 660 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 4 4 252 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 10 620 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT 1358 packets, 169K bytes) num pkts bytes target prot opt in out source destination
ใช้คำสั่ง iptables ออปชั่น “-I” เพิ่มด้วยการแทรก (insert) rule ใหม่เข้าไปแทนที่ rule num 5 ระบุว่าอนุญาต (ACCEPT) ให้การเชื่อมต่อใหม่ (NEW) เข้า (INPUT) พอร์ต tcp 80 ได้
[root@cent6 ~]# iptables -I INPUT 5 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
ตรวจสอบผลลัพธ์ที่ได้จาก iptables ออปชั่น “-L”
[root@cent6 ~]# iptables -L -v -n --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 2383 184K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 2 168 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
3 11 660 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
4 4 252 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80
6 10 620 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 5 packets, 692 bytes)
num pkts bytes target prot opt in out source destination
ทดสอบจากเครื่องอื่นด้วยการ telnet เข้าพอร์ต 80 อีกครั้ง จะสามารถเชื่อมต่อได้แล้ว
$ telnet 192.168.5.62 80 Trying 192.168.5.62... Connected to 192.168.5.62. Escape character is '^]'. HEAD / HTTP/1.0 HTTP/1.1 403 Forbidden Date: Sun, 08 Apr 2012 09:06:10 GMT Server: Apache/2.2.15 (CentOS) Accept-Ranges: bytes Content-Length: 5039 Connection: close Content-Type: text/html; charset=UTF-8 Connection closed by foreign host.
ลบ (delete) rule
หากต้องการยกเลิก rule ที่ใส่ไว้ เช่นไม่ต้องการให้เครื่องอื่นสามารถเชื่อมต่อเข้าพอร์ต 80 ได้อีกต่อไปแล้ว สามารถทำได้โดยใช้คำสั่ง iptables ออปชั่น -D ตามด้วย rule num ที่ต้องการลบ (delete) ใช้คำสั่ง iptables ออปชั่น “-L” เพื่อแสดง rule ที่เปิดใช้งานอยู่
[root@cent6 ~]# iptables -L -v -n --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 2417 186K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
2 2 168 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
3 11 660 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
4 4 252 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
5 1 60 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:80
6 10 620 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 27 packets, 5466 bytes)
num pkts bytes target prot opt in out source destination
สมมติว่าต้องการลบ rule ที่อนุญาตการเชื่อมต่อเข้า (INPUT) พอร์ต 80 หรือ rule num 5 สามารถทำได้โดย
[root@cent6 ~]# iptables -D INPUT 5
ใช้คำสั่ง iptables -L จะเห็นว่า rule num 5 ถูกลบไป
[root@cent6 ~]# iptables -L -v -n --line-numbers Chain INPUT (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 2518 194K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 2 168 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 3 11 660 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 4 4 252 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 10 620 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) num pkts bytes target prot opt in out source destination 1 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT 6 packets, 728 bytes) num pkts bytes target prot opt in out source destination
ลองทดสอบ telnet เข้าพอร์ต 80 จากเครื่องอื่นดู ก็ไม่สามารถเชื่อมต่อได้แล้ว
$ telnet 192.168.5.62 80 Trying 192.168.5.62... telnet: connect to address 192.168.5.62: No route to host