Skip to content

Commit

Permalink
removed authorization header rename
Browse files Browse the repository at this point in the history
- since https://issuetracker.google.com/issues/207477241 was resolved it is no longer needed
- using fork of goproxy to avoid proxy-authorization header from being removed
- added cache for the MITM generated certificate
  • Loading branch information
mvanholsteijn committed Dec 28, 2021
1 parent c571388 commit f2b54da
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 95 deletions.
2 changes: 2 additions & 0 deletions cmd/generate_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ import (
"github.com/spf13/cobra"
)

// GeneratedCertificate command
type GenerateCertificate struct {
RootCommand
DNSName string
}

// NewGenerateCertificateCmd creates a generate certificate commmand
func NewGenerateCertificateCmd() *cobra.Command {
c := GenerateCertificate{
RootCommand: RootCommand{
Expand Down
1 change: 1 addition & 0 deletions gkeclient/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/spf13/cobra"
)

// NewGKEClientCmd create a gke client command
func NewGKEClientCmd() *cobra.Command {
c := Proxy{
RootCommand: cmd.RootCommand{
Expand Down
43 changes: 34 additions & 9 deletions gkeclient/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,37 @@ func (p *Proxy) IsClusterEndpoint() goproxy.ReqConditionFunc {
}
}

// removeProxyHeaders before setting our own, copied from goproxy source as we need to set our own proxy-header
func removeProxyHeaders(ctx *goproxy.ProxyCtx, r *http.Request) {
r.RequestURI = "" // this must be reset when serving a request with the client
ctx.Logf("Sending request %v %v", r.Method, r.URL.String())
// If no Accept-Encoding header exists, Transport will add the headers it can accept
// and would wrap the response body with the relevant reader.
r.Header.Del("Accept-Encoding")
// curl can add that, see
// https://jdebp.eu./FGA/web-proxy-connection-header.html
r.Header.Del("Proxy-Connection")
r.Header.Del("Proxy-Authenticate")
r.Header.Del("Proxy-Authorization")
// Connection, Authenticate and Authorization are single hop Header:
// http://www.w3.org/Protocols/rfc2616/rfc2616.txt
// 14.10 Connection
// The Connection general-header field allows the sender to specify
// options that are desired for that particular connection and MUST NOT
// be communicated by proxies over further connections.

// When server reads http request it sets req.Close to true if
// "Connection" header contains "close".
// https://github.com/golang/go/blob/master/src/net/http/request.go#L1080
// Later, transfer.go adds "Connection: close" back when req.Close is true
// https://github.com/golang/go/blob/master/src/net/http/transfer.go#L275
// That's why tests that checks "Connection: close" removal fail
if r.Header.Get("Connection") == "close" {
r.Close = false
}
r.Header.Del("Connection")
}

// OnRequest inserts the IAP required token and renames an existing Authorization header
func (p *Proxy) OnRequest(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request, *http.Response) {
log.Printf("on request to %s", r.URL)
Expand All @@ -143,16 +174,9 @@ func (p *Proxy) OnRequest(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request
fmt.Sprintf("failed to obtain IAP token, %s", err))
}

// If there is a Authorization header, make it X-Real-Authorization header
if authHeaders := r.Header.Values("Authorization"); len(authHeaders) > 0 {
for _, v := range r.Header.Values("Authorization") {
r.Header.Add("X-Real-Authorization", v)
}
r.Header.Del("Authorization")
}

removeProxyHeaders(ctx, r)
authorization := fmt.Sprintf("%s %s", token.Type(), token.AccessToken)
r.Header.Set("Authorization", authorization)
r.Header.Set("Proxy-Authorization", authorization)
RewriteRequestURL(r, p.targetURL)

return r, nil
Expand All @@ -161,6 +185,7 @@ func (p *Proxy) OnRequest(r *http.Request, ctx *goproxy.ProxyCtx) (*http.Request
func (p *Proxy) createProxy() *goproxy.ProxyHttpServer {
proxy := goproxy.NewProxyHttpServer()
proxy.Verbose = p.Debug
proxy.KeepHeader = true
proxy.OnRequest(p.IsClusterEndpoint()).HandleConnect(goproxy.AlwaysMitm)
proxy.OnRequest(p.IsClusterEndpoint()).DoFunc(p.OnRequest)

Expand Down
1 change: 1 addition & 0 deletions gkeserver/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/spf13/cobra"
)

// NewGKEServerCmd create a gke server command
func NewGKEServerCmd() *cobra.Command {
c := ReverseProxy{
RootCommand: cmd.RootCommand{
Expand Down
8 changes: 0 additions & 8 deletions gkeserver/reverseproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,6 @@ func (p *ReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
},
}

// If there is a X-Real-Authorization header, make it Authorization header
if realAuthHeaders := r.Header.Values("X-Real-Authorization"); len(realAuthHeaders) > 0 {
r.Header.Del("Authorization")
for _, v := range r.Header.Values("X-Real-Authorization") {
r.Header.Add("Authorization", v)
}
}

proxy.ServeHTTP(w, r)
}

Expand Down
22 changes: 5 additions & 17 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,28 @@ module github.com/binxio/simple-iap-proxy
go 1.17

require (
github.com/binxio/gcloudconfig v0.1.5
github.com/elazarl/goproxy v0.0.0-00010101000000-000000000000
github.com/spf13/cobra v1.2.1
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
google.golang.org/api v0.60.0
)

require (
cloud.google.com/go v0.97.0 // indirect
github.com/binxio/gcloudconfig v0.1.5 // indirect
github.com/elazarl/goproxy v0.0.0-20211114080932-d06c3be7c11b // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.2 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/cobra v1.2.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.9.0 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.8 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c // indirect
google.golang.org/grpc v1.40.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

replace github.com/elazarl/goproxy => github.com/mvanholsteijn/goproxy v0.0.0-20211228151242-0a646221af82
Loading

0 comments on commit f2b54da

Please sign in to comment.