istio

Форк
0
227 строк · 8.8 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package config
16

17
import (
18
	"encoding/json"
19
	"fmt"
20
	"net"
21
	"net/netip"
22
	"os/user"
23
	"strconv"
24
	"strings"
25
	"time"
26

27
	"github.com/miekg/dns"
28

29
	"istio.io/istio/pkg/env"
30
	"istio.io/istio/pkg/log"
31
	netutil "istio.io/istio/pkg/util/net"
32
	"istio.io/istio/tools/istio-iptables/pkg/constants"
33
)
34

35
func DefaultConfig() *Config {
36
	return &Config{
37
		RestoreFormat:           true,
38
		ProxyPort:               "15001",
39
		InboundCapturePort:      "15006",
40
		InboundTunnelPort:       "15008",
41
		InboundTProxyMark:       "1337",
42
		InboundTProxyRouteTable: "133",
43
		IptablesProbePort:       constants.DefaultIptablesProbePortUint,
44
		ProbeTimeout:            constants.DefaultProbeTimeout,
45
		OwnerGroupsInclude:      constants.OwnerGroupsInclude.DefaultValue,
46
		OwnerGroupsExclude:      constants.OwnerGroupsExclude.DefaultValue,
47
		HostIPv4LoopbackCidr:    constants.HostIPv4LoopbackCidr.DefaultValue,
48
	}
49
}
50

51
// Command line options
52
// nolint: maligned
53
type Config struct {
54
	ProxyPort               string        `json:"PROXY_PORT"`
55
	InboundCapturePort      string        `json:"INBOUND_CAPTURE_PORT"`
56
	InboundTunnelPort       string        `json:"INBOUND_TUNNEL_PORT"`
57
	ProxyUID                string        `json:"PROXY_UID"`
58
	ProxyGID                string        `json:"PROXY_GID"`
59
	InboundInterceptionMode string        `json:"INBOUND_INTERCEPTION_MODE"`
60
	InboundTProxyMark       string        `json:"INBOUND_TPROXY_MARK"`
61
	InboundTProxyRouteTable string        `json:"INBOUND_TPROXY_ROUTE_TABLE"`
62
	InboundPortsInclude     string        `json:"INBOUND_PORTS_INCLUDE"`
63
	InboundPortsExclude     string        `json:"INBOUND_PORTS_EXCLUDE"`
64
	OwnerGroupsInclude      string        `json:"OUTBOUND_OWNER_GROUPS_INCLUDE"`
65
	OwnerGroupsExclude      string        `json:"OUTBOUND_OWNER_GROUPS_EXCLUDE"`
66
	OutboundPortsInclude    string        `json:"OUTBOUND_PORTS_INCLUDE"`
67
	OutboundPortsExclude    string        `json:"OUTBOUND_PORTS_EXCLUDE"`
68
	OutboundIPRangesInclude string        `json:"OUTBOUND_IPRANGES_INCLUDE"`
69
	OutboundIPRangesExclude string        `json:"OUTBOUND_IPRANGES_EXCLUDE"`
70
	KubeVirtInterfaces      string        `json:"KUBE_VIRT_INTERFACES"`
71
	ExcludeInterfaces       string        `json:"EXCLUDE_INTERFACES"`
72
	IptablesProbePort       uint16        `json:"IPTABLES_PROBE_PORT"`
73
	ProbeTimeout            time.Duration `json:"PROBE_TIMEOUT"`
74
	DryRun                  bool          `json:"DRY_RUN"`
75
	RestoreFormat           bool          `json:"RESTORE_FORMAT"`
76
	SkipRuleApply           bool          `json:"SKIP_RULE_APPLY"`
77
	RunValidation           bool          `json:"RUN_VALIDATION"`
78
	RedirectDNS             bool          `json:"REDIRECT_DNS"`
79
	DropInvalid             bool          `json:"DROP_INVALID"`
80
	CaptureAllDNS           bool          `json:"CAPTURE_ALL_DNS"`
81
	EnableInboundIPv6       bool          `json:"ENABLE_INBOUND_IPV6"`
82
	DNSServersV4            []string      `json:"DNS_SERVERS_V4"`
83
	DNSServersV6            []string      `json:"DNS_SERVERS_V6"`
84
	NetworkNamespace        string        `json:"NETWORK_NAMESPACE"`
85
	CNIMode                 bool          `json:"CNI_MODE"`
86
	TraceLogging            bool          `json:"IPTABLES_TRACE_LOGGING"`
87
	DualStack               bool          `json:"DUAL_STACK"`
88
	HostIP                  netip.Addr    `json:"HOST_IP"`
89
	HostIPv4LoopbackCidr    string        `json:"HOST_IPV4_LOOPBACK_CIDR"`
90
}
91

