Tuesday, July 24, 2007

NAT DMZ Firewall

#!/bin/bash
# main code is from Ziegler's book "Linux Firewalls":
# "optimized code for stand-alone firewall"
#
# modified to include NAT.
# First Date: Oct. 2nd, 2002

#################################################################
# Load Modules
modprobe ip_tables
modprobe ip_conntrack
modprobe ip_conntrack_ftp
modprobe ipt_state
modprobe iptable_nat
modprobe iptable_filter

EXT_IF="eth0" # network interface to the external: x.x.x.x
LAN_IF="eth1" # network interface to the LAN: 192.168.1.1
DMZ_IF="eth2" # DMZ interface: 192.168.0.1

LOOPBACK_INTERFACE="lo" # however your system names it

EXT_IPADDR="x.x.x.x" # DMZ IP address
LAN_ADDRESSES="192.168.1.0/24" # LAN IP address range
NAMESERVER1="x.x.x.x" # address of a remote name server
NAMESERVER2="x.x.x.x"
TIME_SERVERS="x.x.x.x" # address of remote time server for NTP time synchronization.
LAN_MAINSERVER="192.168.1.2" # address of internal main server, which holds
# user home, email server, NIS, SMB, matlab, printer
DMZ_SERVER="192.168.0.80" # DMZ server
TRUST_EXT="x.x.x.x" # trust outside computer for accepting printing request.

CLASS_A="10.0.0.0/8" # class A private networks
CLASS_B="172.16.0.0/12" # class B private networks
CLASS_C="192.168.0.0/16" # class C private networks
CLASS_D_MULTICAST="224.0.0.0/4" # class D multicast addresses
CLASS_E_RESERVED_NET="240.0.0.0/5" # class E reserved addresses
BROADCAST_SRC="0.0.0.0" # broadcast source address
BROADCAST_DEST="255.255.255.255" # broadcast destination address

PRIVPORTS="0:1023" # well-known, privileged port range
UNPRIVPORTS="1024:65535" # unprivileged port range
SSH_GATEWAY_PORT="3022" # SSH tunneling port to connect to gateway.
SSH_DMZ_PORT="3023" # ssh tunneling port from outside to DMZ web server.
DNS_PORT="53"
IMAP4SSL_PORT="993"
NTP_PORT="123"
PRINTER_PORT="515"
MATLAB_PORT="1711"
MATLAB_SERVER="x.x.x.x" # outside matlab license server.

# IMAP "143", HTTP "80", HTTPS "443", AUTH_PORT "113", IMAP3 "220", SMTP "25", FTP "20"
###############################################################
# Enable IP forwarding for NAT
echo 1 > /proc/sys/net/ipv4/ip_forward

# Enable broadcast echo Protection
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Disable Source Routed Packets
for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do
echo 0 > $f
done
# Enable TCP SYN Cookie Protection
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# Disable ICMP Redirect Acceptance
for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do
echo 0 > $f
done
# Don't send Redirect Messages
for f in /proc/sys/net/ipv4/conf/*/send_redirects; do
echo 0 > $f
done
# Drop Spoofed Packets coming in on an interface, which if replied to,
# would result in the reply going out a different interface.
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
echo 1 > $f
done
# Do not Log packets with impossible addresses.
for f in /proc/sys/net/ipv4/conf/*/log_martians; do
echo 0 > $f
done
###############################################################

# Remove any existing rules from all chains
iptables --flush
iptables -t nat --flush
iptables -t mangle --flush
# Unlimited traffic on the loopback interface
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Set the default policy to drop
iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP

#------- I can't set default drop policy for NAT and mangle, otherwise even DNS can't work. ???
iptables -t nat --policy PREROUTING ACCEPT
iptables -t nat --policy OUTPUT ACCEPT
iptables -t nat --policy POSTROUTING ACCEPT
iptables -t mangle --policy PREROUTING ACCEPT
iptables -t mangle --policy OUTPUT ACCEPT

# Remove any pre-existing user-defined chains
iptables --delete-chain
iptables -t nat --delete-chain
iptables -t mangle --delete-chain

