diff --git a/server/controllers/guacamoleProxy.js b/server/controllers/guacamoleProxy.js index 69fc32f..4071629 100644 --- a/server/controllers/guacamoleProxy.js +++ b/server/controllers/guacamoleProxy.js @@ -1,7 +1,9 @@ const WebSocket = require("ws"); +const { getGuacamolePort } = require("../utils/guacamoleStarter"); + module.exports = async (ws, token) => { try { - const guacdUrl = `ws://localhost:58391/?token=${token}`; + const guacdUrl = `ws://localhost:${getGuacamolePort()}/?token=${token}`; const guacdSocket = new WebSocket(guacdUrl); ws.on("message", (message) => { diff --git a/server/index.js b/server/index.js index 73e2ac2..956f57c 100644 --- a/server/index.js +++ b/server/index.js @@ -5,9 +5,9 @@ const express = require("express"); const path = require("path"); const db = require("./utils/database"); const { authenticate } = require("./middlewares/auth"); -const GuacamoleLite = require("guacamole-lite"); const expressWs = require("express-ws"); const { startPVEUpdater } = require("./utils/pveUpdater"); +const { startGuacamole } = require("./utils/guacamoleStarter"); require("./utils/folder"); // Create needed data folders @@ -36,11 +36,6 @@ app.use("/api/servers", authenticate, require("./routes/server")); app.use("/api/pve-servers", authenticate, require("./routes/pveServer")); app.use("/api/identities", authenticate, require("./routes/identity")); -new GuacamoleLite({ port: 58391 }, { port: 4822 }, { - crypt: { cypher: "AES-256-CBC", key: module.exports.GUACD_TOKEN }, - log: { level: 0 }, -}); - if (process.env.NODE_ENV === "production") { app.use(express.static(path.join(__dirname, "../dist"))); @@ -55,6 +50,8 @@ db.authenticate().catch(err => { }).then(async () => { console.log("Successfully connected to the database " + (process.env.DB_TYPE === "mysql" ? "server" : "file")); + await startGuacamole(); + await db.sync({ alter: true, force: false }); startPVEUpdater(); diff --git a/server/utils/guacamoleStarter.js b/server/utils/guacamoleStarter.js new file mode 100644 index 0000000..180dc81 --- /dev/null +++ b/server/utils/guacamoleStarter.js @@ -0,0 +1,42 @@ +const GuacamoleLite = require("guacamole-lite"); +const net = require("net"); +const { GUACD_TOKEN } = require("../index"); + +let GUACAMOLE_LITE_PORT = 58390; + +const checkFreePort = async (port) => { + return new Promise((resolve) => { + const server = net.createServer(); + server.once("error", () => resolve(false)); + server.once("listening", () => { + server.close(); + resolve(true); + }); + server.listen(port, "::"); + }); +}; + +const getFreePort = async () => { + for (let i = 0; i < 10; i++) { + const port = Math.floor(Math.random() * 10000) + 50000; + if (await checkFreePort(port)) { + return port; + } + } + throw new Error("Could not find a free port for Guacamole"); +}; + +module.exports.startGuacamole = async () => { + GUACAMOLE_LITE_PORT = await getFreePort(); + + console.log("Starting Guacamole on port " + GUACAMOLE_LITE_PORT); + + new GuacamoleLite({ port: GUACAMOLE_LITE_PORT, host: "::" }, { port: 4822 }, { + crypt: { cypher: "AES-256-CBC", key: GUACD_TOKEN }, + log: { level: 0 }, + }).on("error", () => { + console.error("Could not connect to guacd. Is it running?"); + }); +}; + +module.exports.getGuacamolePort = () => GUACAMOLE_LITE_PORT; \ No newline at end of file