forked from serverless-dns/serverless-dns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.js
160 lines (140 loc) · 4.85 KB
/
config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* Copyright (c) 2021 RethinkDNS and its authors.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/**
* Configuration file for node runtime
* TODO: Remove all side-effects and use a constructor?
* This module has side effects, sequentially setting up the environment.
*/
import { atob, btoa } from "buffer";
import process from "node:process";
import { fetch, Headers, Request, Response } from "undici";
import * as util from "./util.js";
import * as blocklists from "./blocklists.js";
import Log from "../log.js";
import * as system from "../../system.js";
import { services, stopAfter } from "../svc.js";
import EnvManager from "../env.js";
import * as swap from "../linux/swap.js";
(async (main) => {
system.when("prepare").then(prep);
system.when("steady").then(up);
})();
process.on("SIGINT", (sig) => stopAfter());
async function prep() {
// if this file execs... assume we're on nodejs.
const isProd = process.env.NODE_ENV === "production";
const onFly = process.env.CLOUD_PLATFORM === "fly";
const profiling = process.env.PROFILE_DNS_RESOLVES === "true";
let devutils = null;
let dotenv = null;
// dev utilities
if (!isProd) {
devutils = await import("./util-dev.js");
// TODO: remove .env
dotenv = await import("dotenv");
}
/** Environment Variables */
// Load env variables from .env file to process.env (if file exists)
// NOTE: this won't overwrite existing
if (dotenv) {
dotenv.config();
console.log("loading local .env");
}
globalThis.envManager = new EnvManager();
/** Logger */
globalThis.log = new Log({
level: envManager.get("LOG_LEVEL"),
levelize: isProd || profiling, // levelize if prod or profiling
withTimestamps: true, // always log timestamps on node
});
// ---- log and envManager available only after this line ---- \\
/** TLS crt and key */
// If TLS_OFFLOAD == true, skip loading TLS certs and keys; otherwise:
// Raw TLS CERT and KEY are stored (base64) in an env var for fly deploys
// (fly deploys are dev/prod nodejs deploys where env TLS_CN or TLS_ is set).
// Otherwise, retrieve KEY and CERT from the filesystem (this is the case
// for local non-prod nodejs deploys with self-signed certs).
// If requisite TLS secrets are missing, set tlsoffload to true, eventually.
let tlsoffload = envManager.get("TLS_OFFLOAD");
const _TLS_CRT_AND_KEY =
eval(`process.env.TLS_${process.env.TLS_CN}`) || process.env.TLS_;
const TLS_CERTKEY = process.env.TLS_CERTKEY;
if (tlsoffload) {
log.i("TLS offload enabled");
} else if (isProd) {
if (TLS_CERTKEY) {
const [tlsKey, tlsCrt] = util.getCertKeyFromEnv(TLS_CERTKEY);
envManager.set("TLS_KEY", tlsKey);
envManager.set("TLS_CRT", tlsCrt);
log.i("env (fly) tls setup with tls_certkey");
} else if (_TLS_CRT_AND_KEY) {
const [tlsKey, tlsCrt] = util.getCertKeyFromEnv(_TLS_CRT_AND_KEY);
envManager.set("TLS_KEY", tlsKey);
envManager.set("TLS_CRT", tlsCrt);
log.i("[deprecated] env (fly) tls setup with tls_cn");
} else {
log.w("Skip TLS: neither TLS_CERTKEY nor TLS_CN set; enable TLS offload");
tlsoffload = true;
}
} else {
try {
const [tlsKey, tlsCrt] = devutils.getTLSfromFile(
envManager.get("TLS_KEY_PATH"),
envManager.get("TLS_CRT_PATH")
);
envManager.set("TLS_KEY", tlsKey);
envManager.set("TLS_CRT", tlsCrt);
log.i("dev (local) tls setup from tls_key_path");
} catch (ex) {
// this can happen when running server in BLOCKLIST_DOWNLOAD_ONLY mode
log.w("Skipping TLS: test TLS crt/key missing; enable TLS offload");
tlsoffload = true;
}
}
envManager.set("TLS_OFFLOAD", tlsoffload);
/** Polyfills */
if (!globalThis.fetch) {
globalThis.fetch = isProd ? fetch : devutils.fetchPlus;
globalThis.Headers = Headers;
globalThis.Request = Request;
globalThis.Response = Response;
log.i("polyfill fetch web api");
} else {
log.i("no fetch polyfill required");
}
if (!globalThis.atob || !globalThis.btoa) {
globalThis.atob = atob;
globalThis.btoa = btoa;
log.i("polyfill atob / btoa");
} else {
log.i("no atob/btoa polyfill required");
}
/** Swap on Fly */
if (onFly) {
const ok = swap.mkswap();
log.i("mkswap done?", ok);
} else {
log.i("no swap required");
}
/** signal ready */
system.pub("ready");
}
async function up() {
if (!services.ready) {
log.e("services not yet ready yet and there is a sig-up!?");
return;
}
const bw = services.blocklistWrapper;
if (bw != null && !bw.disabled()) {
await blocklists.setup(bw);
} else {
log.w("Config", "blocklists unavailable / disabled");
}
// signal all system are-a go
system.pub("go");
}