###############################################################
# Using Connection State to By-pass Rule Checking

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -m state --state INVALID -j DROP
iptables -A OUTPUT -m state --state INVALID -j DROP
iptables -A FORWARD -m state --state INVALID -j DROP

###############################################################
# Stealth Scans and TCP State Flags

# All of the bits are cleared
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j DROP
# SYN and FIN are both set
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A FORWARD -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# SYN and RST are both set
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# FIN and RST are both set
iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A FORWARD -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
# FIN is the only bit set, without the expected accompanying ACK
iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -A FORWARD -p tcp --tcp-flags ACK,FIN FIN -j DROP
# PSH is the only bit set, without the expected accompanying ACK
iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -A FORWARD -p tcp --tcp-flags ACK,PSH PSH -j DROP
# URG is the only bit set, without the expected accompanying ACK
iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -A FORWARD -p tcp --tcp-flags ACK,URG URG -j DROP

###############################################################
# Source Address Spoofing and Other Bad Addresses

# Prevent spoofed packets coming out of my network
iptables -A FORWARD -i $LAN_IF -o $EXT_IF -s ! $LAN_ADDRESSES -j DROP
iptables -A FORWARD -i $DMZ_IF -s ! $DMZ_SERVER -j DROP
iptables -A OUTPUT -o $EXT_IF -s ! $EXT_IPADDR -j DROP

# Refuse malformed broadcast packets
iptables -A INPUT -i $LAN_IF -d $BROADCAST_SRC -j DROP

# Don't forward limited broadcasts in either direction
iptables -A FORWARD -d $BROADCAST_DEST -j DROP
iptables -A INPUT -p ! udp -d $CLASS_D_MULTICAST -j DROP
iptables -A FORWARD -p ! udp -d $CLASS_D_MULTICAST -j DROP


###############################################################
# DNS Name Server

# LAN clients to remote DNS server (53 udp and tcp)
iptables -A OUTPUT -o $EXT_IF -p udp --sport $UNPRIVPORTS -d $NAMESERVER1 --dport 53 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p udp --sport $UNPRIVPORTS -d $NAMESERVER2 --dport 53 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p tcp --sport $UNPRIVPORTS -d $NAMESERVER1 --dport 53 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p tcp --sport $UNPRIVPORTS -d $NAMESERVER2 --dport 53 -m state --state NEW -j ACCEPT

iptables -A FORWARD -o $EXT_IF -p udp --sport $UNPRIVPORTS -d $NAMESERVER1 --dport 53 -m state --state NEW -j ACCEPT
iptables -A FORWARD -o $EXT_IF -p udp --sport $UNPRIVPORTS -d $NAMESERVER2 --dport 53 -m state --state NEW -j ACCEPT
iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS -d $NAMESERVER1 --dport 53 -m state --state NEW -j ACCEPT
iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS -d $NAMESERVER2 --dport 53 -m state --state NEW -j ACCEPT

##############################################################
# NAT table
iptables -t nat -A POSTROUTING -o $EXT_IF -j SNAT --to-source $EXT_IPADDR

#--------- DNAT for SMTP mail forwarding and IMAP+SSL retrieving to internal mainserver.
iptables -t nat -A PREROUTING -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport 25 -j DNAT --to-destination $LAN_MAINSERVER
iptables -t nat -A PREROUTING -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport $IMAP4SSL_PORT -j DNAT --to-destination $LAN_MAINSERVER

iptables -A FORWARD -i $EXT_IF -o $LAN_IF -p tcp --sport $UNPRIVPORTS -d $LAN_MAINSERVER \
--dport 25 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i $EXT_IF -o $LAN_IF -p tcp --sport $UNPRIVPORTS -d $LAN_MAINSERVER \
--dport $IMAP4SSL_PORT -m state --state NEW -j ACCEPT

#------------- DNAT for Printing request from outside trust server to internal MainServer (TCP Port 515).
iptables -t nat -A PREROUTING -p tcp -s $TRUST_EXT -d $EXT_IPADDR \
--dport $PRINTER_PORT -j DNAT --to-destination $LAN_MAINSERVER

iptables -A FORWARD -i $EXT_IF -o $LAN_IF -p tcp -s $TRUST_EXT --dport $PRINTER_PORT -m state \
--state NEW -j ACCEPT

