feat: Support SSL without reverse proxy (#2959)
* Enable (optional) reading SSL certificates on startup * Update gitignore * fix: Expect ssl environment variables to be Base64 encoded * docs: Add env variables to .env.sample
This commit is contained in:
@@ -102,6 +102,12 @@ OIDC_SCOPES="openid profile email"
|
||||
|
||||
# –––––––––––––––– OPTIONAL ––––––––––––––––
|
||||
|
||||
# Base64 encoded private key and certificate for HTTPS termination. This is only
|
||||
# required if you do not use an external reverse proxy. See documentation:
|
||||
# https://wiki.generaloutline.com/share/1c922644-40d8-41fe-98f9-df2b67239d45
|
||||
SSL_KEY=
|
||||
SSL_CERT=
|
||||
|
||||
# If using a Cloudfront/Cloudflare distribution or similar it can be set below.
|
||||
# This will cause paths to javascript, stylesheets, and images to be updated to
|
||||
# the hostname defined in CDN_URL. In your CDN configuration the origin server
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,3 +9,5 @@ stats.json
|
||||
fakes3/*
|
||||
.idea
|
||||
*.pem
|
||||
*.key
|
||||
*.cert
|
||||
|
||||
@@ -4,6 +4,7 @@ import env from "./env";
|
||||
import "./tracing"; // must come before importing any instrumented module
|
||||
|
||||
import http from "http";
|
||||
import https from "https";
|
||||
import Koa from "koa";
|
||||
import compress from "koa-compress";
|
||||
import helmet from "koa-helmet";
|
||||
@@ -18,6 +19,7 @@ import Logger from "./logging/logger";
|
||||
import { requestErrorHandler } from "./logging/sentry";
|
||||
import services from "./services";
|
||||
import { getArg } from "./utils/args";
|
||||
import { getSSLOptions } from "./utils/ssl";
|
||||
import { checkEnv, checkMigrations } from "./utils/startup";
|
||||
import { checkUpdates } from "./utils/updates";
|
||||
|
||||
@@ -67,10 +69,18 @@ function master() {
|
||||
|
||||
// This function will only be called in each forked process
|
||||
async function start(id: number, disconnect: () => void) {
|
||||
// Find if SSL certs are available
|
||||
const ssl = getSSLOptions();
|
||||
const useHTTPS = !!ssl.key && !!ssl.cert;
|
||||
|
||||
// If a --port flag is passed then it takes priority over the env variable
|
||||
const normalizedPortFlag = getArg("port", "p");
|
||||
const app = new Koa();
|
||||
const server = stoppable(http.createServer(app.callback()));
|
||||
const server = stoppable(
|
||||
useHTTPS
|
||||
? https.createServer(ssl, app.callback())
|
||||
: http.createServer(app.callback())
|
||||
);
|
||||
const router = new Router();
|
||||
|
||||
// install basic middleware shared by all services
|
||||
@@ -108,7 +118,9 @@ async function start(id: number, disconnect: () => void) {
|
||||
|
||||
Logger.info(
|
||||
"lifecycle",
|
||||
`Listening on http://localhost:${(address as AddressInfo).port}`
|
||||
`Listening on ${useHTTPS ? "https" : "http"}://localhost:${
|
||||
(address as AddressInfo).port
|
||||
}`
|
||||
);
|
||||
});
|
||||
server.listen(normalizedPortFlag || env.PORT || "3000");
|
||||
|
||||
42
server/utils/ssl.ts
Normal file
42
server/utils/ssl.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import env from "../env";
|
||||
|
||||
/**
|
||||
* Find if SSL certs are available in the environment or filesystem and return
|
||||
* as a valid ServerOptions object
|
||||
*/
|
||||
export function getSSLOptions() {
|
||||
function safeReadFile(name: string) {
|
||||
try {
|
||||
return fs.readFileSync(
|
||||
path.normalize(`${__dirname}/../../../${name}`),
|
||||
"utf8"
|
||||
);
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return {
|
||||
key:
|
||||
(env.SSL_KEY
|
||||
? Buffer.from(env.SSL_KEY, "base64").toString("ascii")
|
||||
: undefined) ||
|
||||
safeReadFile("private.key") ||
|
||||
safeReadFile("private.pem"),
|
||||
cert:
|
||||
(env.SSL_CERT
|
||||
? Buffer.from(env.SSL_CERT, "base64").toString("ascii")
|
||||
: undefined) ||
|
||||
safeReadFile("public.cert") ||
|
||||
safeReadFile("public.pem"),
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
key: undefined,
|
||||
cert: undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user