การทำ
Inbound & Outbound NAT +
Firewall บน Linux
ด้วย
iptables
ตัวอย่างเครือข่ายและ script นี้ดัดแปลงจาก
www.boingworld.com |
|
บทนำ
การนำเอา Linux Server
มาทำเป็น Firewall
ให้กับองค์กรในการใช้งานอินเตอร์เน็ต
เป็นทางเลือกทางหนึ่งที่ได้ผลดีเนื่องจาก Linux
OS เป็นของฟรี และมี
Applications ต่าง ๆ
มากับแผ่นให้เลือกใช้ได้มากมาย
ในที่นี้จะขอเน้นเรื่อง Firewall
ที่มีมากับ Linux OS
นั่นคือ iptables
ซึ่งเป็น Stateful Firewall
ที่สามารถนำมาประยุกต์ใช้งานได้โดยที่ไม่ต้องซื้อ
Firewall ราคาแพงมาใช้
ในตัวอย่างที่จะเสนอต่อไปนี้
เป็นรูปเบบการเชื่อมต่ออินเตอร์เน็ตแบบที่มี
Registered IP แค่ IP
เดียว แต่ภายในองค์กรประกอบด้วย
Server ต่าง ๆ
อยู่ซึ่งจะต้องใช้ Private IP
ดังรูป

