feat: bindAddress (#2766)
Some checks failed
Build Docker image / docker-amd64 (push) Waiting to run
Build Docker image / docker-arm64 (push) Has been cancelled
Build / build (push) Has been cancelled

so people can limit the server to only be reachable via 127.0.0.1 etc

Reviewed-on: #2766
Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com>
Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
Sainan 2025-09-09 23:54:33 -07:00 committed by Sainan
parent 39f898cd30
commit 5a9415ae0c
4 changed files with 43 additions and 18 deletions

View File

@ -5,6 +5,7 @@
"level": "trace"
},
"myAddress": "localhost",
"bindAddress": "0.0.0.0",
"httpPort": 80,
"httpsPort": 443,
"administratorNames": [],

View File

@ -12,6 +12,7 @@ export interface IConfig {
level: string; // "fatal" | "error" | "warn" | "info" | "http" | "debug" | "trace";
};
myAddress: string;
bindAddress?: string;
httpPort?: number;
httpsPort?: number;
ircAddress?: string;
@ -188,3 +189,17 @@ export const getReflexiveAddress = (request: Request): { myAddress: string; myUr
}
return { myAddress, myUrlBase };
};
export interface IBindings {
address: string;
httpPort: number;
httpsPort: number;
}
export const configGetWebBindings = (): IBindings => {
return {
address: config.bindAddress || "0.0.0.0",
httpPort: config.httpPort || 80,
httpsPort: config.httpsPort || 443
};
};

View File

@ -2,6 +2,7 @@ import chokidar from "chokidar";
import { logger } from "../utils/logger.ts";
import {
config,
configGetWebBindings,
configPath,
configRemovedOptionsKeys,
loadConfig,
@ -9,7 +10,7 @@ import {
type IConfig
} from "./configService.ts";
import { saveConfig, shouldReloadConfig } from "./configWriterService.ts";
import { getWebPorts, startWebServer, stopWebServer } from "./webService.ts";
import { getWebBindings, startWebServer, stopWebServer } from "./webService.ts";
import { sendWsBroadcast } from "./wsService.ts";
import varzia from "../../static/fixed_responses/worldState/varzia.json" with { type: "json" };
@ -25,9 +26,14 @@ chokidar.watch(configPath).on("change", () => {
validateConfig();
syncConfigWithDatabase();
const webPorts = getWebPorts();
if (config.httpPort != webPorts.http || config.httpsPort != webPorts.https) {
logger.info(`Restarting web server to apply port changes.`);
const configBindings = configGetWebBindings();
const bindings = getWebBindings();
if (
configBindings.address != bindings.address ||
configBindings.httpPort != bindings.httpPort ||
configBindings.httpsPort != bindings.httpsPort
) {
logger.info(`Restarting web server to apply binding changes.`);
// Tell webui clients to reload with new port
sendWsBroadcast({ ports: { http: config.httpPort, https: config.httpsPort } });

View File

@ -1,7 +1,7 @@
import http from "http";
import https from "https";
import fs from "node:fs";
import { config } from "./configService.ts";
import { configGetWebBindings, type IBindings } from "./configService.ts";
import { logger } from "../utils/logger.ts";
import { app } from "../app.ts";
import type { AddressInfo } from "node:net";
@ -17,33 +17,35 @@ const tlsOptions = {
};
export const startWebServer = (): void => {
const httpPort = config.httpPort || 80;
const httpsPort = config.httpsPort || 443;
const bindings = configGetWebBindings();
// eslint-disable-next-line @typescript-eslint/no-misused-promises
httpServer = http.createServer(app);
httpServer.listen(httpPort, () => {
httpServer.listen(bindings.httpPort, bindings.address, () => {
startWsServer(httpServer!);
logger.info("HTTP server started on port " + httpPort);
logger.info(`HTTP server started on ${bindings.address}:${bindings.httpPort}`);
// eslint-disable-next-line @typescript-eslint/no-misused-promises
httpsServer = https.createServer(tlsOptions, app);
httpsServer.listen(httpsPort, () => {
httpsServer.listen(bindings.httpsPort, bindings.address, () => {
startWssServer(httpsServer!);
logger.info("HTTPS server started on port " + httpsPort);
logger.info(`HTTPS server started on ${bindings.address}:${bindings.httpsPort}`);
logger.info(
"Access the WebUI in your browser at http://localhost" + (httpPort == 80 ? "" : ":" + httpPort)
"Access the WebUI in your browser at http://localhost" +
(bindings.httpPort == 80 ? "" : ":" + bindings.httpPort)
);
void runWsSelfTest("wss", httpsPort).then(ok => {
void runWsSelfTest("wss", bindings.httpsPort).then(ok => {
if (!ok) {
logger.warn(`WSS self-test failed. The server may not actually be reachable at port ${httpsPort}.`);
logger.warn(
`WSS self-test failed. The server may not be reachable locally on port ${bindings.httpsPort}.`
);
if (process.platform == "win32") {
logger.warn(
`You can check who actually has that port via powershell: Get-Process -Id (Get-NetTCPConnection -LocalPort ${httpsPort}).OwningProcess`
`You can check who has that port via powershell: Get-Process -Id (Get-NetTCPConnection -LocalPort ${bindings.httpsPort}).OwningProcess`
);
}
}
@ -80,10 +82,11 @@ const runWsSelfTest = (protocol: "ws" | "wss", port: number): Promise<boolean> =
});
};
export const getWebPorts = (): Record<"http" | "https", number | undefined> => {
export const getWebBindings = (): Partial<IBindings> => {
return {
http: (httpServer?.address() as AddressInfo | undefined)?.port,
https: (httpsServer?.address() as AddressInfo | undefined)?.port
address: (httpServer?.address() as AddressInfo | undefined)?.address,
httpPort: (httpServer?.address() as AddressInfo | undefined)?.port,
httpsPort: (httpsServer?.address() as AddressInfo | undefined)?.port
};
};