Skip to content
This repository was archived by the owner on Jul 11, 2023. It is now read-only.

Commit f922b5c

Browse files
nojnhuhshashankram
andauthored
feat(injector): add list of ignored network interfaces (#4700)
* feat(injector): add list of ignored network interfaces This change adds a new configurable list of ignored network interface names. Traffic received from and sent to those interfaces is not forwarded to the sidecar container by iptables. When this list is empty (the default), osm-injector produces the exact same iptables commands as it did before. The list is configured in the chart at `osm.networkInterfaceExclusionList` and in the MeshConfig at `spec.traffic.networkInterfaceExclusionList`. Fixes #4546 Signed-off-by: Jon Huhn <[email protected]> * codegen Signed-off-by: Jon Huhn <[email protected]> * add comment Signed-off-by: Jon Huhn <[email protected]> Co-authored-by: Shashank Ram <[email protected]>
1 parent ddd10e2 commit f922b5c

File tree

12 files changed

+73
-18
lines changed

12 files changed

+73
-18
lines changed

charts/osm/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ The following table lists the configurable parameters of the osm chart and their
143143
| osm.meshName | string | `"osm"` | Identifier for the instance of a service mesh within a cluster |
144144
| osm.multicluster | object | `{"gatewayLogLevel":"error"}` | OSM multicluster feature configuration |
145145
| osm.multicluster.gatewayLogLevel | string | `"error"` | Log level for the multicluster gateway |
146+
| osm.networkInterfaceExclusionList | list | `[]` | Specifies a global list of network interface names to exclude for inbound and outbound traffic interception by the sidecar proxy. |
146147
| osm.osmBootstrap.podLabels | object | `{}` | OSM bootstrap's pod labels |
147148
| osm.osmBootstrap.replicaCount | int | `1` | OSM bootstrap's replica count |
148149
| osm.osmBootstrap.resource | object | `{"limits":{"cpu":"0.5","memory":"128M"},"requests":{"cpu":"0.3","memory":"128M"}}` | OSM bootstrap's container resource parameters |

charts/osm/templates/preset-mesh-config.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ data:
1818
"outboundPortExclusionList": {{.Values.osm.outboundPortExclusionList | mustToJson}},
1919
"inboundPortExclusionList": {{.Values.osm.inboundPortExclusionList | mustToJson}},
2020
"outboundIPRangeExclusionList": {{.Values.osm.outboundIPRangeExclusionList | mustToJson}},
21-
"outboundIPRangeInclusionList": {{.Values.osm.outboundIPRangeInclusionList | mustToJson}}
21+
"outboundIPRangeInclusionList": {{.Values.osm.outboundIPRangeInclusionList | mustToJson}},
22+
"networkInterfaceExclusionList": {{.Values.osm.networkInterfaceExclusionList | mustToJson}}
2223
},
2324
"observability": {
2425
"enableDebugServer": {{.Values.osm.enableDebugServer | mustToJson}},

charts/osm/values.schema.json

+15
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,21 @@
11311131
]
11321132
]
11331133
},
1134+
"networkInterfaceExclusionList": {
1135+
"$id": "#/properties/osm/properties/networkInterfaceExclusionList",
1136+
"type": "array",
1137+
"title": "The networkInterfaceExclusionList schema",
1138+
"description": "Network interface exluclusion list for sidecar traffic interception",
1139+
"items": {
1140+
"type": "string"
1141+
},
1142+
"examples": [
1143+
[
1144+
"eth0",
1145+
"net1"
1146+
]
1147+
]
1148+
},
11341149
"grafana": {
11351150
"$id": "#/properties/osm/properties/grafana",
11361151
"type": "object",

charts/osm/values.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ osm:
262262
# If specified, must be a list of positive integers.
263263
inboundPortExclusionList: []
264264

265+
# -- Specifies a global list of network interface names to exclude for inbound and outbound traffic interception by the sidecar proxy.
266+
networkInterfaceExclusionList: []
267+
265268
#
266269
# -- OSM's sidecar injector parameters
267270
injector:

cmd/osm-bootstrap/crds/config_meshconfig.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ spec:
156156
type: integer
157157
minimum: 1
158158
maximum: 65535
159+
networkInterfaceExclusionList:
160+
description: NetworkInterfaceExclusionList defines a global list of network interface names to exclude from inbound and outbound traffic interception by the sidecar proxy.
161+
type: array
162+
items:
163+
type: string
159164
enablePermissiveTrafficPolicyMode:
160165
description: True for allowing traffic to flow between client and service pods within the mesh without SMI traffic policies, i.e. no traffic policy enforcement in the mesh. If set to false, enables deny-all traffic policy in mesh i.e. an SMI Traffic Target is necessary for services to communicate.
161166
type: boolean

pkg/apis/config/v1alpha2/mesh_config.go

+5
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ type TrafficSpec struct {
116116
// InboundExternalAuthorization defines a ruleset that, if enabled, will configure a remote external authorization endpoint
117117
// for all inbound and ingress traffic in the mesh.
118118
InboundExternalAuthorization ExternalAuthzSpec `json:"inboundExternalAuthorization,omitempty"`
119+
120+
// NetworkInterfaceExclusionList defines a global list of network interface
121+
// names to exclude from inbound and outbound traffic interception by the
122+
// sidecar proxy.
123+
NetworkInterfaceExclusionList []string `json:"networkInterfaceExclusionList"`
119124
}
120125

121126
// ObservabilitySpec is the type to represent OSM's observability configurations.

pkg/apis/config/v1alpha2/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/injector/init_container.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99

1010
func getInitContainerSpec(containerName string, cfg configurator.Configurator, outboundIPRangeExclusionList []string,
1111
outboundIPRangeInclusionList []string, outboundPortExclusionList []int,
12-
inboundPortExclusionList []int, enablePrivilegedInitContainer bool, pullPolicy corev1.PullPolicy) corev1.Container {
13-
iptablesInitCommand := generateIptablesCommands(outboundIPRangeExclusionList, outboundIPRangeInclusionList, outboundPortExclusionList, inboundPortExclusionList)
12+
inboundPortExclusionList []int, enablePrivilegedInitContainer bool, pullPolicy corev1.PullPolicy, networkInterfaceExclusionList []string) corev1.Container {
13+
iptablesInitCommand := generateIptablesCommands(outboundIPRangeExclusionList, outboundIPRangeInclusionList, outboundPortExclusionList, inboundPortExclusionList, networkInterfaceExclusionList)
1414

1515
return corev1.Container{
1616
Name: containerName,

pkg/injector/init_container_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ var _ = Describe("Test functions creating Envoy bootstrap configuration", func()
2727
It("Creates init container without ip range exclusion list", func() {
2828
mockConfigurator.EXPECT().GetInitContainerImage().Return(containerImage).Times(1)
2929
privileged := privilegedFalse
30-
actual := getInitContainerSpec(containerName, mockConfigurator, nil, nil, nil, nil, privileged, corev1.PullAlways)
30+
actual := getInitContainerSpec(containerName, mockConfigurator, nil, nil, nil, nil, privileged, corev1.PullAlways, nil)
3131

3232
expected := corev1.Container{
3333
Name: "-container-name-",

pkg/injector/iptables.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ var iptablesInboundStaticRules = []string{
6060
}
6161

6262
// generateIptablesCommands generates a list of iptables commands to set up sidecar interception and redirection
63-
func generateIptablesCommands(outboundIPRangeExclusionList []string, outboundIPRangeInclusionList []string, outboundPortExclusionList []int, inboundPortExclusionList []int) string {
63+
func generateIptablesCommands(outboundIPRangeExclusionList []string, outboundIPRangeInclusionList []string, outboundPortExclusionList []int, inboundPortExclusionList []int, networkInterfaceExclusionList []string) string {
6464
var rules strings.Builder
6565

6666
fmt.Fprintln(&rules, `# OSM sidecar interception rules
@@ -74,6 +74,13 @@ func generateIptablesCommands(outboundIPRangeExclusionList []string, outboundIPR
7474
// 1. Create inbound rules
7575
cmds = append(cmds, iptablesInboundStaticRules...)
7676

77+
// Ignore inbound traffic on specified interfaces
78+
for _, iface := range networkInterfaceExclusionList {
79+
// *Note: it is important to use the insert option '-I' instead of the append option '-A' to ensure the
80+
// exclusion of traffic to the network interface happens before the rule that redirects traffic to the proxy
81+
cmds = append(cmds, fmt.Sprintf("-I OSM_PROXY_INBOUND -i %s -j RETURN", iface))
82+
}
83+
7784
// 2. Create dynamic inbound ports exclusion rules
7885
if len(inboundPortExclusionList) > 0 {
7986
var portExclusionListStr []string
@@ -88,6 +95,11 @@ func generateIptablesCommands(outboundIPRangeExclusionList []string, outboundIPR
8895
// 3. Create outbound rules
8996
cmds = append(cmds, iptablesOutboundStaticRules...)
9097

98+
// Ignore outbound traffic in specified interfaces
99+
for _, iface := range networkInterfaceExclusionList {
100+
cmds = append(cmds, fmt.Sprintf("-A OSM_PROXY_OUTBOUND -o %s -j RETURN", iface))
101+
}
102+
91103
//
92104
// Create outbound exclusion and inclusion rules.
93105
// *Note: exclusion rules must be applied before inclusions as order matters

pkg/injector/iptables_test.go

+18-12
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import (
88

99
func TestGenerateIptablesCommands(t *testing.T) {
1010
testCases := []struct {
11-
name string
12-
outboundIPRangeExclusions []string
13-
outboundIPRangeInclusions []string
14-
outboundPortExclusions []int
15-
inboundPortExclusions []int
16-
expected string
11+
name string
12+
outboundIPRangeExclusions []string
13+
outboundIPRangeInclusions []string
14+
outboundPortExclusions []int
15+
inboundPortExclusions []int
16+
networkInterfaceExclusions []string
17+
expected string
1718
}{
1819
{
1920
name: "no exclusions or inclusions",
@@ -45,11 +46,12 @@ EOF
4546
`,
4647
},
4748
{
48-
name: "with exclusions and inclusions",
49-
outboundIPRangeExclusions: []string{"1.1.1.1/32", "2.2.2.2/32"},
50-
outboundIPRangeInclusions: []string{"3.3.3.3/32", "4.4.4.4/32"},
51-
outboundPortExclusions: []int{10, 20},
52-
inboundPortExclusions: []int{30, 40},
49+
name: "with exclusions and inclusions",
50+
outboundIPRangeExclusions: []string{"1.1.1.1/32", "2.2.2.2/32"},
51+
outboundIPRangeInclusions: []string{"3.3.3.3/32", "4.4.4.4/32"},
52+
outboundPortExclusions: []int{10, 20},
53+
inboundPortExclusions: []int{30, 40},
54+
networkInterfaceExclusions: []string{"eth0", "eth1"},
5355
expected: `iptables-restore --noflush <<EOF
5456
# OSM sidecar interception rules
5557
*nat
@@ -65,6 +67,8 @@ EOF
6567
-A OSM_PROXY_INBOUND -p tcp --dport 15903 -j RETURN
6668
-A OSM_PROXY_INBOUND -p tcp --dport 15904 -j RETURN
6769
-A OSM_PROXY_INBOUND -p tcp -j OSM_PROXY_IN_REDIRECT
70+
-I OSM_PROXY_INBOUND -i eth0 -j RETURN
71+
-I OSM_PROXY_INBOUND -i eth1 -j RETURN
6872
-I OSM_PROXY_INBOUND -p tcp --match multiport --dports 30,40 -j RETURN
6973
-A OSM_PROXY_OUT_REDIRECT -p tcp -j REDIRECT --to-port 15001
7074
-A OSM_PROXY_OUT_REDIRECT -p tcp --dport 15000 -j ACCEPT
@@ -73,6 +77,8 @@ EOF
7377
-A OSM_PROXY_OUTBOUND -o lo -m owner ! --uid-owner 1500 -j RETURN
7478
-A OSM_PROXY_OUTBOUND -m owner --uid-owner 1500 -j RETURN
7579
-A OSM_PROXY_OUTBOUND -d 127.0.0.1/32 -j RETURN
80+
-A OSM_PROXY_OUTBOUND -o eth0 -j RETURN
81+
-A OSM_PROXY_OUTBOUND -o eth1 -j RETURN
7682
-A OSM_PROXY_OUTBOUND -d 1.1.1.1/32 -j RETURN
7783
-A OSM_PROXY_OUTBOUND -d 2.2.2.2/32 -j RETURN
7884
-A OSM_PROXY_OUTBOUND -p tcp --match multiport --dports 10,20 -j RETURN
@@ -88,7 +94,7 @@ EOF
8894
for _, tc := range testCases {
8995
t.Run(tc.name, func(t *testing.T) {
9096
a := assert.New(t)
91-
actual := generateIptablesCommands(tc.outboundIPRangeExclusions, tc.outboundIPRangeInclusions, tc.outboundPortExclusions, tc.inboundPortExclusions)
97+
actual := generateIptablesCommands(tc.outboundIPRangeExclusions, tc.outboundIPRangeInclusions, tc.outboundPortExclusions, tc.inboundPortExclusions, tc.networkInterfaceExclusions)
9298
a.Equal(tc.expected, actual)
9399
})
94100
}

pkg/injector/patch.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,10 @@ func (wh *mutatingWebhook) configurePodInit(podOS string, pod *corev1.Pod, names
205205
globalOutboundIPRangeInclusionList := wh.configurator.GetMeshConfig().Spec.Traffic.OutboundIPRangeInclusionList
206206
outboundIPRangeInclusionList := mergeIPRangeLists(podOutboundIPRangeInclusionList, globalOutboundIPRangeInclusionList)
207207

208+
networkInterfaceExclusionList := wh.configurator.GetMeshConfig().Spec.Traffic.NetworkInterfaceExclusionList
209+
208210
// Add the init container to the pod spec
209-
initContainer := getInitContainerSpec(constants.InitContainerName, wh.configurator, outboundIPRangeExclusionList, outboundIPRangeInclusionList, outboundPortExclusionList, inboundPortExclusionList, wh.configurator.IsPrivilegedInitContainer(), wh.osmContainerPullPolicy)
211+
initContainer := getInitContainerSpec(constants.InitContainerName, wh.configurator, outboundIPRangeExclusionList, outboundIPRangeInclusionList, outboundPortExclusionList, inboundPortExclusionList, wh.configurator.IsPrivilegedInitContainer(), wh.osmContainerPullPolicy, networkInterfaceExclusionList)
210212
pod.Spec.InitContainers = append(pod.Spec.InitContainers, initContainer)
211213

212214
return nil

0 commit comments

Comments
 (0)