92
func (c *Config) String() string {
93
	output, err := json.MarshalIndent(c, "", "\t")
94
	if err != nil {
95
		log.Fatalf("Unable to marshal config object: %v", err)
96
	}
97
	return string(output)
98
}
99

100
func (c *Config) Print() {
101
	var b strings.Builder
102
	b.WriteString(fmt.Sprintf("PROXY_PORT=%s\n", c.ProxyPort))
103
	b.WriteString(fmt.Sprintf("PROXY_INBOUND_CAPTURE_PORT=%s\n", c.InboundCapturePort))
104
	b.WriteString(fmt.Sprintf("PROXY_TUNNEL_PORT=%s\n", c.InboundTunnelPort))
105
	b.WriteString(fmt.Sprintf("PROXY_UID=%s\n", c.ProxyUID))
106
	b.WriteString(fmt.Sprintf("PROXY_GID=%s\n", c.ProxyGID))
107
	b.WriteString(fmt.Sprintf("INBOUND_INTERCEPTION_MODE=%s\n", c.InboundInterceptionMode))
108
	b.WriteString(fmt.Sprintf("INBOUND_TPROXY_MARK=%s\n", c.InboundTProxyMark))
109
	b.WriteString(fmt.Sprintf("INBOUND_TPROXY_ROUTE_TABLE=%s\n", c.InboundTProxyRouteTable))
110
	b.WriteString(fmt.Sprintf("INBOUND_PORTS_INCLUDE=%s\n", c.InboundPortsInclude))
111
	b.WriteString(fmt.Sprintf("INBOUND_PORTS_EXCLUDE=%s\n", c.InboundPortsExclude))
112
	b.WriteString(fmt.Sprintf("OUTBOUND_OWNER_GROUPS_INCLUDE=%s\n", c.OwnerGroupsInclude))
113
	b.WriteString(fmt.Sprintf("OUTBOUND_OWNER_GROUPS_EXCLUDE=%s\n", c.OwnerGroupsExclude))
114
	b.WriteString(fmt.Sprintf("OUTBOUND_IP_RANGES_INCLUDE=%s\n", c.OutboundIPRangesInclude))
115
	b.WriteString(fmt.Sprintf("OUTBOUND_IP_RANGES_EXCLUDE=%s\n", c.OutboundIPRangesExclude))
116
	b.WriteString(fmt.Sprintf("OUTBOUND_PORTS_INCLUDE=%s\n", c.OutboundPortsInclude))
117
	b.WriteString(fmt.Sprintf("OUTBOUND_PORTS_EXCLUDE=%s\n", c.OutboundPortsExclude))
118
	b.WriteString(fmt.Sprintf("KUBE_VIRT_INTERFACES=%s\n", c.KubeVirtInterfaces))
119
	b.WriteString(fmt.Sprintf("ENABLE_INBOUND_IPV6=%t\n", c.EnableInboundIPv6))
120
	b.WriteString(fmt.Sprintf("DUAL_STACK=%t\n", c.DualStack))
121
	b.WriteString(fmt.Sprintf("DNS_CAPTURE=%t\n", c.RedirectDNS))
122
	b.WriteString(fmt.Sprintf("DROP_INVALID=%t\n", c.DropInvalid))
123
	b.WriteString(fmt.Sprintf("CAPTURE_ALL_DNS=%t\n", c.CaptureAllDNS))
124
	b.WriteString(fmt.Sprintf("DNS_SERVERS=%s,%s\n", c.DNSServersV4, c.DNSServersV6))
125
	b.WriteString(fmt.Sprintf("NETWORK_NAMESPACE=%s\n", c.NetworkNamespace))
126
	b.WriteString(fmt.Sprintf("CNI_MODE=%s\n", strconv.FormatBool(c.CNIMode)))
127
	b.WriteString(fmt.Sprintf("EXCLUDE_INTERFACES=%s\n", c.ExcludeInterfaces))
128
	log.Infof("Istio iptables variables:\n%s", b.String())
129
}
130

