mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
enable tls on lens proxy
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
51b21347da
commit
69a3f7435f
@ -204,6 +204,7 @@
|
||||
"react-router": "^5.2.0",
|
||||
"request": "^2.88.2",
|
||||
"request-promise-native": "^1.0.8",
|
||||
"selfsigned": "^1.10.8",
|
||||
"semver": "^7.3.2",
|
||||
"serializr": "^2.0.3",
|
||||
"shell-env": "^3.0.0",
|
||||
|
||||
@ -14,6 +14,7 @@ import { getFeatures, installFeature, uninstallFeature, upgradeFeature } from ".
|
||||
import request, { RequestPromiseOptions } from "request-promise-native"
|
||||
import { apiResources } from "../common/rbac";
|
||||
import logger from "./logger"
|
||||
import { getProxyCertificate } from "./lens-proxy-cert";
|
||||
|
||||
export enum ClusterStatus {
|
||||
AccessGranted = 2,
|
||||
@ -93,7 +94,7 @@ export class Cluster implements ClusterModel {
|
||||
try {
|
||||
this.contextHandler = new ContextHandler(this);
|
||||
this.kubeconfigManager = new KubeconfigManager(this, this.contextHandler, port);
|
||||
this.kubeProxyUrl = `http://localhost:${port}${apiKubePrefix}`;
|
||||
this.kubeProxyUrl = `https://localhost:${port}${apiKubePrefix}`;
|
||||
this.initialized = true;
|
||||
logger.info(`[CLUSTER]: "${this.contextName}" init success`, {
|
||||
id: this.id,
|
||||
@ -234,6 +235,7 @@ export class Cluster implements ClusterModel {
|
||||
return request(apiUrl, {
|
||||
json: true,
|
||||
timeout: 5000,
|
||||
strictSSL: false, // TODO: use proxy CA
|
||||
...options,
|
||||
headers: {
|
||||
Host: `${this.id}.${new URL(this.kubeProxyUrl).host}`, // required in ClusterManager.getClusterForRequest()
|
||||
|
||||
@ -18,6 +18,7 @@ import { userStore } from "../common/user-store";
|
||||
import { workspaceStore } from "../common/workspace-store";
|
||||
import { tracker } from "../common/tracker";
|
||||
import logger from "./logger"
|
||||
import { getProxyCertificate } from "./lens-proxy-cert";
|
||||
|
||||
const workingDir = path.join(app.getPath("appData"), appName);
|
||||
app.setName(appName);
|
||||
@ -73,6 +74,15 @@ async function main() {
|
||||
app.quit();
|
||||
}
|
||||
|
||||
const proxyCert = getProxyCertificate()
|
||||
app.on("certificate-error", (event: Electron.Event, webContents: Electron.WebContents, url: string, error: string, certificate: Electron.Certificate, callback: (isTrusted: boolean) => void) => {
|
||||
if (certificate.data.trim().replace(/(?:\r\n)/g, "\n") === proxyCert.cert.trim().replace(/(?:\r\n)/g, "\n")) {
|
||||
callback(true)
|
||||
} else {
|
||||
callback(false)
|
||||
}
|
||||
})
|
||||
|
||||
// create window manager and open app
|
||||
windowManager = new WindowManager(proxyPort);
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ export class KubeAuthProxy {
|
||||
return;
|
||||
}
|
||||
const proxyBin = await this.kubectl.getPath()
|
||||
logger.info(proxyBin)
|
||||
const args = [
|
||||
"proxy",
|
||||
"-p", `${this.port}`,
|
||||
|
||||
@ -6,6 +6,7 @@ import path from "path"
|
||||
import fs from "fs-extra"
|
||||
import { dumpConfigYaml, loadConfig } from "../common/kube-helpers"
|
||||
import logger from "./logger"
|
||||
import { getProxyCertificate } from "./lens-proxy-cert";
|
||||
|
||||
export class KubeconfigManager {
|
||||
protected configDir = app.getPath("temp")
|
||||
@ -29,7 +30,7 @@ export class KubeconfigManager {
|
||||
}
|
||||
|
||||
protected resolveProxyUrl() {
|
||||
return `http://127.0.0.1:${this.port}/${this.cluster.id}`
|
||||
return `https://127.0.0.1:${this.port}/${this.cluster.id}`
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,11 +48,11 @@ export class KubeconfigManager {
|
||||
{
|
||||
name: contextName,
|
||||
server: this.resolveProxyUrl(),
|
||||
skipTLSVerify: undefined,
|
||||
skipTLSVerify: true
|
||||
}
|
||||
],
|
||||
users: [
|
||||
{ name: "proxy" },
|
||||
{ name: "proxy", username: "lens", password: "lens" },
|
||||
],
|
||||
contexts: [
|
||||
{
|
||||
|
||||
27
src/main/lens-proxy-cert.ts
Normal file
27
src/main/lens-proxy-cert.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import * as path from "path"
|
||||
import * as fs from "fs"
|
||||
import * as selfsigned from "selfsigned"
|
||||
import logger from "./logger"
|
||||
|
||||
export type SelfSignedCert = {
|
||||
private: string;
|
||||
public: string;
|
||||
cert: string;
|
||||
}
|
||||
|
||||
let selfSignedCertificate: SelfSignedCert = null
|
||||
|
||||
export function getProxyCertificate(): SelfSignedCert {
|
||||
if (selfSignedCertificate == null) {
|
||||
const attrs = [{ name: "commonName", value: "localhost"}]
|
||||
selfSignedCertificate = selfsigned.generate(attrs, {
|
||||
keySize: 2048,
|
||||
algorithm: "sha256",
|
||||
days: 365,
|
||||
extensions: [{ name: 'basicConstraints', cA: true }]
|
||||
}) as SelfSignedCert
|
||||
console.log(selfSignedCertificate)
|
||||
}
|
||||
|
||||
return selfSignedCertificate
|
||||
}
|
||||
@ -10,6 +10,7 @@ import { Router } from "./router"
|
||||
import { ClusterManager } from "./cluster-manager"
|
||||
import { ContextHandler } from "./context-handler";
|
||||
import logger from "./logger"
|
||||
import { getProxyCertificate } from "./lens-proxy-cert";
|
||||
|
||||
export class LensProxy {
|
||||
protected origin: string
|
||||
@ -23,7 +24,7 @@ export class LensProxy {
|
||||
}
|
||||
|
||||
private constructor(protected port: number, protected clusterManager: ClusterManager) {
|
||||
this.origin = `http://localhost:${port}`
|
||||
this.origin = `https://localhost:${port}`
|
||||
this.router = new Router();
|
||||
}
|
||||
|
||||
@ -41,9 +42,12 @@ export class LensProxy {
|
||||
|
||||
protected buildCustomProxy(): http.Server {
|
||||
const proxy = this.createProxy();
|
||||
const proxyCert = getProxyCertificate()
|
||||
const spdyProxy = spdy.createServer({
|
||||
key: proxyCert.private,
|
||||
cert: proxyCert.cert,
|
||||
spdy: {
|
||||
plain: true,
|
||||
plain: false,
|
||||
protocols: ["http/1.1", "spdy/3.1"]
|
||||
}
|
||||
}, (req: http.IncomingMessage, res: http.ServerResponse) => {
|
||||
|
||||
@ -71,7 +71,7 @@ export class WindowManager {
|
||||
async showMain() {
|
||||
try {
|
||||
await this.showSplash();
|
||||
await this.mainView.loadURL(`http://localhost:${this.proxyPort}`)
|
||||
await this.mainView.loadURL(`https://localhost:${this.proxyPort}`)
|
||||
this.mainView.show();
|
||||
this.splashWindow.close();
|
||||
} catch (err) {
|
||||
|
||||
1
types/mocks.d.ts
vendored
1
types/mocks.d.ts
vendored
@ -3,6 +3,7 @@ declare module "mac-ca"
|
||||
declare module "win-ca"
|
||||
declare module "@hapi/call"
|
||||
declare module "@hapi/subtext"
|
||||
declare module "selfsigned"
|
||||
|
||||
// Global path to static assets
|
||||
declare const __static: string;
|
||||
|
||||
12
yarn.lock
12
yarn.lock
@ -8297,6 +8297,11 @@ node-abi@^2.11.0:
|
||||
dependencies:
|
||||
semver "^5.4.1"
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
|
||||
integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==
|
||||
|
||||
node-forge@^0.7.5:
|
||||
version "0.7.6"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
|
||||
@ -10321,6 +10326,13 @@ select-hose@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
|
||||
|
||||
selfsigned@^1.10.8:
|
||||
version "1.10.8"
|
||||
resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
|
||||
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
|
||||
dependencies:
|
||||
node-forge "^0.10.0"
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user