feat(Port80Handler): Add automatic certificate issuance with ACME client

This commit is contained in:
2025-02-24 10:00:57 +00:00
parent 266895ccc5
commit 31e15b65ec
6 changed files with 210 additions and 11 deletions

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartproxy',
version: '3.10.5',
version: '3.11.0',
description: 'a proxy for handling high workloads of proxying'
}

View File

@ -55,8 +55,8 @@ export class Port80Handler {
if (this.acmeClient) {
return this.acmeClient;
}
// Generate a new account key.
this.accountKey = await acme.forge.createPrivateKey();
// Generate a new account key and convert Buffer to string.
this.accountKey = (await acme.forge.createPrivateKey()).toString();
this.acmeClient = new acme.Client({
directoryUrl: acme.directory.letsencrypt.production, // Use production for a real certificate
// For testing, you could use:
@ -170,7 +170,11 @@ export class Port80Handler {
domainInfo.challengeKeyAuthorization = keyAuthorization;
// Notify the ACME server that the challenge is ready.
await client.verifyChallenge(authz, challenge, keyAuthorization);
// The acme-client examples show that verifyChallenge takes three arguments:
// (authorization, challenge, keyAuthorization). However, the official TypeScript
// types appear to be out-of-sync. As a workaround, we cast client to 'any'.
await (client as any).verifyChallenge(authz, challenge, keyAuthorization);
await client.completeChallenge(challenge);
// Wait until the challenge is validated.
await client.waitForValidStatus(challenge);
@ -178,9 +182,12 @@ export class Port80Handler {
}
// Generate a CSR and a new private key for the domain.
const [csr, privateKey] = await acme.forge.createCsr({
// Convert the resulting Buffers to strings.
const [csrBuffer, privateKeyBuffer] = await acme.forge.createCsr({
commonName: domain,
});
const csr = csrBuffer.toString();
const privateKey = privateKeyBuffer.toString();
// Finalize the order and obtain the certificate.
await client.finalizeOrder(order, csr);
@ -195,8 +202,7 @@ export class Port80Handler {
delete domainInfo.challengeKeyAuthorization;
console.log(`Certificate obtained for ${domain}`);
// In a real application, you would persist the certificate and key,
// then reload your TLS server with the new credentials.
// In a production system, persist the certificate and key and reload your TLS server.
} catch (error) {
console.error(`Error during certificate issuance for ${domain}:`, error);
const domainInfo = this.domainCertificates.get(domain);
@ -206,7 +212,3 @@ export class Port80Handler {
}
}
}
// Example usage:
// const handler = new Port80Handler();
// handler.addDomain('example.com');

View File

@ -1,3 +1,4 @@
export * from './classes.networkproxy.js';
export * from './classes.portproxy.js';
export * from './classes.port80handler.js';
export * from './classes.sslredirect.js';