131
func (c *Config) Validate() error {
132
	if err := ValidateOwnerGroups(c.OwnerGroupsInclude, c.OwnerGroupsExclude); err != nil {
133
		return err
134
	}
135
	return ValidateIPv4LoopbackCidr(c.HostIPv4LoopbackCidr)
136
}
137

138
var envoyUserVar = env.Register(constants.EnvoyUser, "istio-proxy", "Envoy proxy username")
139

140
func (c *Config) FillConfigFromEnvironment() {
141
	// Fill in env-var only options
142
	c.OwnerGroupsInclude = constants.OwnerGroupsInclude.Get()
143
	c.OwnerGroupsExclude = constants.OwnerGroupsExclude.Get()
144

145
	c.HostIPv4LoopbackCidr = constants.HostIPv4LoopbackCidr.Get()
146

147
	// TODO: Make this more configurable, maybe with an allowlist of users to be captured for output instead of a denylist.
148
	if c.ProxyUID == "" {
149
		usr, err := user.Lookup(envoyUserVar.Get())
150
		var userID string
151
		// Default to the UID of ENVOY_USER
152
		if err != nil {
153
			userID = constants.DefaultProxyUID
154
		} else {
155
			userID = usr.Uid
156
		}
157
		c.ProxyUID = userID
158
	}
159

160
	// For TPROXY as its uid and gid are same.
161
	if c.ProxyGID == "" {
162
		c.ProxyGID = c.ProxyUID
163
	}
164
	// Detect whether IPv6 is enabled by checking if the pod's IP address is IPv4 or IPv6.
165
	hostIP, isIPv6, err := getLocalIP(c.DualStack)
166
	if err != nil {
167
		log.Fatal(err)
168
	}
169

170
	c.HostIP = hostIP
171
	c.EnableInboundIPv6 = isIPv6
172

173
	// Lookup DNS nameservers. We only do this if DNS is enabled in case of some obscure theoretical
174
	// case where reading /etc/resolv.conf could fail.
175
	// If capture all DNS option is enabled, we don't need to read from the dns resolve conf. All
176
	// traffic to port 53 will be captured.
177
	if c.RedirectDNS && !c.CaptureAllDNS {
178
		dnsConfig, err := dns.ClientConfigFromFile("/etc/resolv.conf")
179
		if err != nil {
180
			log.Fatalf("failed to load /etc/resolv.conf: %v", err)
181
		}
182
		c.DNSServersV4, c.DNSServersV6 = netutil.IPsSplitV4V6(dnsConfig.Servers)
183
	}
184
}
185

186
// mock net.InterfaceAddrs to make its unit test become available
187
var (
188
	LocalIPAddrs = net.InterfaceAddrs
189
)
190

191
// getLocalIP returns one of the local IP address and it should support IPv6 or not
192
func getLocalIP(dualStack bool) (netip.Addr, bool, error) {
193
	var isIPv6 bool
194
	var ipAddrs []netip.Addr
195
	addrs, err := LocalIPAddrs()
196
	if err != nil {
197
		return netip.Addr{}, isIPv6, err
198
	}
199

200
	for _, a := range addrs {
201
		if ipnet, ok := a.(*net.IPNet); ok {
202
			ip := ipnet.IP
203
			ipAddr, ok := netip.AddrFromSlice(ip)
204
			if !ok {
205
				continue
206
			}
207
			// unwrap the IPv4-mapped IPv6 address
208
			unwrapAddr := ipAddr.Unmap()
209
			if !unwrapAddr.IsLoopback() && !unwrapAddr.IsLinkLocalUnicast() && !unwrapAddr.IsLinkLocalMulticast() {
210
				isIPv6 = unwrapAddr.Is6()
211
				ipAddrs = append(ipAddrs, unwrapAddr)
212
				if !dualStack {
213
					return unwrapAddr, isIPv6, nil
214
				}
215
				if isIPv6 {
216
					break
217
				}
218
			}
219
		}
220
	}
221

222
	if len(ipAddrs) > 0 {
223
		return ipAddrs[0], isIPv6, nil
224
	}
225

226
	return netip.Addr{}, isIPv6, fmt.Errorf("no valid local IP address found")
227
}
228

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.