Commit 8795dd09 authored by nanahira's avatar nanahira

fix acme drift

parent 202f4043
Pipeline #41770 failed with stages
in 1 minute and 21 seconds
......@@ -7,6 +7,9 @@ import { promisify } from 'util';
const execFile = promisify(_execFile);
const DEBUG = process.env.DEBUG === '1';
const NGINX_CONF_PATH = process.env.NGINX_CONF_PATH || '/etc/nginx/nginx.conf';
async function reloadNginx() {
console.error('[nginx] Reloading...');
try {
......@@ -20,27 +23,57 @@ async function reloadNginx() {
}
}
function renderTemplate(parsed: any): string {
const tpl = fs.readFileSync(
path.join(__dirname, '..', 'views', 'nginx.conf.mustache'),
'utf8',
);
const rendered = Mustache.render(tpl, parsed, undefined, {
escape: (v) => v,
});
return rendered;
}
function writeConfig(rendered: string) {
if (DEBUG) {
// DEBUG=1:和原来一样,直接往 stdout 打
console.error('[render] DEBUG=1, writing config to stdout instead of file');
console.log(rendered);
} else {
fs.writeFileSync(NGINX_CONF_PATH, rendered, 'utf8');
console.error('[render] Nginx config written to', NGINX_CONF_PATH);
}
}
async function main() {
try {
if (process.argv[2] === 'renewCert') {
const mode = process.argv[2];
if (mode === 'renewCert') {
console.error('[acme] Signing start');
await getData(process.env as any, 61000);
// 带超时的 getData
const parsed = await getData(process.env as any, 61000);
console.error('[acme] Signing done');
await reloadNginx();
console.error('[render] Nginx config render start (renewCert)');
const rendered = renderTemplate(parsed);
writeConfig(rendered);
console.error('[render] Nginx config render done (renewCert)');
if (!DEBUG) {
await reloadNginx();
} else {
console.error('[nginx] DEBUG=1, skip reload');
}
} else {
console.error('[render] Nginx config render start');
const parsed = await getData(process.env as any);
console.error('[render] parsed');
const tpl = fs.readFileSync(
path.join(__dirname, '..', 'views', 'nginx.conf.mustache'),
'utf8',
);
const rendered = Mustache.render(tpl, parsed, undefined, {
escape: (v) => v,
});
console.log(rendered);
const rendered = renderTemplate(parsed);
writeConfig(rendered);
console.error('[render] Nginx config render done');
}
process.exit(0);
} catch (e) {
console.error('[main] Error:', e);
......
......@@ -8,7 +8,7 @@ let email: string;
export const domainsToBeSigned: string[] = [];
export async function addSignCert(domains: string[], payload: string) {
const pickedCert = await pickCert(domains);
const pickedCert = await pickCert(domains, true);
if (pickedCert) {
return pickedCert;
}
......
......@@ -10,12 +10,12 @@ class Cert {
);
constructor(public dir: string) {}
isNotExpired() {
isNotExpired(acme = false) {
const now = new Date();
const validFrom = new Date(this.cert.validFrom);
const validTo = new Date(this.cert.validTo);
if (process.argv[2] === 'renewCert') {
if (process.argv[2] === 'renewCert' && acme) {
const threshold = new Date(validTo.getTime() - 7 * 24 * 60 * 60 * 1000);
return now > validFrom && now < threshold;
}
......@@ -27,8 +27,8 @@ class Cert {
return this.cert.checkHost(domain);
}
isOkWithDomains(domains: string[]) {
return domains.every((domain) => this.isOkWithDomain(domain));
isOkWithDomains(domains: string[], acme = false) {
return domains.every((domain) => this.isOkWithDomain(domain, acme));
}
}
......@@ -40,8 +40,8 @@ const certs = fs
.map((dir) => new Cert(dir))
.filter((cert) => cert.isNotExpired());
export async function pickCert(domains: string[]) {
const okCerts = certs.filter((cert) => cert.isOkWithDomains(domains));
export async function pickCert(domains: string[], acme = false) {
const okCerts = certs.filter((cert) => cert.isOkWithDomains(domains, acme));
if (!okCerts.length) {
return;
}
......
#!/bin/sh
set -e
node dist > /etc/nginx/nginx.conf
NGINX_CONF_PATH="${NGINX_CONF_PATH:-/etc/nginx/nginx.conf}"
if grep -q 'acme_required' /etc/nginx/nginx.conf; then
node dist
# 检查是否需要 ACME
if grep -q 'acme_required' "$NGINX_CONF_PATH"; then
echo "[entrypoint] ACME required detected, scheduling daily renewCert task" >&2
(
while true; do
sleep 86400 # 24h
echo "[entrypoint] Running daily cert renewal..." >&2
node dist renewCert || echo "[entrypoint] renewCert failed" >&2
if ! node dist renewCert; then
echo "[entrypoint] renewCert failed" >&2
fi
echo "[entrypoint] Daily cert renewal finished." >&2
done
) &
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment