mirror of https://github.com/certd/certd
perf: google eab授权支持自动获取,不过要配置代理
parent
c5e58770d1
commit
592791d135
|
@ -14,9 +14,10 @@
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@certd/basic": "^1.25.9",
|
|
||||||
"@certd/acme-client": "^1.25.9",
|
"@certd/acme-client": "^1.25.9",
|
||||||
|
"@certd/basic": "^1.25.9",
|
||||||
"@certd/pipeline": "^1.25.9",
|
"@certd/pipeline": "^1.25.9",
|
||||||
|
"@google-cloud/publicca": "^1.3.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"node-forge": "^0.10.0",
|
"node-forge": "^0.10.0",
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
import { IsAccess, AccessInput, BaseAccess } from "@certd/pipeline";
|
||||||
|
|
||||||
|
@IsAccess({
|
||||||
|
name: "google",
|
||||||
|
title: "google cloud",
|
||||||
|
desc: "谷歌云授权",
|
||||||
|
})
|
||||||
|
export class GoogleAccess extends BaseAccess {
|
||||||
|
@AccessInput({
|
||||||
|
title: "密钥类型",
|
||||||
|
value: "serviceAccount",
|
||||||
|
component: {
|
||||||
|
placeholder: "密钥类型",
|
||||||
|
name: "a-select",
|
||||||
|
vModel: "value",
|
||||||
|
options: [
|
||||||
|
{ value: "serviceAccount", label: "服务账号密钥" },
|
||||||
|
{ value: "apiKey", label: "ApiKey,暂不可用", disabled: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
helper: "密钥类型",
|
||||||
|
required: true,
|
||||||
|
encrypt: false,
|
||||||
|
})
|
||||||
|
type = "";
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "项目ID",
|
||||||
|
component: {
|
||||||
|
placeholder: "ProjectId",
|
||||||
|
},
|
||||||
|
helper: "ProjectId",
|
||||||
|
required: true,
|
||||||
|
encrypt: false,
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show:ctx.compute(({form})=>{
|
||||||
|
return form.access.type === 'apiKey'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
projectId = "";
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "ApiKey",
|
||||||
|
component: {
|
||||||
|
placeholder: "ApiKey",
|
||||||
|
},
|
||||||
|
helper: "不要选,目前没有用",
|
||||||
|
required: true,
|
||||||
|
encrypt: true,
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show:ctx.compute(({form})=>{
|
||||||
|
return form.access.type === 'apiKey'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
apiKey = "";
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "服务账号密钥",
|
||||||
|
component: {
|
||||||
|
placeholder: "serviceAccountSecret",
|
||||||
|
name: "a-textarea",
|
||||||
|
vModel: "value",
|
||||||
|
rows: 4,
|
||||||
|
},
|
||||||
|
helper:
|
||||||
|
"[如何创建服务账号](https://cloud.google.com/iam/docs/service-accounts-create?hl=zh-CN) \n[获取密钥](https://console.cloud.google.com/iam-admin/serviceaccounts?hl=zh-cn),点击详情,点击创建密钥,将下载json文件,把内容填在此处",
|
||||||
|
required: true,
|
||||||
|
encrypt: true,
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show:ctx.compute(({form})=>{
|
||||||
|
return form.access.type === 'serviceAccount'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
serviceAccountSecret = "";
|
||||||
|
|
||||||
|
@AccessInput({
|
||||||
|
title: "https代理",
|
||||||
|
component: {
|
||||||
|
placeholder: "http://127.0.0.1:10811",
|
||||||
|
},
|
||||||
|
helper: "Google的请求需要走代理,如果不配置,则会使用环境变量中的全局HTTPS_PROXY配置\n或者服务器本身在海外,则不需要配置",
|
||||||
|
required: false,
|
||||||
|
encrypt: false,
|
||||||
|
})
|
||||||
|
httpsProxy = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
new GoogleAccess();
|
|
@ -1 +1,2 @@
|
||||||
export * from "./eab-access.js";
|
export * from "./eab-access.js";
|
||||||
|
export * from "./google-access.js";
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import { EabAccess, GoogleAccess } from "../access/index.js";
|
||||||
|
import { ILogger } from "@certd/basic";
|
||||||
|
|
||||||
|
export class GoogleClient {
|
||||||
|
access: GoogleAccess;
|
||||||
|
logger: ILogger;
|
||||||
|
constructor(opts: { logger: ILogger; access: GoogleAccess }) {
|
||||||
|
this.access = opts.access;
|
||||||
|
this.logger = opts.logger;
|
||||||
|
}
|
||||||
|
async getEab() {
|
||||||
|
// https://cloud.google.com/docs/authentication/api-keys-use#using-with-client-libs
|
||||||
|
const { v1 } = await import("@google-cloud/publicca");
|
||||||
|
// process.env.HTTPS_PROXY = "http://127.0.0.1:10811";
|
||||||
|
const access = this.access;
|
||||||
|
if (!access.serviceAccountSecret) {
|
||||||
|
throw new Error("服务账号密钥 不能为空");
|
||||||
|
}
|
||||||
|
const credentials = JSON.parse(access.serviceAccountSecret);
|
||||||
|
|
||||||
|
const client = new v1.PublicCertificateAuthorityServiceClient({ credentials });
|
||||||
|
const parent = `projects/${access.projectId}/locations/global`;
|
||||||
|
const externalAccountKey = {};
|
||||||
|
const request = {
|
||||||
|
parent,
|
||||||
|
externalAccountKey,
|
||||||
|
};
|
||||||
|
|
||||||
|
let envHttpsProxy = "";
|
||||||
|
try {
|
||||||
|
if (this.access.httpsProxy) {
|
||||||
|
//设置临时使用代理
|
||||||
|
envHttpsProxy = process.env.HTTPS_PROXY;
|
||||||
|
process.env.HTTPS_PROXY = this.access.httpsProxy;
|
||||||
|
}
|
||||||
|
this.logger.info("开始获取google eab授权");
|
||||||
|
const response = await client.createExternalAccountKey(request);
|
||||||
|
const { keyId, b64MacKey } = response[0];
|
||||||
|
const eabAccess = new EabAccess();
|
||||||
|
eabAccess.kid = keyId;
|
||||||
|
eabAccess.hmacKey = b64MacKey.toString();
|
||||||
|
this.logger.info(`google eab授权获取成功,kid: ${eabAccess.kid}`);
|
||||||
|
return eabAccess;
|
||||||
|
} finally {
|
||||||
|
if (envHttpsProxy) {
|
||||||
|
process.env.HTTPS_PROXY = envHttpsProxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const access = new GoogleAccess();
|
||||||
|
// access.projectId = "hip-light-432411-d4";
|
||||||
|
// access.serviceAccountSecret = `
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// `;
|
||||||
|
// // process.env.HTTPS_PROXY = "http://127.0.0.1:10811";
|
||||||
|
// const client = new GoogleClient(access);
|
||||||
|
// client.getEab().catch((e) => {
|
||||||
|
// console.error(e);
|
||||||
|
// });
|
|
@ -5,6 +5,7 @@ import _ from "lodash-es";
|
||||||
import { createDnsProvider, DnsProviderContext, IDnsProvider } from "../../dns-provider/index.js";
|
import { createDnsProvider, DnsProviderContext, IDnsProvider } from "../../dns-provider/index.js";
|
||||||
import { CertReader } from "./cert-reader.js";
|
import { CertReader } from "./cert-reader.js";
|
||||||
import { CertApplyBasePlugin } from "./base.js";
|
import { CertApplyBasePlugin } from "./base.js";
|
||||||
|
import { GoogleClient } from "../../libs/google.js";
|
||||||
|
|
||||||
export type { CertInfo };
|
export type { CertInfo };
|
||||||
export * from "./cert-reader.js";
|
export * from "./cert-reader.js";
|
||||||
|
@ -145,18 +146,56 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
||||||
},
|
},
|
||||||
maybeNeed: true,
|
maybeNeed: true,
|
||||||
required: true,
|
required: true,
|
||||||
helper:
|
helper: "需要提供EAB授权\nZeroSSL:请前往[zerossl开发者中心](https://app.zerossl.com/developer),生成 'EAB Credentials'",
|
||||||
"需要提供EAB授权\nZeroSSL:请前往[zerossl开发者中心](https://app.zerossl.com/developer),生成 'EAB Credentials' \n Google:请查看[google获取eab帮助文档](https://github.com/certd/certd/blob/v2/doc/google/google.md)",
|
|
||||||
mergeScript: `
|
mergeScript: `
|
||||||
return {
|
return {
|
||||||
show: ctx.compute(({form})=>{
|
show: ctx.compute(({form})=>{
|
||||||
return form.sslProvider === 'zerossl' || form.sslProvider === 'google'
|
return form.sslProvider === 'zerossl'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
})
|
})
|
||||||
eabAccessId!: number;
|
eabAccessId!: number;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: "GoogleEAB授权",
|
||||||
|
component: {
|
||||||
|
name: "access-selector",
|
||||||
|
type: "eab",
|
||||||
|
},
|
||||||
|
maybeNeed: true,
|
||||||
|
required: false,
|
||||||
|
helper:
|
||||||
|
"请查看[google获取eab帮助文档](https://github.com/certd/certd/blob/v2/doc/google/google.md)\n注意此方式获取的EAB授权是一次性的,下次申请需要重新获取授权\n推荐使用Google服务账号授权自动获取EAB",
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.sslProvider === 'google'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
googleEabAccessId!: number;
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: "Google服务账号授权",
|
||||||
|
component: {
|
||||||
|
name: "access-selector",
|
||||||
|
type: "google",
|
||||||
|
},
|
||||||
|
maybeNeed: true,
|
||||||
|
required: false,
|
||||||
|
helper: "google服务账号授权,需要配置代理或者服务器本身在海外\n代理配置方法:配置环境变量https_proxy",
|
||||||
|
mergeScript: `
|
||||||
|
return {
|
||||||
|
show: ctx.compute(({form})=>{
|
||||||
|
return form.sslProvider === 'google'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
googleAccessId!: number;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
title: "加密算法",
|
title: "加密算法",
|
||||||
value: "rsa_2048",
|
value: "rsa_2048",
|
||||||
|
@ -205,9 +244,30 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
||||||
|
|
||||||
async onInit() {
|
async onInit() {
|
||||||
let eab: any = null;
|
let eab: any = null;
|
||||||
if (this.eabAccessId) {
|
|
||||||
|
if (this.sslProvider === "google") {
|
||||||
|
if (this.googleAccessId) {
|
||||||
|
const googleAccess = await this.ctx.accessService.getById(this.googleAccessId);
|
||||||
|
const googleClient = new GoogleClient({
|
||||||
|
access: googleAccess,
|
||||||
|
logger: this.logger,
|
||||||
|
});
|
||||||
|
eab = await googleClient.getEab();
|
||||||
|
} else if (this.googleEabAccessId || this.eabAccessId) {
|
||||||
|
this.logger.warn("您正在使用google一次性EAB授权,下次申请证书需要重新获取");
|
||||||
|
eab = await this.ctx.accessService.getById(this.googleEabAccessId);
|
||||||
|
} else {
|
||||||
|
this.logger.error("google需要配置EAB授权或服务账号授权");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (this.sslProvider === "zerossl") {
|
||||||
|
if (this.eabAccessId) {
|
||||||
|
this.logger.error("zerossl需要EAB授权");
|
||||||
|
return;
|
||||||
|
}
|
||||||
eab = await this.ctx.accessService.getById(this.eabAccessId);
|
eab = await this.ctx.accessService.getById(this.eabAccessId);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.acme = new AcmeService({
|
this.acme = new AcmeService({
|
||||||
userContext: this.userContext,
|
userContext: this.userContext,
|
||||||
logger: this.logger,
|
logger: this.logger,
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre
|
||||||
return (
|
return (
|
||||||
<ul>
|
<ul>
|
||||||
<li>JS-ACME:使用简单方便,功能强大【推荐】</li>
|
<li>JS-ACME:使用简单方便,功能强大【推荐】</li>
|
||||||
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用【即将废弃】</li>
|
<li>Lego-ACME:基于Lego实现,支持海量DNS提供商,熟悉LEGO的用户可以使用</li>
|
||||||
</ul>
|
</ul>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue