ipn/ipnlocal: support https+insecure:// backend proxy targets

Updates tailscale/corp#7515

Change-Id: Ie50295c09e4a16959b37087d8165c4d7360db37f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/6271/head
Brad Fitzpatrick 2 years ago committed by Brad Fitzpatrick
parent 9dfb0916c2
commit d7bfef12cf

@ -23,6 +23,7 @@ import (
"tailscale.com/ipn" "tailscale.com/ipn"
"tailscale.com/net/netutil" "tailscale.com/net/netutil"
"tailscale.com/tailcfg" "tailscale.com/tailcfg"
"tailscale.com/util/strs"
) )
// serveHTTPContextKey is the context.Value key for a *serveHTTPContext. // serveHTTPContextKey is the context.Value key for a *serveHTTPContext.
@ -198,7 +199,8 @@ func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) {
// TODO(bradfitz): this is a lot of setup per HTTP request. We should // TODO(bradfitz): this is a lot of setup per HTTP request. We should
// build the whole http.Handler with all the muxing and child handlers // build the whole http.Handler with all the muxing and child handlers
// only on start/config change. But this works for now (2022-11-09). // only on start/config change. But this works for now (2022-11-09).
u, err := url.Parse(expandProxyArg(v)) targetURL, insecure := expandProxyArg(v)
u, err := url.Parse(targetURL)
if err != nil { if err != nil {
http.Error(w, "bad proxy config", http.StatusInternalServerError) http.Error(w, "bad proxy config", http.StatusInternalServerError)
return return
@ -206,6 +208,9 @@ func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) {
rp := httputil.NewSingleHostReverseProxy(u) rp := httputil.NewSingleHostReverseProxy(u)
rp.Transport = &http.Transport{ rp.Transport = &http.Transport{
DialContext: b.dialer.SystemDial, DialContext: b.dialer.SystemDial,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: insecure,
},
} }
rp.ServeHTTP(w, r) rp.ServeHTTP(w, r)
return return
@ -219,17 +224,21 @@ func (b *LocalBackend) serveWebHandler(w http.ResponseWriter, r *http.Request) {
// * port number ("8080") // * port number ("8080")
// * host:port ("localhost:8080") // * host:port ("localhost:8080")
// * full URL ("http://localhost:8080", in which case it's returned unchanged) // * full URL ("http://localhost:8080", in which case it's returned unchanged)
func expandProxyArg(s string) string { // * insecure TLS ("https+insecure://127.0.0.1:4430")
func expandProxyArg(s string) (targetURL string, insecureSkipVerify bool) {
if s == "" { if s == "" {
return "" return "", false
} }
if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") { if strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://") {
return s return s, false
}
if rest, ok := strs.CutPrefix(s, "https+insecure://"); ok {
return "https://" + rest, true
} }
if allNumeric(s) { if allNumeric(s) {
return "http://127.0.0.1:" + s return "http://127.0.0.1:" + s, false
} }
return "http://" + s return "http://" + s, false
} }
func allNumeric(s string) bool { func allNumeric(s string) bool {

@ -0,0 +1,33 @@
// Copyright (c) 2022 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ipnlocal
import "testing"
func TestExpandProxyArg(t *testing.T) {
type res struct {
target string
insecure bool
}
tests := []struct {
in string
want res
}{
{"", res{}},
{"3030", res{"http://127.0.0.1:3030", false}},
{"localhost:3030", res{"http://localhost:3030", false}},
{"10.2.3.5:3030", res{"http://10.2.3.5:3030", false}},
{"http://foo.com", res{"http://foo.com", false}},
{"https://foo.com", res{"https://foo.com", false}},
{"https+insecure://10.2.3.4", res{"https://10.2.3.4", true}},
}
for _, tt := range tests {
target, insecure := expandProxyArg(tt.in)
got := res{target, insecure}
if got != tt.want {
t.Errorf("expandProxyArg(%q) = %v, want %v", tt.in, got, tt.want)
}
}
}
Loading…
Cancel
Save