1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

tls fixes & refactor

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
Jari Kolehmainen 2022-03-11 13:31:29 +02:00
parent 1976ce521b
commit 6c2741677d
7 changed files with 31 additions and 17 deletions

View File

@ -14,6 +14,7 @@ import logger from "../logger";
import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy"; import type { KubeAuthProxy } from "../kube-auth-proxy/kube-auth-proxy";
import path from "path"; import path from "path";
import { readFile } from "fs/promises"; import { readFile } from "fs/promises";
import type { CreateKubeAuthProxy } from "../kube-auth-proxy/create-kube-auth-proxy.injectable";
export interface PrometheusDetails { export interface PrometheusDetails {
prometheusPath: string; prometheusPath: string;
@ -28,7 +29,7 @@ interface PrometheusServicePreferences {
} }
interface Dependencies { interface Dependencies {
createKubeAuthProxy: (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy; createKubeAuthProxy: CreateKubeAuthProxy;
certPath: string; certPath: string;
} }
@ -121,7 +122,11 @@ export class ContextHandler {
await this.ensureServer(); await this.ensureServer();
const path = this.clusterUrl.path !== "/" ? this.clusterUrl.path : ""; const path = this.clusterUrl.path !== "/" ? this.clusterUrl.path : "";
return `http://127.0.0.1:${this.kubeAuthProxy.port}${this.kubeAuthProxy.apiPrefix}${path}`; return `https://127.0.0.1:${this.kubeAuthProxy.port}${this.kubeAuthProxy.apiPrefix}${path}`;
}
async resolveAuthProxyCa() {
return readFile(path.join(this.dependencies.certPath, "proxy.crt"));
} }
async getApiTarget(isLongRunningRequest = false): Promise<httpProxy.ServerOptions> { async getApiTarget(isLongRunningRequest = false): Promise<httpProxy.ServerOptions> {
@ -137,7 +142,9 @@ export class ContextHandler {
protected async newApiTarget(timeout: number): Promise<httpProxy.ServerOptions> { protected async newApiTarget(timeout: number): Promise<httpProxy.ServerOptions> {
await this.ensureServer(); await this.ensureServer();
const ca = (await readFile(path.join(this.dependencies.certPath, "proxy.crt"))).toString(); const caFileContents = await this.resolveAuthProxyCa();
const clusterPath = this.clusterUrl.path !== "/" ? this.clusterUrl.path : "";
const apiPrefix = `${this.kubeAuthProxy.apiPrefix}${clusterPath}`;
return { return {
//target: await this.resolveAuthProxyUrl(), //target: await this.resolveAuthProxyUrl(),
@ -145,7 +152,8 @@ export class ContextHandler {
protocol: "https:", protocol: "https:",
host: "127.0.0.1", host: "127.0.0.1",
port: this.kubeAuthProxy.port, port: this.kubeAuthProxy.port,
ca, path: apiPrefix,
ca: caFileContents.toString(),
}, },
changeOrigin: true, changeOrigin: true,
timeout, timeout,

View File

@ -39,7 +39,7 @@ import { WeblinkStore } from "../common/weblink-store";
import { SentryInit } from "../common/sentry"; import { SentryInit } from "../common/sentry";
import { ensureDir } from "fs-extra"; import { ensureDir } from "fs-extra";
import { initMenu } from "./menu/menu"; import { initMenu } from "./menu/menu";
import { kubeApiRequest } from "./proxy-functions"; import { kubeApiUpgradeRequest } from "./proxy-functions";
import { initTray } from "./tray/tray"; import { initTray } from "./tray/tray";
import { ShellSession } from "./shell-session/shell-session"; import { ShellSession } from "./shell-session/shell-session";
import { getDi } from "./getDi"; import { getDi } from "./getDi";
@ -231,7 +231,7 @@ app.on("ready", async () => {
const lensProxy = LensProxy.createInstance(router, httpProxy.createProxy(), { const lensProxy = LensProxy.createInstance(router, httpProxy.createProxy(), {
getClusterForRequest: (req) => ClusterManager.getInstance().getClusterForRequest(req), getClusterForRequest: (req) => ClusterManager.getInstance().getClusterForRequest(req),
kubeApiRequest, kubeApiUpgradeRequest,
shellApiRequest, shellApiRequest,
}); });

View File

@ -11,10 +11,12 @@ import { getBinaryName } from "../../common/vars";
import directoryForBundledBinariesInjectable from "../../common/app-paths/directory-for-bundled-binaries/directory-for-bundled-binaries.injectable"; import directoryForBundledBinariesInjectable from "../../common/app-paths/directory-for-bundled-binaries/directory-for-bundled-binaries.injectable";
import getKubeAuthProxyCertDirInjectable from "./kube-auth-proxy-cert.injectable"; import getKubeAuthProxyCertDirInjectable from "./kube-auth-proxy-cert.injectable";
export type CreateKubeAuthProxy = (cluster: Cluster, environmentVariables: NodeJS.ProcessEnv) => KubeAuthProxy;
const createKubeAuthProxyInjectable = getInjectable({ const createKubeAuthProxyInjectable = getInjectable({
id: "create-kube-auth-proxy", id: "create-kube-auth-proxy",
instantiate: (di) => { instantiate: (di): CreateKubeAuthProxy => {
const binaryName = getBinaryName("lens-k8s-proxy"); const binaryName = getBinaryName("lens-k8s-proxy");
const dependencies: KubeAuthProxyDependencies = { const dependencies: KubeAuthProxyDependencies = {
proxyBinPath: path.join(di.inject(directoryForBundledBinariesInjectable), binaryName), proxyBinPath: path.join(di.inject(directoryForBundledBinariesInjectable), binaryName),

View File

@ -44,7 +44,7 @@ export class KubeAuthProxy {
} }
const proxyBin = this.dependencies.proxyBinPath; const proxyBin = this.dependencies.proxyBinPath;
const certPath = await this.dependencies.proxyCertPath; const certPath = this.dependencies.proxyCertPath;
this.proxyProcess = this.dependencies.spawn(proxyBin, [], { this.proxyProcess = this.dependencies.spawn(proxyBin, [], {
env: { env: {

View File

@ -22,7 +22,7 @@ type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | null;
export interface LensProxyFunctions { export interface LensProxyFunctions {
getClusterForRequest: GetClusterForRequest; getClusterForRequest: GetClusterForRequest;
shellApiRequest: (args: ProxyApiRequestArgs) => void | Promise<void>; shellApiRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
kubeApiRequest: (args: ProxyApiRequestArgs) => void | Promise<void>; kubeApiUpgradeRequest: (args: ProxyApiRequestArgs) => void | Promise<void>;
} }
const watchParam = "watch"; const watchParam = "watch";
@ -61,7 +61,7 @@ export class LensProxy extends Singleton {
public port: number; public port: number;
constructor(protected router: Router, protected proxy: httpProxy, { shellApiRequest, kubeApiRequest, getClusterForRequest }: LensProxyFunctions) { constructor(protected router: Router, protected proxy: httpProxy, { shellApiRequest, kubeApiUpgradeRequest, getClusterForRequest }: LensProxyFunctions) {
super(); super();
this.configureProxy(proxy); this.configureProxy(proxy);
@ -88,7 +88,7 @@ export class LensProxy extends Singleton {
return socket.destroy(); return socket.destroy();
} }
const reqHandler = isInternal ? shellApiRequest : kubeApiRequest; const reqHandler = isInternal ? shellApiRequest : kubeApiUpgradeRequest;
(async () => reqHandler({ req, socket, head, cluster }))() (async () => reqHandler({ req, socket, head, cluster }))()
.catch(error => logger.error("[LENS-PROXY]: failed to handle proxy upgrade", error)); .catch(error => logger.error("[LENS-PROXY]: failed to handle proxy upgrade", error));

View File

@ -2,5 +2,5 @@
* Copyright (c) OpenLens Authors. All rights reserved. * Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information. * Licensed under MIT License. See LICENSE in root directory for more information.
*/ */
export * from "./kube-api-request"; export * from "./kube-api-upgrade-request";
export * from "./types"; export * from "./types";

View File

@ -4,21 +4,25 @@
*/ */
import { chunk } from "lodash"; import { chunk } from "lodash";
import net from "net"; import tls from "tls";
import url from "url"; import url from "url";
import { apiKubePrefix } from "../../common/vars"; import { apiKubePrefix } from "../../common/vars";
import type { ProxyApiRequestArgs } from "./types"; import type { ProxyApiRequestArgs } from "./types";
const skipRawHeaders = new Set(["Host", "Authorization"]); const skipRawHeaders = new Set(["Host", "Authorization"]);
export async function kubeApiRequest({ req, socket, head, cluster }: ProxyApiRequestArgs) { export async function kubeApiUpgradeRequest({ req, socket, head, cluster }: ProxyApiRequestArgs) {
const proxyUrl = await cluster.contextHandler.resolveAuthProxyUrl() + req.url.replace(apiKubePrefix, ""); const proxyUrl = await cluster.contextHandler.resolveAuthProxyUrl() + req.url.replace(apiKubePrefix, "");
const proxyCa = await cluster.contextHandler.resolveAuthProxyCa();
const apiUrl = url.parse(cluster.apiUrl); const apiUrl = url.parse(cluster.apiUrl);
const pUrl = url.parse(proxyUrl); const pUrl = url.parse(proxyUrl);
const connectOpts = { port: parseInt(pUrl.port), host: pUrl.hostname }; const connectOpts = {
const proxySocket = new net.Socket(); port: parseInt(pUrl.port),
host: pUrl.hostname,
ca: proxyCa,
};
proxySocket.connect(connectOpts, () => { const proxySocket = tls.connect(connectOpts, () => {
proxySocket.write(`${req.method} ${pUrl.path} HTTP/1.1\r\n`); proxySocket.write(`${req.method} ${pUrl.path} HTTP/1.1\r\n`);
proxySocket.write(`Host: ${apiUrl.host}\r\n`); proxySocket.write(`Host: ${apiUrl.host}\r\n`);