Blame SOURCES/bz1303037-1-portblock.patch

937446
diff -uNr a/heartbeat/portblock b/heartbeat/portblock
937446
--- a/heartbeat/portblock	2013-06-18 15:22:27.000000000 +0200
937446
+++ b/heartbeat/portblock	2016-02-29 13:51:22.205860012 +0100
937446
@@ -24,8 +24,10 @@
937446
 
937446
 # Defaults
937446
 OCF_RESKEY_ip_default="0.0.0.0/0"
937446
+OCF_RESKEY_reset_local_on_unblock_stop_default="false"
937446
 
937446
 : ${OCF_RESKEY_ip=${OCF_RESKEY_ip_default}}
937446
+: ${OCF_RESKEY_reset_local_on_unblock_stop=${OCF_RESKEY_reset_local_on_unblock_stop_default}}
937446
 #######################################################################
937446
 CMD=`basename $0`
937446
 TICKLETCP=$HA_BIN/tickle_tcp
937446
@@ -37,16 +39,22 @@
937446
 
937446
 	$CMD is used to temporarily block ports using iptables.
937446
 
937446
-	It can be used to turn off a port before bringing
937446
+	It can be used to blackhole a port before bringing
937446
 	up an IP address, and enable it after a service is started.
937446
-	To do that for samba, the following resource line can be used:
937446
+	To do that for samba, the following can be used:
937446
 
937446
-	$CMD::tcp::137,138::block		\\
937446
-	    10.10.10.20				\\
937446
-	    nmbd smbd 				\\
937446
-	    $CMD::tcp::137,138::unblock
937446
+	crm configure <
937446
+	primitive portblock-samba ocf:heartbeat:portblock \\
937446
+	  params protocol=tcp portno=137,138 action=block
937446
+	primitive portunblock-samba ocf:heartbeat:portblock \\
937446
+	  params protocol=tcp portno=137,138 action=unblock
937446
+	primitive samba-vip ocf:heartbeat:IPaddr2 \\
937446
+	  params ip=10.10.10.20
937446
+	group g-samba \\
937446
+	  portblock-samba samba-vip nmbd smbd portunblock-samba
937446
+	EOF
937446
 
937446
-	This will do the follwing things:
937446
+	This will do the following things:
937446
 
937446
 	  - DROP all incoming packets for TCP ports 137 and 138
937446
 	  - Bring up the IP alias 10.10.10.20
937446
@@ -54,13 +62,16 @@
937446
 	  - Re-enable TCP ports 137 and 138
937446
 	        (enable normal firewall rules on those ports)
937446
 
937446
-	This prevents clients from getting ICMP port unreachable
937446
-	if they try to reconnect to the service after the alias is
937446
-	enabled but before nmbd and smbd are running.  These packets
937446
-	will cause some clients to give up attempting to reconnect to
937446
-	the server.
937446
+	This prevents clients from getting TCP RST if they try to reconnect
937446
+	to the service after the alias is enabled but before nmbd and smbd
937446
+	are running.  These packets will cause some clients to give up
937446
+	attempting to reconnect to the server.
937446
+
937446
+	Attempts to connect to UDP and other non-TCP ports which have nothing
937446
+	listening can result in ICMP port unreachable responses, which can
937446
+	have the same undesirable affect on some clients.
937446
 
937446
-	NOTE:  iptables is linux-specific...
937446
+	NOTE: iptables is Linux-specific.
937446
 
937446
 	An additional feature in the portblock RA is the tickle ACK function
937446
 	enabled by specifying the tickle_dir parameter. The tickle ACK 
937446
@@ -138,7 +149,7 @@
937446
 The port number used to be blocked/unblocked.
937446
 </longdesc>
937446
 <shortdesc lang="en">portno</shortdesc>
937446
-<content type="integer" default="" />
937446
+<content type="string" default="" />
937446
 </parameter>
937446
 
937446
 <parameter name="action" unique="0" required="1">
937446
@@ -149,6 +160,26 @@
937446
 <content type="string" default="" />
937446
 </parameter>
937446
 
937446
+<parameter name="reset_local_on_unblock_stop" unique="0" required="0">
937446
+<content type="boolean" default="${OCF_RESKEY_reset_local_on_unblock_stop_default}" />
937446
+<shortdesc lang="en">(try to) reset server TCP sessions when unblock stops</shortdesc>
937446
+<longdesc>
937446
+If for some reason the long lived server side TCP sessions won't be cleaned up
937446
+by a reconfiguration/flush/stop of whatever services this portblock protects,
937446
+they would linger in the connection table, even after the IP is gone
937446
+and services have been switched over to an other node.
937446
+
937446
+An example would be the default NFS kernel server.
937446
+
937446
+These "known" connections may seriously confuse and delay a later switchback.
937446
+
937446
+Enabling this option will cause this agent to try to get rid of these connections
937446
+by injecting a temporary iptables rule to TCP-reset outgoing packets from the
937446
+blocked ports, and additionally tickle them locally,
937446
+just before it starts to DROP incoming packets on "unblock stop".
937446
+</longdesc>
937446
+</parameter>
937446
+
937446
 <parameter name="ip" unique="0" required="0">
