แก้ไขคอนฟิก firewall บนลีนุกซ์ด้วย iptables

บนลีนุกซ์มีคุณสมบัติ 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

 

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

Leave a Reply

Your email address will not be published.