#----------- DNAT for ssh forwarding to internal LAN_MAINSERVER
# Internet --> lan mainserver
iptables -t nat -A PREROUTING -i $EXT_IF -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport 22 -j DNAT --to-destination $LAN_MAINSERVER

iptables -A FORWARD -i $EXT_IF -o $LAN_IF -p tcp --sport $UNPRIVPORTS -d $LAN_MAINSERVER --dport 22 \
-m state --state NEW -j LOG --log-prefix "Internet->mainserver(ssh): "
iptables -A FORWARD -i $EXT_IF -o $LAN_IF -p tcp --sport $UNPRIVPORTS -d $LAN_MAINSERVER --dport 22 \
-m state --state NEW -j ACCEPT

# Internet --> gateway itself. Use 3022 as alternative port (default port 22 has been used
# to forward SSH connection to internal Main Server).
iptables -t nat -A PREROUTING -i $EXT_IF -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport $SSH_GATEWAY_PORT -j DNAT --to-destination $EXT_IPADDR:22

# Internet --> DMZ webserver.
iptables -t nat -A PREROUTING -i $EXT_IF -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport $SSH_DMZ_PORT -j DNAT --to-destination $DMZ_SERVER:22
iptables -A FORWARD -i $EXT_IF -o $DMZ_IF -p tcp --sport $UNPRIVPORTS -d $DMZ_SERVER --dport 22 \
-m state --state NEW -j LOG --log-prefix "Internet->webserver(ssh): "
iptables -A FORWARD -i $EXT_IF -o $DMZ_IF -p tcp --sport $UNPRIVPORTS -d $DMZ_SERVER --dport 22 \
-m state --state NEW -j ACCEPT

#----------- DNAT for HTTP forwarding to DMZ web server ( port 80, 443 SSL )
iptables -t nat -A PREROUTING -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport 80 -j DNAT --to-destination $DMZ_SERVER
iptables -t nat -A PREROUTING -p tcp --sport $UNPRIVPORTS -d $EXT_IPADDR \
--dport 443 -j DNAT --to-destination $DMZ_SERVER

iptables -A FORWARD -o $DMZ_IF -p tcp --sport $UNPRIVPORTS -d $DMZ_SERVER \
--dport 80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -o $DMZ_IF -p tcp --sport $UNPRIVPORTS -d $DMZ_SERVER \
--dport 443 -m state --state NEW -j ACCEPT

###############################################################
# ICMP Control and Status Messages

# allow outgoing pings to anywhere
iptables -A OUTPUT -p icmp --icmp-type echo-request -m state --state NEW -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -s $LAN_ADDRESSES \
-m state --state NEW -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type echo-request -s $DMZ_SERVER \
-m state --state NEW -j ACCEPT

# allow incoming pings from anywhere
iptables -A INPUT -i $EXT_IF -p icmp --icmp-type echo-request -d $EXT_IPADDR \
-m state --state NEW -j ACCEPT
iptables -A INPUT -i $LAN_IF -p icmp -s $LAN_ADDRESSES --icmp-type echo-request \
-m state --state NEW -j ACCEPT

# Drop initial ICMP fragments
iptables -A INPUT -p icmp --fragment -j DROP
iptables -A OUTPUT -p icmp --fragment -j DROP
iptables -A FORWARD -p icmp --fragment -j DROP

iptables -A INPUT -p icmp --icmp-type source-quench -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type source-quench -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type source-quench -j ACCEPT

iptables -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type parameter-problem -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type parameter-problem -j ACCEPT

iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A OUTPUT -o $LAN_IF -p icmp --icmp-type destination-unreachable -d $LAN_ADDRESSES -j ACCEPT
iptables -A FORWARD -o $LAN_IF -p icmp --icmp-type destination-unreachable -d $LAN_ADDRESSES -j ACCEPT

iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT
iptables -A FORWARD -p icmp --icmp-type fragmentation-needed -j ACCEPT

# Don¹t log dropped outgoing ICMP error messages
iptables -A OUTPUT -p icmp --icmp-type destination-unreachable -j DROP
iptables -A FORWARD -o $EXT_IF -p icmp --icmp-type destination-unreachable -j DROP

