mirror of https://github.com/certd/certd
perf: 优化证书申请成功率
parent
453f1baa0b
commit
968c4690a0
|
@ -137,7 +137,12 @@ module.exports = async (client, userOpts) => {
|
|||
}
|
||||
else {
|
||||
log(`[auto] [${d}] Running challenge verification`);
|
||||
await client.verifyChallenge(authz, challenge);
|
||||
try {
|
||||
await client.verifyChallenge(authz, challenge);
|
||||
}
|
||||
catch (e) {
|
||||
log(`[auto] [${d}] challenge verification threw error: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/* Complete challenge and wait for valid status */
|
||||
|
@ -170,11 +175,41 @@ module.exports = async (client, userOpts) => {
|
|||
throw e;
|
||||
}
|
||||
};
|
||||
const domainSets = [];
|
||||
|
||||
const challengePromises = authorizations.map((authz) => async () => {
|
||||
await challengeFunc(authz);
|
||||
authorizations.forEach((authz) => {
|
||||
const d = authz.identifier.value;
|
||||
let setd = false;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const group of domainSets) {
|
||||
if (!group[d]) {
|
||||
group[d] = authz;
|
||||
setd = true;
|
||||
}
|
||||
}
|
||||
if (!setd) {
|
||||
const group = {};
|
||||
group[d] = authz;
|
||||
domainSets.push(group);
|
||||
}
|
||||
});
|
||||
|
||||
const allChallengePromises = [];
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const domainSet of domainSets) {
|
||||
const challengePromises = [];
|
||||
// eslint-disable-next-line guard-for-in,no-restricted-syntax
|
||||
for (const domain in domainSet) {
|
||||
const authz = domainSet[domain];
|
||||
challengePromises.push(async () => {
|
||||
log(`[auto] [${domain}] Starting challenge`);
|
||||
await challengeFunc(authz);
|
||||
});
|
||||
}
|
||||
allChallengePromises.push(challengePromises);
|
||||
}
|
||||
|
||||
log(`[auto] challengeGroups:${allChallengePromises.length}`);
|
||||
function runAllPromise(tasks) {
|
||||
let promise = Promise.resolve();
|
||||
tasks.forEach((task) => {
|
||||
|
@ -195,9 +230,15 @@ module.exports = async (client, userOpts) => {
|
|||
}
|
||||
|
||||
try {
|
||||
log('开始challenge');
|
||||
await runPromisePa(challengePromises);
|
||||
|
||||
log(`开始challenge,共${allChallengePromises.length}组`);
|
||||
let i = 0;
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const challengePromises of allChallengePromises) {
|
||||
i += 1;
|
||||
log(`开始第${i}组`);
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await runPromisePa(challengePromises);
|
||||
}
|
||||
log('challenge结束');
|
||||
|
||||
// log('[auto] Waiting for challenge valid status');
|
||||
|
|
|
@ -55,7 +55,7 @@ class HttpClient {
|
|||
*/
|
||||
|
||||
async request(url, method, opts = {}) {
|
||||
if (this.urlMapping && this.urlMapping.enabled === true && this.urlMapping.mappings) {
|
||||
if (this.urlMapping && this.urlMapping.mappings) {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const key in this.urlMapping.mappings) {
|
||||
if (url.includes(key)) {
|
||||
|
|
|
@ -72,7 +72,7 @@ async function spawn(opts: SpawnOption): Promise<string> {
|
|||
let stderr = "";
|
||||
return safePromise((resolve, reject) => {
|
||||
const ls = childProcess.spawn(cmd, {
|
||||
shell: process.platform == "win32",
|
||||
shell: true,
|
||||
env: {
|
||||
...process.env,
|
||||
...opts.env,
|
||||
|
|
|
@ -13,7 +13,7 @@ export type CertInfo = {
|
|||
key: string;
|
||||
csr: string;
|
||||
};
|
||||
export type SSLProvider = "letsencrypt" | "buypass" | "zerossl";
|
||||
export type SSLProvider = "letsencrypt" | "google" | "zerossl";
|
||||
type AcmeServiceOptions = {
|
||||
userContext: IContext;
|
||||
logger: Logger;
|
||||
|
@ -42,10 +42,18 @@ export class AcmeService {
|
|||
});
|
||||
}
|
||||
|
||||
async getAccountConfig(email: string): Promise<any> {
|
||||
async getAccountConfig(email: string, urlMapping: UrlMapping): Promise<any> {
|
||||
const conf = (await this.userContext.getObj(this.buildAccountKey(email))) || {};
|
||||
if (conf.accountUrl?.indexOf("letsencrypt.proxy.handsfree.work")) {
|
||||
conf.accountUrl = conf.accountUrl.replace("letsencrypt.proxy.handsfree.work", "acme-v02.api.letsencrypt.org");
|
||||
if (urlMapping && urlMapping.mappings) {
|
||||
for (const key in urlMapping.mappings) {
|
||||
if (Object.prototype.hasOwnProperty.call(urlMapping.mappings, key)) {
|
||||
const element = urlMapping.mappings[key];
|
||||
if (conf.accountUrl?.indexOf(element) > -1) {
|
||||
//如果用了代理url,要替换回去
|
||||
conf.accountUrl = conf.accountUrl.replace(element, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return conf;
|
||||
}
|
||||
|
@ -59,7 +67,14 @@ export class AcmeService {
|
|||
}
|
||||
|
||||
async getAcmeClient(email: string, isTest = false): Promise<acme.Client> {
|
||||
const conf = await this.getAccountConfig(email);
|
||||
const urlMapping: UrlMapping = {
|
||||
enabled: false,
|
||||
mappings: {
|
||||
"acme-v02.api.letsencrypt.org": "letsencrypt.proxy.handsfree.work",
|
||||
"dv.acme-v02.api.pki.goog": "google.proxy.handsfree.work",
|
||||
},
|
||||
};
|
||||
const conf = await this.getAccountConfig(email, urlMapping);
|
||||
if (conf.key == null) {
|
||||
conf.key = await this.createNewKey();
|
||||
await this.saveAccountConfig(email, conf);
|
||||
|
@ -70,19 +85,15 @@ export class AcmeService {
|
|||
} else {
|
||||
directoryUrl = acme.directory[this.sslProvider].production;
|
||||
}
|
||||
const urlMapping: UrlMapping = { enabled: false, mappings: {} };
|
||||
if (this.options.useMappingProxy) {
|
||||
urlMapping.enabled = true;
|
||||
urlMapping.mappings = {
|
||||
"acme-v02.api.letsencrypt.org": "letsencrypt.proxy.handsfree.work",
|
||||
};
|
||||
}
|
||||
const client = new acme.Client({
|
||||
directoryUrl: directoryUrl,
|
||||
accountKey: conf.key,
|
||||
accountUrl: conf.accountUrl,
|
||||
externalAccountBinding: this.eab,
|
||||
backoffAttempts: 30,
|
||||
backoffAttempts: 15,
|
||||
backoffMin: 5000,
|
||||
backoffMax: 10000,
|
||||
urlMapping,
|
||||
|
|
|
@ -34,7 +34,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
options: [
|
||||
{ value: "letsencrypt", label: "Let's Encrypt" },
|
||||
// { value: "letsencrypt-proxy", label: "Let's Encrypt代理,letsencrypt.org无法访问时使用" },
|
||||
// { value: "buypass", label: "Buypass" },
|
||||
{ value: "google", label: "Google" },
|
||||
{ value: "zerossl", label: "ZeroSSL" },
|
||||
],
|
||||
},
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<a-input v-model:value="testFormState.receiver" />
|
||||
</a-form-item>
|
||||
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
|
||||
<a-button type="primary" html-type="submit">测试</a-button>
|
||||
<a-button type="primary" :loading="testFormState.loading" html-type="submit">测试</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
|
|
|
@ -6,3 +6,6 @@ typeorm:
|
|||
default:
|
||||
logging: false
|
||||
|
||||
|
||||
plus:
|
||||
serverBaseUrl: 'https://api.ai.handsfree.work/'
|
||||
|
|
|
@ -88,6 +88,9 @@ const development = {
|
|||
system: {
|
||||
resetAdminPasswd: false,
|
||||
},
|
||||
plus: {
|
||||
serverBaseUrl: 'http://127.0.0.1:11007',
|
||||
},
|
||||
} as MidwayConfig;
|
||||
mergeConfig(development, 'development');
|
||||
|
||||
|
|
Loading…
Reference in New Issue