หมายเหตุ ถ้าองค์กรของท่านมี
Registered IP
หลาย IP
ก็สามารถใช้รูปข้างบนนี้มาประยุกต์ใช้ได้เช่นกัน
นั่นคือการกำหนดให้ eth0
เป็นหลาย IP ตามจำนวนของ
Server ภายใน
เช่นจากรูปข้างบนนี้ก็อาจจะกำหนด IP
ของ eth0 เป็น
4 IP (1 IP ของ Linux
Server + 3 IP ของ Server)
จากนั้นก็ทำ Inbound NAT
ที่จะได้กล่าวต่อไป
วิธีการ
จากรูปข้างบนก็นำ Linux Server
มาใช้งานโดยให้มีการ์ดแลน 2
การ์ด การ์ดหนี่งให้เป็น Public IP
(202.129.16.30) และอีกการ์ดเป็น
Private IP (192.168.1.1)
ส่วนเครื่อง Server และ
Client ก็ใช้ Private IP
ดังรูป
โดยบนเครื่อง Linux Server
ให้ใช้ iptables
ในการควบคุมการไหลของข้อมูล
ความต้องการของระบบ
มีความต้องการอยู่ 2 อย่างคือ
1. Linux Server
ต้องทำหน้าที่แปลง IP
ของเครือข่ายภายในทั้งหมดซึ่งเป็น Private IP
ให้กลายเป็น Public IP
ซึ่งในที่นี้คือ 202.129.16.30
เพื่อให้สามารถติดต่อกับเครือข่ายภายนอกได้
2. เมื่อเครือข่ายภายนอกมีการเรียกใช้งานเข้ามาที่
DNS Server , Web Server และ
Mail Server
ซึ่งจะถูกประกาศให้เครือข่ายภานนอกรู้จักเป็น
Public IP อันเดียวกันคือ
202.129.16.30 นั้น ตัว Linux Server
ต้องทำการแปลง Public IP
ให้กลายเป็น Private IP
เพื่อที่จะให้เครือข่ายภายนอกสามารถติดต่อเข้าสู่
Server ทั้ง 3 ได้
ด้วยความแตกต่างของ Port
ดังนี้ :
- DNS Server ทำงานที่พอร์ต
TCP:53 และ UDP:53
- Web Server (http)
ทำงานที่พอร์ต TCP:80
- Mail Server (smtp)
ทำงานที่พอร์ต TCP:25
ในกรณีที่มี Server อื่น ๆ
นอกเหนือจากนี้ก็สามารถทำได้ด้วยหลักการเดียวกัน
3. การทำ
Firewall
คำสั่ง
iptables
ที่ใช้
คำสั่งที่ใช้ทั้งหมดเป็นดังนี้
:
#----Start
script------#
#
Define variable
INET_IP="202.129.16.30"
INET_IFACE="eth0"
DNS_IP="202.129.16.30"
HTTP_IP="202.129.16.30"
SMTP_IP="202.129.16.30"
LAN_IP="192.168.1.1"
LAN_BCAST_ADRESS="192.168.1.255"
LAN_IFACE="eth1"
LAN_DNS_IP="192.168.1.2"
LAN_HTTP_IP="192.168.1.3"
LAN_SMTP_IP="192.168.1.4"
LO_IFACE="lo"
LO_IP="127.0.0.1"
# Enable
ip_forward, this is critical since it is turned off
as defaul in Linux.
echo "1" > /proc/sys/net/ipv4/ip_forward
#Clear all chains of rule
iptables -F
iptables -X allowed
iptables -X icmp_packets
iptables -X tcp_packets
iptables -X udpincoming_packets
iptables -t nat -F
# Enable
simple IP Forwarding and Network Address Translation
(Outbound NAT)
iptables -t nat -A POSTROUTING -o $INET_IFACE -j
SNAT --to-source $INET_IP
# Bad TCP
packets we don't want
iptables -A FORWARD -p tcp ! --syn -m state
--state NEW -j LOG --log-prefix "New not syn:"
iptables -A FORWARD -p tcp ! --syn -m state --state
NEW -j DROP
# Accept
the packets we actually want to forward
iptables -A FORWARD -i $LAN_IFACE -j ACCEPT
iptables -A FORWARD -m state --state
ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m limit --limit 3/minute
--limit-burst 3 -j LOG --log-level DEBUG
--log-prefix "IPT FORWARD packet died: "
# Set
default policies for the INPUT, FORWARD and OUTPUT
chains
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Create
separate chains for ICMP, TCP and UDP to traverse
iptables -N icmp_packets
iptables -N tcp_packets
iptables -N udpincoming_packets
# The
allowed chain for TCP connections
iptables -N allowed
iptables -A allowed -p TCP --syn -j ACCEPT
iptables -A allowed -p TCP -m state --state
ESTABLISHED,RELATED -j ACCEPT
iptables -A allowed -p TCP -j DROP
# ICMP
rules
iptables -A icmp_packets -p ICMP -s 0/0
--icmp-type 0 -j ACCEPT
iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type
3 -j ACCEPT
iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type
5 -j ACCEPT
iptables -A icmp_packets -p ICMP -s 0/0 --icmp-type
11 -j ACCEPT
# TCP
rules
iptables -A tcp_packets -p TCP -s 0/0 --dport
21 -j allowed
iptables -A tcp_packets -p TCP -s 0/0 --dport 22 -j
allowed
iptables -A tcp_packets -p TCP -s 0/0 --dport 25 -j
allowed
iptables -A tcp_packets -p TCP -s 0/0 --dport 80 -j
allowed
iptables -A tcp_packets -p TCP -s 0/0 --dport 113 -j
allowed
# UDP
ports
iptables -A udpincoming_packets -p UDP -s 0/0
--source-port 53 -j ACCEPT
iptables -A udpincoming_packets -p UDP -s 0/0
--source-port 123 -j ACCEPT
iptables -A udpincoming_packets -p UDP -s 0/0
--source-port 2074 -j ACCEPT
iptables -A udpincoming_packets -p UDP -s 0/0
--source-port 4000 -j ACCEPT
#
PREROUTING chain.
# Do some checks for obviously spoofed IP's
iptables -t nat -A PREROUTING -i $INET_IFACE -s
192.168.0.0/16 -j DROP
iptables -t nat -A PREROUTING -i $INET_IFACE -s
10.0.0.0/8 -j DROP
iptables -t nat -A PREROUTING -i $INET_IFACE -s
172.16.0.0/12 -j DROP
#Inbound Nat
iptables -t nat -A PREROUTING -p TCP -i $INET_IFACE
-d $DNS_IP --dport 53 -j DNAT --to-destination
$LAN_DNS_IP
iptables -t nat -A PREROUTING -p UDP -i $INET_IFACE
-d $DNS_IP --dport 53 -j DNAT --to-destination
$LAN_DNS_IP
iptables -t nat -A PREROUTING -p TCP -i $INET_IFACE
-d $HTTP_IP --dport 80 -j DNAT --to-destination
$LAN_HTTP_IP
iptables -t nat -A PREROUTING -p TCP -i $INET_IFACE
-d $SMTP_IP --dport 25 -j DNAT --to-destination
$LAN_SMTP_IP
#FORWARD
chain
#
Forward for
DNS server
iptables -A FORWARD -p TCP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_DNS_IP --dport 53 -j allowed
iptables -A FORWARD -p UDP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_DNS_IP --dport 53 -j ACCEPT
iptables -A FORWARD -p ICMP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_DNS_IP -j icmp_packets
#Forward
for
HTTP server
iptables -A FORWARD -p TCP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_HTTP_IP --dport 80 -j allowed
iptables -A FORWARD -p ICMP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_HTTP_IP -j icmp_packets
#Forward for
SMTP server
iptables -A FORWARD -p TCP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_SMTP_IP --dport 25 -j allowed
iptables -A FORWARD -p ICMP -i $INET_IFACE -o
$LAN_IFACE -d $LAN_SMTP_IP -j icmp_packets
# INPUT
chain
# Take care of bad TCP packets that we don't want
iptables -A INPUT -p tcp ! --syn -m state --state
NEW -j LOG --log-prefix "New not syn:"
iptables -A INPUT -p tcp ! --syn -m state --state
NEW -j DROP
# Rules for incoming packets from the internet
iptables -A INPUT -p ICMP -i $INET_IFACE -j
icmp_packets
iptables -A INPUT -p TCP -i $INET_IFACE -j
tcp_packets
iptables -A INPUT -p UDP -i $INET_IFACE -j
udpincoming_packets
# Rules for special networks not part of the
Internet
iptables -A INPUT -p ALL -i $LAN_IFACE -d
$LAN_BCAST_ADRESS -j ACCEPT
iptables -A INPUT -p ALL -i $LO_IFACE -d $LO_IP -j
ACCEPT
iptables -A INPUT -p ALL -i $LAN_IFACE -d $LAN_IP -j
ACCEPT
iptables -A INPUT -p ALL -d $INET_IP -m state
--state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m limit --limit 3/minute
--limit-burst 3 -j LOG --log-level DEBUG
--log-prefix "IPT INPUT packet died: "
# OUTPUT
chain
iptables -A OUTPUT -p tcp ! --syn -m state
--state NEW -j LOG --log-prefix "New not syn:"
iptables -A OUTPUT -p tcp ! --syn -m state --state
NEW -j DROP
iptables -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
iptables -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
iptables -A OUTPUT -p ALL -s $INET_IP -j ACCEPT
iptables -A OUTPUT -m limit --limit 3/minute
--limit-burst 3 -j LOG --log-level DEBUG
--log-prefix "IPT OUTPUT packet died: "
#----End script------# |
|