github.com/cilium/cilium@v1.16.2/pkg/policy/api/l4.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package api
     5  
     6  import (
     7  	"github.com/cilium/proxy/pkg/policy/api/kafka"
     8  )
     9  
    10  // L4Proto is a layer 4 protocol name
    11  type L4Proto string
    12  
    13  const (
    14  	// Keep pkg/u8proto up-to-date with any additions here
    15  
    16  	ProtoTCP    L4Proto = "TCP"
    17  	ProtoUDP    L4Proto = "UDP"
    18  	ProtoSCTP   L4Proto = "SCTP"
    19  	ProtoICMP   L4Proto = "ICMP"
    20  	ProtoICMPv6 L4Proto = "ICMPV6"
    21  	ProtoAny    L4Proto = "ANY"
    22  
    23  	PortProtocolAny = "0/ANY"
    24  )
    25  
    26  // IsAny returns true if an L4Proto represents ANY protocol
    27  func (l4 L4Proto) IsAny() bool {
    28  	return l4 == ProtoAny || string(l4) == ""
    29  }
    30  
    31  // PortProtocol specifies an L4 port with an optional transport protocol
    32  type PortProtocol struct {
    33  	// Port can be an L4 port number, or a name in the form of "http"
    34  	// or "http-8080".
    35  	//
    36  	// +kubebuilder:validation:Pattern=`^(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[0-9]{1,4})|([a-zA-Z0-9]-?)*[a-zA-Z](-?[a-zA-Z0-9])*$`
    37  	Port string `json:"port"`
    38  
    39  	// EndPort can only be an L4 port number.
    40  	//
    41  	// +kubebuilder:validation:Minimum=0
    42  	// +kubebuilder:validation:Maximum=65535
    43  	// +kubebuilder:validation:Optional
    44  	EndPort int32 `json:"endPort,omitempty"`
    45  
    46  	// Protocol is the L4 protocol. If omitted or empty, any protocol
    47  	// matches. Accepted values: "TCP", "UDP", "SCTP", "ANY"
    48  	//
    49  	// Matching on ICMP is not supported.
    50  	//
    51  	// Named port specified for a container may narrow this down, but may not
    52  	// contradict this.
    53  	//
    54  	// +kubebuilder:validation:Enum=TCP;UDP;SCTP;ANY
    55  	// +kubebuilder:validation:Optional
    56  	Protocol L4Proto `json:"protocol,omitempty"`
    57  }
    58  
    59  // Covers returns true if the ports and protocol specified in the received
    60  // PortProtocol are equal to or a superset of the ports and protocol in 'other'.
    61  // Named ports only cover other named ports with exactly the same name.
    62  func (p PortProtocol) Covers(other PortProtocol) bool {
    63  	if p.Port != other.Port {
    64  		return false
    65  	}
    66  	if p.Protocol != other.Protocol {
    67  		return p.Protocol.IsAny()
    68  	}
    69  	return true
    70  }
    71  
    72  // Secret is a reference to a secret, backed by k8s or local file system.
    73  type Secret struct {
    74  	// Namespace is the namespace in which the secret exists. Context of use
    75  	// determines the default value if left out (e.g., "default").
    76  	//
    77  	// +kubebuilder:validation:Optional
    78  	Namespace string `json:"namespace,omitempty"`
    79  
    80  	// Name is the name of the secret.
    81  	//
    82  	// +kubebuilder:validation:Required
    83  	Name string `json:"name"`
    84  }
    85  
    86  // TLSContext provides TLS configuration via reference to either k8s secrets
    87  // or via filepath. If both are set, directory is given priority over
    88  // k8sSecrets.
    89  type TLSContext struct {
    90  	// Secret is the secret that contains the certificates and private key for
    91  	// the TLS context.
    92  	// By default, Cilium will search in this secret for the following items:
    93  	//  - 'ca.crt'  - Which represents the trusted CA to verify remote source.
    94  	//  - 'tls.crt' - Which represents the public key certificate.
    95  	//  - 'tls.key' - Which represents the private key matching the public key
    96  	//                certificate.
    97  	//
    98  	// +kubebuilder:validation:Required
    99  	Secret *Secret `json:"secret"`
   100  
   101  	// TrustedCA is the file name or k8s secret item name for the trusted CA.
   102  	// If omitted, 'ca.crt' is assumed, if it exists. If given, the item must
   103  	// exist.
   104  	//
   105  	// +kubebuilder:validation:Optional
   106  	TrustedCA string `json:"trustedCA,omitempty"`
   107  
   108  	// Certificate is the file name or k8s secret item name for the certificate
   109  	// chain. If omitted, 'tls.crt' is assumed, if it exists. If given, the
   110  	// item must exist.
   111  	//
   112  	// +kubebuilder:validation:Optional
   113  	Certificate string `json:"certificate,omitempty"`
   114  
   115  	// PrivateKey is the file name or k8s secret item name for the private key
   116  	// matching the certificate chain. If omitted, 'tls.key' is assumed, if it
   117  	// exists. If given, the item must exist.
   118  	//
   119  	// +kubebuilder:validation:Optional
   120  	PrivateKey string `json:"privateKey,omitempty"`
   121  }
   122  
   123  // EnvoyConfig defines a reference to a CiliumEnvoyConfig or CiliumClusterwideEnvoyConfig
   124  type EnvoyConfig struct {
   125  	// Kind is the resource type being referred to. Defaults to CiliumEnvoyConfig or
   126  	// CiliumClusterwideEnvoyConfig for CiliumNetworkPolicy and CiliumClusterwideNetworkPolicy,
   127  	// respectively. The only case this is currently explicitly needed is when referring to a
   128  	// CiliumClusterwideEnvoyConfig from CiliumNetworkPolicy, as using a namespaced listener
   129  	// from a cluster scoped policy is not allowed.
   130  	//
   131  	// +kubebuilder:validation:Enum=CiliumEnvoyConfig;CiliumClusterwideEnvoyConfig
   132  	// +kubebuilder:validation:Optional
   133  	Kind string `json:"kind"`
   134  
   135  	// Name is the resource name of the CiliumEnvoyConfig or CiliumClusterwideEnvoyConfig where
   136  	// the listener is defined in.
   137  	//
   138  	// +kubebuilder:validation:MinLength=1
   139  	// +kubebuilder:validation:Required
   140  	Name string `json:"name"`
   141  }
   142  
   143  // Listener defines a reference to an Envoy listener specified in a CEC or CCEC resource.
   144  type Listener struct {
   145  	// EnvoyConfig is a reference to the CEC or CCEC resource in which
   146  	// the listener is defined.
   147  	//
   148  	// +kubebuilder:validation:Required
   149  	EnvoyConfig *EnvoyConfig `json:"envoyConfig"`
   150  
   151  	// Name is the name of the listener.
   152  	//
   153  	// +kubebuilder:validation:MinLength=1
   154  	// +kubebuilder:validation:Required
   155  	Name string `json:"name"`
   156  
   157  	// Priority for this Listener that is used when multiple rules would apply different
   158  	// listeners to a policy map entry. Behavior of this is implementation dependent.
   159  	//
   160  	// +kubebuilder:validation:Minimum=1
   161  	// +kubebuilder:validation:Maximum=100
   162  	// +kubebuilder:validation:Optional
   163  	Priority uint16 `json:"priority"`
   164  }
   165  
   166  // PortRule is a list of ports/protocol combinations with optional Layer 7
   167  // rules which must be met.
   168  type PortRule struct {
   169  	// Ports is a list of L4 port/protocol
   170  	//
   171  	// +kubebuilder:validation:Optional
   172  	// +kubebuilder:validation:MaxItems=40
   173  	Ports []PortProtocol `json:"ports,omitempty"`
   174  
   175  	// TerminatingTLS is the TLS context for the connection terminated by
   176  	// the L7 proxy.  For egress policy this specifies the server-side TLS
   177  	// parameters to be applied on the connections originated from the local
   178  	// endpoint and terminated by the L7 proxy. For ingress policy this specifies
   179  	// the server-side TLS parameters to be applied on the connections
   180  	// originated from a remote source and terminated by the L7 proxy.
   181  	//
   182  	// +kubebuilder:validation:Optional
   183  	TerminatingTLS *TLSContext `json:"terminatingTLS,omitempty"`
   184  
   185  	// OriginatingTLS is the TLS context for the connections originated by
   186  	// the L7 proxy.  For egress policy this specifies the client-side TLS
   187  	// parameters for the upstream connection originating from the L7 proxy
   188  	// to the remote destination. For ingress policy this specifies the
   189  	// client-side TLS parameters for the connection from the L7 proxy to
   190  	// the local endpoint.
   191  	//
   192  	// +kubebuilder:validation:Optional
   193  	OriginatingTLS *TLSContext `json:"originatingTLS,omitempty"`
   194  
   195  	// ServerNames is a list of allowed TLS SNI values. If not empty, then
   196  	// TLS must be present and one of the provided SNIs must be indicated in the
   197  	// TLS handshake.
   198  	//
   199  	// +kubebuilder:validation:Optional
   200  	ServerNames []string `json:"serverNames,omitempty"`
   201  
   202  	// listener specifies the name of a custom Envoy listener to which this traffic should be
   203  	// redirected to.
   204  	//
   205  	// +kubebuilder:validation:Optional
   206  	Listener *Listener `json:"listener,omitempty"`
   207  
   208  	// Rules is a list of additional port level rules which must be met in
   209  	// order for the PortRule to allow the traffic. If omitted or empty,
   210  	// no layer 7 rules are enforced.
   211  	//
   212  	// +kubebuilder:validation:Optional
   213  	Rules *L7Rules `json:"rules,omitempty"`
   214  }
   215  
   216  // GetPortProtocols returns the Ports field of the PortRule.
   217  func (pd PortRule) GetPortProtocols() []PortProtocol {
   218  	return pd.Ports
   219  }
   220  
   221  // GetPortRule returns the PortRule.
   222  func (pd *PortRule) GetPortRule() *PortRule {
   223  	return pd
   224  }
   225  
   226  // PortDenyRule is a list of ports/protocol that should be used for deny
   227  // policies. This structure lacks the L7Rules since it's not supported in deny
   228  // policies.
   229  type PortDenyRule struct {
   230  	// Ports is a list of L4 port/protocol
   231  	//
   232  	// +kubebuilder:validation:Optional
   233  	Ports []PortProtocol `json:"ports,omitempty"`
   234  }
   235  
   236  // GetPortProtocols returns the Ports field of the PortDenyRule.
   237  func (pd PortDenyRule) GetPortProtocols() []PortProtocol {
   238  	return pd.Ports
   239  }
   240  
   241  // GetPortRule returns nil has it is not a PortRule.
   242  func (pd *PortDenyRule) GetPortRule() *PortRule {
   243  	return nil
   244  }
   245  
   246  // L7Rules is a union of port level rule types. Mixing of different port
   247  // level rule types is disallowed, so exactly one of the following must be set.
   248  // If none are specified, then no additional port level rules are applied.
   249  type L7Rules struct {
   250  	// HTTP specific rules.
   251  	//
   252  	// +kubebuilder:validation:Optional
   253  	// +kubebuilder:validation:OneOf
   254  	HTTP []PortRuleHTTP `json:"http,omitempty"`
   255  
   256  	// Kafka-specific rules.
   257  	//
   258  	// +kubebuilder:validation:Optional
   259  	// +kubebuilder:validation:OneOf
   260  	Kafka []kafka.PortRule `json:"kafka,omitempty"`
   261  
   262  	// DNS-specific rules.
   263  	//
   264  	// +kubebuilder:validation:Optional
   265  	// +kubebuilder:validation:OneOf
   266  	DNS []PortRuleDNS `json:"dns,omitempty"`
   267  
   268  	// Name of the L7 protocol for which the Key-value pair rules apply.
   269  	//
   270  	// +kubebuilder:validation:Optional
   271  	// +kubebuilder:validation:OneOf
   272  	L7Proto string `json:"l7proto,omitempty"`
   273  
   274  	// Key-value pair rules.
   275  	//
   276  	// +kubebuilder:validation:Optional
   277  	L7 []PortRuleL7 `json:"l7,omitempty"`
   278  }
   279  
   280  // Len returns the total number of rules inside `L7Rules`.
   281  // Returns 0 if nil.
   282  func (rules *L7Rules) Len() int {
   283  	if rules == nil {
   284  		return 0
   285  	}
   286  	return len(rules.HTTP) + len(rules.Kafka) + len(rules.DNS) + len(rules.L7)
   287  }
   288  
   289  // IsEmpty returns whether the `L7Rules` is nil or contains no rules.
   290  func (rules *L7Rules) IsEmpty() bool {
   291  	return rules.Len() == 0
   292  }
   293  
   294  // PortRules is a slice of PortRule.
   295  type PortRules []PortRule
   296  
   297  // Iterate iterates over all elements of PortRules.
   298  func (pr PortRules) Iterate(f func(pr Ports) error) error {
   299  	for i := range pr {
   300  		err := f(&pr[i])
   301  		if err != nil {
   302  			return err
   303  		}
   304  	}
   305  	return nil
   306  }
   307  
   308  // Len returns the length of the elements of PortRules.
   309  func (pr PortRules) Len() int {
   310  	return len(pr)
   311  }
   312  
   313  // PortDenyRules is a slice of PortDenyRule.
   314  type PortDenyRules []PortDenyRule
   315  
   316  // Iterate iterates over all elements of PortDenyRules.
   317  func (pr PortDenyRules) Iterate(f func(pr Ports) error) error {
   318  	for i := range pr {
   319  		err := f(&pr[i])
   320  		if err != nil {
   321  			return err
   322  		}
   323  	}
   324  	return nil
   325  }
   326  
   327  // Len returns the length of the elements of PortDenyRules.
   328  func (pr PortDenyRules) Len() int {
   329  	return len(pr)
   330  }
   331  
   332  // Ports is an interface that should be used by all implementations of the
   333  // PortProtocols.
   334  type Ports interface {
   335  	// GetPortProtocols returns the slice PortProtocol
   336  	GetPortProtocols() []PortProtocol
   337  	// GetPortRule returns a PortRule, if the implementation does not support
   338  	// it, then returns nil.
   339  	GetPortRule() *PortRule
   340  }
   341  
   342  // PortsIterator is an interface that should be implemented by structures that
   343  // can iterate over a list of Ports interfaces.
   344  type PortsIterator interface {
   345  	Iterate(f func(pr Ports) error) error
   346  	Len() int
   347  }