You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js搭建全域名HTTP/HTTPS代理 如何解决SSL证书安全警告问题

实现方案

核心思路

利用你已经导入浏览器信任的自签根CA,收到HTTPS请求时动态为当前访问域名签发对应证书,无需提前配置所有域名,也不用重启代理服务。

具体实现步骤

  • 第一步:安装依赖
    执行npm install node-forge安装纯JS实现的SSL证书处理库,无需依赖系统OpenSSL。
  • 第二步:复用你已经生成并导入浏览器信任的根CA证书和私钥,将其PEM格式内容保存在代理服务的配置文件中。
  • 第三步:实现动态证书生成逻辑,增加缓存机制避免重复生成,核心代码示例:
const forge = require('node-forge');
const certCache = new Map(); // 域名证书缓存,可持久化到本地磁盘

// 替换为你自己生成的根CA证书、私钥的PEM格式内容
const rootCaCert = forge.pki.certificateFromPem('ROOT_CA_CERT_PEM_CONTENT');
const rootCaKey = forge.pki.privateKeyFromPem('ROOT_CA_KEY_PEM_CONTENT');

function generateCertForDomain(domain) {
  if (certCache.has(domain)) return certCache.get(domain);
  
  // 生成服务端密钥对
  const keys = forge.pki.rsa.generateKeyPair(2048);
  const cert = forge.pki.createCertificate();
  
  cert.publicKey = keys.publicKey;
  cert.serialNumber = Date.now().toString();
  cert.validity.notBefore = new Date();
  cert.validity.notAfter = new Date();
  // 证书有效期设置为1年,可按需调整
  cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
  
  // 配置证书主体信息
  const attrs = [
    { name: 'commonName', value: domain },
    { name: 'organizationName', value: 'Local Proxy' }
  ];
  cert.setSubject(attrs);
  cert.setIssuer(rootCaCert.subject.attributes); // 用根CA信息作为颁发者
  
  // 核心配置:添加当前域名到subjectAltName字段
  cert.setExtensions([
    { name: 'basicConstraints', cA: false },
    { name: 'keyUsage', digitalSignature: true, keyEncipherment: true, dataEncipherment: true },
    { name: 'extKeyUsage', serverAuth: true },
    { 
      name: 'subjectAltName',
      altNames: [
        { type: 2, value: domain } // type=2代表DNS类型记录
      ]
    }
  ]);
  
  // 用根CA私钥签名证书
  cert.sign(rootCaKey, forge.md.sha256.create());
  
  const result = {
    key: forge.pki.privateKeyToPem(keys.privateKey),
    cert: forge.pki.certificateToPem(cert)
  };
  certCache.set(domain, result);
  return result;
}
  • 第四步:改造HTTPS服务逻辑,通过SNI回调动态返回对应域名的证书,直接复用你原有处理HTTP请求的Express逻辑即可:
const https = require('https');
const tls = require('tls');
// yourExpressApp替换为你原来处理HTTP请求的Express实例
const httpsServer = https.createServer({
  SNICallback: (domain, cb) => {
    const certInfo = generateCertForDomain(domain);
    cb(null, tls.createSecureContext({
      key: certInfo.key,
      cert: certInfo.cert
    }));
  }
}, yourExpressApp);

你原有CONNECT事件的处理逻辑不需要做太大调整,只要把请求转发到上面的HTTPS服务即可。

注意事项

  • 单域名证书生成耗时仅几毫秒,完全不会导致服务 downtime
  • 如果需要支持泛域名,可以在生成证书时给alt_names额外添加*.${domain}的DNS记录,一次生成即可支持该域名的所有子域名
  • 缓存可以持久化到本地磁盘,代理服务重启后不需要重新生成之前访问过的域名证书

内容的提问来源于stack exchange,提问作者3dprogramin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 11:45:01