Skip to content

Commit

Permalink
Merge pull request #896 from KTruesdellENA/master
Browse files Browse the repository at this point in the history
setting sni to match host
  • Loading branch information
nathanejohnson authored Jul 18, 2022
2 parents 81bec58 + 5703491 commit e758455
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 17 deletions.
20 changes: 5 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"crypto/tls"
"encoding/json"
"fmt"
"github.com/fabiolb/fabio/transport"
gkm "github.com/go-kit/kit/metrics"
"io"
"log"
Expand Down Expand Up @@ -68,6 +69,8 @@ func main() {
return
}

transport.SetConfig(cfg)

log.Printf("[INFO] Setting log level to %s", logOutput.Level())
if !logOutput.SetLevel(cfg.Log.Level) {
log.Printf("[INFO] Cannot set log level to %s", cfg.Log.Level)
Expand Down Expand Up @@ -208,19 +211,6 @@ func newHTTPProxy(cfg *config.Config, statsHandler *proxy.HttpStatsHandler) *pro
log.Printf("[INFO] Using routing strategy %q", cfg.Proxy.Strategy)
log.Printf("[INFO] Using route matching %q", cfg.Proxy.Matcher)

newTransport := func(tlscfg *tls.Config) *http.Transport {
return &http.Transport{
ResponseHeaderTimeout: cfg.Proxy.ResponseHeaderTimeout,
IdleConnTimeout: cfg.Proxy.IdleConnTimeout,
MaxIdleConnsPerHost: cfg.Proxy.MaxConn,
Dial: (&net.Dialer{
Timeout: cfg.Proxy.DialTimeout,
KeepAlive: cfg.Proxy.KeepAliveTimeout,
}).Dial,
TLSClientConfig: tlscfg,
}
}

authSchemes, err := auth.LoadAuthSchemes(cfg.Proxy.AuthSchemes)

if err != nil {
Expand All @@ -229,8 +219,8 @@ func newHTTPProxy(cfg *config.Config, statsHandler *proxy.HttpStatsHandler) *pro

return &proxy.HTTPProxy{
Config: cfg.Proxy,
Transport: newTransport(nil),
InsecureTransport: newTransport(&tls.Config{InsecureSkipVerify: true}),
Transport: transport.NewTransport(nil),
InsecureTransport: transport.NewTransport(&tls.Config{InsecureSkipVerify: true}),
Lookup: func(r *http.Request) *route.Target {
t := route.GetTable().Lookup(r, r.Header.Get("trace"), pick, match, globCache, cfg.GlobMatchingDisabled)
if t == nil {
Expand Down
42 changes: 42 additions & 0 deletions proxy/http_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,48 @@ func TestProxyHTTPSUpstream(t *testing.T) {
}
}

type sniHandler struct {
sni string
}

func (s *sniHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
if request.TLS != nil {
s.sni = request.TLS.ServerName
}
writer.Write([]byte(`OK`))
}

func TestProxyHTTPSTransport(t *testing.T) {
sni := &sniHandler{}

server := httptest.NewUnstartedServer(sni)
server.TLS = tlsServerConfig()
server.StartTLS()
defer server.Close()

proxy := httptest.NewServer(&HTTPProxy{
Config: config.Proxy{},
Transport: &http.Transport{TLSClientConfig: tlsClientConfig()},
Lookup: func(r *http.Request) *route.Target {
tbl, _ := route.NewTable(bytes.NewBufferString("route add srv / " + server.URL + ` opts "proto=https host=foo.com tlsskipverify=true"`))
return tbl.Lookup(r, "", route.Picker["rr"], route.Matcher["prefix"], globCache, globEnabled)
},
})
defer proxy.Close()

resp, body := mustGet(proxy.URL)
if got, want := resp.StatusCode, http.StatusOK; got != want {
t.Fatalf("got status %d want %d", got, want)
}
if got, want := string(body), "OK"; got != want {
t.Fatalf("got body %q want %q", got, want)
}
if got, want := sni.sni, "foo.com"; got != want {
t.Fatalf("got sni %q want %q", got, want)
}

}

func TestProxyHTTPSUpstreamSkipVerify(t *testing.T) {
server := httptest.NewUnstartedServer(okHandler)
server.TLS = &tls.Config{}
Expand Down
6 changes: 4 additions & 2 deletions proxy/http_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,11 @@ func (p *HTTPProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
trace.InjectHeaders(span, r)

upgrade, accept := r.Header.Get("Upgrade"), r.Header.Get("Accept")

tr := p.Transport
if t.TLSSkipVerify {
if t.Transport != nil {
tr = t.Transport
} else if t.TLSSkipVerify {
tr = p.InsecureTransport
}

Expand Down
7 changes: 7 additions & 0 deletions route/route.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package route

import (
"crypto/tls"
"fmt"
"github.com/fabiolb/fabio/transport"
"log"
"net/url"
"reflect"
Expand Down Expand Up @@ -66,12 +68,17 @@ func (r *Route) addTarget(service string, targetURL *url.URL, fixedWeight float6

var err error
if opts != nil {

t.StripPath = opts["strip"]
t.PrependPath = opts["prepend"]
t.TLSSkipVerify = opts["tlsskipverify"] == "true"
t.Host = opts["host"]
t.ProxyProto = opts["pxyproto"] == "true"

if t.Host != "" && (t.URL.Scheme == "https" || opts["proto"] == "https") {
t.Transport = transport.NewTransport(&tls.Config{ServerName: t.Host, InsecureSkipVerify: t.TLSSkipVerify})
}

if opts["redirect"] != "" {
t.RedirectCode, err = strconv.Atoi(opts["redirect"])
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions route/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package route

import (
gkm "github.com/go-kit/kit/metrics"
"net/http"
"net/url"
"strings"
)
Expand Down Expand Up @@ -67,6 +68,9 @@ type Target struct {

// ProxyProto enables PROXY Protocol on upstream connection
ProxyProto bool

// Transport allows for different types of transports
Transport *http.Transport
}

func (t *Target) BuildRedirectURL(requestURL *url.URL) {
Expand Down
29 changes: 29 additions & 0 deletions transport/transport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package transport

import (
"crypto/tls"
"github.com/fabiolb/fabio/config"
"net"
"net/http"
)

var (
cfg *config.Config = &config.Config{}
)

func NewTransport(tlscfg *tls.Config) *http.Transport {
return &http.Transport{
ResponseHeaderTimeout: cfg.Proxy.ResponseHeaderTimeout,
IdleConnTimeout: cfg.Proxy.IdleConnTimeout,
MaxIdleConnsPerHost: cfg.Proxy.MaxConn,
Dial: (&net.Dialer{
Timeout: cfg.Proxy.DialTimeout,
KeepAlive: cfg.Proxy.KeepAliveTimeout,
}).Dial,
TLSClientConfig: tlscfg,
}
}

func SetConfig(cfg *config.Config) {
cfg = cfg
}

0 comments on commit e758455

Please sign in to comment.