Skip to content

Commit 88650bd

Browse files
Merge pull request #83 from enj/enj/i/request_header_route
Move to a passthrough route to support mTLS
2 parents 64836d4 + 931d508 commit 88650bd

File tree

5 files changed

+59
-12
lines changed

5 files changed

+59
-12
lines changed

pkg/operator2/deployment.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func (c *authOperator) getGeneration() int64 {
2828
func defaultDeployment(
2929
operatorConfig *operatorv1.Authentication,
3030
syncData *configSyncData,
31+
routerSecret *corev1.Secret,
3132
resourceVersions ...string,
3233
) *appsv1.Deployment {
3334
replicas := int32(1) // TODO configurable?
@@ -63,6 +64,12 @@ func defaultDeployment(
6364
path: serviceCAMount,
6465
keys: []string{serviceCAKey},
6566
},
67+
{
68+
name: routerCertsLocalName,
69+
configmap: false,
70+
path: routerCertsLocalMount,
71+
keys: sets.StringKeySet(routerSecret.Data).List(),
72+
},
6673
} {
6774
v, m := data.split()
6875
volumes = append(volumes, v)

pkg/operator2/oauth.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
func (c *authOperator) handleOAuthConfig(
2121
operatorConfig *operatorv1.Authentication,
2222
route *routev1.Route,
23+
routerSecret *corev1.Secret,
2324
service *corev1.Service,
2425
consoleConfig *configv1.Console,
2526
infrastructureConfig *configv1.Infrastructure,
@@ -86,13 +87,14 @@ func (c *authOperator) handleOAuthConfig(
8687
ServingInfo: configv1.ServingInfo{
8788
BindAddress: fmt.Sprintf("0.0.0.0:%d", containerPort),
8889
BindNetwork: "tcp4",
89-
// we have valid serving certs provided by service-ca so that we can use reencrypt routes
90+
// we have valid serving certs provided by service-ca
91+
// this is our main server cert which is used if SNI does not match
9092
CertInfo: configv1.CertInfo{
9193
CertFile: servingCertPathCert,
9294
KeyFile: servingCertPathKey,
9395
},
9496
ClientCA: "", // I think this can be left unset
95-
NamedCertificates: nil,
97+
NamedCertificates: routerSecretToSNI(routerSecret),
9698
MinTLSVersion: crypto.TLSVersionToNameOrDie(crypto.DefaultTLSVersion()),
9799
CipherSuites: crypto.CipherSuitesToNamesOrDie(crypto.DefaultCiphers()),
98100
},

pkg/operator2/operator.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ const (
6969

7070
oauthMetadataName = systemConfigPrefix + "metadata"
7171

72+
routerCertsSharedName = "router-certs"
73+
routerCertsLocalName = systemConfigPrefix + routerCertsSharedName
74+
routerCertsLocalMount = systemConfigPathSecrets + "/" + routerCertsLocalName
75+
7276
userConfigPath = "/var/config/user"
7377

7478
servicePort = 443
@@ -185,11 +189,11 @@ func (c *authOperator) handleSync(operatorConfig *operatorv1.Authentication) err
185189
// BLOCK 1: Metadata
186190
// ==================================
187191

188-
route, err := c.handleRoute()
192+
route, routerSecret, err := c.handleRoute()
189193
if err != nil {
190194
return err
191195
}
192-
resourceVersions = append(resourceVersions, route.GetResourceVersion())
196+
resourceVersions = append(resourceVersions, route.GetResourceVersion(), routerSecret.GetResourceVersion())
193197

194198
// make sure API server sees our metadata as soon as we've got a route with a host
195199
metadata, _, err := resourceapply.ApplyConfigMap(c.configMaps, c.recorder, getMetadataConfigMap(route))
@@ -241,7 +245,7 @@ func (c *authOperator) handleSync(operatorConfig *operatorv1.Authentication) err
241245
infrastructureConfig := c.handleInfrastructureConfig()
242246
resourceVersions = append(resourceVersions, infrastructureConfig.GetResourceVersion())
243247

244-
oauthConfig, expectedCLIconfig, syncData, err := c.handleOAuthConfig(operatorConfig, route, service, consoleConfig, infrastructureConfig)
248+
oauthConfig, expectedCLIconfig, syncData, err := c.handleOAuthConfig(operatorConfig, route, routerSecret, service, consoleConfig, infrastructureConfig)
245249
if err != nil {
246250
return err
247251
}
@@ -274,6 +278,7 @@ func (c *authOperator) handleSync(operatorConfig *operatorv1.Authentication) err
274278
expectedDeployment := defaultDeployment(
275279
operatorConfig,
276280
syncData,
281+
routerSecret,
277282
resourceVersions...,
278283
)
279284
// TODO add support for spec.operandSpecs.unsupportedResourcePatches, like:

pkg/operator2/route.go

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@ import (
55

66
"github.com/golang/glog"
77

8+
corev1 "k8s.io/api/core/v1"
89
"k8s.io/apimachinery/pkg/api/errors"
910
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1011
"k8s.io/apimachinery/pkg/util/intstr"
1112

13+
configv1 "github.com/openshift/api/config/v1"
1214
routev1 "github.com/openshift/api/route/v1"
1315
)
1416

15-
func (c *authOperator) handleRoute() (*routev1.Route, error) {
17+
func (c *authOperator) handleRoute() (*routev1.Route, *corev1.Secret, error) {
1618
route, err := c.route.Get(targetName, metav1.GetOptions{})
1719
if errors.IsNotFound(err) {
1820
route, err = c.route.Create(defaultRoute())
1921
}
2022
if err != nil {
21-
return nil, err
23+
return nil, nil, err
2224
}
2325

2426
if len(route.Spec.Host) == 0 {
25-
return nil, fmt.Errorf("route has no host: %#v", route)
27+
return nil, nil, fmt.Errorf("route has no host: %#v", route)
2628
}
2729

2830
if err := isValidRoute(route); err != nil {
@@ -32,14 +34,23 @@ func (c *authOperator) handleRoute() (*routev1.Route, error) {
3234
if err := c.route.Delete(route.Name, opts); err != nil && !errors.IsNotFound(err) {
3335
glog.Infof("failed to delete invalid route: %v", err)
3436
}
35-
return nil, err
37+
return nil, nil, err
3638
}
3739

38-
return route, nil
40+
routerSecret, err := c.secrets.Secrets(targetName).Get(routerCertsLocalName, metav1.GetOptions{})
41+
if err != nil {
42+
return nil, nil, err
43+
}
44+
if len(routerSecret.Data) == 0 {
45+
return nil, nil, fmt.Errorf("router secret is empty: %#v", routerSecret)
46+
}
47+
48+
return route, routerSecret, nil
3949
}
4050

4151
func isValidRoute(route *routev1.Route) error {
4252
// TODO: return all errors at once
53+
// TODO error when fields that should be empty are set
4354

4455
// get the expected settings from the default route
4556
expectedRoute := defaultRoute()
@@ -64,7 +75,7 @@ func isValidRoute(route *routev1.Route) error {
6475
return fmt.Errorf("route contains wrong TLS termination - '%s' is required: %#v", expTLSTermination, route)
6576
}
6677

67-
if route.Spec.TLS.InsecureEdgeTerminationPolicy != routev1.InsecureEdgeTerminationPolicyRedirect {
78+
if route.Spec.TLS.InsecureEdgeTerminationPolicy != expInsecureEdgeTerminationPolicy {
6879
return fmt.Errorf("route contains wrong insecure termination policy - '%s' is required: %#v", expInsecureEdgeTerminationPolicy, route)
6980
}
7081

@@ -83,9 +94,23 @@ func defaultRoute() *routev1.Route {
8394
TargetPort: intstr.FromInt(containerPort),
8495
},
8596
TLS: &routev1.TLSConfig{
86-
Termination: routev1.TLSTerminationReencrypt,
97+
Termination: routev1.TLSTerminationPassthrough,
8798
InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
8899
},
89100
},
90101
}
91102
}
103+
104+
func routerSecretToSNI(routerSecret *corev1.Secret) []configv1.NamedCertificate {
105+
var out []configv1.NamedCertificate
106+
for key := range routerSecret.Data {
107+
out = append(out, configv1.NamedCertificate{
108+
Names: []string{"*." + key}, // ingress domain is always a wildcard
109+
CertInfo: configv1.CertInfo{ // the cert and key are appended together
110+
CertFile: routerCertsLocalMount + "/" + key,
111+
KeyFile: routerCertsLocalMount + "/" + key,
112+
},
113+
})
114+
}
115+
return out
116+
}

pkg/operator2/starter.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ func RunOperator(ctx *controllercmd.ControllerContext) error {
140140
return err
141141
}
142142

143+
// add syncing for router certs for all cluster ingresses
144+
if err := resourceSyncer.SyncSecret(
145+
resourcesynccontroller.ResourceLocation{Namespace: targetName, Name: routerCertsLocalName},
146+
resourcesynccontroller.ResourceLocation{Namespace: machineConfigNamespace, Name: routerCertsSharedName},
147+
); err != nil {
148+
return err
149+
}
150+
143151
operator := NewAuthenticationOperator(
144152
*operatorClient,
145153
kubeInformersNamespaced,

0 commit comments

Comments
 (0)