github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/supervisor/iptablesctrl/templates.go (about)

     1  package iptablesctrl
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/md5"
     6  	"encoding/base64"
     7  	"fmt"
     8  	"io"
     9  	"net"
    10  	"strconv"
    11  	"strings"
    12  	"text/template"
    13  
    14  	"github.com/kballard/go-shellquote"
    15  	"go.aporeto.io/enforcerd/trireme-lib/common"
    16  	cconstants "go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    17  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/nfqdatapath/afinetrawsocket"
    18  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packet"
    19  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    20  	"go.aporeto.io/enforcerd/trireme-lib/utils/constants"
    21  )
    22  
    23  func extractRulesFromTemplate(tmpl *template.Template, data interface{}) ([][]string, error) {
    24  
    25  	buffer := bytes.NewBuffer([]byte{})
    26  	if err := tmpl.Execute(buffer, data); err != nil {
    27  		return [][]string{}, fmt.Errorf("unable to execute template:%s", err)
    28  	}
    29  
    30  	rules := [][]string{}
    31  
    32  	for _, m := range strings.Split(buffer.String(), "\n") {
    33  
    34  		rule, err := shellquote.Split(m)
    35  		if err != nil {
    36  			return [][]string{}, err
    37  		}
    38  
    39  		// ignore empty lines in the buffer
    40  		if len(rule) <= 1 {
    41  			continue
    42  		}
    43  
    44  		rules = append(rules, rule)
    45  	}
    46  	return rules, nil
    47  }
    48  
    49  // ACLInfo keeps track of all information to create ACLs
    50  type ACLInfo struct {
    51  	ContextID string
    52  	PUType    common.PUType
    53  
    54  	// Tables
    55  	MangleTable string
    56  	NatTable    string
    57  
    58  	// Chains
    59  	MainAppChain        string
    60  	MainNetChain        string
    61  	BPFPath             string
    62  	HostInput           string
    63  	HostOutput          string
    64  	NfqueueOutput       string
    65  	NfqueueInput        string
    66  	NetworkSvcInput     string
    67  	NetworkSvcOutput    string
    68  	TriremeInput        string
    69  	TriremeOutput       string
    70  	NatProxyNetChain    string
    71  	NatProxyAppChain    string
    72  	MangleProxyNetChain string
    73  	MangleProxyAppChain string
    74  	PreRouting          string
    75  
    76  	AppChain   string
    77  	NetChain   string
    78  	AppSection string
    79  	NetSection string
    80  
    81  	// serviceMesh chains
    82  	IstioChain string
    83  
    84  	// common info
    85  	DefaultConnmark         string
    86  	DefaultDropConnmark     string
    87  	DefaultExternalConnmark string
    88  	PacketMarkToSetConnmark string
    89  	DefaultInputMark        string
    90  	DefaultHandShakeMark    string
    91  
    92  	RawSocketMark   string
    93  	TargetTCPNetSet string
    94  	TargetUDPNetSet string
    95  	ExclusionsSet   string
    96  	IpsetPrefix     string
    97  	// IPv4 IPv6
    98  	DefaultIP     string
    99  	needICMPRules bool
   100  
   101  	// UDP rules
   102  	Numpackets   string
   103  	InitialCount string
   104  	UDPSignature string
   105  
   106  	// Linux PUs
   107  	TCPPorts   string
   108  	UDPPorts   string
   109  	TCPPortSet string
   110  
   111  	// ProxyRules
   112  	DestIPSet     string
   113  	SrvIPSet      string
   114  	ProxyPort     string
   115  	DNSProxyPort  string
   116  	DNSServerIP   string
   117  	CgroupMark    string
   118  	ProxyMark     string
   119  	AuthPhaseMark string
   120  
   121  	PacketMark string
   122  	Mark       string
   123  	PortSet    string
   124  
   125  	AppNFLOGPrefix              string
   126  	AppNFLOGDropPacketLogPrefix string
   127  	AppDefaultAction            string
   128  
   129  	NetNFLOGPrefix              string
   130  	NetNFLOGDropPacketLogPrefix string
   131  	NetDefaultAction            string
   132  
   133  	NFQueues    []int
   134  	NumNFQueues int
   135  	// icmpv6 allow bytecode
   136  	ICMPv6Allow string
   137  
   138  	// Istio Iptable rules
   139  	IstioEnabled bool
   140  }
   141  
   142  func chainName(contextID string, version int) (app, net string, err error) {
   143  	hash := md5.New()
   144  
   145  	if _, err := io.WriteString(hash, contextID); err != nil {
   146  		return "", "", err
   147  	}
   148  	output := base64.URLEncoding.EncodeToString(hash.Sum(nil))
   149  	if len(contextID) > 4 {
   150  		contextID = contextID[:4] + output[:6]
   151  	} else {
   152  		contextID = contextID + output[:6]
   153  	}
   154  
   155  	app = appChainPrefix + contextID + "-" + strconv.Itoa(version)
   156  	net = netChainPrefix + contextID + "-" + strconv.Itoa(version)
   157  
   158  	return app, net, nil
   159  }
   160  
   161  func (i *iptables) newACLInfo(version int, contextID string, p *policy.PUInfo, puType common.PUType) (*ACLInfo, error) {
   162  	var appChain, netChain string
   163  	var err error
   164  	var nfqueues []int
   165  
   166  	numQueues := i.fqc.GetNumQueues()
   167  
   168  	ipFilter := i.impl.IPFilter()
   169  
   170  	if contextID != "" {
   171  		appChain, netChain, err = chainName(contextID, version)
   172  		if err != nil {
   173  			return nil, err
   174  		}
   175  	}
   176  
   177  	parseDNSServerIP := func() string {
   178  		for _, ipString := range i.fqc.GetDNSServerAddresses() {
   179  			if ip := net.ParseIP(ipString); ip != nil {
   180  				if ipFilter(ip) {
   181  					return ipString
   182  				}
   183  
   184  				continue
   185  			}
   186  			// parseCIDR
   187  			if ip, _, err := net.ParseCIDR(ipString); err == nil {
   188  				if ipFilter(ip) {
   189  					return ipString
   190  				}
   191  			}
   192  		}
   193  		return ""
   194  	}
   195  
   196  	appDefaultAction := policy.Reject | policy.Log
   197  	netDefaultAction := policy.Reject | policy.Log
   198  
   199  	var tcpPorts, udpPorts string
   200  	var servicePort, mark, dnsProxyPort, packetMark string
   201  	if p != nil {
   202  		tcpPorts, udpPorts = common.ConvertServicesToProtocolPortList(p.Runtime.Options().Services)
   203  		puType = p.Runtime.PUType()
   204  		servicePort = p.Policy.ServicesListeningPort()
   205  		dnsProxyPort = p.Policy.DNSProxyPort()
   206  		mark = p.Runtime.Options().CgroupMark
   207  		packetMark = mark
   208  		appDefaultAction = p.Policy.AppDefaultPolicyAction()
   209  		netDefaultAction = p.Policy.NetDefaultPolicyAction()
   210  	}
   211  
   212  	destSetName, srvSetName := i.ipsetmanager.GetProxySetNames(contextID)
   213  
   214  	tcpTargetSetName, udpTargetSetName, excludedNetworkSetName := i.ipsetmanager.GetIPsetNamesForTargetAndExcludedNetworks()
   215  
   216  	appSection := ""
   217  	netSection := ""
   218  	switch puType {
   219  	case common.LinuxProcessPU, common.WindowsProcessPU:
   220  		appSection = TriremeOutput
   221  		netSection = TriremeInput
   222  	case common.HostNetworkPU:
   223  		appSection = NetworkSvcOutput
   224  		netSection = NetworkSvcInput
   225  	case common.HostPU:
   226  		appSection = HostModeOutput
   227  		netSection = HostModeInput
   228  	default:
   229  		appSection = mainAppChain
   230  		netSection = mainNetChain
   231  	}
   232  
   233  	portSetName := i.ipsetmanager.GetServerPortSetName(contextID)
   234  
   235  	for i := 0; i < numQueues; i++ {
   236  		nfqueues = append(nfqueues, i)
   237  	}
   238  
   239  	cfg := &ACLInfo{
   240  		ContextID: contextID,
   241  		PUType:    puType,
   242  		// Chains
   243  		MangleTable:         "mangle",
   244  		NatTable:            "nat",
   245  		MainAppChain:        mainAppChain,
   246  		MainNetChain:        mainNetChain,
   247  		HostInput:           HostModeInput,
   248  		HostOutput:          HostModeOutput,
   249  		NfqueueOutput:       NfqueueOutput,
   250  		NfqueueInput:        NfqueueInput,
   251  		NFQueues:            nfqueues,
   252  		NumNFQueues:         numQueues,
   253  		NetworkSvcInput:     NetworkSvcInput,
   254  		NetworkSvcOutput:    NetworkSvcOutput,
   255  		TriremeInput:        TriremeInput,
   256  		TriremeOutput:       TriremeOutput,
   257  		NatProxyNetChain:    natProxyInputChain,
   258  		NatProxyAppChain:    natProxyOutputChain,
   259  		MangleProxyNetChain: proxyInputChain,
   260  		MangleProxyAppChain: proxyOutputChain,
   261  		PreRouting:          ipTableSectionPreRouting,
   262  
   263  		AppChain:   appChain,
   264  		NetChain:   netChain,
   265  		AppSection: appSection,
   266  		NetSection: netSection,
   267  		IstioChain: istioChain,
   268  
   269  		// common info
   270  		DefaultConnmark:         strconv.Itoa(int(constants.DefaultConnMark)),
   271  		DefaultDropConnmark:     strconv.Itoa(int(constants.DropConnmark)),
   272  		DefaultExternalConnmark: strconv.Itoa(int(constants.DefaultExternalConnMark)),
   273  		PacketMarkToSetConnmark: strconv.Itoa(int(constants.PacketMarkToSetConnmark)),
   274  		DefaultInputMark:        strconv.Itoa(int(constants.DefaultInputMark)),
   275  		RawSocketMark:           strconv.Itoa(afinetrawsocket.ApplicationRawSocketMark),
   276  		DefaultHandShakeMark:    strconv.Itoa(int(constants.HandshakeConnmark)),
   277  		CgroupMark:              mark,
   278  		TargetTCPNetSet:         tcpTargetSetName,
   279  		TargetUDPNetSet:         udpTargetSetName,
   280  		ExclusionsSet:           excludedNetworkSetName,
   281  		// IPv4 vs IPv6
   282  		DefaultIP:     i.impl.GetDefaultIP(),
   283  		needICMPRules: i.impl.NeedICMP(),
   284  
   285  		// UDP rules
   286  		Numpackets:   numPackets,
   287  		InitialCount: initialCount,
   288  		UDPSignature: packet.UDPAuthMarker,
   289  
   290  		// // Linux PUs
   291  		TCPPorts:   tcpPorts,
   292  		UDPPorts:   udpPorts,
   293  		TCPPortSet: portSetName,
   294  
   295  		// // ProxyRules
   296  		DestIPSet:    destSetName,
   297  		SrvIPSet:     srvSetName,
   298  		ProxyPort:    servicePort,
   299  		DNSProxyPort: dnsProxyPort,
   300  		DNSServerIP:  parseDNSServerIP(),
   301  		ProxyMark:    cconstants.ProxyMark,
   302  
   303  		// PUs
   304  		PacketMark: packetMark,
   305  		Mark:       mark,
   306  		PortSet:    portSetName,
   307  
   308  		AppNFLOGPrefix:              policy.DefaultLogPrefix(contextID, appDefaultAction),
   309  		AppNFLOGDropPacketLogPrefix: policy.DefaultDropPacketLogPrefix(contextID),
   310  		AppDefaultAction:            policy.DefaultAction(appDefaultAction),
   311  
   312  		NetNFLOGPrefix:              policy.DefaultLogPrefix(contextID, netDefaultAction),
   313  		NetNFLOGDropPacketLogPrefix: policy.DefaultDropPacketLogPrefix(contextID),
   314  		NetDefaultAction:            policy.DefaultAction(netDefaultAction),
   315  	}
   316  
   317  	allowICMPv6(cfg)
   318  	if i.bpf != nil {
   319  		cfg.BPFPath = i.bpf.GetBPFPath()
   320  	}
   321  
   322  	return cfg, nil
   323  }