Skip to content

Commit 1be87f4

Browse files
authored
Merge pull request #3392 from stevecrozz/auto-renew-uses-bulitin-renew
Make auto-renew use built-in renew function
2 parents 58ef9a6 + 9c54d1b commit 1be87f4

File tree

1 file changed

+46
-55
lines changed

1 file changed

+46
-55
lines changed

backend/internal/certificate.js

+46-55
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const config = require('../lib/config');
88
const error = require('../lib/error');
99
const utils = require('../lib/utils');
1010
const certificateModel = require('../models/certificate');
11+
const tokenModel = require('../models/token');
1112
const dnsPlugins = require('../global/certbot-dns-plugins');
1213
const internalAuditLog = require('./audit-log');
1314
const internalNginx = require('./nginx');
@@ -26,10 +27,11 @@ function omissions() {
2627

2728
const internalCertificate = {
2829

29-
allowedSslFiles: ['certificate', 'certificate_key', 'intermediate_certificate'],
30-
intervalTimeout: 1000 * 60 * 60, // 1 hour
31-
interval: null,
32-
intervalProcessing: false,
30+
allowedSslFiles: ['certificate', 'certificate_key', 'intermediate_certificate'],
31+
intervalTimeout: 1000 * 60 * 60, // 1 hour
32+
interval: null,
33+
intervalProcessing: false,
34+
renewBeforeExpirationBy: [30, 'days'],
3335

3436
initTimer: () => {
3537
logger.info('Let\'s Encrypt Renewal Timer initialized');
@@ -44,62 +46,51 @@ const internalCertificate = {
4446
processExpiringHosts: () => {
4547
if (!internalCertificate.intervalProcessing) {
4648
internalCertificate.intervalProcessing = true;
47-
logger.info('Renewing SSL certs close to expiry...');
48-
49-
const cmd = certbotCommand + ' renew --non-interactive --quiet ' +
50-
'--config "' + letsencryptConfig + '" ' +
51-
'--work-dir "/tmp/letsencrypt-lib" ' +
52-
'--logs-dir "/tmp/letsencrypt-log" ' +
53-
'--preferred-challenges "dns,http" ' +
54-
'--disable-hook-validation ' +
55-
(letsencryptStaging ? '--staging' : '');
56-
57-
return utils.exec(cmd)
58-
.then((result) => {
59-
if (result) {
60-
logger.info('Renew Result: ' + result);
49+
logger.info('Renewing SSL certs expiring within ' + internalCertificate.renewBeforeExpirationBy[0] + ' ' + internalCertificate.renewBeforeExpirationBy[1] + ' ...');
50+
51+
const expirationThreshold = moment().add(internalCertificate.renewBeforeExpirationBy[0], internalCertificate.renewBeforeExpirationBy[1]).format('YYYY-MM-DD HH:mm:ss');
52+
53+
// Fetch all the letsencrypt certs from the db that will expire within the configured threshold
54+
certificateModel
55+
.query()
56+
.where('is_deleted', 0)
57+
.andWhere('provider', 'letsencrypt')
58+
.andWhere('expires_on', '<', expirationThreshold)
59+
.then((certificates) => {
60+
if (!certificates || !certificates.length) {
61+
return null;
6162
}
6263

63-
return internalNginx.reload()
64-
.then(() => {
65-
logger.info('Renew Complete');
66-
return result;
67-
});
68-
})
69-
.then(() => {
70-
// Now go and fetch all the letsencrypt certs from the db and query the files and update expiry times
71-
return certificateModel
72-
.query()
73-
.where('is_deleted', 0)
74-
.andWhere('provider', 'letsencrypt')
75-
.then((certificates) => {
76-
if (certificates && certificates.length) {
77-
let promises = [];
78-
79-
certificates.map(function (certificate) {
80-
promises.push(
81-
internalCertificate.getCertificateInfoFromFile('/etc/letsencrypt/live/npm-' + certificate.id + '/fullchain.pem')
82-
.then((cert_info) => {
83-
return certificateModel
84-
.query()
85-
.where('id', certificate.id)
86-
.andWhere('provider', 'letsencrypt')
87-
.patch({
88-
expires_on: moment(cert_info.dates.to, 'X').format('YYYY-MM-DD HH:mm:ss')
89-
});
90-
})
91-
.catch((err) => {
92-
// Don't want to stop the train here, just log the error
93-
logger.error(err.message);
94-
})
95-
);
96-
});
64+
/**
65+
* Renews must be run sequentially or we'll get an error 'Another
66+
* instance of Certbot is already running.'
67+
*/
68+
let sequence = Promise.resolve();
69+
70+
certificates.forEach(function (certificate) {
71+
sequence = sequence.then(() =>
72+
internalCertificate
73+
.renew(
74+
{
75+
can: () =>
76+
Promise.resolve({
77+
permission_visibility: 'all',
78+
}),
79+
token: new tokenModel(),
80+
},
81+
{ id: certificate.id },
82+
)
83+
.catch((err) => {
84+
// Don't want to stop the train here, just log the error
85+
logger.error(err.message);
86+
}),
87+
);
88+
});
9789

98-
return Promise.all(promises);
99-
}
100-
});
90+
return sequence;
10191
})
10292
.then(() => {
93+
logger.info('Completed SSL cert renew process');
10394
internalCertificate.intervalProcessing = false;
10495
})
10596
.catch((err) => {

0 commit comments

Comments
 (0)