937446
 <longdesc lang="en">
937446
 The IP address used to be blocked/unblocked.
937446
@@ -233,12 +264,34 @@
937446
 	fi
937446
 }
937446
 
937446
-run_tickle_tcp()
937446
+tickle_remote()
937446
 {
937446
 	[ -z "$OCF_RESKEY_tickle_dir" ] && return
937446
 	echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
937446
 	f=$OCF_RESKEY_tickle_dir/$OCF_RESKEY_ip
937446
-	[ -f $f ] && cat $f | $TICKLETCP -n 3
937446
+	[ -r $f ] || return
937446
+	$TICKLETCP -n 3 < $f
937446
+}
937446
+
937446
+tickle_local()
937446
+{
937446
+	[ -z "$OCF_RESKEY_tickle_dir" ] && return
937446
+	f=$OCF_RESKEY_tickle_dir/$OCF_RESKEY_ip
937446
+	[ -r $f ] || return
937446
+	# swap "local" and "remote" address,
937446
+	# so we tickle ourselves.
937446
+	# We set up a REJECT with tcp-reset before we do so, so we get rid of
937446
+	# the no longer wanted potentially long lived "ESTABLISHED" connection
937446
+	# entries on the IP we are going to delet in a sec.  These would get in
937446
+	# the way if we switch-over and then switch-back in quick succession.
937446
+	local i
937446
+	awk '{ print $2, $1; }' $f | $TICKLETCP
937446
+	netstat -tn | grep -Fw $OCF_RESKEY_ip || return
937446
+	for i in 0.1 0.5 1 2 4 ; do
937446
+		sleep $i
937446
+		awk '{ print $2, $1; }' $f | $TICKLETCP
937446
+		netstat -tn | grep -Fw $OCF_RESKEY_ip || break
937446
+	done
937446
 }
937446
 
937446
 SayActive()
937446
@@ -304,15 +357,30 @@
937446
 #IptablesBLOCK  {udp|tcp} portno,portno ip
937446
 IptablesBLOCK()
937446
 {
937446
+  local rc=0
937446
+  local try_reset=false
937446
+  if	[ "$1/$4/$__OCF_ACTION" = tcp/unblock/stop ] &&
937446
+	ocf_is_true $reset_local_on_unblock_stop
937446
+  then
937446
+	try_reset=true
937446
+  fi
937446
   if
937446
     chain_isactive "$1" "$2" "$3"
937446
   then
937446
     : OK -- chain already active
937446
   else
937446
+    if $try_reset ; then
937446
+      $IPTABLES -I OUTPUT -p "$1" -s "$3" -m multiport --sports "$2" -j REJECT --reject-with tcp-reset
937446
+      tickle_local
937446
+    fi
937446
     $IPTABLES -I INPUT -p "$1" -d "$3" -m multiport --dports "$2" -j DROP
937446
+    rc=$?
937446
+    if $try_reset ; then
937446
+      $IPTABLES -D OUTPUT -p "$1" -s "$3" -m multiport --sports "$2" -j REJECT --reject-with tcp-reset
937446
+    fi
937446
   fi
937446
 
937446
-  return $?
937446
+  return $rc
937446
 }
937446
 
937446
 #IptablesUNBLOCK  {udp|tcp} portno,portno ip
937446
@@ -338,7 +406,7 @@
937446
     unblock)
937446
 		IptablesUNBLOCK "$@"
937446
 		rc=$?
937446
-		run_tickle_tcp
937446
+		tickle_remote
937446
 		#ignore run_tickle_tcp exit code!
937446
 		return $rc
937446
 		;;
937446
@@ -411,6 +479,17 @@
937446
 	exit $OCF_ERR_CONFIGURED
937446
 	;; 
937446
   esac
937446
+
937446
+  if ocf_is_true $reset_local_on_unblock_stop; then
937446
+	if [ $action != unblock ] ; then
937446
+		ocf_log err "reset_local_on_unblock_stop is only relevant with action=unblock"
937446
+		exit $OCF_ERR_CONFIGURED
937446
+	fi
937446
+	if [ -z $OCF_RESKEY_tickle_dir ] ; then
937446
+		ocf_log warn "reset_local_on_unblock_stop works best with tickle_dir enabled as well"
937446
+	fi
937446
+  fi
937446
+
937446
   return $OCF_SUCCESS
937446
 }
937446
 
937446
@@ -451,6 +530,7 @@
937446
 portno=$OCF_RESKEY_portno
937446
 action=$OCF_RESKEY_action
937446
 ip=$OCF_RESKEY_ip
937446
+reset_local_on_unblock_stop=$OCF_RESKEY_reset_local_on_unblock_stop
937446
 
937446
 case $1 in
937446
   start)