#!/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" # external global IP address (the "Out.IP" shown in figure) 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 --sport $UNPRIVPORTS -d $TIME_SERVERS --dport 123 \ -m state --state NEW -j ACCEPT iptables -A FORWARD -o $EXT_IF -p udp --sport $UNPRIVPORTS \ -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