diff --git a/.changeset/good-rabbits-exist.md b/.changeset/good-rabbits-exist.md new file mode 100644 index 0000000000..df38293783 --- /dev/null +++ b/.changeset/good-rabbits-exist.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +--- + +Fixed bug in KubernetesProxy where Host header was not propagated, leading to certificate issues diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts index 97a0daa074..4ed1c8a7ae 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.test.ts @@ -155,6 +155,44 @@ describe('KubernetesProxy', () => { expect(response.body).toStrictEqual(apiResponse); }); + it('sets host header to support clusters behind name-based virtual hosts', async () => { + worker.use( + rest.get( + 'http://localhost:9999/api/v1/namespaces', + (req: any, res: any, ctx: any) => { + const host = req.headers.get('Host'); + return host === 'localhost:9999' + ? res(ctx.status(200)) + : res.networkError(`Host '${host}' is not in the cert's altnames`); + }, + ), + ); + permissionApi.authorize.mockResolvedValue([ + { result: AuthorizeResult.ALLOW }, + ]); + clusterSupplier.getClusters.mockResolvedValue([ + { + name: 'cluster1', + url: 'http://localhost:9999', + authProvider: '', + }, + ]); + authTranslator.decorateClusterDetailsWithAuth.mockImplementation( + async x => x, + ); + const app = express().use( + Router().use('/mountpath', proxy.createRequestHandler({ permissionApi })), + ); + + const requestPromise = request(app) + .get('/mountpath/api/v1/namespaces') + .set(HEADER_KUBERNETES_CLUSTER, 'cluster1'); + worker.use(rest.all(requestPromise.url, (req: any) => req.passthrough())); + const response = await requestPromise; + + expect(response.status).toEqual(200); + }); + it('should default to using a authTranslator provided serviceAccountToken as authorization headers to kubeapi when backstage-kubernetes-auth field is not provided', async () => { worker.use( rest.get( diff --git a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts index 1a705feb84..b4ca87d6f0 100644 --- a/plugins/kubernetes-backend/src/service/KubernetesProxy.ts +++ b/plugins/kubernetes-backend/src/service/KubernetesProxy.ts @@ -137,6 +137,7 @@ export class KubernetesProxy { middleware = createProxyMiddleware({ logProvider: () => logger, secure: !originalCluster.skipTLSVerify, + changeOrigin: true, router: async req => { // Re-evaluate the cluster on each request, in case it has changed const cluster = await this.getClusterForRequest(req);