roster-server 2.2.7 → 2.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/tasks/lessons.md +1 -0
- package/vendor/acme-dns-01-cli-wrapper.js +41 -71
package/package.json
CHANGED
package/tasks/lessons.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
# Lessons Learned
|
|
2
2
|
|
|
3
3
|
- When wildcard TLS must run under Bun, do not rely on manual DNS instructions; default to API-driven DNS-01 TXT creation/removal (Linode/Akamai) with propagation polling, then fall back to manual mode only when no provider token is configured.
|
|
4
|
+
- Prefer the simplest robust DNS verification path first (dig against 1.1.1.1/8.8.8.8) and avoid adding extra resolver complexity unless there is clear evidence it improves reliability.
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const legacyCli = require('acme-dns-01-cli');
|
|
4
4
|
const log = require('lemonlog')('acme-dns-01');
|
|
5
5
|
const dns = require('node:dns').promises;
|
|
6
|
+
const { execFileSync } = require('node:child_process');
|
|
6
7
|
let envFileLoadAttempted = false;
|
|
7
8
|
|
|
8
9
|
function loadEnvFileSafely() {
|
|
@@ -120,7 +121,6 @@ module.exports.create = function create(config = {}) {
|
|
|
120
121
|
resolver.setServers([server]);
|
|
121
122
|
return { server, resolver };
|
|
122
123
|
});
|
|
123
|
-
const authoritativeResolverClientsByHost = new Map();
|
|
124
124
|
const normalizeProvider = (value) => String(value || '').trim().toLowerCase();
|
|
125
125
|
const configuredProvider = normalizeProvider(
|
|
126
126
|
config.provider
|
|
@@ -150,85 +150,55 @@ module.exports.create = function create(config = {}) {
|
|
|
150
150
|
return candidate ? String(candidate).trim() : '';
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
function zoneCandidatesFromDnsHost(dnsHost) {
|
|
154
|
-
const normalized = String(dnsHost || '')
|
|
155
|
-
.replace(/^_acme-challenge\./, '')
|
|
156
|
-
.replace(/^_greenlock-[^.]+\./, '')
|
|
157
|
-
.replace(/\.$/, '')
|
|
158
|
-
.toLowerCase();
|
|
159
|
-
if (!normalized) return [];
|
|
160
|
-
|
|
161
|
-
const labels = normalized.split('.').filter(Boolean);
|
|
162
|
-
const candidates = [];
|
|
163
|
-
for (let i = 0; i <= labels.length - 2; i += 1) {
|
|
164
|
-
candidates.push(labels.slice(i).join('.'));
|
|
165
|
-
}
|
|
166
|
-
return candidates;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async function resolveAuthoritativeResolverClients(dnsHost) {
|
|
170
|
-
const cached = authoritativeResolverClientsByHost.get(dnsHost);
|
|
171
|
-
if (cached) return cached;
|
|
172
|
-
|
|
173
|
-
const candidates = zoneCandidatesFromDnsHost(dnsHost);
|
|
174
|
-
for (const zone of candidates) {
|
|
175
|
-
let nsRecords = [];
|
|
176
|
-
try {
|
|
177
|
-
nsRecords = await dns.resolveNs(zone);
|
|
178
|
-
} catch {
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (!Array.isArray(nsRecords) || nsRecords.length === 0) continue;
|
|
182
|
-
|
|
183
|
-
const clients = [];
|
|
184
|
-
for (const nsNameRaw of nsRecords) {
|
|
185
|
-
const nsName = String(nsNameRaw || '').replace(/\.$/, '');
|
|
186
|
-
if (!nsName) continue;
|
|
187
|
-
let ips = [];
|
|
188
|
-
try {
|
|
189
|
-
ips = await dns.resolve4(nsName);
|
|
190
|
-
} catch {}
|
|
191
|
-
if (ips.length === 0) {
|
|
192
|
-
try {
|
|
193
|
-
ips = await dns.resolve6(nsName);
|
|
194
|
-
} catch {}
|
|
195
|
-
}
|
|
196
|
-
for (const ip of ips) {
|
|
197
|
-
try {
|
|
198
|
-
const resolver = new dns.Resolver();
|
|
199
|
-
resolver.setServers([ip]);
|
|
200
|
-
clients.push({ server: `${nsName}/${ip}`, resolver });
|
|
201
|
-
} catch {}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
if (clients.length > 0) {
|
|
206
|
-
authoritativeResolverClientsByHost.set(dnsHost, clients);
|
|
207
|
-
return clients;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
authoritativeResolverClientsByHost.set(dnsHost, []);
|
|
212
|
-
return [];
|
|
213
|
-
}
|
|
214
|
-
|
|
215
153
|
async function resolveTxtRecords(dnsHost) {
|
|
216
154
|
const records = [];
|
|
217
155
|
const errors = [];
|
|
218
|
-
const
|
|
219
|
-
const resolverClients = [...staticResolverClients, ...authClients];
|
|
156
|
+
const resolverClients = staticResolverClients;
|
|
220
157
|
const seenServers = new Set();
|
|
221
158
|
|
|
222
159
|
for (const { server, resolver } of resolverClients) {
|
|
223
160
|
if (seenServers.has(server)) continue;
|
|
224
161
|
seenServers.add(server);
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
162
|
+
|
|
163
|
+
// Primary path: query with dig directly (more reliable under Bun).
|
|
164
|
+
const serverTarget = String(server || '');
|
|
165
|
+
let digAttempted = false;
|
|
166
|
+
if (typeof execFileSync === 'function' && serverTarget) {
|
|
167
|
+
digAttempted = true;
|
|
168
|
+
try {
|
|
169
|
+
const output = execFileSync('dig', ['+short', 'TXT', dnsHost, `@${serverTarget}`], {
|
|
170
|
+
encoding: 'utf8',
|
|
171
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
172
|
+
timeout: 4000
|
|
173
|
+
});
|
|
174
|
+
const lines = String(output || '')
|
|
175
|
+
.split('\n')
|
|
176
|
+
.map((line) => line.trim())
|
|
177
|
+
.filter(Boolean);
|
|
178
|
+
if (lines.length > 0) {
|
|
179
|
+
for (const line of lines) {
|
|
180
|
+
const normalized = normalizeTxtChunk(line);
|
|
181
|
+
if (normalized) records.push([normalized]);
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
errors.push(`${server}:ENOTFOUND`);
|
|
185
|
+
}
|
|
186
|
+
continue;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
errors.push(`${server}:DIG_${error?.code || error?.signal || 'ERROR'}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Fallback path only if dig is unavailable/failed unexpectedly.
|
|
193
|
+
if ((!digAttempted || records.length === 0) && resolver) {
|
|
194
|
+
try {
|
|
195
|
+
const result = await resolver.resolveTxt(dnsHost);
|
|
196
|
+
if (Array.isArray(result)) {
|
|
197
|
+
records.push(...result);
|
|
198
|
+
}
|
|
199
|
+
} catch (error) {
|
|
200
|
+
errors.push(`${server}:${error?.code || error?.message || error}`);
|
|
229
201
|
}
|
|
230
|
-
} catch (error) {
|
|
231
|
-
errors.push(`${server}:${error?.code || error?.message || error}`);
|
|
232
202
|
}
|
|
233
203
|
}
|
|
234
204
|
return { records, errors };
|