fix(mitm): generate root ca on server startup (#2228)
Direct MITM server startup read rootCA.key/.crt immediately and exited when either was missing, bypassing the manager.js CA setup path. - generate Root CA from server.js when key/cert is missing - make generateRootCA()/generateCert() synchronous to avoid a startup race before readFileSync - add unit test covering synchronous Root CA creation Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
parent
0b3c794075
commit
182c849979
@@ -7,8 +7,8 @@ const { generateRootCA, loadRootCA, generateLeafCert } = require("./rootCA");
|
||||
* Generate Root CA certificate (one-time setup)
|
||||
* This replaces the old static wildcard cert approach
|
||||
*/
|
||||
async function generateCert() {
|
||||
return await generateRootCA();
|
||||
function generateCert() {
|
||||
return generateRootCA();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,7 @@ function isCertExpired(certPath) {
|
||||
* Generate Root CA certificate (only once, auto-regenerate if expired)
|
||||
* This Root CA will sign all dynamic leaf certificates
|
||||
*/
|
||||
async function generateRootCA() {
|
||||
function generateRootCA() {
|
||||
const exists = fs.existsSync(ROOT_CA_KEY_PATH) && fs.existsSync(ROOT_CA_CERT_PATH);
|
||||
if (exists && !isCertExpired(ROOT_CA_CERT_PATH)) {
|
||||
console.log("✅ Root CA already exists");
|
||||
|
||||
@@ -9,7 +9,7 @@ const { execSync } = require("child_process");
|
||||
const { log, err, dumpRequest, createResponseDumper, clearDumpDir } = require("./logger");
|
||||
const { IS_DEV, LSOF_BIN, TARGET_HOSTS, URL_PATTERNS, MODEL_SYNONYMS, MODEL_PATTERNS, MODEL_NO_MAP, getToolForHost } = require("./config");
|
||||
const { DATA_DIR, MITM_DIR } = require("./paths");
|
||||
const { getCertForDomain } = require("./cert/generate");
|
||||
const { generateCert, getCertForDomain } = require("./cert/generate");
|
||||
const { getMitmAlias } = require("./dbReader");
|
||||
const { applyAntigravityIdeVersionOverride } = require("./antigravityIdeVersion");
|
||||
const LOCAL_PORT = 443;
|
||||
@@ -57,6 +57,11 @@ function sniCallback(servername, cb) {
|
||||
|
||||
let sslOptions;
|
||||
try {
|
||||
if (!fs.existsSync(path.join(MITM_DIR, "rootCA.key")) || !fs.existsSync(path.join(MITM_DIR, "rootCA.crt"))) {
|
||||
log("Root CA missing, generating...");
|
||||
generateCert();
|
||||
}
|
||||
|
||||
const rootKey = fs.readFileSync(path.join(MITM_DIR, "rootCA.key"));
|
||||
const rootCert = fs.readFileSync(path.join(MITM_DIR, "rootCA.crt"));
|
||||
rootCAPem = rootCert.toString("utf8");
|
||||
|
||||
35
tests/unit/mitm-root-ca.test.js
Normal file
35
tests/unit/mitm-root-ca.test.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createRequire } from "module";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
|
||||
function loadRootCAWithDataDir(dataDir) {
|
||||
const rootCAPath = require.resolve("../../src/mitm/cert/rootCA.js");
|
||||
const pathsPath = require.resolve("../../src/mitm/paths.js");
|
||||
delete require.cache[rootCAPath];
|
||||
delete require.cache[pathsPath];
|
||||
|
||||
const oldDataDir = process.env.DATA_DIR;
|
||||
process.env.DATA_DIR = dataDir;
|
||||
try {
|
||||
return require("../../src/mitm/cert/rootCA.js");
|
||||
} finally {
|
||||
if (oldDataDir === undefined) delete process.env.DATA_DIR;
|
||||
else process.env.DATA_DIR = oldDataDir;
|
||||
}
|
||||
}
|
||||
|
||||
describe("MITM Root CA generation", () => {
|
||||
it("creates Root CA files synchronously for direct server startup", () => {
|
||||
const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "9router-mitm-ca-"));
|
||||
const { generateRootCA } = loadRootCAWithDataDir(dataDir);
|
||||
|
||||
generateRootCA();
|
||||
|
||||
expect(fs.existsSync(path.join(dataDir, "mitm", "rootCA.key"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(dataDir, "mitm", "rootCA.crt"))).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user