ในบทความนี้จะอธิบายการคอนฟิก NAT (Network Address Translation) บนลีนุกซ์ ด้วย iptables โดยจะแยกเป็นข้อต่างๆ ตามลักษณะการใช้งาน ซึ่งในแต่ละข้อ จะเคลียร์คอนฟิก rule ทั้งหมดของ nat ออกก่อน ด้วยออปชั่น ‘-F’ แล้วเริ่มคอนฟิกใหม่ ทั้งนี้เพื่อให้ผู้อ่านสามารถนำไปทดสอบดูผลลัพธ์ที่เกิดขึ้นได้ แล้วหลังจากเข้าใจ สามารถนำ rule ต่างๆ มารวมกันเพื่อคอนฟิก NAT ในหลายรูปแบบพร้อมๆ กันได้
เครื่องที่ทดสอบ
- ติดตั้งลีนุกซ์ kernel 2.6
- พอร์ตแลนที่ 1 : eth0, ip address: 192.168.1.1/24 ต่อเน็ตเวิร์กภายในองค์การ
- พอร์ตแลนที่ 2 : eth1, ip address: 172.16.1.1/24 ต่อออกภายนอก
- ปิด iptables rule ที่ทำหน้าที่เป็น firewall
- คอนฟิกลีนุกซ์ทำหน้าที่เป็น Router
- ทุกเครื่องที่อยู่เน็ตเวิร์กภายใน (192.168.1.0/24) ชี้ default gateway ที่ 192.168.1.1
1. เปลี่ยน Source IP Address แบบ MASQUERADE
ความต้องการ: เปลี่ยน Source IP Address ของ packet ที่ส่งจากเน็ตเวิร์ก 192.168.1.0/24 ไปยังเครื่องภายนอก เช่น 172.16.1.0/24
[root@linux-nat ~]# iptables -t nat -F [root@linux-nat ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j MASQUERADE [root@linux-nat ~]# iptables -t nat -L -v -n Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 MASQUERADE all -- * eth1 192.168.1.0/24 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 31 packets, 2328 bytes) pkts bytes target prot opt in out source destination
การใช้งาน:
- เป็นการทำ NAT เพื่อให้เครื่องที่อยู่ในองค์กรที่ใช้ Private IP Address สามารถใช้งานเน็ตเวิร์กภายนอกหรืออินเตอร์เน็ตได้พร้อมกัน
- IP Address ของพอร์ต eth1 ที่ต่อกับเน็ตเวิ์กภายนอก มีการเปลี่ยนแปลงไปเรื่อยๆ เช่น ต่อเน็ตโดยใช้ ADSL, คุณสมบัติของ MASQUERADE จะเปลี่ยน Source IP Address เป็น IP ของพอร์ต eth1 โดยอัตโนมัติ
2. เปลี่ยน Source IP Address แบบ SNAT
ความต้องการ: เปลี่ยน Source IP Address ใน packet ที่ส่งจากเน็ตเวิร์ก 192.168.1.0/24 ไปยังเครื่องภายนอก เช่น 172.16.1.0/24 ให้กลายเป็น Source IP 172.16.1.1
[root@linux-nat ~]# iptables -t nat -F [root@linux-nat ~]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j SNAT --to-source 172.16.1.1 [root@linux-nat ~]# iptables -t nat -L -v -n Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * * 192.168.1.0/24 0.0.0.0/0 to:172.16.1.1
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
การใช้งาน:
- เป็นการทำ NAT เพื่อให้เครื่องที่อยู่ในองค์กรที่ใช้ Private IP Address สามารถใช้งานเน็ตเวิร์กภายนอกหรืออินเตอร์เน็ตได้พร้อมกัน
- IP Address ของพอร์ต eth1 ที่ต่อกับเน็ตเวิ์กภายนอก ไม่เปลี่ยนแปลง มีการ fix ไว้ ต้องระบุ IP ลงไปในคำสั่งเลย หลังออปชั่น ‘–to-source’
- ถ้าเรารู้ IP ของพอร์ตขานอกแน่นอน ให้เราใช้เป็น SNAT แล้วระบุ ‘–to-source’ เพื่อเพิ่มประสิทธิภาพการทำ NAT เพราะว่าในการทำงาน ลีนุกซ์ไม่ต้องเสียเวลาไปค้นหา IP Address จากพอร์ตอีกครั้ง
3. เปลี่ยน Destination IP Address แบบ DNAT
ความต้องการ: เปลี่ยน Destination IP Address ใน packet เพื่อส่งต่อ (redirect) packet ไปยัง IP Address ภายในที่ต้องการได้
ตัวอย่างเช่น เมื่อเน็ตเวิร์กภายนอกเชื่อมต่อมาที่ IP 172.16.1.1 พอร์ต 80 ให้ส่งต่อ packet นี้ไปยังเครื่องภายในที่มี IP 192.168.1.2 พอร์ต 80
[root@linux-nat ~]# iptables -t nat -F [root@linux-nat ~]# iptables -t nat -A PREROUTING -p tcp -d 172.16.1.1 --dport 80 -j DNAT --to-destination 192.168.1.2:80 [root@linux-nat ~]# iptables -t nat -A POSTROUTING -p tcp -s 192.168.1.2 --sport 80 -j SNAT --to-source 172.16.1.1:80 [root@linux-nat ~]# iptables -t nat -L -v -n Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- * * 0.0.0.0/0 172.16.1.1 tcp dpt:80 to:192.168.1.2:80
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT tcp -- * * 192.168.1.2 0.0.0.0/0 tcp spt:80 to:172.16.1.1:80
Chain OUTPUT (policy ACCEPT 31 packets, 2328 bytes) pkts bytes target prot opt in out source destination
การใช้งาน:
- ตั้ง web server ไว้เน็ตเวิร์กภายในองค์กร แต่ต้องการให้คนภายนอกเช่นจากอินเตอร์เน็ตสามารถเรียกใช้งานได้ เราต้องคอนฟิกให้ภายนอกเชื่อมต่อเข้ามาที่ ip ของพอร์ตภายนอก (172.16.1.1) แล้วคอนฟิก DNAT เพื่อส่งต่อ packet เข้ามายังเครื่องภายใน
- การคอนฟิกตัวอย่างด้านบน เป็นการระบุที่พอร์ตเลย เราสามารถใช้หลายๆ พอร์ต พร้อมกัน คอนฟิกจากพอร์ตนึงไปเป็นอีกพอร์ต หรือแต่ละพอร์ตส่งต่อไปยังหลายๆ เครื่องได้
เพิ่มคอนฟิกในไฟล์ /etc/sysconfig/iptables
สุดท้ายหลังจากทดสอบการทำ NAT แบบต่างๆ ตามที่ต้องการได้แล้ว ต้องนำ rule ที่ได้ เพิ่มเข้าไปในไฟล์ /etc/sysconfig/iptables ซึ่งเป็นไฟล์กำหนด rule ของ iptables ที่ถูกโหลดโดย service iptables ตอนบู๊ตเครื่อง
วิธีการเพิ่มแบบแรกคือ จากคำสั่งที่ใช้รันตัดคำว่า iptables -t nat ออกไป แล้วพิมพ์ส่วนที่เหลือต่อท้ายบรรทัดที่มีคำว่า COMMIT ของคอนฟิก table filter เช่นต้องการเพิ่มคอนฟิกทำ DNAT จากข้อ 3 สามารถทำได้โดย
[root@linux-nat ~]# cat /etc/sysconfig/iptables *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] COMMIT
*nat :PREROUTING ACCEPT [0:0] :POSTROUTING ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A PREROUTING -p tcp -d 172.16.1.1 --dport 80 -j DNAT --to-destination 192.168.1.2:80 -A POSTROUTING -p tcp -s 192.168.1.2 --sport 80 -j SNAT --to-source 172.16.1.1:80 COMMIT
อีกวิธีการหนึ่งในการบันทีก rule ที่ใช้งานอยู่ ลงในไฟล์ /etc/sysconfig/iptables คือ รันคำสั่ง service iptables save
[root@linux-nat ~]# iptables -t nat -L -v -n Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- * * 0.0.0.0/0 172.16.1.1 tcp dpt:80 to:192.168.1.2:80
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT tcp -- * * 192.168.1.2 0.0.0.0/0 tcp spt:80 to:172.16.1.1:80
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
[root@linux-nat ~]# service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
[root@linux-nat ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.1.1 on Sun Feb 8 19:25:37 2009
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -d 172.16.1.1/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80
-A POSTROUTING -s 192.168.1.2/32 -p tcp -m tcp --sport 80 -j SNAT --to-source 172.16.1.1:80
COMMIT
# Completed on Sun Feb 8 19:25:37 2009
# Generated by iptables-save v1.4.1.1 on Sun Feb 8 19:25:37 2009
*filter
:INPUT ACCEPT [425:31352]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [393:41372]
COMMIT
# Completed on Sun Feb 8 19:25:37 2009
ทดสอบการรีโหลด iptables rules ด้วยคำสั่ง service iptables
เราสามารถใช้คำสั่ง service iptables restart เพื่อตรวจสอบคอนฟิกไฟล์ /etc/sysconfig/iptables ถูกต้อง
[root@linux-nat ~]# service iptables restart iptables: Flushing firewall rules: [ OK ] iptables: Setting chains to policy ACCEPT: nat filter [ OK ] iptables: Unloading modules: [ OK ] iptables: Applying firewall rules: [ OK ]