diff --git a/cmd/minikube/cmd/tunnel.go b/cmd/minikube/cmd/tunnel.go index 8baa76a9df1e..4d53a45e71f4 100644 --- a/cmd/minikube/cmd/tunnel.go +++ b/cmd/minikube/cmd/tunnel.go @@ -41,6 +41,7 @@ import ( ) var cleanup bool +var bindAddress string // tunnelCmd represents the tunnel command var tunnelCmd = &cobra.Command{ @@ -93,7 +94,7 @@ var tunnelCmd = &cobra.Command{ sshKey := filepath.Join(localpath.MiniPath(), "machines", cname, "id_rsa") outputTunnelStarted() - kicSSHTunnel := kic.NewSSHTunnel(ctx, sshPort, sshKey, clientset.CoreV1(), clientset.NetworkingV1()) + kicSSHTunnel := kic.NewSSHTunnel(ctx, sshPort, sshKey, bindAddress, clientset.CoreV1(), clientset.NetworkingV1()) err = kicSSHTunnel.Start() if err != nil { exit.Error(reason.SvcTunnelStart, "error starting tunnel", err) @@ -119,4 +120,5 @@ func outputTunnelStarted() { func init() { tunnelCmd.Flags().BoolVarP(&cleanup, "cleanup", "c", true, "call with cleanup=true to remove old tunnels") + tunnelCmd.Flags().StringVar(&bindAddress, "bind-address", "", "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces") } diff --git a/pkg/minikube/tunnel/kic/ssh_conn.go b/pkg/minikube/tunnel/kic/ssh_conn.go index f7468aefde8e..c188bc270eca 100644 --- a/pkg/minikube/tunnel/kic/ssh_conn.go +++ b/pkg/minikube/tunnel/kic/ssh_conn.go @@ -38,7 +38,7 @@ type sshConn struct { suppressStdOut bool } -func createSSHConn(name, sshPort, sshKey string, resourcePorts []int32, resourceIP string, resourceName string) *sshConn { +func createSSHConn(name, sshPort, sshKey, bindAddress string, resourcePorts []int32, resourceIP string, resourceName string) *sshConn { // extract sshArgs sshArgs := []string{ // TODO: document the options here @@ -53,12 +53,25 @@ func createSSHConn(name, sshPort, sshKey string, resourcePorts []int32, resource askForSudo := false var privilegedPorts []int32 for _, port := range resourcePorts { - arg := fmt.Sprintf( - "-L %d:%s:%d", - port, - resourceIP, - port, - ) + var arg string + if bindAddress == "" || bindAddress == "*" { + // bind on all interfaces + arg = fmt.Sprintf( + "-L %d:%s:%d", + port, + resourceIP, + port, + ) + } else { + // bind on specify address only + arg = fmt.Sprintf( + "-L %s:%d:%s:%d", + bindAddress, + port, + resourceIP, + port, + ) + } // check if any port is privileged if port < 1024 { diff --git a/pkg/minikube/tunnel/kic/ssh_tunnel.go b/pkg/minikube/tunnel/kic/ssh_tunnel.go index dafa3f94a9d2..bcc355c1bf42 100644 --- a/pkg/minikube/tunnel/kic/ssh_tunnel.go +++ b/pkg/minikube/tunnel/kic/ssh_tunnel.go @@ -37,6 +37,7 @@ type SSHTunnel struct { ctx context.Context sshPort string sshKey string + bindAddress string v1Core typed_core.CoreV1Interface v1Networking typed_networking.NetworkingV1Interface LoadBalancerEmulator tunnel.LoadBalancerEmulator @@ -45,11 +46,12 @@ type SSHTunnel struct { } // NewSSHTunnel ... -func NewSSHTunnel(ctx context.Context, sshPort, sshKey string, v1Core typed_core.CoreV1Interface, v1Networking typed_networking.NetworkingV1Interface) *SSHTunnel { +func NewSSHTunnel(ctx context.Context, sshPort, sshKey, bindAddress string, v1Core typed_core.CoreV1Interface, v1Networking typed_networking.NetworkingV1Interface) *SSHTunnel { return &SSHTunnel{ ctx: ctx, sshPort: sshPort, sshKey: sshKey, + bindAddress: bindAddress, v1Core: v1Core, LoadBalancerEmulator: tunnel.NewLoadBalancerEmulator(v1Core), v1Networking: v1Networking, @@ -124,7 +126,7 @@ func (t *SSHTunnel) startConnection(svc v1.Service) { } // create new ssh conn - newSSHConn := createSSHConn(uniqName, t.sshPort, t.sshKey, resourcePorts, svc.Spec.ClusterIP, svc.Name) + newSSHConn := createSSHConn(uniqName, t.sshPort, t.sshKey, t.bindAddress, resourcePorts, svc.Spec.ClusterIP, svc.Name) t.conns[newSSHConn.name] = newSSHConn go func() { @@ -154,7 +156,7 @@ func (t *SSHTunnel) startConnectionIngress(ingress v1_networking.Ingress) { resourceIP := "127.0.0.1" // create new ssh conn - newSSHConn := createSSHConn(uniqName, t.sshPort, t.sshKey, resourcePorts, resourceIP, ingress.Name) + newSSHConn := createSSHConn(uniqName, t.sshPort, t.sshKey, t.bindAddress, resourcePorts, resourceIP, ingress.Name) t.conns[newSSHConn.name] = newSSHConn go func() { diff --git a/site/content/en/docs/commands/tunnel.md b/site/content/en/docs/commands/tunnel.md index 74198bb27225..caea57de2cc1 100644 --- a/site/content/en/docs/commands/tunnel.md +++ b/site/content/en/docs/commands/tunnel.md @@ -20,7 +20,8 @@ minikube tunnel [flags] ### Options ``` - -c, --cleanup call with cleanup=true to remove old tunnels (default true) + --bind-address string set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces + -c, --cleanup call with cleanup=true to remove old tunnels (default true) ``` ### Options inherited from parent commands diff --git a/translations/de.json b/translations/de.json index 49681af5cd5c..86b706c7e303 100644 --- a/translations/de.json +++ b/translations/de.json @@ -981,6 +981,7 @@ "retrieving node": "Ermittele Node", "scheduled stop is not supported on the none driver, skipping scheduling": "Das geplante Stoppen wird von none Treiber nicht unterstützt, überspringe Planung", "service {{.namespace_name}}/{{.service_name}} has no node port": "Service {{.namespace_name}}/{{.service_name}} hat keinen Node Port", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "state Fehler", "status json failure": "Status json Fehler", "status text failure": "Status text Fehler", diff --git a/translations/es.json b/translations/es.json index 1df332f737ea..05733115758c 100644 --- a/translations/es.json +++ b/translations/es.json @@ -977,6 +977,7 @@ "retrieving node": "", "scheduled stop is not supported on the none driver, skipping scheduling": "", "service {{.namespace_name}}/{{.service_name}} has no node port": "", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "", "status json failure": "", "status text failure": "", diff --git a/translations/fr.json b/translations/fr.json index a7121e5551dc..06bcd73a001a 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -946,6 +946,7 @@ "retrieving node": "récupération du nœud", "scheduled stop is not supported on the none driver, skipping scheduling": "l'arrêt programmé n'est pas pris en charge sur le pilote none, programmation non prise en compte", "service {{.namespace_name}}/{{.service_name}} has no node port": "le service {{.namespace_name}}/{{.service_name}} n'a pas de port de nœud", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "stat en échec", "status json failure": "état du JSON en échec", "status text failure": "état du texte en échec", diff --git a/translations/ja.json b/translations/ja.json index 78457ca9d0d9..dbd5d0d6249e 100644 --- a/translations/ja.json +++ b/translations/ja.json @@ -998,6 +998,7 @@ "saving node": "ノードを保存しています", "scheduled stop is not supported on the none driver, skipping scheduling": "none ドライバーでは予定停止がサポートされていません (予約をスキップします)", "service {{.namespace_name}}/{{.service_name}} has no node port": "サービス {{.namespace_name}}/{{.service_name}} は NodePort がありません", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "startup failed": "起動に失敗しました", "stat failed": "stat に失敗しました", "status json failure": "status json に失敗しました", diff --git a/translations/ko.json b/translations/ko.json index d83061230f9a..4d4536ec9b5f 100644 --- a/translations/ko.json +++ b/translations/ko.json @@ -987,6 +987,7 @@ "retrieving node": "", "scheduled stop is not supported on the none driver, skipping scheduling": "", "service {{.namespace_name}}/{{.service_name}} has no node port": "", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "", "status json failure": "", "status text failure": "", diff --git a/translations/pl.json b/translations/pl.json index 1647bd0e61f9..17f838b48fc5 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -990,6 +990,7 @@ "retrieving node": "przywracanie węzła", "scheduled stop is not supported on the none driver, skipping scheduling": "", "service {{.namespace_name}}/{{.service_name}} has no node port": "", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "wykonanie komendy stat nie powiodło się", "status json failure": "", "status text failure": "", diff --git a/translations/ru.json b/translations/ru.json index 3e39023e1443..8c8bdef38697 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -911,6 +911,7 @@ "retrieving node": "", "scheduled stop is not supported on the none driver, skipping scheduling": "", "service {{.namespace_name}}/{{.service_name}} has no node port": "", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "", "status json failure": "", "status text failure": "", diff --git a/translations/strings.txt b/translations/strings.txt index 450fbe871b66..dbf487fa6e95 100644 --- a/translations/strings.txt +++ b/translations/strings.txt @@ -911,6 +911,7 @@ "retrieving node": "", "scheduled stop is not supported on the none driver, skipping scheduling": "", "service {{.namespace_name}}/{{.service_name}} has no node port": "", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "", "status json failure": "", "status text failure": "", diff --git a/translations/zh-CN.json b/translations/zh-CN.json index fdb007fbefa6..b4fa54927517 100644 --- a/translations/zh-CN.json +++ b/translations/zh-CN.json @@ -1100,6 +1100,7 @@ "retrieving node": "", "scheduled stop is not supported on the none driver, skipping scheduling": "", "service {{.namespace_name}}/{{.service_name}} has no node port": "", + "set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "", "stat failed": "", "status json failure": "", "status text failure": "",