Skip to content

Commit

Permalink
Upstream CA TLS Verification (louketo#260)
Browse files Browse the repository at this point in the history
- addresses the feature from louketo#256
- permits the user to load a root ca in order to verify the upstream endpoint
- updated the README and the CHANGELOG to reflect the changes
  • Loading branch information
gambol99 committed Aug 4, 2017
1 parent 983d58a commit 1741a5b
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ FEATURES
* updated the base image to apline 3.6 in commit [0fdebaf821](https://github.com/gambol99/keycloak-proxy/pull/236/commits/0fdebaf8215e9480896f01ec7ab2ef7caa242da1)
* moved to use zap for the logging [#PR237](https://github.com/gambol99/keycloak-proxy/pull/237)
* making the X-Auth-Token optional in the upstream headers via the --enable-token-header [#PR247](https://github.com/gambol99/keycloak-proxy/pull/247)
* adding the ability to load a CA authority to provide trust on upstream endpoint [#PR248](https://github.com/gambol99/keycloak-proxy/pull/248)

BREAKING CHANGES:
* the proxy no longer uses prefixes for resources, if you wish to use wildcard urls you need
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ USAGE:
keycloak-proxy [options]

VERSION:
v2.1.0-rc2 (git+sha: ffe2fc4, built: 21-07-2017)
v2.1.0-rc2 (git+sha: 6782490-dirty, built: 06-07-2017)

AUTHOR:
Rohith <gambol99@gmail.com>
Expand All @@ -54,6 +54,7 @@ GLOBAL OPTIONS:
--skip-openid-provider-tls-verify skip the verification of any TLS communication with the openid provider (default: false)
--scopes value list of scopes requested when authenticating the user
--upstream-url value url for the upstream endpoint you wish to proxy [$PROXY_UPSTREAM_URL]
--upstream-ca value the path to a file container a CA certificate to validate the upstream tls endpoint
--resources value list of resources 'uri=/admin|methods=GET,PUT|roles=role1,role2'
--headers value custom headers to the upstream request, key=value
--enable-token-header enables the token authentication header X-Auth-Token to upstream (default: true)
Expand Down
6 changes: 4 additions & 2 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ func (r *Config) isValid() error {
if r.TLSCaCertificate != "" && !fileExists(r.TLSCaCertificate) {
return fmt.Errorf("the tls ca certificate file %s does not exist", r.TLSCaCertificate)
}

if r.TLSClientCertificate != "" && !fileExists(r.TLSClientCertificate) {
return fmt.Errorf("the tls client certificate %s does not exist", r.TLSClientCertificate)
}

if r.UseLetsEncrypt && r.LetsEncryptCacheDir == "" {
return fmt.Errorf("the letsencrypt cache dir has not been set")
}
Expand Down Expand Up @@ -100,6 +98,10 @@ func (r *Config) isValid() error {
if _, err := url.Parse(r.Upstream); err != nil {
return fmt.Errorf("the upstream endpoint is invalid, %s", err)
}
if r.SkipUpstreamTLSVerify && r.UpstreamCA != "" {
return fmt.Errorf("you cannot skip upstream tls and load a root ca: %s to verify it", r.UpstreamCA)
}

// step: if the skip verification is off, we need the below
if !r.SkipTokenVerification {
if r.ClientID == "" {
Expand Down
2 changes: 2 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ type Config struct {
Scopes []string `json:"scopes" yaml:"scopes" usage:"list of scopes requested when authenticating the user"`
// Upstream is the upstream endpoint i.e whom were proxying to
Upstream string `json:"upstream-url" yaml:"upstream-url" usage:"url for the upstream endpoint you wish to proxy" env:"UPSTREAM_URL"`
// UpstreamCA is the path to a CA certificate in PEM format to validate the upstream certificate
UpstreamCA string `json:"upstream-ca" yaml:"upstream-ca" usage:"the path to a file container a CA certificate to validate the upstream tls endpoint"`
// Resources is a list of protected resources
Resources []*Resource `json:"resources" yaml:"resources" usage:"list of resources 'uri=/admin|methods=GET,PUT|roles=role1,role2'"`
// Headers permits adding customs headers across the board
Expand Down
14 changes: 14 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,20 @@ func (r *oauthProxy) createUpstreamProxy(upstream *url.URL) error {
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
}

{
// @check if we have a upstream ca to verify the upstream
if r.config.UpstreamCA != "" {
r.log.Info("loading the upstream ca", zap.String("path", r.config.UpstreamCA))
ca, err := ioutil.ReadFile(r.config.UpstreamCA)
if err != nil {
return err
}
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(ca)
tlsConfig.RootCAs = pool
}
}

// create the forwarding proxy
proxy := goproxy.NewProxyHttpServer()
proxy.Logger = httplog.New(ioutil.Discard, "", 0)
Expand Down

0 comments on commit 1741a5b

Please sign in to comment.