Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # iptables firewall script by matthew fillpot
- # Partially derived from AlienBOB's firewall generator
- # http://connie.slackware.com/~alien/efg/index.php
- # Local Settings
- #
- # sysctl location. If set, it will use sysctl to adjust the kernel parameters.
- # If this is set to the empty string (or is unset), the use of sysctl
- # is disabled.
- SYSCTL="/sbin/sysctl -w"
- # To echo the value directly to the /proc file instead
- # SYSCTL=""
- # IPTables Location - adjust if needed
- IPT="/usr/sbin/iptables"
- IPTS="/usr/sbin/iptables-save"
- IPTR="/usr/sbin/iptables-restore"
- # Internet Interface
- INET_IFACE="wlan0"
- # Localhost Interface
- LO_IFACE="lo"
- LO_IP="127.0.0.1"
- LOC_SUB="192.168.1.1/24"
- KMACS=(00:00:00:00:00:00 \
- 00:00:00:00:00:00)
- # Color_options
- txtblk=$'\e[0;30m' # Black - Regular
- txtred=$'\e[0;31m' # Red
- txtgrn=$'\e[0;32m' # Green
- txtylw=$'\e[0;33m' # Yellow
- txtblu=$'\e[0;34m' # Blue
- txtpur=$'\e[0;35m' # Purple
- txtcyn=$'\e[0;36m' # Cyan
- txtwht=$'\e[0;37m' # White
- bldblk=$'\e[1;30m' # Black - Bold
- bldred=$'\e[1;31m' # Red
- bldgrn=$'\e[1;32m' # Green
- bldylw=$'\e[1;33m' # Yellow
- bldblu=$'\e[1;34m' # Blue
- bldpur=$'\e[1;35m' # Purple
- bldcyn=$'\e[1;36m' # Cyan
- bldwht=$'\e[1;37m' # White
- unkblk=$'\e[4;30m' # Black - Underline
- undred=$'\e[4;31m' # Red
- undgrn=$'\e[4;32m' # Green
- undylw=$'\e[4;33m' # Yellow
- undblu=$'\e[4;34m' # Blue
- undpur=$'\e[4;35m' # Purple
- undcyn=$'\e[4;36m' # Cyan
- undwht=$'\e[4;37m' # White
- bakblk=$'\e[40m' # Black - Background
- bakred=$'\e[41m' # Red
- bakgrn=$'\e[42m' # Green
- bakylw=$'\e[43m' # Yellow
- bakblu=$'\e[44m' # Blue
- bakpur=$'\e[45m' # Purple
- bakcyn=$'\e[46m' # Cyan
- bakwht=$'\e[47m' # White
- NORMAL=$'\e[0m'
- # SET COLORS
- #RED=$'\e[31;01m'
- URGENT=${bakred}${bldwht}
- KERNCOLOR=${bldblu}
- PROCCOLOR=${bakblu}${bldwht}
- CAUTION=${bakylw}${bldwht}
- # Save and Restore arguments handled here
- #if [ "$1" = "save" ]
- #then
- # echo -n "Saving firewall to /etc/sysconfig/iptables ... "
- # $IPTS > /etc/sysconfig/iptables
- # echo "done"
- # exit 0
- #elif [ "$1" = "restore" ]
- #then
- # echo -n "Restoring firewall from /etc/sysconfig/iptables ... "
- # $IPTR < /etc/sysconfig/iptables
- # echo "done"
- # exit 0
- #fi
- #######################################################
- fw_start() {
- # Display a message stating the firewall is starting
- echo "${PROCCOLOR}Firewall is being configured.....${NORMAL}"
- # Flush the current rules
- flush_rules
- # load the appropriate kernel modules
- load_modules
- # load the necessary kernel bits
- load_kernel_bits
- # Make the user Chains
- make_chains
- # Allow all on localhost interface
- #$IPT -A INPUT -p ALL -i $LO_IFACE -j ACCEPT
- # Accept Established Connections
- $IPT -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT
- # check for bad packets
- check_bad_packets
- # Drop bad packets
- $IPT -A INPUT -p ALL -j bad_packets
- # check the icmp packets
- check_icmp
- # Open ports for selected services
- check_services
- #### INPUT ###############################################
- # Add the rules for specific packet types
- udp_out
- udp_in
- tcp_out
- tcp_in
- # Route the rest to the appropriate user chain
- $IPT -A INPUT -p TCP -j tcp_inbound
- $IPT -A INPUT -p UDP -j udp_inbound
- $IPT -A INPUT -p ICMP -j icmp_packets
- # Drop without logging broadcasts that get this far.
- # Cuts down on log clutter.
- # Comment this line if testing new rules that impact
- # broadcast protocols.
- $IPT -A INPUT -m pkttype --pkt-type broadcast -j DROP
- # Log packets that still don't match
- #$IPT -A INPUT -j LOG --log-prefix "fp=INPUT:99 a=DROP "
- #### OUTPUT ###############################################
- # Generally trust the firewall on output
- $IPT -A OUTPUT -p TCP -j tcp_outbound
- $IPT -A OUTPUT -p UDP -j udp_outbound
- # However, invalid icmp packets need to be dropped
- # to prevent a possible exploit.
- $IPT -A OUTPUT -m state -p icmp --state INVALID -j DROP
- # To internet
- $IPT -A OUTPUT -p ALL -o $INET_IFACE -j ACCEPT
- # Log packets that still don't match
- #$IPT -A OUTPUT -j LOG --log-prefix "fp=OUTPUT:99 a=DROP "
- ###############################################################################
- # block all other incoming traffic
- $IPT -A INPUT -j DROP
- # Display a message stating the firewall has been started
- echo "${PROCCOLOR}Firewall Started.....${NORMAL}"
- }
- fw_stop() {
- # Flush all rules
- flush_rules
- echo "${URGENT}Firewall Stopped.....${NORMAL}"
- }
- flush_rules() {
- #echo "Start flush"
- # Flush all rules
- $IPT -F
- for CHN in `$IPT -L|grep references|cut -d " " -f 2`
- do
- $IPT -X $CHN
- done
- #echo "Flush Complete"
- }
- #######################################################
- load_modules() {
- # Load Modules
- #
- # You should uncomment the line below and run it the first time just to
- # ensure all kernel module dependencies are OK. There is no need to run
- # every time, however.
- # /sbin/depmod -a
- # Unless you have kernel module auto-loading disabled, you should not
- # need to manually load each of these modules. Other than ip_tables,
- # ip_conntrack, and some of the optional modules, I've left these
- # commented by default. Uncomment if you have any problems or if
- # you have disabled module autoload. Note that some modules must
- # be loaded by another kernel module.
- # core netfilter module
- load_module ip_tables
- # the stateful connection tracking module
- #/sbin/modprobe ip_conntrack
- load_module nf_conntrack
- load_module nf_conntrack_ipv4
- # filter table module
- # /sbin/modprobe iptable_filter
- # mangle table module
- # /sbin/modprobe iptable_mangle
- # nat table module
- # /sbin/modprobe iptable_nat
- # LOG target module
- # /sbin/modprobe ipt_LOG
- # This is used to limit the number of packets per sec/min/hrs
- load_module ipt_limit
- # masquerade target module
- # /sbin/modprobe ipt_MASQUERADE
- # filter using owner as part of the match
- # /sbin/modprobe ipt_owner
- # REJECT target drops the packet and returns an ICMP response.
- # The response is configurable. By default, connection refused.
- # /sbin/modprobe ipt_REJECT
- # This target allows packets to be marked in the mangle table
- # /sbin/modprobe ipt_mark
- # This target affects the TCP MSS
- # /sbin/modprobe ipt_tcpmss
- # This match allows multiple ports instead of a single port or range
- # /sbin/modprobe multiport
- # This match checks against the TCP flags
- #/sbin/modprobe ipt_state
- load_module ipt_state
- # the module for full irc connection tracking
- #/sbin/modprobe ip_conntrack_irc
- load_module ip_conntrack_irc
- # ftp base modules
- load_module nf_conntrack_ftp
- load_module ip_vs_ftp
- load_module nf_nat_ftp
- #####################################################################
- # Kernel Parameter Configuration
- #
- # See http://ipsysctl-tutorial.frozentux.net/chunkyhtml/index.html
- # for a detailed tutorial on sysctl and the various settings
- # available.
- # Required to enable IPv4 forwarding.
- # Redhat users can try setting FORWARD_IPV4 in /etc/sysconfig/network to true
- # Alternatively, it can be set in /etc/sysctl.conf
- #if [ "$SYSCTL" = "" ]
- #then
- # echo "1" > /proc/sys/net/ipv4/ip_forward
- #else
- # $SYSCTL net.ipv4.ip_forward="1"
- #fi
- # This option allows a subnet to be firewalled with a single IP address.
- # It's used to build a DMZ. Since that's not a focus of this firewall
- # script, it's not enabled by default, but is included for reference.
- # See: http://www.sjdjweis.com/linux/proxyarp/
- #if [ "$SYSCTL" = "" ]
- #then
- # echo "1" > /proc/sys/net/ipv4/conf/all/proxy_arp
- #else
- # $SYSCTL net.ipv4.conf.all.proxy_arp="1"
- #fi
- # This option logs packets from impossible addresses.
- #if [ "$SYSCTL" = "" ]
- #then
- # echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
- #else
- # $SYSCTL net.ipv4.conf.all.log_martians="1"
- #fi
- }
- load_module() {
- if [ -z "$(cat /proc/modules|cut -d " " -f 1|grep $1)" ]; then
- echo "${KERNCOLOR}Loading the $1 module......${NORMAL}"
- /sbin/modprobe $1
- fi
- }
- load_kernel_bits() {
- # This enables dynamic address hacking.
- # This may help if you have a dynamic IP address \(e.g. slip, ppp, dhcp\).
- modlkb /proc/sys/net/ipv4/ip_dynaddr 1
- # Drop ICMP echo-request messages sent to broadcast or multicast addresses
- # This kernel parameter instructs the kernel to ignore all ICMP
- # echo requests sent to the broadcast address. This prevents
- # a number of smurfs and similar DoS nasty attacks.
- modlkb /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts 1
- # Drop source routed packets
- # This option can be used to accept or refuse source routed
- # packets. It is usually on by default, but is generally
- # considered a security risk. This option turns it off.
- modlkb /proc/sys/net/ipv4/conf/all/accept_source_route 1
- # Enable TCP SYN cookie protection from SYN floods
- modlkb /proc/sys/net/ipv4/tcp_syncookies 1
- # Don't accept ICMP redirect messages
- # This option can disable ICMP redirects. ICMP redirects
- # are generally considered a security risk and shouldn't be
- # needed by most systems.
- modlkb /proc/sys/net/ipv4/conf/all/accept_redirects 1
- # However, we'll ensure the secure_redirects option is on instead.
- # This option accepts only from gateways in the default gateways list.
- modlkb /proc/sys/net/ipv4/conf/all/secure_redirects 1
- # Don't send ICMP redirect messages
- modlkb /proc/sys/net/ipv4/conf/all/send_redirects 0
- # Enable source address spoofing protection
- # This enables source validation by reversed path according to RFC1812.
- # In other words, did the response packet originate from the same interface
- # through which the source packet was sent? It's recommended for single-homed
- # systems and routers on stub networks. Since those are the configurations
- # this firewall is designed to support, I turn it on by default.
- # Turn it off if you use multiple NICs connected to the same network.
- # 1=on , 0=off
- modlkb /proc/sys/net/ipv4/conf/all/rp_filter 1
- # Log packets with impossible source addresses
- #echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
- }
- modlkb() {
- if [ ! "$(echo $2)" = "$1" ]; then
- echo $2 > $1
- #echo "$1 should be $2"
- #cat $1
- fi
- }
- make_chains() {
- # User-Specified Chains
- # Create a chain to filter INVALID packets
- $IPT -N bad_packets
- # Create another chain to filter bad tcp packets
- # $IPT -N bad_tcp_packets
- # Create separate chains for icmp, tcp (incoming and outgoing),
- # and incoming udp packets.
- $IPT -N icmp_packets
- # Used for UDP packets inbound from the Internet
- $IPT -N udp_inbound
- # Used to block outbound UDP services from internal network
- # Default to allow all
- $IPT -N udp_outbound
- # Used to allow inbound services if desired
- # Default fail except for established sessions
- $IPT -N tcp_inbound
- # Used to block outbound services from internal network
- # Default to allow all
- $IPT -N tcp_outbound
- }
- check_bad_packets() {
- # bad_packets chain
- #
- # Drop INVALID packets immediately
- #$IPT -A bad_packets -p ALL -m state --state INVALID -j LOG \
- # --log-prefix "fp=bad_packets:1 a=DROP "
- $IPT -A bad_packets -p ALL -m state --state INVALID -j DROP
- # Then check the tcp packets for additional problems
- #$IPT -A bad_packets -p tcp -j bad_tcp_packets
- # All good, so return
- $IPT -A bad_packets -p ALL -j RETURN
- # bad_tcp_packets chain
- #
- # All tcp packets will traverse this chain.
- # Every new connection attempt should begin with
- # a syn packet. If it doesn't, it is likely a
- # port scan. This drops packets in state
- # NEW that are not flagged as syn packets.
- #$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
- # --log-prefix "fp=bad_tcp_packets:1 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j LOG \
- # --log-prefix "fp=bad_tcp_packets:2 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL NONE -j DROP
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j LOG \
- # --log-prefix "fp=bad_tcp_packets:3 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL ALL -j DROP
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG \
- # --log-prefix "fp=bad_tcp_packets:4 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
- #
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOG \
- # --log-prefix "fp=bad_tcp_packets:5 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
- #
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j LOG \
- # --log-prefix "fp=bad_tcp_packets:6 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j LOG \
- # --log-prefix "fp=bad_tcp_packets:7 a=DROP "
- #$IPT -A bad_tcp_packets -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
- }
- check_icmp() {
- # icmp_packets chain
- #
- # This chain is for inbound (from the Internet) icmp packets only.
- # Type 8 (Echo Request) is not accepted by default
- # Enable it if you want remote hosts to be able to reach you.
- # 11 (Time Exceeded) is the only one accepted
- # that would not already be covered by the established
- # connection rule. Applied to INPUT on the external interface.
- #
- # See: http://www.ee.siue.edu/~rwalden/networking/icmp.html
- # for more info on ICMP types.
- #
- # Note that the stateful settings allow replies to ICMP packets.
- # These rules allow new packets of the specified types.
- # ICMP packets should fit in a Layer 2 frame, thus they should
- # never be fragmented. Fragmented ICMP packets are a typical sign
- # of a denial of service attack.
- $IPT -A icmp_packets --fragment -p ICMP -j LOG \
- --log-prefix "fp=icmp_packets:1 a=DROP "
- $IPT -A icmp_packets --fragment -p ICMP -j DROP
- # Echo - uncomment to allow your system to be pinged.
- # Uncomment the LOG command if you also want to log PING attempts
- #
- # $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j LOG \
- # --log-prefix "fp=icmp_packets:2 a=ACCEPT "
- # $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j ACCEPT
- # By default, however, drop pings without logging. Blaster
- # and other worms have infected systems blasting pings.
- # Comment the line below if you want pings logged, but it
- # will likely fill your logs.
- $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 8 -j DROP
- # Time Exceeded
- $IPT -A icmp_packets -p ICMP -s 0/0 --icmp-type 11 -j ACCEPT
- # Not matched, so return so it will be logged
- $IPT -A icmp_packets -p ICMP -j DROP
- ############ MY RULES ############################
- # Allow pings per minute to block ping DOS attacks
- # $IPT -A INPUT -p icmp --icmp-type echo-request -m limit --limit 4/m -j ACCEPT
- # Allow all echo replies including destination unreachable and time exceeded
- # $IPT -A icmp_packets -p icmp --icmp-type echo-reply -j ACCEPT
- # $IPT -A icmp_packets -p icmp --icmp-type destination-unreachable -j ACCEPT
- # $IPT -A icmp_packets -p icmp --icmp-type time-exceeded -j ACCEPT
- # Block all other icmp traffic
- # $IPT -A icmp_packets -p icmp -j DROP
- }
- udp_out() {
- # udp_outbound chain
- #
- # This chain is used with a private network to prevent forwarding for
- # UDP requests on specific protocols. Applied to the FORWARD rule from
- # the internal network. Ends with an ACCEPT
- # No match, so ACCEPT
- $IPT -A udp_outbound -p UDP -s 0/0 -j ACCEPT
- }
- udp_in() {
- # udp_inbound chain
- #
- # This chain describes the inbound UDP packets it will accept.
- # It's applied to INPUT on the external or Internet interface.
- # Note that the stateful settings allow replies.
- # These rules are for new requests.
- # It drops netbios packets (windows) immediately without logging.
- # Drop netbios calls
- # Please note that these rules do not really change the way the firewall
- # treats netbios connections. Connections from the localhost and
- # internal interface (if one exists) are accepted by default.
- # Responses from the Internet to requests initiated by or through
- # the firewall are also accepted by default. To get here, the
- # packets would have to be part of a new request received by the
- # Internet interface. You would have to manually add rules to
- # accept these. I added these rules because some network connections,
- # such as those via cable modems, tend to be filled with noise from
- # unprotected Windows machines. These rules drop those packets
- # quickly and without logging them. This prevents them from traversing
- # the whole chain and keeps the log from getting cluttered with
- # chatter from Windows systems.
- $IPT -A udp_inbound -p UDP -s 0/0 --dport 137 -j DROP
- $IPT -A udp_inbound -p UDP -s 0/0 --dport 138 -j DROP
- # Ident requests (Port 113) must have a REJECT rule rather than the
- # default DROP rule. This is the minimum requirement to avoid
- # long delays while connecting. Also see the tcp_inbound rule.
- $IPT -A udp_inbound -p UDP -s 0/0 --dport 113 -j REJECT
- # A more sophisticated configuration could accept the ident requests.
- # $IPT -A udp_inbound -p UDP -s 0/0 --dport 113 -j ACCEPT
- # Dynamic Address
- # If DHCP, the initial request is a broadcast. The response
- # doesn't exactly match the outbound packet. This explicitly
- # allow the DHCP ports to alleviate this problem.
- # If you receive your dynamic address by a different means, you
- # can probably comment this line.
- $IPT -A udp_inbound -p UDP -s 0/0 --source-port 67 --dport 68 \
- -j ACCEPT
- # Not matched, so return for logging
- $IPT -A udp_inbound -p UDP -j DROP
- }
- tcp_out() {
- # tcp_outbound chain
- #
- # This chain is used with a private network to prevent forwarding for
- # requests on specific protocols. Applied to the FORWARD rule from
- # the internal network. Ends with an ACCEPT
- # No match, so ACCEPT
- $IPT -A tcp_outbound -p TCP -s 0/0 -j ACCEPT
- }
- tcp_in() {
- # tcp_inbound chain
- #
- # This chain is used to allow inbound connections to the
- # system/gateway. Use with care. It defaults to none.
- # It's applied on INPUT from the external or Internet interface.
- # Ident requests (Port 113) must have a REJECT rule rather than the
- # default DROP rule. This is the minimum requirement to avoid
- # long delays while connecting. Also see the tcp_inbound rule.
- $IPT -A tcp_inbound -p TCP -s 0/0 --dport 113 -j REJECT
- # Not matched, so return so it will be logged
- $IPT -A tcp_inbound -p TCP -j DROP
- }
- #######################################################
- check_services() {
- # choose services to allow
- Srv=1
- # For items with values listed $1 = WEB or LOCAL
- # Otherwise it assumes LOCAL of WEB based upon the type of service#
- # Verified services
- #serv_allow sshd KNOWN 666
- #serv_allow ftp LOCAL "ftp" "ftp"
- #serv_allow CUPSD LOCAL 631 631
- #serv_allow nfsd KNOWN "2049 42118 47181" "2049 42118 47181"
- #serv_allow rpc KNOWN 111 111
- #serv_allow VNC WEB "5900 5800 5500" "5900 5800 5500"
- gtalk_allow
- }
- gtalk_allow() {
- GPRT=$(lsof -i|grep GoogleTal|grep LISTEN|tr -s " "|cut -d " " -f 9|cut -d ":" -f 2|cut -d "-" -f 1|uniq)
- if [ "$GPRT" != "" ]; then
- serv_allow "Gtalk:$GPRT" WEB $GPRT
- fi
- }
- serv_allow() {
- #symtax - serv allow {service} {domain} {tcp ports} {udp ports}
- if [[ -x /etc/rc.d/rc.$1 || ! -f /etc/rc.d/rc.$i ]]; then
- # get tcp ports
- declare -a PRTS
- PORTS=($3)
- for PRT in "${PORTS[@]}"
- do
- case "$2" in
- "WEB")
- $IPT -A tcp_inbound -p TCP -s 0/0 --dport $PRT -j ACCEPT
- ;;
- "KNOWN")
- for MAC in "${KMACS[@]}"
- do
- $IPT -A tcp_inbound -p TCP -s 0/0 --dport $PRT -m mac --mac-source $MAC -j ACCEPT
- done
- ;;
- *)
- $IPT -A tcp_inbound -p TCP -s $LOC_SUB --dport $PRT -j ACCEPT
- ;;
- esac
- done
- # get the udp ports
- PORTS=($4)
- for PRT in "${PORTS[@]}"
- do
- case "$2" in
- "WEB")
- $IPT -A udp_inbound -p UDP -s 0/0 --dport $PRT -j ACCEPT
- ;;
- "KNOWN")
- for MAC in "${KMACS[@]}"
- do
- $IPT -A udp_inbound -p UDP -s 0/0 --dport $PRT -m mac --mac-source $MAC -j ACCEPT
- done
- ;;
- *)
- $IPT -A udp_inbound -p UDP -s $LOC_SUB --dport $PRT -j ACCEPT
- ;;
- esac
- done
- # Write a visible notification
- case "$2" in
- "WEB")
- echo "${URGENT}Allowing $1 for all hosts......${NORMAL}"
- ;;
- "KNOWN")
- echo "${CAUTION}Allowing $1 for known hosts......${NORMAL}"
- ;;
- *)
- echo "${CAUTION}Allowing $1 for local hosts......${NORMAL}"
- ;;
- esac
- fi
- }
- #######################################################
- case "$1" in
- start)
- fw_start
- ;;
- stop)
- fw_stop
- ;;
- restart)
- fw_stop
- fw_start
- ;;
- *)
- echo $"Usage: $0 {start|stop|restart}"
- ;;
- esac
- # TO-DO
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement