github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/edgemesh/tools/initContainer/script/edgemesh-iptables.sh (about)

     1  #!/usr/bin/env bash
     2  
     3  function usage() {
     4  	echo 'this is the edgemesh-iptables usage'
     5  	echo "${0} -p PROXY_PORT [-i HIJACK_IP] [-t HIJACK_PORT] [-b EXCLUDE_IP] [-c EXCLUDE_PORT] [-h]"
     6  	echo ''
     7  	echo '  -p: Specify the edgemesh port to which all TCP traffic from the Pod will be redirectd to. (default 10001)'
     8  	echo '  -i: Comma separated list of outbound IP for which tarffic is to be redirectd to edgemesh. The'
     9  	echo '      wildcard character "*" can be used to configure redirection for all IPs. (default "*")'
    10  	echo '  -t: Comma separated list of outbound Port for which tarffic is to be redirectd to edgemesh. The'
    11  	echo '      wildcard character "*" can be used to configure redirection for all Ports. (default "*")'
    12  	echo '  -b: Comma separated list of outbound IP range in CIDR to be excluded from redirection to edgemesh.'
    13  	echo '      The Empty character "" can be used to configure redirection for all IPs. (default "")'
    14  	echo '  -c: Comma separated list of outbound Port to be excluded from redirection to edgemesh. The'
    15  	echo '      Empty character "" can be used to configure redirection for all Ports. (default "")'
    16  	echo '  -h: for some help'
    17  }
    18  
    19  # network namespace 
    20  NETMODE=
    21  
    22  # get the container network mode 
    23  function getContainerNetMode() {
    24  	if ip link |grep docker0 > /dev/null; then
    25  		echo 'this is the host mode,share with net namespace with host'
    26  		NETMODE='HOST'
    27  	else
    28  		echo 'this is the ohter container net mode(none,bridge),independent of the host net namespace'
    29  		NETMODE='OTHER'
    30  	fi
    31  }
    32  
    33  # judge if agrument is a valid ip address
    34  function isValidIP() {
    35  	if isIPv4 "${1}"; then
    36  		true
    37  	elif isIPv6 "${1}"; then
    38  		true
    39  	else
    40  		false
    41  	fi		
    42  }
    43  
    44  function isIPv4() {
    45  	local ipv4matchString="^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
    46  	if [[ ${1} =~ ${ipv4matchString} ]]; then
    47  		true
    48  	else
    49  		false
    50  	fi
    51  }
    52  
    53  function isIPv6() {
    54  	local ipv6matchString="^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$"
    55  	if [[ ${1} =~ ${ipv6matchString} ]]; then
    56  		true
    57  	else
    58  		false
    59  	fi
    60  }
    61  
    62  function hostNetMode() {
    63  	echo 'this func used for host net mode'
    64  	echo 'TODO'
    65  }
    66  
    67  function bridgeNetMode() {
    68  	echo 'this func used for bridge net mode'
    69  	# get default route
    70  	default_route=$(ip route show |grep default |awk '{print $3}')
    71  	
    72  	#clear EDGEMESH chain and rule,if exist
    73  	iptables -t nat -D OUTPUT -p tcp -j EDGEMESH_OUTBOUND 2>/dev/null
    74  	iptables -t nat -D OUTPUT -p udp --dport "53" -j EDGEMESH_OUTBOUND_DNS 2>/dev/null
    75  	iptables -t nat -F EDGEMESH_OUTBOUND 2>/dev/null
    76  	iptables -t nat -X EDGEMESH_OUTBOUND 2>/dev/null
    77  	
    78  	iptables -t nat -F EDGEMESH_OUTBOUND_REDIRECT 2>/dev/null
    79  	iptables -t nat -X EDGEMESH_OUTBOUND_REDIRECT 2>/dev/null
    80  	
    81  	iptables -t nat -F EDGEMESH_OUTBOUND_DNS 2>/dev/null
    82  	iptables -t nat -X EDGEMESH_OUTBOUND_DNS 2>/dev/null
    83  	
    84  	# make chain for edgemesh hijacking
    85  	iptables -t nat -N EDGEMESH_OUTBOUND_REDIRECT
    86  	iptables -t nat -A EDGEMESH_OUTBOUND_REDIRECT -p tcp -j DNAT --to-destination "${default_route}:${EDGEMESH_PROXY_PORT}"
    87  	iptables -t nat -N EDGEMESH_OUTBOUND
    88  	iptables -t nat -A OUTPUT -p tcp -j EDGEMESH_OUTBOUND
    89  	
    90  	# support dns use udp for dest port 53
    91  	iptables -t nat -N EDGEMESH_OUTBOUND_DNS
    92  	iptables -t nat -A EDGEMESH_OUTBOUND_DNS -j DNAT --to-destination "${default_route}"
    93  	iptables -t nat -A OUTPUT -p udp --dport "53" -j EDGEMESH_OUTBOUND_DNS
    94  	
    95  	# excluded traffic for some port incloude some special port,such as 22
    96  	iptables -t nat -A EDGEMESH_OUTBOUND -p tcp --dport "22" -j RETURN
    97  	if [ -n "${EDGEMESH_EXCLUDE_PORT}" ]; then 
    98  		for port in "${port_exclude_list[@]}"; do 
    99  			iptables -t nat -A EDGEMESH_OUTBOUND -p tcp --dport "${port}" -j RETURN
   100  		done
   101  	fi
   102  	# excluded traffic for some ips
   103  	if [ ${#ipv4_exclude_list[@]} -gt 0 ]; then
   104  		for ip in "${ipv4_exclude_list[@]}"; do
   105  			iptables -t nat -A EDGEMESH_OUTBOUND -d "${ip}" -j RETURN
   106  		done
   107  	fi
   108  	
   109  	# Redirect app callback to itself via Servie IP (default not redirectd)
   110  	get_local_IP=$(ip addr |grep inet|grep -v inet6|awk '{print $2}'|tr -d "addr:")
   111  	
   112  	for LOCAL_IP in $get_local_IP; do
   113  		ele=${LOCAL_IP%$splt}
   114  		echo "LOCAL_IP: $LOCAL_IP , $ele"
   115  		if isIPv4 $ele; then
   116  			iptables -t nat -A EDGEMESH_OUTBOUND -o lo ! -d "${LOCAL_IP}" -j EDGEMESH_OUTBOUND_REDIRECT
   117  		fi
   118  	done
   119  	# loopback traffic
   120  	iptables -t nat -A EDGEMESH_OUTBOUND -d 127.0.0.1/32 -j RETURN
   121  	
   122  	# hijacking
   123  	if [ ${#ipv4_include_list[@]} -gt 0 ]; then
   124  		# include Ips and ports are *
   125  		if [[ "${ipv4_include_list}" == "*" && "${EDGEMESH_HIJACK_PORT}" == "*" ]]; then
   126  			iptables -t nat -A EDGEMESH_OUTBOUND -p tcp -j EDGEMESH_OUTBOUND_REDIRECT
   127  		else
   128  			if [ "${ipv4_include_list}" != "*" ]; then
   129  				for ip in "${ipv4_include_list[@]}"; do
   130  					iptables -t nat -A EDGEMESH_OUTBOUND -p tcp -d "${ip}" -j EDGEMESH_OUTBOUND_REDIRECT
   131  				done
   132  			fi
   133  			if [ "${EDGEMESH_HIJACK_PORT}" != "*" ]; then
   134  				for port in "${port_include_list[@]}"; do 
   135  					iptables -t nat -A EDGEMESH_OUTBOUND -p tcp --dport "${port}" -j EDGEMESH_OUTBOUND_REDIRECT
   136  				done
   137  			fi
   138  			
   139  			iptables -t nat -A EDGEMESH_OUTBOUND -j RETURN
   140  		fi
   141  	fi
   142  }
   143  
   144  # variable
   145  ipv4_exclude_list=()
   146  ipv4_include_list=()
   147  ipv6_exclude_list=()
   148  ipv6_exclude_list=()
   149  port_exclude_list=()
   150  port_include_list=()
   151  
   152  splt='/*'
   153  EDGEMESH_PROXY_PORT=${PROXY_PORT-10001}  # default PROXY_PORT 10001
   154  EDGEMESH_HIJACK_IP=${HIJACK_IP-"*"}
   155  EDGEMESH_HIJACK_PORT=${HIJACK_PORT-"*"}
   156  EDGEMESH_EXCLUDE_IP=${EXCLUDE_IP-}
   157  EDGEMESH_EXCLUDE_PORT=${EXCLUDE_PORT-}
   158  
   159  function main() {
   160  	getContainerNetMode
   161  	
   162  	while getopts ":p:i:t:b:c:h" opt; do
   163  		case ${opt} in
   164  			p)
   165  				EDGEMESH_PROXY_PORT=${OPTARG}
   166  				;;
   167  			i)
   168  				EDGEMESH_HIJACK_IP=${OPTARG}
   169  				;;
   170  			t) 
   171  				EDGEMESH_HIJACK_PORT=${OPTARG}
   172  				;;
   173  			b)
   174  				EDGEMESH_EXCLUDE_IP=${OPTARG}
   175  				;;
   176  			c) 
   177  				EDGEMESH_EXCLUDE_PORT=${OPTARG}
   178  				;;
   179  			h)
   180  				usage
   181  				exit 0
   182  				;;
   183  			?)
   184  				echo "Invalid option: -$OPTARG" >&2
   185  				usage
   186  				exit 1
   187  				;;
   188  		esac
   189  	done
   190  	
   191  	echo "EdgeMesh iptables configration:"
   192  	echo "====================================="
   193  	echo "Container Network mode is: ${NETMODE}"
   194  	echo "Variables:"
   195  	echo "EDGEMESH_PROXY_PORT=${EDGEMESH_PROXY_PORT-10001}"
   196  	echo "EDGEMESH_HIJACK_IP=${EDGEMESH_HIJACK_IP-"*"}"
   197  	echo "EDGEMESH_HIJACK_PORT=${EDGEMESH_HIJACK_PORT-"*"}"
   198  	echo "EDGEMESH_EXCLUDE_IP=${EDGEMESH_EXCLUDE_IP-}"
   199  	echo "EDGEMESH_EXCLUDE_PORT=${EDGEMESH_EXCLUDE_PORT-}"
   200  	
   201  	# parse parameter
   202  	IFS=',' read -ra EXCLUDE_IP <<< "${EDGEMESH_EXCLUDE_IP}"
   203  	IFS=',' read -ra INCLUDE_IP <<< "${EDGEMESH_HIJACK_IP}"
   204  	# echo "EXCLUDE_IP: ${EXCLUDE_IP}"
   205  	for range in "${EXCLUDE_IP[@]}"; do
   206  		r=${range%$splt}
   207  		if isValidIP "$r"; then
   208  			if isIPv4 "$r"; then
   209  				ipv4_exclude_list+=("$range")
   210  			elif isIPv6 "$r"; then
   211  				ipv6_exclude_list+=("$range")
   212  			fi
   213  		fi
   214  	done
   215  	
   216  	if [ "${EDGEMESH_HIJACK_IP}" == "*" ]; then
   217  		ipv4_include_list=("*")
   218  		ipv6_include_list=("*")
   219  	else
   220  		for range in "${INCLUDE_IP[@]}"; do
   221  			r=${range%$splt}
   222  			if isValidIP "$r";then
   223  				if isIPv4 "$r"; then
   224  					ipv4_include_list+=("$range")
   225  				elif isIPv6 "$r"; then
   226  					ipv6_include_list+=("$range")
   227  				fi
   228  			fi		
   229  		done
   230  	fi
   231  	
   232  	IFS=',' read -ra INCLUDE_PORT <<< "${EDGEMESH_HIJACK_PORT}"
   233  	IFS=',' read -ra EXCLUDE_PORT <<< "${EDGEMESH_EXCLUDE_PORT}"
   234  	if [ "${EDGEMESH_HIJACK_PORT}" != "*" ]; then
   235  		for port in "${INCLUDE_PORT[@]}"; do
   236  			port_include_list+=("$port")
   237  		done
   238  	fi
   239  	
   240  	if [ -n "${EDGEMESH_EXCLUDE_PORT}" ]; then 
   241  		for port in "${EXCLUDE_PORT[@]}"; do 
   242  			port_exclude_list+=("$port")
   243  		done
   244  	fi
   245  	
   246  	echo "ipv4_include_list : ${ipv4_include_list[@]}"
   247  	echo "ipv4_exclude_list : ${ipv4_exclude_list[@]}"
   248  	echo "port_include_list : ${port_include_list[@]}"
   249  	echo "port_exclude_list : ${port_exclude_list[@]}"
   250  	
   251  	# bridge mode(port map) container network
   252  	if [ "${NETMODE}" = "OTHER" ]; then	
   253  		echo " ${NETMODE} iptables configration"
   254  		bridgeNetMode
   255  		# if set ipv6 option
   256  		if false; then
   257  			echo 'TODO'
   258  		fi
   259  	# host mode container network
   260  	elif [ "${NETMODE}" = "HOST" ]; then
   261  		#hostNetMode
   262  		echo ${NETMODE}
   263  		# if set ipv6 option
   264  		if false; then
   265  			echo 'TODO'
   266  		fi
   267  	else
   268  		echo 'Dont support this container network '
   269  	fi
   270  }
   271  
   272  # start to configure
   273  main "${@}"