|
| 1 | +# KEP-2079: Network Policy to support Port Ranges |
| 2 | + |
1 | 3 | <!-- toc -->
|
2 | 4 | - [Release Signoff Checklist](#release-signoff-checklist)
|
3 | 5 | - [Summary](#summary)
|
4 | 6 | - [Motivation](#motivation)
|
5 | 7 | - [Goals](#goals)
|
6 | 8 | - [Non-Goals](#non-goals)
|
7 | 9 | - [Proposal](#proposal)
|
8 |
| - - [User Stories (Optional)](#user-stories-optional) |
9 |
| - - [Story 1](#story-1) |
| 10 | + - [User Stories](#user-stories) |
| 11 | + - [Story 1 - Opening communication to NodePorts of other cluster](#story-1---opening-communication-to-nodeports-of-other-cluster) |
| 12 | + - [Story 2 - Blocking the egress for not allowed insecure ports](#story-2---blocking-the-egress-for-not-allowed-insecure-ports) |
| 13 | + - [Story 3 - Containerized Passive FTP Server](#story-3---containerized-passive-ftp-server) |
10 | 14 | - [Notes/Constraints/Caveats](#notesconstraintscaveats)
|
11 | 15 | - [Risks and Mitigations](#risks-and-mitigations)
|
12 | 16 | - [Design Details](#design-details)
|
|
25 | 29 | - [Troubleshooting](#troubleshooting)
|
26 | 30 | - [Implementation History](#implementation-history)
|
27 | 31 | - [Drawbacks](#drawbacks)
|
| 32 | +- [Alternatives](#alternatives) |
28 | 33 | <!-- /toc -->
|
29 | 34 |
|
30 | 35 | ## Release Signoff Checklist
|
@@ -90,31 +95,51 @@ creation of NetworkPolicy to the user.
|
90 | 95 |
|
91 | 96 | ### Goals
|
92 | 97 |
|
93 |
| -Add Range field to Ports in NetworkPolicy |
| 98 | +Add Port Range field in a NetworkPolicy |
94 | 99 |
|
95 | 100 | ### Non-Goals
|
96 | 101 |
|
97 | 102 | N/A
|
98 | 103 |
|
99 | 104 | ## Proposal
|
100 | 105 |
|
101 |
| -In NetworkPolicy specification, inside ``NetworkPolicyPort`` object struct |
102 |
| -specify a new ``Range`` field composed of the minimum and maximum ports |
103 |
| -inside the range. |
| 106 | +In NetworkPolicy specification, inside ``NetworkPolicyIngressRule`` and |
| 107 | +``NetworkPolicyEgressRule`` object struct specify a new ``PortRanges`` field |
| 108 | +composed of the minimum and maximum ports inside the range, and the exceptions |
| 109 | +within this range. |
104 | 110 |
|
105 | 111 | If both ``Port`` and ``Range`` are specified, they are cumulative and no further
|
106 | 112 | validation might occur. It's up to the CNI to summarize both of the fields in a
|
107 | 113 | single rule.
|
108 | 114 |
|
109 |
| -### User Stories (Optional) |
| 115 | +### User Stories |
110 | 116 |
|
111 |
| -#### Story 1 |
| 117 | +#### Story 1 - Opening communication to NodePorts of other cluster |
112 | 118 |
|
113 | 119 | I have an application that communicates with NodePorts of a different cluster
|
114 | 120 | and I want to allow the egress of the traffic only the NodePort range
|
115 | 121 | (eg. 30000-32767) as I don't know which port is going to be allocated on the
|
116 | 122 | other side, but don't want to create a rule for each of them.
|
117 | 123 |
|
| 124 | +#### Story 2 - Blocking the egress for not allowed insecure ports |
| 125 | +As a developer, I need to create an application that scrapes informations from |
| 126 | +multiple sources, being those sources databases running in random ports, web |
| 127 | +applications and other sources. But the security policy of my company asks me |
| 128 | +to block communication with well known ports, like 111 and 445, so I need to create |
| 129 | +a network policy that allows me to communicate with any port except those two and so |
| 130 | +I can be compliant with the company's policy. |
| 131 | + |
| 132 | +#### Story 3 - Containerized Passive FTP Server |
| 133 | +As a Kubernetes User, I've received a demand from my boss to run our FTP server in an |
| 134 | +existing Kubernetes cluster, to support some of my legacy applications. |
| 135 | +his FTP Server must be acessible from inside the cluster and outside the cluster, |
| 136 | +but I still need to keep the basic security policies from my company, that demands |
| 137 | +the existence of a default deny rule for all workloads and allowing only specific ports. |
| 138 | + |
| 139 | +Because this FTP Server runs in PASV mode, I need to open the Network Policy to ports 21 |
| 140 | +and also to the range 49152-65535 without allowing any other ports. |
| 141 | + |
| 142 | + |
118 | 143 | ### Notes/Constraints/Caveats
|
119 | 144 |
|
120 | 145 | * The technology used by the CNI provider might not support port range in a
|
@@ -142,44 +167,82 @@ type NetworkPolicyPortRange struct {
|
142 | 167 | To uint16
|
143 | 168 |
|
144 | 169 | // Except defines all the exceptions in the port range
|
145 |
| - Except: []uint16 |
| 170 | + +optional |
| 171 | + Except []uint16 |
146 | 172 | }
|
147 | 173 | ```
|
148 |
| -* Add a new field ``spec.ingress|egress.ports.range`` that points to the |
149 |
| -new struct: |
| 174 | +* Add a new field ``PortRanges`` that defines an array of |
| 175 | +``NetworkPolicyPortRange`` in both ``NetworkPolicyIngressRule`` and |
| 176 | +``NetworkPolicyEgressRule`` |
| 177 | + |
150 | 178 | ```
|
151 |
| -// NetworkPolicyPort describes a port or a range of ports to allow traffic on |
152 |
| -type NetworkPolicyPort struct { |
153 |
| - // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this |
154 |
| - // field defaults to TCP. |
155 |
| - // +optional |
156 |
| - Protocol *api.Protocol |
157 |
| - |
158 |
| - // The port on the given protocol. This can either be a numerical or named |
159 |
| - // port on a pod. If this field is not provided but a Range is |
160 |
| - // provided, this field is ignored. Otherwise this matches all port names and |
161 |
| - // numbers. |
162 |
| - // +optional |
163 |
| - Port *intstr.IntOrString |
| 179 | +// NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods |
| 180 | +// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from. |
| 181 | +type NetworkPolicyIngressRule struct { |
| 182 | + // List of ports which should be made accessible on the pods selected for this |
| 183 | + // rule. Each item in this list is combined using a logical OR. If this field is |
| 184 | + // empty or missing, this rule matches all ports (traffic not restricted by port). |
| 185 | + // If this field is present and contains at least one item, then this rule allows |
| 186 | + // traffic only if the traffic matches at least one port in the list. |
| 187 | + // +optional |
| 188 | + Ports []NetworkPolicyPort |
| 189 | +
|
| 190 | + // List of sources which should be able to access the pods selected for this rule. |
| 191 | + // Items in this list are combined using a logical OR operation. If this field is |
| 192 | + // empty or missing, this rule matches all sources (traffic not restricted by |
| 193 | + // source). If this field is present and contains at least one item, this rule |
| 194 | + // allows traffic only if the traffic matches at least one item in the from list. |
| 195 | + // +optional |
| 196 | + From []NetworkPolicyPeer |
| 197 | +
|
| 198 | + // List of port ranges which should be made accessible on the pods selected for this |
| 199 | + // rule. Each item in this list is combined using a logical OR. If this field is |
| 200 | + // empty or missing, AND the Ports field is also empty or missing, |
| 201 | + // this rule matches all ports (traffic not restricted by port). |
| 202 | + // If this field is present and contains at least one item, then this rule allows |
| 203 | + // traffic only if the traffic matches at least one port in the list. |
| 204 | + // +optional |
| 205 | + PortRanges []NetworkPolicyPortRange |
| 206 | +} |
| 207 | +
|
| 208 | +// NetworkPolicyEgressRule describes a particular set of traffic that is allowed out of pods |
| 209 | +// matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and to. |
| 210 | +// This type is beta-level in 1.8 |
| 211 | +type NetworkPolicyEgressRule struct { |
| 212 | + // List of destination ports for outgoing traffic. |
| 213 | + // Each item in this list is combined using a logical OR. If this field is |
| 214 | + // empty or missing, this rule matches all ports (traffic not restricted by port). |
| 215 | + // If this field is present and contains at least one item, then this rule allows |
| 216 | + // traffic only if the traffic matches at least one port in the list. |
| 217 | + // +optional |
| 218 | + Ports []NetworkPolicyPort |
| 219 | +
|
| 220 | + // List of destinations for outgoing traffic of pods selected for this rule. |
| 221 | + // Items in this list are combined using a logical OR operation. If this field is |
| 222 | + // empty or missing, this rule matches all destinations (traffic not restricted by |
| 223 | + // destination). If this field is present and contains at least one item, this rule |
| 224 | + // allows traffic only if the traffic matches at least one item in the to list. |
| 225 | + // +optional |
| 226 | + To []NetworkPolicyPeer |
| 227 | +
|
| 228 | + // List of destination port ranges for outgoing traffic. |
| 229 | + // Each item in this list is combined using a logical OR. If this field is |
| 230 | + // empty or missing AND the Ports field is also empty or missing, |
| 231 | + // this rule matches all ports (traffic not restricted by port). |
| 232 | + // If this field is present and contains at least one item, then this rule allows |
| 233 | + // traffic only if the traffic matches at least one port inside this range. |
| 234 | + // +optional |
| 235 | + PortRanges []NetworkPolicyPortRange |
164 | 236 |
|
165 |
| - // A range of ports on a given protocol and the exceptions. If this field |
166 |
| - // is not provided, this doesn't matches anything |
167 |
| - // +optional |
168 |
| - Range *NetworkPolicyPortRange |
169 | 237 | }
|
170 | 238 | ```
|
171 | 239 |
|
172 | 240 | ### Validations
|
173 | 241 | The range will need to be validated, with the following scenarios:
|
174 |
| -* If there's a ``From`` or a ``To`` field defined, the other one must be defined. |
175 | 242 | * ``From`` needs to be less than or equal to ``To``
|
176 |
| -* All the ports in the ``Exceptions`` array must be inside the defined range. |
177 |
| -* ``Exception`` can only be defined if ``From`` and ``To`` are also defined. |
178 |
| -* Because ``ports`` is a superset of all ports specified in ``port`` and |
179 |
| -``range``, if a port is specified in at least one of the fields it should be |
180 |
| -allowed. |
181 |
| -* If ``Range`` is defined but no ``Port`` is defined, the old behavior of matching |
182 |
| -all should be changed. |
| 243 | +* All the ports in the ``Except`` array must be inside the defined range. |
| 244 | +* If ``PortRange`` is defined but no ``Ports`` is defined, the old behavior of |
| 245 | +matching all Ports should be changed to match only PortRange ports. |
183 | 246 |
|
184 | 247 | ### Test Plan
|
185 | 248 |
|
@@ -215,7 +278,8 @@ with generally positive feedback on its usage.
|
215 | 278 | If upgraded no impact should happen as this is a new field.
|
216 | 279 |
|
217 | 280 | If downgraded the CNI wont be able to look into the new field, as this does not
|
218 |
| -exists and network policies using this field will stop working. |
| 281 | +exists and network policies using this field will stop working correctly and |
| 282 | +start working incorrectly. |
219 | 283 |
|
220 | 284 | ## Production Readiness Review Questionnaire
|
221 | 285 |
|
@@ -297,7 +361,7 @@ the existing API objects?**
|
297 | 361 |
|
298 | 362 | - API type(s): NetworkPolicy / NetworkPolicyPorts
|
299 | 363 | - Estimated increase in size: New struct inside the object with two fields of
|
300 |
| - 16 bits each + 16 bits for each port in the ``Exceptions`` array |
| 364 | + 16 bits each + 16 bits for each port in the ``Except`` array |
301 | 365 | - Estimated amount of new objects: N/A
|
302 | 366 |
|
303 | 367 | * **Will enabling / using this feature result in increasing time taken by any
|
@@ -337,3 +401,34 @@ different way.
|
337 | 401 |
|
338 | 402 | For this cases, CNIs will have to iteract through the Port Range and
|
339 | 403 | populate their packet filtering tables with each port.
|
| 404 | + |
| 405 | +## Alternatives |
| 406 | + |
| 407 | +During the development of this KEP there was an alternative implementation |
| 408 | +of the ``NetworkPolicyPortRange`` field inside the ``NetworkPolicyPort`` as the following: |
| 409 | + |
| 410 | +``` |
| 411 | +// NetworkPolicyPort describes a port or a range of ports to allow traffic on |
| 412 | +type NetworkPolicyPort struct { |
| 413 | + // The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this |
| 414 | + // field defaults to TCP. |
| 415 | + // +optional |
| 416 | + Protocol *api.Protocol |
| 417 | + |
| 418 | + // The port on the given protocol. This can either be a numerical or named |
| 419 | + // port on a pod. If this field is not provided but a Range is |
| 420 | + // provided, this field is ignored. Otherwise this matches all port names and |
| 421 | + // numbers. |
| 422 | + // +optional |
| 423 | + Port *intstr.IntOrString |
| 424 | +
|
| 425 | + // A range of ports on a given protocol and the exceptions. If this field |
| 426 | + // is not provided, this doesn't matches anything |
| 427 | + // +optional |
| 428 | + Range *NetworkPolicyPortRange |
| 429 | +} |
| 430 | +``` |
| 431 | + |
| 432 | +But the main design suggested in this Kep seems more clear, so this alternative |
| 433 | +has been discarded. |
| 434 | + |
0 commit comments