mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-09-20 07:16:05 +08:00
fix(SNI): disable SNI certificate autogeneration by default
This commit is contained in:
parent
ec4a2a25d7
commit
ecbdc9be5f
|
@ -19,7 +19,8 @@ keyExponent = 65537
|
|||
|
||||
[autogenerate]
|
||||
# If enabled then automatically generates TLS certificates based on SNI servernames
|
||||
enabled = true
|
||||
enabled = false
|
||||
|
||||
[autogenerate.cnameMapping]
|
||||
# Sudomain CNAME mapping
|
||||
# "abc" = ["def.com"] means that if the SNI servername domain is "abc.{domain}"
|
||||
|
@ -27,9 +28,10 @@ enabled = true
|
|||
# If multiple CNAME targets are defined (eg ["def.com", "bef.com"], then at least 1 must match.
|
||||
# Additionally, there must be at least 1 email account with "@{domain}" address.
|
||||
# If there is no match, then TLS certificate is not generated.
|
||||
imap = ["imap.example.com"]
|
||||
smtp = ["smtp.example.com"]
|
||||
pop3 = ["imap.example.com"]
|
||||
|
||||
# imap = ["imap.example.com"]
|
||||
# smtp = ["smtp.example.com"]
|
||||
# pop3 = ["imap.example.com"]
|
||||
|
||||
[agent]
|
||||
# If enabled then starts a HTTP server that listens for ACME verification requests
|
||||
|
|
|
@ -631,6 +631,15 @@ indexes:
|
|||
expires: 1
|
||||
'_acme.lastRenewalCheck': 1
|
||||
|
||||
- collection: certs
|
||||
index:
|
||||
name: garbage_check
|
||||
key:
|
||||
acme: 1
|
||||
updated: 1
|
||||
expires: 1
|
||||
autogenerated: 1
|
||||
|
||||
- collection: audits
|
||||
index:
|
||||
name: user_expire_time
|
||||
|
|
|
@ -19,7 +19,9 @@ const { promisify } = require('util');
|
|||
const generateKeyPair = promisify(crypto.generateKeyPair);
|
||||
|
||||
const CERT_RENEW_TTL = 30 * 24 * 3600 * 1000;
|
||||
const CERT_RENEW_DELAY = 24 * 3600 * 100;
|
||||
const CERT_RENEW_DELAY = 24 * 3600 * 1000;
|
||||
// delete uninitialized certificates after 1 day
|
||||
const CERT_GARBAGE_TTL = 24 * 2300 * 1000;
|
||||
|
||||
class CertHandler {
|
||||
constructor(options) {
|
||||
|
@ -110,6 +112,22 @@ class CertHandler {
|
|||
return query;
|
||||
}
|
||||
|
||||
async clearGarbage() {
|
||||
// delete expired and uninitialized SNI certificates
|
||||
let r = await this.database.collection('certs').deleteMany({
|
||||
acme: true,
|
||||
updated: {
|
||||
$lt: new Date(Date.now() + CERT_GARBAGE_TTL)
|
||||
},
|
||||
$or: [{ expires: { $exists: false } }, { expires: { $lt: new Date() } }],
|
||||
autogenerated: true
|
||||
});
|
||||
|
||||
if (r?.deletedCount) {
|
||||
log.verbose('Certs', 'Deleted uninitialized and expired autogenerated certificates. count=%s', r?.deletedCount);
|
||||
}
|
||||
}
|
||||
|
||||
async getNextRenewal() {
|
||||
let r = await this.database.collection('certs').findOneAndUpdate(
|
||||
{
|
||||
|
@ -391,7 +409,14 @@ class CertHandler {
|
|||
{
|
||||
servername
|
||||
},
|
||||
{ $set: certData, $inc: { v: 1 }, $setOnInsert: { servername, created: new Date() } },
|
||||
{
|
||||
$set: certData,
|
||||
$inc: { v: 1 },
|
||||
$setOnInsert: {
|
||||
servername,
|
||||
created: new Date()
|
||||
}
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
returnDocument: 'after'
|
||||
|
@ -659,11 +684,14 @@ class CertHandler {
|
|||
// not a FQDN
|
||||
return false;
|
||||
}
|
||||
|
||||
const subdomain = domain.substring(0, dotPos).toLowerCase().trim();
|
||||
const maindomain = domain
|
||||
.substring(dotPos + 1)
|
||||
.toLowerCase()
|
||||
.trim();
|
||||
const maindomain = tools.normalizeDomain(domain.substring(dotPos + 1));
|
||||
|
||||
if (!this.acmeConfig.autogenerate?.cnameMapping?.hasOwnProperty(subdomain)) {
|
||||
log.verbose('Certs', 'Skip ACME. reason="unsupported subdomain" action=precheck domain=%s', domain);
|
||||
return false;
|
||||
}
|
||||
|
||||
let subdomainTargets = [].concat(this.acmeConfig.autogenerate?.cnameMapping?.[subdomain] || []);
|
||||
if (!subdomainTargets.length) {
|
||||
|
|
|
@ -6,6 +6,12 @@ const config = require('wild-config');
|
|||
let run = async (task, data, options) => {
|
||||
const { acquireCert, certHandler } = options;
|
||||
|
||||
try {
|
||||
await certHandler.clearGarbage();
|
||||
} catch (err) {
|
||||
log.error('Tasks', 'task=acme-update id=%s action=clear-garbage error=%s', task._id, err.message);
|
||||
}
|
||||
|
||||
let certData;
|
||||
while ((certData = await certHandler.getNextRenewal())) {
|
||||
let cert = await acquireCert(certData.servername, config.acme, certData, certHandler);
|
||||
|
|
Loading…
Reference in a new issue