# Intermediate traceroute responses
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A FORWARD -o $LAN_IF -p icmp --icmp-type time-exceeded -d $LAN_ADDRESSES -j ACCEPT

###############################################################
# Outgoing AUTH User Identification Service (TCP Port 113)
# reject outside AUTH request.
iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 113 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 113 -m state --state NEW -j ACCEPT
iptables -A INPUT -i $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 113 -j REJECT --reject-with tcp-reset

###############################################################
# Forwarding SMTP from internal mail server to external Mail Server
iptables -A FORWARD -i $LAN_IF -o $EXT_IF -p tcp -s $LAN_MAINSERVER --sport $UNPRIVPORTS \
--dport 25 -m state --state NEW -j ACCEPT

###############################################################
# ssh (TCP Port 22)

iptables -A OUTPUT -p tcp --sport $UNPRIVPORTS --dport 22 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --sport $UNPRIVPORTS --dport 22 -m state --state NEW -j LOG --log-prefix "SSH input: "
iptables -A INPUT -p tcp --sport $UNPRIVPORTS --dport 22 -m state --state NEW -j ACCEPT

iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 22 -m state --state NEW -j ACCEPT
iptables -A FORWARD -i $LAN_IF -o $DMZ_IF -p tcp --sport $UNPRIVPORTS --dport 22 -m state --state NEW -j ACCEPT

iptables -A FORWARD -i $DMZ_IF -o $LAN_IF -p tcp --sport $UNPRIVPORTS -d $LAN_MAINSERVER --dport 22 \
-m state --state NEW -j LOG --log-prefix "SSH dmz->lan: "
iptables -A FORWARD -i $DMZ_IF -o $LAN_IF -p tcp --sport $UNPRIVPORTS -d $LAN_MAINSERVER --dport 22 \
-m state --state NEW -j ACCEPT

###############################################################
# permit LAN_MAINSERVER to send Matlab license request to outside license server.
# I don't know another port used in Matlab license server beside the MATLAB_PORT="1711", so
# I accept all tcp connection out to the matlab license server.

iptables -A FORWARD -i $LAN_IF -o $EXT_IF -p tcp -d $MATLAB_SERVER -m state --state NEW -j ACCEPT
###############################################################
# ftp (TCP Ports 21)
# Outgoing Local Client Requests from DMZ or LAN to outside.

iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 21 \
-m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 21 \
-m state --state NEW -j ACCEPT

###############################################################
# HTTP Web Traffic (TCP Port 80)

iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 80 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 80 -m state --state NEW -j ACCEPT

# SSL Web Traffic (TCP Port 443)

iptables -A FORWARD -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 443 -m state --state NEW -j ACCEPT
iptables -A OUTPUT -o $EXT_IF -p tcp -s $EXT_IPADDR --sport $UNPRIVPORTS --dport 443 \
-m state --state NEW -j ACCEPT
###############################################################
# allow telnet to outside from LAN.
iptables -A FORWARD -i $LAN_IF -o $EXT_IF -p tcp --sport $UNPRIVPORTS --dport 23 -m state --state NEW -j ACCEPT

##############################################################
# allow gateway to print to MainServer.
iptables -A OUTPUT -o $LAN_IF -p tcp -d $LAN_MAINSERVER --dport $PRINTER_PORT -m state --state NEW -j ACCEPT
###############################################################

# Accessing Network Time Server (UDP 123)

iptables -A OUTPUT -o $EXT_IF -p udp -d $TIME_SERVERS --dport 123 -m state --state NEW -j ACCEPT
iptables -A FORWARD -o $EXT_IF -p udp -d $TIME_SERVERS --dport 123 -m state --state NEW -j ACCEPT

###############################################################
# Logging Dropped Packets
# I do not log in order to save working load on hard drive.
# My gateway Hard Drive is too slow and old. :(

#iptables -A INPUT -j LOG
#iptables -A OUTPUT -j LOG
#iptables -A FORWARD -j LOG


Luggage? GPS? Comic books?
Check out fitting gifts for grads at Yahoo! Search.

0 Comments: