summaryrefslogtreecommitdiff
path: root/edgemesh
diff options
context:
space:
mode:
authorArcanique <strugaml@163.com>2019-06-21 23:54:05 +0800
committerArcanique <strugaml@163.com>2019-06-22 02:42:21 +0800
commit9979fd5bd87d4a35acd1a64b368d894b1d24c5ce (patch)
tree4f9e639e3243990b8d0b061e2b9e25aeaab12095 /edgemesh
parentAdd new feature of servicemesh (#738) (diff)
downloadkubeedge-9979fd5bd87d4a35acd1a64b368d894b1d24c5ce.tar.gz
Add hijacking script tools and initContainer image Dockerfile. Add new feature : dns cheat
Diffstat (limited to 'edgemesh')
-rw-r--r--edgemesh/pkg/server/dns.go399
-rw-r--r--edgemesh/pkg/server/server.go5
-rw-r--r--edgemesh/tools/initContainer/createImg.sh33
-rw-r--r--edgemesh/tools/initContainer/deb/Dockerfile6
-rw-r--r--edgemesh/tools/initContainer/rpm/Dockerfile7
-rw-r--r--edgemesh/tools/initContainer/script/edgemesh-iptables.sh269
6 files changed, 718 insertions, 1 deletions
diff --git a/edgemesh/pkg/server/dns.go b/edgemesh/pkg/server/dns.go
new file mode 100644
index 000000000..4253975eb
--- /dev/null
+++ b/edgemesh/pkg/server/dns.go
@@ -0,0 +1,399 @@
+package server
+
+import (
+ "bufio"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "strings"
+ "unsafe"
+
+ "github.com/golang/glog"
+)
+
+var (
+ inter = "docker0"
+ dnsQr = uint16(0x8000)
+ oneByteSize = uint16(1)
+ twoByteSize = uint16(2)
+ ttl = uint32(64)
+ fakeIp = []byte{5,5,5,5}
+)
+
+const (
+ aRecord = 1
+ bufSize = 1024
+ notImplem = uint16(0x0004)
+)
+
+type dnsHeader struct {
+ transactionID uint16
+ flags uint16
+ queNum uint16
+ ansNum uint16
+ authNum uint16
+ additNum uint16
+}
+
+type dnsQuestion struct{
+ head *dnsHeader
+ name []byte
+ queByte []byte
+ qType uint16
+ qClasss uint16
+ queNum uint16
+}
+
+type dnsAnswer struct{
+ name []byte
+ qType uint16
+ qClass uint16
+ ttl uint32
+ dataLen uint16
+ addr []byte
+}
+
+//define the dns Question list type
+type dnsQs []dnsQuestion
+
+//DnsStart is a External interface
+func DnsStart(){
+ startDnsServer()
+}
+
+// getDnsServer returns the specific interface ip of version 4
+func getDnsServer() (net.IP, error){
+ ifaces , err := net.InterfaceByName(inter)
+ if err != nil {
+ return nil ,err
+ }
+
+ addrs, _ := ifaces.Addrs()
+
+ for _, addr := range addrs {
+ if ip, inet, _ := net.ParseCIDR(addr.String()); len(inet.Mask) == 4 {
+ return ip, nil
+ }
+ }
+
+ return nil, errors.New("the interface" + inter + "have not config ip of version 4")
+}
+
+// startDnsServer start the DNS Server
+func startDnsServer(){
+ lip, err := getDnsServer()
+ if err != nil {
+ glog.Errorf("Dns server Start error : %s",err)
+ }
+
+ laddr := &net.UDPAddr{
+ IP: lip,
+ Port: 53,
+ }
+ dnsConn ,err := net.ListenUDP("udp",laddr)
+ defer dnsConn.Close()
+ if err != nil {
+ glog.Errorf("Dns server Start error : %s",err)
+ }
+
+ for {
+ req := make([]byte,bufSize)
+ n, from, err := dnsConn.ReadFromUDP(req)
+ if err != nil || n <= 0 {
+ glog.Infof("Dns Server get an read mistake : %s", err)
+ continue
+ }
+
+ que,err := parseDnsQuery(req[:n])
+ if err != nil {
+ continue
+ }
+
+ rsp := make([]byte,0)
+ rsp , _ = recordHandler(que, req[0:n])
+
+ dnsConn.WriteTo(rsp,from)
+ }
+}
+
+//recordHandler returns the Answer for the dns question
+func recordHandler(que []dnsQuestion, req []byte) (rsp []byte, err error){
+ var exist bool
+ for _ , q := range que {
+ domainName := string(q.name)
+ exist, err = lookupFromMetaManager(domainName)
+ if err != nil {
+ rsp = nil
+ return
+ }
+ if !exist {
+ break
+ }
+ }
+
+ if !exist {
+ //if this service don't belongs to this cluster
+ rsp = getfromRealDNS(req)
+ err = nil
+ return
+ }
+ //gen
+ pre,err := modifyRspPrefix(que)
+ rsp = append(rsp, pre...)
+ for _ , q := range que{
+ //create a deceptive rep
+ dnsAns := &dnsAnswer{
+ name: q.name,
+ qType: q.qType,
+ qClass: q.qClasss,
+ ttl: ttl,
+ dataLen: uint16(len(fakeIp)),
+ addr: fakeIp,
+ }
+ ans := dnsAns.getAnswer()
+ rsp = append(rsp,ans...)
+ }
+
+ return rsp,nil
+}
+
+//parseDnsQuery returns question of the dns request
+func parseDnsQuery(req [] byte) ( que []dnsQuestion, err error) {
+ head := &dnsHeader{}
+ head.getHeader(req)
+ if !head.isAQurey() {
+ return nil, errors.New("Igenore")
+ }
+
+ question := make(dnsQs, head.queNum)
+
+ offset := uint16(unsafe.Sizeof(dnsHeader{}))
+ question.getQuestion(req, offset, head)
+
+ que = question
+ err = nil
+ return
+}
+
+//isAQuery judge if the dns pkg is a Qurey process
+func (h *dnsHeader)isAQurey()bool {
+ if h.flags & dnsQr != dnsQr {
+ return true
+ }
+ return false
+}
+
+//getHeader get dns pkg head
+func (h *dnsHeader)getHeader(req []byte) {
+ h.transactionID = binary.BigEndian.Uint16(req[0:2])
+ h.flags = binary.BigEndian.Uint16(req[2:4])
+ h.queNum = binary.BigEndian.Uint16(req[4:6])
+ h.ansNum = binary.BigEndian.Uint16(req[6:8])
+ h.authNum = binary.BigEndian.Uint16(req[8:10])
+ h.additNum = binary.BigEndian.Uint16(req[10:12])
+}
+
+//getQuestion get dns questions
+func (q dnsQs)getQuestion(req []byte, offset uint16, head *dnsHeader) {
+ ost := offset
+ qNum := uint16(len(q))
+
+ for i:=uint16(0); i< qNum ; i++ {
+ tmp := ost
+ ost = q[i].getQName(req,ost)
+ q[i].qType = binary.BigEndian.Uint16(req[ost: ost + twoByteSize])
+ ost += twoByteSize
+ q[i].qClasss = binary.BigEndian.Uint16(req[ost: ost + twoByteSize])
+ ost += twoByteSize
+ q[i].head = head
+ q[i].queByte = req[tmp: ost]
+ }
+}
+
+//getAnswer Generate Answer for the dns question
+func (d *dnsAnswer)getAnswer() (ans []byte) {
+ ans = make([]byte,0)
+
+ if d.qType == aRecord {
+ ans = append(ans,0xc0)
+ ans = append(ans,0x0c)
+
+ tmp16 := make([]byte,2)
+ tmp32 := make([]byte,4)
+
+ binary.BigEndian.PutUint16(tmp16,d.qType)
+ ans = append(ans,tmp16...)
+ binary.BigEndian.PutUint16(tmp16, d.qClass)
+ ans = append(ans,tmp16...)
+ binary.BigEndian.PutUint32(tmp32, d.ttl)
+ ans = append(ans,tmp32...)
+ binary.BigEndian.PutUint16(tmp16, d.dataLen)
+ ans = append(ans,tmp16...)
+ ans = append(ans,d.addr...)
+ }
+
+ return ans
+}
+
+// getQName get dns question domain name
+func (q *dnsQuestion)getQName(req []byte, offset uint16) (uint16) {
+ ost := offset
+
+ for {
+ qbyte := uint16(req[ost])
+
+ if qbyte == 0x00 {
+ q.name = q.name[: uint16(len(q.name))- oneByteSize]
+ return ost + oneByteSize
+ }
+ ost += oneByteSize
+ q.name = append(q.name, req[ost: ost+qbyte]...)
+ q.name = append(q.name,0x2e)
+ ost += qbyte
+ }
+}
+
+// lookupFromMetaManager implement confirm the service exists
+// for earlier version returns true by default
+func lookupFromMetaManager(name string) (exist bool ,err error){
+ return true, nil
+}
+
+// getfromRealDNS returns the dns response from the real DNS server
+func getfromRealDNS(req []byte) []byte {
+ ips := parseNameServer()
+
+ rsp := make([]byte,0)
+ laddr := &net.UDPAddr{
+ IP: net.IPv4zero,
+ Port: 0,
+ }
+ for _, ip := range ips { // get from real
+ raddr := &net.UDPAddr{
+ IP: ip,
+ Port: 53,
+ }
+ conn, err := net.DialUDP("udp",laddr,raddr)
+ defer conn.Close()
+ if err != nil {
+ continue
+ }
+
+ _, err = conn.Write(req)
+ if err != nil {
+ continue
+ }
+
+ var n int
+ buf := make([]byte,bufSize)
+ n, err = conn.Read(buf)
+ if err != nil {
+ continue
+ }
+
+ if n >0 {
+ rsp = append(rsp,buf[: n]...)
+ }
+ }
+ return rsp
+}
+
+// parseNameServer gets the nameserver from the resolv.conf
+func parseNameServer()([]net.IP){
+ file, err := os.Open("/etc/resolv.conf")
+ if err != nil {
+ glog.Errorf("error opening /etc/resolv.conf : %s", err)
+ }
+ defer file.Close()
+
+ scan := bufio.NewScanner(file)
+ scan.Split(bufio.ScanLines)
+
+ ip := make([]net.IP,0)
+
+ for scan.Scan() { //get name server
+ serverString := scan.Text()
+ fmt.Println(serverString)
+ if strings.Contains(serverString,"nameserver") {
+ tmpString := strings.Replace(serverString, "nameserver", "",1)
+ nameserver := strings.TrimSpace(tmpString)
+ sip := net.ParseIP(nameserver)
+ if sip != nil {
+ ip = append(ip, sip)
+ }
+ }
+ }
+ return ip
+}
+
+// modifyRspPrefix use req' head generate a rsp head
+func modifyRspPrefix(que []dnsQuestion) (pre []byte, err error) {
+ ansNum := len(que)
+ if ansNum == 0{
+ return
+ }
+ //use head in que. All the same
+ rspHead := que[0].head
+ rspHead.converQueryRsp(true)
+ if que[0].qType == aRecord {
+ rspHead.setAnswerNum(uint16(ansNum))
+ }else{
+ rspHead.setAnswerNum(0)
+ }
+
+ rspHead.setRspRcode(que)
+ pre = rspHead.getByteFromDnsHeader()
+
+ for _ , q := range que {
+ pre = append(pre, q.queByte...)
+ }
+
+ err = nil
+ return
+}
+
+// converQueryRsp conversion the dns head to a response for one query
+func (h *dnsHeader)converQueryRsp(isRsp bool){
+ if isRsp {
+ h.flags |= dnsQr
+ }else {
+ h.flags |= dnsQr
+ }
+}
+
+// set the Answer num for dns head
+func (h *dnsHeader)setAnswerNum(num uint16){
+ h.ansNum = num
+}
+
+// set the dns response return code
+func (h *dnsHeader)setRspRcode(que dnsQs){
+ for _ , q := range que {
+ if q.qType != aRecord {
+ h.flags &= (^notImplem)
+ h.flags |= notImplem
+ }
+ }
+}
+
+//getByteFromDnsHeader implement from dnsHeader struct to []byte
+func (h *dnsHeader)getByteFromDnsHeader() (rspHead []byte){
+ rspHead = make([]byte, unsafe.Sizeof(*h))
+
+ idxTran := unsafe.Sizeof(h.transactionID)
+ idxflag := unsafe.Sizeof(h.flags) + idxTran
+ idxque := unsafe.Sizeof(h.ansNum) + idxflag
+ idxans := unsafe.Sizeof(h.ansNum) + idxque
+ idxaut := unsafe.Sizeof(h.authNum) + idxans
+ idxadd := unsafe.Sizeof(h.additNum) + idxaut
+
+ binary.BigEndian.PutUint16(rspHead[: idxTran], h.transactionID)
+ binary.BigEndian.PutUint16(rspHead[idxTran: idxflag], h.flags)
+ binary.BigEndian.PutUint16(rspHead[idxflag: idxque], h.queNum)
+ binary.BigEndian.PutUint16(rspHead[idxque: idxans], h.ansNum)
+ binary.BigEndian.PutUint16(rspHead[idxans: idxaut], h.authNum)
+ binary.BigEndian.PutUint16(rspHead[idxaut: idxadd], h.additNum)
+ return
+}
diff --git a/edgemesh/pkg/server/server.go b/edgemesh/pkg/server/server.go
index a818d612c..6f4bc1316 100644
--- a/edgemesh/pkg/server/server.go
+++ b/edgemesh/pkg/server/server.go
@@ -3,6 +3,7 @@ package server
import (
"github.com/go-chassis/go-chassis/control"
"github.com/go-chassis/go-chassis/core/config"
+ "github.com/go-chassis/go-chassis/core/config/model"
"github.com/go-chassis/go-chassis/core/loadbalancer"
"github.com/go-chassis/go-chassis/core/registry"
_ "github.com/kubeedge/kubeedge/edgemesh/pkg/panel"
@@ -17,7 +18,7 @@ func Start() {
//Initialize the handlers
//
//
- config.Init()
+ config.GlobalDefinition = &model.GlobalCfg{}
config.GlobalDefinition.Panel.Infra = "fake"
opts := control.Options{
Infra: config.GlobalDefinition.Panel.Infra,
@@ -31,6 +32,8 @@ func Start() {
loadbalancer.InstallStrategy(loadbalancer.StrategyRandom, func() loadbalancer.Strategy {
return &loadbalancer.RandomStrategy{}
})
+ //Start dns server
+ go DnsStart()
//Start server
StartTCP()
}
diff --git a/edgemesh/tools/initContainer/createImg.sh b/edgemesh/tools/initContainer/createImg.sh
new file mode 100644
index 000000000..eb1676cff
--- /dev/null
+++ b/edgemesh/tools/initContainer/createImg.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+echo 'create edgemesh init Container image'
+
+function usage() {
+ echo "execute 'sh createImg.sh [rpm | deb]' to create docker image"
+ echo "execute 'sh createImg.sh help for use help'"
+}
+
+path="${1}"
+
+if [ "${path}" != "rpm" ] && [ "${path}" != "deb" ]; then
+ usage
+ exit 0
+fi
+
+echo "create a ${path} docker image"
+
+cp ./script/edgemesh-iptables.sh ./"${path}"/
+
+cd ./"${path}"/
+
+chmod 0777 edgemesh-iptables.sh
+
+if command -v docker > /dev/null 2>&1 ; then
+ #docker build
+ docker build -t edgemesh_init .
+ # delete iptables script
+ rm ./edgemesh-iptables.sh
+else
+ echo 'the docker command is no found!!'
+ exit 1
+fi
diff --git a/edgemesh/tools/initContainer/deb/Dockerfile b/edgemesh/tools/initContainer/deb/Dockerfile
new file mode 100644
index 000000000..4413853a7
--- /dev/null
+++ b/edgemesh/tools/initContainer/deb/Dockerfile
@@ -0,0 +1,6 @@
+FROM ubuntu
+
+ADD edgemesh-iptables.sh /usr/local/bin
+RUN apt-get update && apt-get install -y iproute2 iptables
+
+ENTRYPOINT ["usr/local/bin/edgemesh-iptables.sh"]
diff --git a/edgemesh/tools/initContainer/rpm/Dockerfile b/edgemesh/tools/initContainer/rpm/Dockerfile
new file mode 100644
index 000000000..2fbf21657
--- /dev/null
+++ b/edgemesh/tools/initContainer/rpm/Dockerfile
@@ -0,0 +1,7 @@
+FROM centos:latest
+
+ADD edgemesh-iptables.sh /usr/local/bin
+
+RUN yum -y update && yum install -y iproute iptables
+
+ENTRYPOINT ["/usr/local/bin/edgemesh-iptables.sh"]
diff --git a/edgemesh/tools/initContainer/script/edgemesh-iptables.sh b/edgemesh/tools/initContainer/script/edgemesh-iptables.sh
new file mode 100644
index 000000000..4bd9d51be
--- /dev/null
+++ b/edgemesh/tools/initContainer/script/edgemesh-iptables.sh
@@ -0,0 +1,269 @@
+#!/usr/bin/bash
+
+function usage() {
+ echo 'this is the edgemesh-iptables usage'
+ echo "${0} -p PROXY_PORT [-i HIJACK_IP] [-t HIJACK_PORT] [-b EXCLUDE_IP] [-c EXCLUDE_PORT] [-h]"
+ echo ''
+ echo ' -p: Specify the edgemesh port to which all TCP traffic from the Pod will be redirectd to. (default 10001)'
+ echo ' -i: Comma separated list of outbound IP for which tarffic is to be redirectd to edgemesh. The'
+ echo ' wildcard character "*" can be used to configure redirection for all IPs. (default "*")'
+ echo ' -t: Comma separated list of outbound Port for which tarffic is to be redirectd to edgemesh. The'
+ echo ' wildcard character "*" can be used to configure redirection for all Ports. (default "*")'
+ echo ' -b: Comma separated list of outbound IP range in CIDR to be excluded from redirection to edgemesh.'
+ echo ' The Empty character "" can be used to configure redirection for all IPs. (default "")'
+ echo ' -c: Comma separated list of outbound Port to be excluded from redirection to edgemesh. The'
+ echo ' Empty character "" can be used to configure redirection for all Ports. (default "")'
+ echo ' -h: for some help'
+}
+
+# network namespace
+NETMODE=
+
+# get the container network mode
+function getContainerNetMode() {
+ if ip link |grep docker0 > /dev/null; then
+ echo 'this is the host mode,share with net namespace with host'
+ NETMODE='HOST'
+ else
+ echo 'this is the ohter container net mode(none,bridge),independent of the host net namespace'
+ NETMODE='OTHER'
+ fi
+}
+
+# judge if agrument is a valid ip address
+function isValidIP() {
+ if isIPv4 "${1}"; then
+ true
+ elif isIPv6 "${1}"; then
+ true
+ else
+ false
+ fi
+}
+
+function isIPv4() {
+ local ipv4matchString="^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
+ if [[ ${1} =~ ${ipv4matchString} ]]; then
+ true
+ else
+ false
+ fi
+}
+
+function isIPv6() {
+ # TODO
+ false
+}
+
+function hostNetMode() {
+ echo 'this func used for host net mode'
+ echo 'TODO'
+}
+
+function bridgeNetMode() {
+ echo 'this func used for bridge net mode'
+ # get default route
+ default_route=$(ip route show |grep default |awk '{print $3}')
+
+ #clear EDGEMESH chain and rule,if exist
+ iptables -t nat -D OUTPUT -p tcp -j EDGEMESH_OUTBOUND 2>/dev/null
+ iptables -t nat -D OUTPUT -p udp --dport "53" -j EDGEMESH_OUTBOUND_DNS 2>/dev/null
+ iptables -t nat -F EDGEMESH_OUTBOUND 2>/dev/null
+ iptables -t nat -X EDGEMESH_OUTBOUND 2>/dev/null
+
+ iptables -t nat -F EDGEMESH_OUTBOUND_REDIRECT 2>/dev/null
+ iptables -t nat -X EDGEMESH_OUTBOUND_REDIRECT 2>/dev/null
+
+ iptables -t nat -F EDGEMESH_OUTBOUND_DNS 2>/dev/null
+ iptables -t nat -X EDGEMESH_OUTBOUND_DNS 2>/dev/null
+
+ # make chain for edgemesh hijacking
+ iptables -t nat -N EDGEMESH_OUTBOUND_REDIRECT
+ iptables -t nat -A EDGEMESH_OUTBOUND_REDIRECT -p tcp -j DNAT --to-destination "${default_route}:${EDGEMESH_PROXY_PORT}"
+ iptables -t nat -N EDGEMESH_OUTBOUND
+ iptables -t nat -A OUTPUT -p tcp -j EDGEMESH_OUTBOUND
+
+ # support dns use udp for dest port 53
+ iptables -t nat -N EDGEMESH_OUTBOUND_DNS
+ iptables -t nat -A EDGEMESH_OUTBOUND_DNS -j DNAT --to-destination "${default_route}"
+ iptables -t nat -A OUTPUT -p udp --dport "53" -j EDGEMESH_OUTBOUND_DNS
+
+ # excluded traffic for some port incloude some special port,such as 22
+ iptables -t nat -A EDGEMESH_OUTBOUND -p tcp --dport "22" -j RETURN
+ if [ -n "${EDGEMESH_EXCLUDE_PORT}" ]; then
+ for port in "${port_exclude_list[@]}"; do
+ iptables -t nat -A EDGEMESH_OUTBOUND -p tcp --dport "${port}" -j RETURN
+ done
+ fi
+ # excluded traffic for some ips
+ if [ ${#ipv4_exclude_list[@]} -gt 0 ]; then
+ for ip in "${ipv4_exclude_list[@]}"; do
+ iptables -t nat -A EDGEMESH_OUTBOUND -d "${ip}" -j RETURN
+ done
+ fi
+
+ # Redirect app callback to itself via Servie IP (default not redirectd)
+ get_local_IP=$(ip addr |grep inet|grep -v inet6|awk '{print $2}'|tr -d "addr:")
+
+ for LOCAL_IP in $get_local_IP; do
+ ele=${LOCAL_IP%$splt}
+ echo "LOCAL_IP: $LOCAL_IP , $ele"
+ if isIPv4 $ele; then
+ iptables -t nat -A EDGEMESH_OUTBOUND -o lo ! -d "${LOCAL_IP}" -j EDGEMESH_OUTBOUND_REDIRECT
+ fi
+ done
+ # loopback traffic
+ iptables -t nat -A EDGEMESH_OUTBOUND -d 127.0.0.1/32 -j RETURN
+
+ # hijacking
+ if [ ${#ipv4_include_list[@]} -gt 0 ]; then
+ # include Ips and ports are *
+ if [[ "${ipv4_include_list}" == "*" && "${EDGEMESH_HIJACK_PORT}" == "*" ]]; then
+ iptables -t nat -A EDGEMESH_OUTBOUND -p tcp -j EDGEMESH_OUTBOUND_REDIRECT
+ else
+ if [ "${ipv4_include_list}" != "*" ]; then
+ for ip in "${ipv4_include_list[@]}"; do
+ iptables -t nat -A EDGEMESH_OUTBOUND -p tcp -d "${ip}" -j EDGEMESH_OUTBOUND_REDIRECT
+ done
+ fi
+ if [ "${EDGEMESH_HIJACK_PORT}" != "*" ]; then
+ for port in "${port_include_list[@]}"; do
+ iptables -t nat -A EDGEMESH_OUTBOUND -p tcp --dport "${port}" -j EDGEMESH_OUTBOUND_REDIRECT
+ done
+ fi
+
+ iptables -t nat -A EDGEMESH_OUTBOUND -j RETURN
+ fi
+ fi
+}
+
+# variable
+ipv4_exclude_list=()
+ipv4_include_list=()
+ipv6_exclude_list=()
+ipv6_exclude_list=()
+port_exclude_list=()
+port_include_list=()
+
+splt='/*'
+EDGEMESH_PROXY_PORT=${PROXY_PORT-10001} # default PROXY_PORT 10001
+EDGEMESH_HIJACK_IP=${HIJACK_IP-"*"}
+EDGEMESH_HIJACK_PORT=${HIJACK_PORT-"*"}
+EDGEMESH_EXCLUDE_IP=${EXCLUDE_IP-}
+EDGEMESH_EXCLUDE_PORT=${EXCLUDE_PORT-}
+
+function main() {
+ getContainerNetMode
+
+ while getopts ":p:i:t:b:c:h" opt; do
+ case ${opt} in
+ p)
+ EDGEMESH_PROXY_PORT=${OPTARG}
+ ;;
+ i)
+ EDGEMESH_HIJACK_IP=${OPTARG}
+ ;;
+ t)
+ EDGEMESH_HIJACK_PORT=${OPTARG}
+ ;;
+ b)
+ EDGEMESH_EXCLUDE_IP=${OPTARG}
+ ;;
+ c)
+ EDGEMESH_EXCLUDE_PORT=${OPTARG}
+ ;;
+ h)
+ usage
+ exit 0
+ ;;
+ ?)
+ echo "Invalid option: -$OPTARG" >&2
+ usage
+ exit 1
+ ;;
+ esac
+ done
+
+ echo "EdgeMesh iptables configration:"
+ echo "====================================="
+ echo "Container Network mode is: ${NETMODE}"
+ echo "Variables:"
+ echo "EDGEMESH_PROXY_PORT=${EDGEMESH_PROXY_PORT-10001}"
+ echo "EDGEMESH_HIJACK_IP=${EDGEMESH_HIJACK_IP-"*"}"
+ echo "EDGEMESH_HIJACK_PORT=${EDGEMESH_HIJACK_PORT-"*"}"
+ echo "EDGEMESH_EXCLUDE_IP=${EDGEMESH_EXCLUDE_IP-}"
+ echo "EDGEMESH_EXCLUDE_PORT=${EDGEMESH_EXCLUDE_PORT-}"
+
+ # parse parameter
+ IFS=',' read -ra EXCLUDE_IP <<< "${EDGEMESH_EXCLUDE_IP}"
+ IFS=',' read -ra INCLUDE_IP <<< "${EDGEMESH_HIJACK_IP}"
+ # echo "EXCLUDE_IP: ${EXCLUDE_IP}"
+ for range in "${EXCLUDE_IP[@]}"; do
+ r=${range%$splt}
+ if isValidIP "$r"; then
+ if isIPv4 "$r"; then
+ ipv4_exclude_list+=("$range")
+ elif isIPv6 "$r"; then
+ ipv6_exclude_list+=("$range")
+ fi
+ fi
+ done
+
+ if [ "${EDGEMESH_HIJACK_IP}" == "*" ]; then
+ ipv4_include_list=("*")
+ ipv6_include_list=("*")
+ else
+ for range in "${INCLUDE_IP[@]}"; do
+ r=${range%$splt}
+ if isValidIP "$r";then
+ if isIPv4 "$r"; then
+ ipv4_include_list+=("$range")
+ elif isIPv6 "$r"; then
+ ipv6_include_list+=("$range")
+ fi
+ fi
+ done
+ fi
+
+ IFS=',' read -ra INCLUDE_PORT <<< "${EDGEMESH_HIJACK_PORT}"
+ IFS=',' read -ra EXCLUDE_PORT <<< "${EDGEMESH_EXCLUDE_PORT}"
+ if [ "${EDGEMESH_HIJACK_PORT}" != "*" ]; then
+ for port in "${INCLUDE_PORT[@]}"; do
+ port_include_list+=("$port")
+ done
+ fi
+
+ if [ -n "${EDGEMESH_EXCLUDE_PORT}" ]; then
+ for port in "${EXCLUDE_PORT[@]}"; do
+ port_exclude_list+=("$port")
+ done
+ fi
+
+ echo "ipv4_include_list : ${ipv4_include_list[@]}"
+ echo "ipv4_exclude_list : ${ipv4_exclude_list[@]}"
+ echo "port_include_list : ${port_include_list[@]}"
+ echo "port_exclude_list : ${port_exclude_list[@]}"
+
+ # bridge mode(port map) container network
+ if [ "${NETMODE}" = "OTHER" ]; then
+ echo " ${NETMODE} iptables configration"
+ bridgeNetMode
+ # if set ipv6 option
+ if false; then
+ echo 'TODO'
+ fi
+ # host mode container network
+ elif [ "${NETMODE}" = "HOST" ]; then
+ #hostNetMode
+ echo ${NETMODE}
+ # if set ipv6 option
+ if false; then
+ echo 'TODO'
+ fi
+ else
+ echo 'Dont support this container network '
+ fi
+}
+
+# start to configure
+main "${@}"