Skip to content

Commit e68882d

Browse files
authored
Merge pull request #17116 from rmsilva1973/master
Masking http(s)_proxy password from startup output.
2 parents 798e39b + df10b09 commit e68882d

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

pkg/minikube/node/config.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ import (
2121
"os"
2222
"os/exec"
2323
"path/filepath"
24+
"regexp"
2425
"strconv"
26+
"strings"
2527
"sync"
2628

2729
"github.com/spf13/viper"
@@ -39,11 +41,43 @@ import (
3941
"k8s.io/minikube/pkg/util/lock"
4042
)
4143

44+
func maskProxyPassword(v string) string {
45+
parts := strings.Split(v, "=")
46+
// Is it an attribution variable?
47+
if len(parts) == 2 {
48+
key := strings.ToUpper(parts[0])
49+
// Is it a proxy setting?
50+
if key == "HTTP_PROXY" || key == "HTTPS_PROXY" {
51+
proxyValue := parts[1]
52+
// Proxy variable values SHOULD have a value like
53+
// https(s)://<whatever>
54+
proxyAddressParts := strings.Split(proxyValue, "://")
55+
if len(proxyAddressParts) == 2 {
56+
proxyURL := ""
57+
proxyURL = proxyAddressParts[1]
58+
// Let's store the username, the URL and and optional port address
59+
pattern := `([^:]+):.+(@[\w\.]+)(:\d+)?`
60+
regexpPattern := regexp.MustCompile(pattern)
61+
matches := regexpPattern.FindStringSubmatch(proxyURL)
62+
mask := "*****"
63+
if len(matches) == 4 {
64+
proxyValue = fmt.Sprintf("%s://%s:%s%s%s", proxyAddressParts[0], matches[1], mask, matches[2], matches[3])
65+
} else if len(matches) == 3 {
66+
proxyValue = fmt.Sprintf("%s//%s:%s@%s", proxyAddressParts[0], matches[1], mask, matches[2])
67+
}
68+
}
69+
v = key + "=" + proxyValue
70+
}
71+
}
72+
return v
73+
}
74+
4275
func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
4376
version, _ := cr.Version()
4477
register.Reg.SetStep(register.PreparingKubernetes)
4578
out.Step(cr.Style(), "Preparing Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}} ...", out.V{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
4679
for _, v := range config.DockerOpt {
80+
v = maskProxyPassword(v)
4781
out.Infof("opt {{.docker_option}}", out.V{"docker_option": v})
4882
}
4983
for _, v := range config.DockerEnv {

pkg/minikube/node/config_test.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Copyright 2016 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package node
18+
19+
import (
20+
"testing"
21+
)
22+
23+
func Test_maskProxyPassword(t *testing.T) {
24+
type dockerOptTest struct {
25+
input string
26+
output string
27+
}
28+
var tests = []dockerOptTest{
29+
{
30+
input: "cats",
31+
output: "cats",
32+
},
33+
{
34+
input: "myDockerOption=value",
35+
output: "myDockerOption=value",
36+
},
37+
{
38+
input: "http_proxy=http://minikube.sigs.k8s.io",
39+
output: "HTTP_PROXY=http://minikube.sigs.k8s.io",
40+
},
41+
{
42+
input: "https_proxy=http://[email protected]:8080",
43+
output: "HTTPS_PROXY=http://[email protected]:8080",
44+
},
45+
{
46+
input: "https_proxy=https://mary:[email protected]:8080",
47+
output: "HTTPS_PROXY=https://mary:*****@minikube.sigs.k8s.io:8080",
48+
},
49+
{
50+
input: "http_proxy=http://jdoe:%n0tRe@al:[email protected]:8080",
51+
output: "HTTP_PROXY=http://jdoe:*****@minikube.sigs.k8s.io:8080",
52+
},
53+
{
54+
input: "http_proxy=http://jo@han:n0tRe@al:&[email protected]:8080",
55+
output: "HTTP_PROXY=http://jo@han:*****@minikube.sigs.k8s.io:8080",
56+
},
57+
{
58+
input: "http_proxy=http://k@r3n!:an0th3erF@akeP@[email protected]",
59+
output: "HTTP_PROXY=http://k@r3n!:*****@minikube.sigs.k8s.io",
60+
},
61+
{
62+
input: "https_proxy=https://fr@ank5t3in:an0th3erF@akeP@[email protected]",
63+
output: "HTTPS_PROXY=https://fr@ank5t3in:*****@minikube.sigs.k8s.io",
64+
},
65+
}
66+
for _, test := range tests {
67+
got := maskProxyPassword(test.input)
68+
if got != test.output {
69+
t.Errorf("maskProxyPassword(\"%v\"): got %v, expected %v", test.input, got, test.output)
70+
}
71+
}
72+
}

pkg/minikube/node/start.go

100644100755
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,15 @@ func validateNetwork(h *host.Host, r command.Runner, imageRepository string) (st
739739
out.Styled(style.Internet, "Found network options:")
740740
optSeen = true
741741
}
742+
k = strings.ToUpper(k) // let's get the key right away to mask password from output
743+
// If http(s)_proxy contains password, let's not splatter on the screen
744+
if k == "HTTP_PROXY" || k == "HTTPS_PROXY" {
745+
pattern := `//(\w+):\w+@`
746+
regexpPattern := regexp.MustCompile(pattern)
747+
v = regexpPattern.ReplaceAllString(v, "//$1:*****@")
748+
}
742749
out.Infof("{{.key}}={{.value}}", out.V{"key": k, "value": v})
743750
ipExcluded := proxy.IsIPExcluded(ip) // Skip warning if minikube ip is already in NO_PROXY
744-
k = strings.ToUpper(k) // for http_proxy & https_proxy
745751
if (k == "HTTP_PROXY" || k == "HTTPS_PROXY") && !ipExcluded && !warnedOnce {
746752
out.WarningT("You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).", out.V{"ip_address": ip})
747753
out.Styled(style.Documentation, "Please see {{.documentation_url}} for more details", out.V{"documentation_url": "https://minikube.sigs.k8s.io/docs/handbook/vpn_and_proxy/"})

0 commit comments

Comments
 (0)