1
1
import {
2
- toPEM ,
3
- readOrCreateAccountKey ,
4
- generateKey ,
5
- createCsr ,
6
- readCertificateInfo ,
7
- acmeServerNames ,
8
- getVariable ,
9
- joinPaths ,
10
- acmeDir ,
11
- acmeChallengeDir ,
12
2
acmeAccountPrivateJWKPath ,
3
+ acmeAltNames ,
4
+ acmeChallengeDir ,
5
+ acmeCommonName ,
6
+ acmeDir ,
13
7
acmeDirectoryURI ,
8
+ acmeServerNames ,
14
9
acmeVerifyProviderHTTPS ,
15
10
acmeZoneName ,
11
+ areEqualSets ,
12
+ createCsr ,
13
+ generateKey ,
14
+ getVariable ,
15
+ joinPaths ,
16
+ readCertificateInfo ,
17
+ readOrCreateAccountKey ,
18
+ toPEM ,
16
19
} from './utils'
17
20
import { HttpClient } from './api'
18
21
import { AcmeClient } from './client'
@@ -21,6 +24,7 @@ import { LogLevel, Logger } from './logger'
21
24
22
25
const KEY_SUFFIX = '.key'
23
26
const CERTIFICATE_SUFFIX = '.crt'
27
+ const CERTIFICATE_REQ_SUFFIX = '.csr'
24
28
const log = new Logger ( )
25
29
26
30
/**
@@ -62,11 +66,11 @@ async function clientNewAccount(r: NginxHTTPRequest): Promise<void> {
62
66
async function clientAutoMode ( r : NginxHTTPRequest ) : Promise < void > {
63
67
const log = new Logger ( 'auto' )
64
68
const prefix = acmeDir ( r )
65
- const serverNames = acmeServerNames ( r )
69
+ const commonName = acmeCommonName ( r )
70
+ const altNames = acmeAltNames ( r )
66
71
67
- const commonName = serverNames [ 0 ]
68
72
const pkeyPath = joinPaths ( prefix , commonName + KEY_SUFFIX )
69
- const csrPath = joinPaths ( prefix , commonName + '.csr' )
73
+ const csrPath = joinPaths ( prefix , commonName + CERTIFICATE_REQ_SUFFIX )
70
74
const certPath = joinPaths ( prefix , commonName + CERTIFICATE_SUFFIX )
71
75
72
76
let email
@@ -88,16 +92,31 @@ async function clientAutoMode(r: NginxHTTPRequest): Promise<void> {
88
92
const privateKeyData = fs . readFileSync ( pkeyPath , 'utf8' )
89
93
90
94
certInfo = await readCertificateInfo ( certData )
91
- // Calculate the date 30 days before the certificate expiration
92
- const renewalThreshold = new Date ( certInfo . notAfter as string )
93
- renewalThreshold . setDate ( renewalThreshold . getDate ( ) - 30 )
94
95
95
- const currentDate = new Date ( )
96
- if ( currentDate > renewalThreshold ) {
96
+ const configDomains = acmeServerNames ( r )
97
+ const certDomains = certInfo . domains . altNames // altNames includes the common name
98
+
99
+ if ( ! areEqualSets ( certDomains , configDomains ) ) {
100
+ log . info (
101
+ `Renewing certificate because the hostnames in the certificate (${ certDomains . join (
102
+ ', '
103
+ ) } ) do not match the configured njs_acme_server_names (${ configDomains . join (
104
+ ','
105
+ ) } )`
106
+ )
97
107
renewCertificate = true
98
108
} else {
99
- certificatePem = certData
100
- pkeyPem = privateKeyData
109
+ // Calculate the date 30 days before the certificate expiration
110
+ const renewalThreshold = new Date ( certInfo . notAfter )
111
+ renewalThreshold . setDate ( renewalThreshold . getDate ( ) - 30 )
112
+
113
+ const currentDate = new Date ( )
114
+ if ( currentDate > renewalThreshold ) {
115
+ renewCertificate = true
116
+ } else {
117
+ certificatePem = certData
118
+ pkeyPem = privateKeyData
119
+ }
101
120
}
102
121
} catch {
103
122
renewCertificate = true
@@ -117,17 +136,17 @@ async function clientAutoMode(r: NginxHTTPRequest): Promise<void> {
117
136
118
137
// Create a new CSR
119
138
const params = {
120
- altNames : serverNames . length > 1 ? serverNames . slice ( 1 ) : [ ] ,
121
- commonName : commonName ,
139
+ commonName ,
140
+ altNames ,
122
141
emailAddress : email ,
123
142
}
124
143
125
- const result = await createCsr ( params )
126
- fs . writeFileSync ( csrPath , toPEM ( result . pkcs10Ber , 'CERTIFICATE REQUEST' ) )
144
+ const csr = await createCsr ( params )
145
+ fs . writeFileSync ( csrPath , toPEM ( csr . pkcs10Ber , 'CERTIFICATE REQUEST' ) )
127
146
128
147
const privKey = ( await crypto . subtle . exportKey (
129
148
'pkcs8' ,
130
- result . keys . privateKey
149
+ csr . keys . privateKey
131
150
) ) as ArrayBuffer
132
151
pkeyPem = toPEM ( privKey , 'PRIVATE KEY' )
133
152
fs . writeFileSync ( pkeyPath , pkeyPem )
@@ -146,8 +165,8 @@ async function clientAutoMode(r: NginxHTTPRequest): Promise<void> {
146
165
}
147
166
148
167
certificatePem = await client . auto ( {
149
- csr : Buffer . from ( result . pkcs10Ber ) ,
150
- email : email ,
168
+ csr : Buffer . from ( csr . pkcs10Ber ) ,
169
+ email,
151
170
termsOfServiceAgreed : true ,
152
171
challengeCreateFn : async ( authz , challenge , keyAuthorization ) => {
153
172
log . info ( 'Challenge Create' , { authz, challenge, keyAuthorization } )
@@ -272,8 +291,7 @@ function read_cert_or_key(r: NginxHTTPRequest, suffix: string) {
272
291
let data = ''
273
292
let path = ''
274
293
const prefix = acmeDir ( r )
275
- const serverNames = acmeServerNames ( r )
276
- const commonName = serverNames [ 0 ] . toLowerCase ( )
294
+ const commonName = acmeCommonName ( r )
277
295
const zone = acmeZoneName ( r )
278
296
path = joinPaths ( prefix , commonName + suffix )
279
297
const key = [ 'acme' , path ] . join ( ':' )
0 commit comments