mirror of
https://github.com/certd/certd.git
synced 2026-04-24 12:27:25 +08:00
perf: 支持使用letencrypt测试环境申请ip证书
This commit is contained in:
Vendored
+2
-1
@@ -4,5 +4,6 @@
|
|||||||
"typescript.tsc.autoDetect": "watch",
|
"typescript.tsc.autoDetect": "watch",
|
||||||
"git.scanRepositories": [
|
"git.scanRepositories": [
|
||||||
"./packages/pro"
|
"./packages/pro"
|
||||||
]
|
],
|
||||||
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,9 @@
|
|||||||
import { readCsrDomains } from "./crypto/index.js";
|
import { readCsrDomains } from "./crypto/index.js";
|
||||||
import { wait } from "./wait.js";
|
import { wait } from "./wait.js";
|
||||||
import { CancelError } from "./error.js";
|
import { CancelError } from "./error.js";
|
||||||
|
import { domainUtils } from '@certd/basic';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const defaultOpts = {
|
const defaultOpts = {
|
||||||
@@ -65,7 +68,7 @@ export default async (client, userOpts) => {
|
|||||||
* Parse domains from CSR
|
* Parse domains from CSR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
log("[auto] Parsing domains from Certificate Signing Request ");
|
log("[auto] Parsing domains from Certificate Signing Request");
|
||||||
const { commonName, altNames } = readCsrDomains(opts.csr);
|
const { commonName, altNames } = readCsrDomains(opts.csr);
|
||||||
const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d)));
|
const uniqueDomains = Array.from(new Set([commonName].concat(altNames).filter((d) => d)));
|
||||||
|
|
||||||
@@ -76,9 +79,21 @@ export default async (client, userOpts) => {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
log("[auto] Placing new certificate order with ACME provider");
|
log("[auto] Placing new certificate order with ACME provider");
|
||||||
const orderPayload = { identifiers: uniqueDomains.map((d) => ({ type: "dns", value: d })) };
|
|
||||||
if (opts.profile && client.sslProvider === 'letsencrypt' ){
|
let hasIp = false
|
||||||
|
const orderPayload = { identifiers: uniqueDomains.map((d) =>{
|
||||||
|
// 判断是否为IP(v4或v6),否则按域名处理
|
||||||
|
const type = domainUtils.isIp(d) ? 'ip' : 'dns';
|
||||||
|
if(type === 'ip'){
|
||||||
|
hasIp = true
|
||||||
|
}
|
||||||
|
return { type, value: d }
|
||||||
|
}) };
|
||||||
|
if (opts.profile && client.sslProvider.startsWith("letsencrypt") ){
|
||||||
orderPayload.profile = opts.profile;
|
orderPayload.profile = opts.profile;
|
||||||
|
if(hasIp){
|
||||||
|
orderPayload.profile = "shortlived"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const order = await client.createOrder(orderPayload);
|
const order = await client.createOrder(orderPayload);
|
||||||
const authorizations = await client.getAuthorizations(order);
|
const authorizations = await client.getAuthorizations(order);
|
||||||
|
|||||||
@@ -7,29 +7,29 @@ function match(targetDomains: string | string[], inDomains: string[]) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof targetDomains === 'string') {
|
if (typeof targetDomains === "string") {
|
||||||
targetDomains = [targetDomains];
|
targetDomains = [targetDomains];
|
||||||
}
|
}
|
||||||
for (let targetDomain of targetDomains) {
|
for (let targetDomain of targetDomains) {
|
||||||
let matched = false;
|
let matched = false;
|
||||||
if (targetDomain.startsWith('.')) {
|
if (targetDomain.startsWith(".")) {
|
||||||
targetDomain = '*' + targetDomain;
|
targetDomain = "*" + targetDomain;
|
||||||
}
|
}
|
||||||
for (let inDomain of inDomains) {
|
for (let inDomain of inDomains) {
|
||||||
if (inDomain.startsWith('.')) {
|
if (inDomain.startsWith(".")) {
|
||||||
inDomain = '*' + inDomain;
|
inDomain = "*" + inDomain;
|
||||||
}
|
}
|
||||||
if (targetDomain === inDomain) {
|
if (targetDomain === inDomain) {
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inDomain.startsWith('*.')) {
|
if (!inDomain.startsWith("*.")) {
|
||||||
//不可能匹配
|
//不可能匹配
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//子域名匹配通配符即可
|
//子域名匹配通配符即可
|
||||||
const firstDotIndex = targetDomain.indexOf('.');
|
const firstDotIndex = targetDomain.indexOf(".");
|
||||||
const targetDomainSuffix = targetDomain.substring(firstDotIndex + 1);
|
const targetDomainSuffix = targetDomain.substring(firstDotIndex + 1);
|
||||||
if (targetDomainSuffix === inDomain.substring(2)) {
|
if (targetDomainSuffix === inDomain.substring(2)) {
|
||||||
matched = true;
|
matched = true;
|
||||||
@@ -46,6 +46,32 @@ function match(targetDomains: string | string[], inDomains: string[]) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isIpv4(d: string) {
|
||||||
|
if (!d) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isIPv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
|
||||||
|
return isIPv4Regex.test(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIpv6(d: string) {
|
||||||
|
if (!d) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const isIPv6Regex = /^([\da-f]{1,4}:){2,7}[\da-f]{1,4}$/i;
|
||||||
|
return isIPv6Regex.test(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIp(d: string) {
|
||||||
|
if (!d) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isIpv4(d) || isIpv6(d);
|
||||||
|
}
|
||||||
|
|
||||||
export const domainUtils = {
|
export const domainUtils = {
|
||||||
match,
|
match,
|
||||||
|
isIpv4,
|
||||||
|
isIpv6,
|
||||||
|
isIp,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -364,15 +364,13 @@ export class AcmeService {
|
|||||||
//兼容老版本
|
//兼容老版本
|
||||||
createCsr = acme.forge.createCsr;
|
createCsr = acme.forge.createCsr;
|
||||||
}
|
}
|
||||||
const [key, csr] = await createCsr(
|
const csrData: any = {
|
||||||
{
|
// commonName,
|
||||||
commonName,
|
...csrInfo,
|
||||||
...csrInfo,
|
altNames,
|
||||||
altNames,
|
// emailAddress: email,
|
||||||
// emailAddress: email,
|
};
|
||||||
},
|
const [key, csr] = await createCsr(csrData, privateKey);
|
||||||
privateKey
|
|
||||||
);
|
|
||||||
|
|
||||||
if (dnsProvider == null && domainsVerifyPlan == null) {
|
if (dnsProvider == null && domainsVerifyPlan == null) {
|
||||||
throw new Error("dnsProvider 、 domainsVerifyPlan不能都为空");
|
throw new Error("dnsProvider 、 domainsVerifyPlan不能都为空");
|
||||||
@@ -417,7 +415,7 @@ export class AcmeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buildCommonNameByDomains(domains: string | string[]): {
|
buildCommonNameByDomains(domains: string | string[]): {
|
||||||
commonName: string;
|
commonName?: string;
|
||||||
altNames: string[] | undefined;
|
altNames: string[] | undefined;
|
||||||
} {
|
} {
|
||||||
if (typeof domains === "string") {
|
if (typeof domains === "string") {
|
||||||
@@ -426,14 +424,14 @@ export class AcmeService {
|
|||||||
if (domains.length === 0) {
|
if (domains.length === 0) {
|
||||||
throw new Error("domain can not be empty");
|
throw new Error("domain can not be empty");
|
||||||
}
|
}
|
||||||
const commonName = domains[0];
|
// const commonName = domains[0];
|
||||||
let altNames: undefined | string[] = undefined;
|
// let altNames: undefined | string[] = undefined;
|
||||||
if (domains.length > 1) {
|
// if (domains.length > 1) {
|
||||||
altNames = _.slice(domains, 1);
|
// altNames = _.slice(domains, 1);
|
||||||
}
|
// }
|
||||||
return {
|
return {
|
||||||
commonName,
|
// commonName,
|
||||||
altNames,
|
altNames: domains,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user