From 36c680b7928e5e0df5d2871f6ad20c7cba93a3ee Mon Sep 17 00:00:00 2001 From: Phil Cameron Date: Fri, 1 Apr 2016 14:26:49 -0400 Subject: [PATCH] haproxy obfuscated internal IP in routing cookie The cookie currently returns the openshift internal pod IP address. This is a security issue as an attacker can develop a map of the pods in the cluster just by observing the returned cookie. This change returns a hash of the internal address and internal service name to obfuscate the internal information. The service name is configured when the service is created and is not visible to outside users. This in combination with the internal ip:port is hashed and presented in the cookie. addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1318796 --- images/router/haproxy/conf/haproxy-config.template | 4 ++-- pkg/router/template/plugin.go | 9 +++++++++ pkg/router/template/router_test.go | 10 ++++++---- pkg/router/template/types.go | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/images/router/haproxy/conf/haproxy-config.template b/images/router/haproxy/conf/haproxy-config.template index eb5b5657c34c..16e948042158 100644 --- a/images/router/haproxy/conf/haproxy-config.template +++ b/images/router/haproxy/conf/haproxy-config.template @@ -214,7 +214,7 @@ backend be_edge_http_{{$cfgIdx}} {{ end }} http-request set-header Forwarded for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)] {{ range $idx, $endpoint := endpointsForAlias $cfg $serviceUnit }} - server {{$endpoint.ID}} {{$endpoint.IP}}:{{$endpoint.Port}} check inter 5000ms cookie {{$endpoint.ID}} + server {{$endpoint.IdHash}} {{$endpoint.IP}}:{{$endpoint.Port}} check inter 5000ms cookie {{$endpoint.IdHash}} {{ end }} {{ end }} @@ -236,7 +236,7 @@ backend be_secure_{{$cfgIdx}} timeout check 5000ms cookie OPENSHIFT_REENCRYPT_{{$cfgIdx}}_SERVERID insert indirect nocache httponly secure {{ range $idx, $endpoint := endpointsForAlias $cfg $serviceUnit }} - server {{$endpoint.ID}} {{$endpoint.IP}}:{{$endpoint.Port}} ssl check inter 5000ms verify required ca-file {{ $workingDir }}/cacerts/{{$cfgIdx}}.pem cookie {{$endpoint.ID}} + server {{$endpoint.IdHash}} {{$endpoint.IP}}:{{$endpoint.Port}} ssl check inter 5000ms verify required ca-file {{ $workingDir }}/cacerts/{{$cfgIdx}}.pem cookie {{$endpoint.IdHash}} {{ end }} {{ end }} {{ end }}{{/* $serviceUnit.ServiceAliasConfigs*/}} diff --git a/pkg/router/template/plugin.go b/pkg/router/template/plugin.go index c4ec8207cd8e..a02cecef727f 100644 --- a/pkg/router/template/plugin.go +++ b/pkg/router/template/plugin.go @@ -1,6 +1,7 @@ package templaterouter import ( + "crypto/md5" "fmt" "os" "path/filepath" @@ -230,6 +231,14 @@ func createRouterEndpoints(endpoints *kapi.Endpoints, excludeUDP bool) []Endpoin } else { ep.TargetName = ep.IP } + + // IdHash contains an obfuscated internal IP address + // that is the value passed in the cookie. The IP address + // is made more difficult to extract by including other + // internal information in the hash. + s := ep.ID + ep.TargetName + ep.PortName + ep.IdHash = fmt.Sprintf("%x", md5.Sum([]byte(s))) + out = append(out, ep) } } diff --git a/pkg/router/template/router_test.go b/pkg/router/template/router_test.go index e5c30eadc370..9acd3876cfc8 100644 --- a/pkg/router/template/router_test.go +++ b/pkg/router/template/router_test.go @@ -1,6 +1,7 @@ package templaterouter import ( + "crypto/md5" "fmt" "testing" @@ -47,9 +48,10 @@ func TestAddEndpoints(t *testing.T) { } endpoint := Endpoint{ - ID: "ep1", - IP: "ip", - Port: "port", + ID: "ep1", + IP: "ip", + Port: "port", + IdHash: fmt.Sprintf("%x", md5.Sum([]byte("ep1ipport"))), } router.AddEndpoints(suKey, []Endpoint{endpoint}) @@ -63,7 +65,7 @@ func TestAddEndpoints(t *testing.T) { t.Errorf("Expected endpoint table to contain 1 entry") } else { actualEp := su.EndpointTable[0] - if endpoint.IP != actualEp.IP || endpoint.Port != actualEp.Port { + if endpoint.IP != actualEp.IP || endpoint.Port != actualEp.Port || endpoint.IdHash != actualEp.IdHash { t.Errorf("Expected endpoint %v did not match actual endpoint %v", endpoint, actualEp) } } diff --git a/pkg/router/template/types.go b/pkg/router/template/types.go index 2cfe4f297016..7cf8b4c43157 100644 --- a/pkg/router/template/types.go +++ b/pkg/router/template/types.go @@ -62,6 +62,7 @@ type Endpoint struct { Port string TargetName string PortName string + IdHash string } // certificateManager provides the ability to write certificates for a ServiceAliasConfig