hq8501 发表于 2018-8-26 11:01:22

经典好用anti-DDos的iptables shell脚本

  #!/bin/bash
  # Description: This script applies to both RHEL and CentOS systems.This is
  # a powerful firewall, anti DDOS attacks, and not limitedto this, you can
  # make your Linux server as router, http/ftp server etc. ,but also as
  # required to open SNAT, DNAT function.
  # Author:JianJie
  # Version:1.0
  # Date:2017-09-17
  # Checking if script is run as root
  if [ $(id -u) -ne 0 ];then
  echo "Script is not run as root, exiting..."
  exit 1
  fi
  # To avoid being unable to connect to the server, the following schedule has been worked out
  string=$(cat /etc/redhat-release)
  vers=$(echo ${string##*release}|sed 's/^[[:space:]]*//g'|awk -F"." '{print $1}')
  if [ $vers -eq 7 ];then
  if echo "*/3 * * * * /usr/bin/systemctl stop iptables.service" >> /etc/crontab ;then
  echo "Plans have been added to /etc/crontab: */3 * * * * /usr/bin/systemctl stop iptables.service"
  echo "If you are sure that iptables will work properly, you can close the schedule task"
  else
  echo "Failed to add task plan to /etc/crontab,stop running this script for security"
  exit 1
  fi
  elif [ $vers -eq 6 ];then
  if echo "*/3 * * * * /sbin/service iptables stop" >> /etc/crontab ;then
  echo "Plans have been added to /etc/crontab: */3 * * * * /sbin/service iptables stop"
  echo "If you are sure that iptables will work properly, you can close the schedule task"
  else
  echo "Failed to add task plan to /etc/crontab,stop running this script for security"
  exit 1
  fi
  else
  echo "Your system is not RHEL or CentOS, if you want to use this script, you can manually modify certain code,now exit"
  exit 1
  fi
  ########################GLOBAL_PARAMETER_SETING_START#####################
  export PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin"
  IPTABLES="/sbin/iptables"
  MODPROBE="/sbin/modprobe"
  IP6TABLES="/sbin/ip6tables"
  # Internal web server IP addr
  HTTP_SERVER=""
  # Internal ftp server IP addr
  FTP_SERVER="172.16.0.66"
  # Internal dns server IP addr
  DNS_SERVER=""
  # The path to the script is currently running
  RUN_DIR="$( cd "$( dirname "${BASH_SOURCE}" )" && pwd )"
  # Enable ip froward
  IP_FORWARD=1
  # Enable MASQUERADE
  INTERNAL_MASQUERADE_SWITCH="1"
  # Enable DNAT
  INTERNAL_DNAT_SWITCH="1"
  # Conntrack parameter optimization
  CONNTRACK_MAX=300000#CONNTRACK_MAX=RAMSIZE(in bytes)/16384/(ARCH/32)
  ESTAB_TIMEOUT=3600
  TIME_WAIT=120
  CLOSE_WAIT=60
  FIN_WAIT=120
  CONNTRACK_BUCKETS=50000#min: CONNTRACK_MAX / 8; max: CONNTRACK_MAX / 2
  MODULES="ip_tables iptable_nat nf_nat_ftp nf_nat_irc nf_conntrack nf_conntrack_ftp nf_conntrack_irc ipt_MASQUERADE"
  # The path in which the script is running
  CURRENTDIR="$( cd "$( dirname "${BASH_SOURCE}" )" && pwd )"
  LOG="LOG --log-level debug --log-tcp-sequence --log-tcp-options"
  RLIMIT="-m limit --limit 3/sec --limit-burst 8"
  ##############################################
  # Please set the port you need to open here#
  ##############################################
  # input udp all
  INPUT_SERVICES_UDP_ALL="53 67 1194"
  # input tcp all
  INPUT_SERVICES_TCP_ALL="21 22 53 80 443"
  # input udp internal
  INPUT_SERVICES_UDP_INTERNAL="53 123 137 138"
  # input tcp internal
  INPUT_SERVICES_TCP_INTERNAL="21 22 80 139 445"
  # output udp all dport
  OUTPUT_SERVICES_UDP_ALL_DPORT="53 67 68 123 443 1194"
  # output tcp all dport
  OUTPUT_SERVICES_TCP_ALL_DPORT="21 22 53 80 443"
  OUTPUT_SERVICES_TCP_ALL_DPORT_FTP=""
  # output udp all sport
  OUTPUT_SERVICES_UDP_ALL_SPORT=""
  # output tcp all sport
  OUTPUT_SERVICES_TCP_ALL_SPORT=""
  OUTPUT_SERVICES_TCP_ALL_SPORT_FTP=""
  # output udp internal
  OUTPUT_SERVICES_UDP_INTERNAL="53"
  # output tcp internal
  OUTPUT_SERVICES_TCP_INTERNAL="80 443"
  # forward udp internal
  FORWARD_SERVICES_UDP_INTERNAL="53 123"
  # forward tcp internal
  FORWARD_SERVICES_TCP_INTERNAL="21 22 53 80 443"
  ######################## NETWORK_AND_INTERFACE############################
  # Sub net pattern,e.g. 192.168.1.0/24
  SUBNET_PATTERN="((\|\|\)\.){3}(\|\|\)/(\|\|\)"
  # Get the default network interface
  if [[ $DEFAULT_INTERFACE == "" ]];then
  DEFAULT_INTERFACE=$(ip route | grep default.* | sed '1!d' | grep -Po '(? $i; done
  for i in /proc/sys/net/ipv4/conf/*/send_redirects; do echo 0 > $i; done
  # Don't accept source routed packets.
  for i in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 > $i; done
  # Disable proxy_arp.
  for i in /proc/sys/net/ipv4/conf/*/proxy_arp; do echo 0 > $i; done
  # Ignore ICMP echo requests to broadcast
  echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
  # Don't log invalid responses to broadcast
  echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
  #######################Kernel configuration stop########################
  #######################Set default policies start#######################
  # Drop everything by default.
  $IPTABLES -P INPUT DROP
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P OUTPUT DROP
  # Set the nat/mangle/raw tables' chains to ACCEPT
  $IPTABLES -t nat -P PREROUTING ACCEPT
  $IPTABLES -t nat -P OUTPUT ACCEPT
  $IPTABLES -t nat -P POSTROUTING ACCEPT
  $IPTABLES -t mangle -P PREROUTING ACCEPT
  $IPTABLES -t mangle -P INPUT ACCEPT
  $IPTABLES -t mangle -P FORWARD ACCEPT
  $IPTABLES -t mangle -P OUTPUT ACCEPT
  $IPTABLES -t mangle -P POSTROUTING ACCEPT
  #######################Set default policies stop#######################
  #######################Clean tables start##############################
  # Delete all
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -t mangle -F
  $IPTABLES -t security -F
  # Delete all
  $IPTABLES -X
  $IPTABLES -t nat -X
  $IPTABLES -t mangle -X
  $IPTABLES -t security -X
  # Zero all packets and counters.
  $IPTABLES -Z
  $IPTABLES -t nat -Z
  $IPTABLES -t mangle -Z
  #######################Clean tables stop###############################
  #######################Disable ip6tables start#########################
  # Block all IPv6 traffic
  # If the ip6tables command is available, try to block all IPv6 traffic.
  if test -x $IP6TABLES; then
  # Set the default policies
  # drop everything
  $IP6TABLES -P INPUT DROP &>/dev/null
  $IP6TABLES -P FORWARD DROP &>/dev/null
  $IP6TABLES -P OUTPUT DROP &>/dev/null
  # The mangle table can pass everything
  $IP6TABLES -t mangle -P PREROUTING ACCEPT &>/dev/null
  $IP6TABLES -t mangle -P INPUT ACCEPT &>/dev/null
  $IP6TABLES -t mangle -P FORWARD ACCEPT &>/dev/null
  $IP6TABLES -t mangle -P OUTPUT ACCEPT &>/dev/null
  $IP6TABLES -t mangle -P POSTROUTING ACCEPT &>/dev/null
  # Delete all rules.
  $IP6TABLES -F &>/dev/null
  $IP6TABLES -t mangle -F &>/dev/null
  # Delete all chains.
  $IP6TABLES -X &>/dev/null
  $IP6TABLES -t mangle -X &>/dev/null
  # Zero all packets and counters.
  $IP6TABLES -Z &>/dev/null
  $IP6TABLES -t mangle -Z &>/dev/null
  fi
  #######################Disable ip6tables start#########################
  #######################USER_DEFINED_CHAIN##############################
  # Custom user-defined chains.
  # LOG packets, then ACCEPT.
  $IPTABLES -N accept_log
  $IPTABLES -A accept_log -j $LOG $RLIMIT --log-prefix "ACCEPT "
  $IPTABLES -A accept_log -j ACCEPT
  $IPTABLES -A accept_log -p ALL -j RETURN
  # LOG packets, then DROP.
  $IPTABLES -N drop_log
  $IPTABLES -A drop_log -j $LOG $RLIMIT --log-prefix "DROP "
  $IPTABLES -A drop_log -j DROP
  $IPTABLES -A drop_log -p ALL -j RETURN
  ### security
  # port scanning
  $IPTABLES -N port_scanning
  $IPTABLES -A port_scanning -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s --limit-burst 2 -j DROP
  $IPTABLES -A port_scanning -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A port_scanning -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A port_scanning -d 255.255.255.255 -p icmp -j DROP
  $IPTABLES -A port_scanning -p tcp ! --syn -m state --state NEW -j DROP
  $IPTABLES -A port_scanning -j RETURN
  ### Limit RST packets ###
  $IPTABLES -N limit_rst
  $IPTABLES -A limit_rst -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT
  $IPTABLES -A limit_rst -p tcp --tcp-flags RST RST -j DROP
  $IPTABLES -A limit_rst -p tcp -j RETURN
  # ddos
  # 50/m200
  # 60/s20
  $IPTABLES -N ddos
  ### Limit new TCP connections per second per source IP ###
  $IPTABLES -A ddos -p tcp -m connlimit --connlimit-above 111 -j DROP
  $IPTABLES -A ddos -f -m limit --limit 100/sec --limit-burst 100 -j ACCEPT
  $IPTABLES -A ddos -j RETURN
  # syn flood tcp
  ##      1/s             -
  #       1/s             3
  #       5/s             10
  $IPTABLES -N synflood_tcp
  $IPTABLES -A synflood_tcp -p tcp -m conntrack --ctstate NEW -m limit --limit 3/s --limit-burst 6 -j RETURN
  $IPTABLES -A synflood_tcp -p tcp -m conntrack --ctstate NEW -j DROP
  $IPTABLES -A synflood_tcp -p tcp -j RETURN
  # syn flood udp
  $IPTABLES -N synflood_udp
  $IPTABLES -A synflood_udp -p udp -m limit --limit 3/s --limit-burst 5 -j RETURN
  $IPTABLES -A synflood_udp -p udp -j DROP
  $IPTABLES -A synflood_udp -p udp -j RETURN
  # ssh limits
  $IPTABLES -N ssh_limits
  # limiting ssh connections, drop all requests that are more than --hitcount x tries within --seconds y
  # if ssh port is closed, packages are sent to input_log_reject if not matching the spefcified criteria, after that they are dropped without log
  $IPTABLES -A ssh_limits -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --set
  $IPTABLES -A ssh_limits -p tcp --dport 22 -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
  $IPTABLES -A ssh_limits -p tcp --dport 22 -m connlimit --connlimit-above 5 -j DROP
  $IPTABLES -A ssh_limits -p tcp --dport 22 -j RETURN
  # ping limits
  $IPTABLES -N icmp_limits
  $IPTABLES -A icmp_limits -p icmp --icmp-type 8 -m limit --limit 1/sec --limit-burst 2 -j accept_log
  $IPTABLES -A icmp_limits -p icmp --icmp-type 8 -m connlimit ! --connlimit-above 3 -j accept_log
  # drop all fragmented ICMP packets (almost always malicious).
  $IPTABLES -A icmp_limits -p icmp -f -j DROP
  $IPTABLES -A icmp_limits -j RETURN
  services_all() {
  if [ "$2" != "" ];then
  for port in $2
  do
  $IPTABLES -A $1 -p $3 $4 $port -j ACCEPT
  done
  fi
  }
  ### services input all
  $IPTABLES -N input_services_all
  services_all input_services_all "$INPUT_SERVICES_TCP_ALL" tcp --dport
  services_all input_services_all "$INPUT_SERVICES_UDP_ALL" udp --dport
  # leaving table "input_services_all"
  $IPTABLES -A input_services_all -p ALL -j RETURN
  ### services output all
  $IPTABLES -N output_services_all
  services_all output_services_all "$OUTPUT_SERVICES_TCP_ALL_DPORT" tcp --dport
  services_all output_services_all "$OUTPUT_SERVICES_UDP_ALL_DPORT" udp --dport
  services_all output_services_all "$OUTPUT_SERVICES_TCP_ALL_SPORT" tcp --sport
  services_all output_services_all "$OUTPUT_SERVICES_UDP_ALL_SPORT" udp --sport
  #$IPTABLES -A output_services_all -p tcp --sport $OUTPUT_SERVICES_TCP_ALL_SPORT_FTP --dport $OUTPUT_SERVICES_TCP_ALL_DPORT_FTP -j ACCEPT
  # leaving table "output_services_all"
  $IPTABLES -A output_services_all -p ALL -j RETURN
  services_internal() {
  if [ "$IPTABLES_SUBNETS" != "" ];then
  for i in $IPTABLES_SUBNETS;
  do
  if [ "$i" != "" ];then
  if [ "$2" != "" ];then
  for port in $2
  do
  iptables -A $1 -p tcp -s $i $4 $port -j ACCEPT
  done
  fi
  if [ "$3" != "" ];then
  for port in $3
  do
  # for udp connections allow specified port
  iptables -A $1 -p udp -s $i $4 $port -j ACCEPT
  done
  fi
  else
  echo 'No entry for $i, skipping setting internal input port openings...'
  fi
  done
  fi
  }
  if [ "$IPTABLES_SUBNETS" != "" ];then
  iptables -N input_services_internal
  services_internal input_services_internal "$INPUT_SERVICES_TCP_INTERNAL" "$INPUT_SERVICES_UDP_INTERNAL" --dport
  # leaving table "input_services_internal"
  iptables -A input_services_internal -p ALL -j RETURN
  iptables -N output_services_internal
  services_internal output_services_internal "$OUTPUT_SERVICES_TCP_INTERNAL" "$OUTPUT_SERVICES_UDP_INTERNAL" --dport
  iptables -A output_services_internal -p ALL -j RETURN
  iptables -N forward_services_internal
  services_internal forward_services_internal "$FORWARD_SERVICES_TCP_INTERNAL" "$FORWARD_SERVICES_UDP_INTERNAL" --dport
  iptables -A forward_services_internal -p ALL -j RETURN
  fi
  #
  #######################User defined chains stop######################
  ### prerouting
  ### Drop invalid packets ###
  $IPTABLES -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
  ### Drop TCP packets that are new and are not SYN ###
  $IPTABLES -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
  ### Drop SYN packets with suspicious MSS value ###
  $IPTABLES -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
  ### Block packets with bogus TCP flags ###
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
  $IPTABLES -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  ### Block spoofed packets ###
  $IPTABLES -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP
  $IPTABLES -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
  #$IPTABLES -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
  $IPTABLES -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
  #$IPTABLES -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP
  #$IPTABLES -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
  $IPTABLES -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP
  $IPTABLES -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
  $IPTABLES -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP
  ### Drop ICMP (you usually don't need this protocol) ###
  #$IPTABLES -t mangle -A PREROUTING -p icmp -j DROP
  ### Drop fragments in all chains ###
  $IPTABLES -t mangle -A PREROUTING -f -j DROP
  #######################INPUT_RULES_START###############################
  $IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  # broadcast
  $IPTABLES -A INPUT -m pkttype --pkt-type broadcast -j DROP
  # muticast
  $IPTABLES -A INPUT -m pkttype --pkt-type multicast -j DROP
  $IPTABLES -A INPUT -j port_scanning
  $IPTABLES -A INPUT -j limit_rst
  $IPTABLES -A INPUT -j ddos
  $IPTABLES -A INPUT -j synflood_tcp
  $IPTABLES -A INPUT -j synflood_udp
  $IPTABLES -A INPUT -j icmp_limits
  $IPTABLES -A INPUT -j ssh_limits
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -p ALL -j input_services_all
  $IPTABLES -A INPUT -p ALL -j input_services_internal

  # Allow incoming connections>  # Explicitly drop invalid incoming traffic
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  #Start the extra firewall script module
  if [ -f $CURRENTDIR/iptables.deny ]; then
  sh $CURRENTDIR/iptables.deny
  fi
  if [ -f $CURRENTDIR/iptables.allow ]; then
  sh $CURRENTDIR/iptables.allow
  fi
  if [ -f $CURRENTDIR/iptables.http ]; then
  sh $CURRENTDIR/iptables.http
  fi
  # Use DROP instead of drop_log if you don't need logging.
  $IPTABLES -A INPUT -j DROP
  #######################INPUT_RULES_STOP################################
  #######################OUTPUT_RULES_START##############################
  # Allow outgoing connections EXCEPT invalid
  $IPTABLES -A OUTPUT -p icmp -f -j DROP
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
  # Drop invalid outgoing traffic, too.
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  ### sending packages through tables
  $IPTABLES -A OUTPUT -p ALL -j output_services_all
  $IPTABLES -A OUTPUT -p ALL -j output_services_internal
  $IPTABLES -A OUTPUT -m state --state ESTABLISHED -j ACCEPT
  $IPTABLES -A OUTPUT -j DROP
  #######################OUTPUT_RULES_STOP##############################
  ######################FORWARD_RULES_START#############################
  $IPTABLES -A FORWARD -j port_scanning
  $IPTABLES -A FORWARD -j limit_rst
  $IPTABLES -A FORWARD -j ddos
  $IPTABLES -A FORWARD -j synflood_tcp
  $IPTABLES -A FORWARD -j synflood_udp
  $IPTABLES -A FORWARD -j icmp_limits
  $IPTABLES -A FORWARD -j ssh_limits
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  ### sending packages through custom chains
  $IPTABLES -A FORWARD -p ALL -j forward_services_internal
  ### open*** tun routing
  if [ "$IPTABLES_TUN_SUBNETS" != "" ];then
  for i in $IPTABLES_TUN_SUBNETS
  do
  if [ "$i" != "" ];then
  # variable not empty
  if [ $i == "$CONNECTED_TUN_SUBNET0" ]; then TUNINTERFACE="$TUN0"; elif [ $i == "$CONNECTED_TUN_SUBNET1" ]; then TUNINTERFACE="$TUN1"; else :; fi
  #echo "Configuring open*** $TUNINTERFACE for $i"
  iptables -I FORWARD -i $TUNINTERFACE -s $i -m conntrack --ctstate NEW -j ACCEPT

  iptables -I FORWARD -m conntrack --ctstate>  iptables -I FORWARD -i $TUNINTERFACE -o $DEFAULT_INTERFACE -s $i -d $DEFAULT_CONNECTED_SUBNET -m conntrack --ctstate NEW -j ACCEPT
  iptables -t nat -A POSTROUTING -s $i -j MASQUERADE
  else
  # variable empty
  echo 'No entry for $i, skipping open*** tun configuration...'
  fi
  done
  fi
  $IPTABLES -A FORWARD -j DROP
  ######################FORWARD_RULES_STOP#############################
  #######################NAT_RULES_START###############################
  if [ $INTERNAL_MASQUERADE_SWITCH -eq 1 ];then
  if [ "$INTERNAL_SUBNET" != "" ];then
  for net in $INTERNAL_SUBNET
  do
  $IPTABLES -t nat -A POSTROUTING -s $net ! -d $net -j MASQUERADE
  done
  fi
  if [ $INTERNAL_DNAT_SWITCH -eq 1 ];then
  if [ "$INT_IP_ONLINE" != "" ];then
  $IPTABLES -t nat -A PREROUTING -d $INT_IP_ONLINE -p tcp --dport 21 -j DNAT --to-destination ${FTP_SERVER}:21
  #$IPTABLES -t nat -A PREROUTING -d $INT_IP_ONLINE -p tcp --dport 80 -j DNAT --to-destination ${HTTP_SERVER}:80
  fi
  fi
  fi
  #######################NAT_RULES_STOP################################

页: [1]
查看完整版本: 经典好用anti-DDos的iptables shell脚本