Add support for user provided CA certificate to establish secure connections with a mysql/mariadb server

pull/5418/head
Gabriel Ngandu-Biseba 4 weeks ago
parent c0fe669cd8
commit d2b48a648f

@ -1,3 +1,4 @@
/* eslint-disable linebreak-style */
const isFreeBSD = /^freebsd/.test(process.platform); const isFreeBSD = /^freebsd/.test(process.platform);
// Interop with browser // Interop with browser
@ -19,6 +20,9 @@ const sslKeyPassphrase = args["ssl-key-passphrase"] || process.env.UPTIME_KUMA_S
const isSSL = sslKey && sslCert; const isSSL = sslKey && sslCert;
const mariaDbSslCert = args["UPTIME_KUMA_DB_SSL_CERT"] || process.env.UPTIME_KUMA_DB_SSL_CERT || process.env.MARIADB_SSL_CERT || undefined;
const mariaDbUseSSL = mariaDbSslCert ? "true" : "false";
/** /**
* Get the local WebSocket URL * Get the local WebSocket URL
* @returns {string} The local WebSocket URL * @returns {string} The local WebSocket URL
@ -43,4 +47,6 @@ module.exports = {
isSSL, isSSL,
localWebSocketURL, localWebSocketURL,
demoMode, demoMode,
mariaDbSslCert,
mariaDbUseSSL
}; };

@ -1,3 +1,4 @@
/* eslint-disable linebreak-style */
const fs = require("fs"); const fs = require("fs");
const { R } = require("redbean-node"); const { R } = require("redbean-node");
const { setSetting, setting } = require("./util-server"); const { setSetting, setting } = require("./util-server");
@ -11,6 +12,7 @@ const { UptimeCalculator } = require("./uptime-calculator");
const dayjs = require("dayjs"); const dayjs = require("dayjs");
const { SimpleMigrationServer } = require("./utils/simple-migration-server"); const { SimpleMigrationServer } = require("./utils/simple-migration-server");
const KumaColumnCompiler = require("./utils/knex/lib/dialects/mysql2/schema/mysql2-columncompiler"); const KumaColumnCompiler = require("./utils/knex/lib/dialects/mysql2/schema/mysql2-columncompiler");
const { mariaDbSslCert, mariaDbUseSSL } = require("./config");
/** /**
* Database & App Data Folder * Database & App Data Folder
@ -259,11 +261,22 @@ class Database {
throw Error("Invalid database name. A database name can only consist of letters, numbers and underscores"); throw Error("Invalid database name. A database name can only consist of letters, numbers and underscores");
} }
let sslConfig = null;
let serverCa = undefined;
if (mariaDbUseSSL) {
serverCa = [ fs.readFileSync(mariaDbSslCert, "utf8") ];
sslConfig = {
rejectUnauthorized: true,
ca: serverCa
};
}
const connection = await mysql.createConnection({ const connection = await mysql.createConnection({
host: dbConfig.hostname, host: dbConfig.hostname,
port: dbConfig.port, port: dbConfig.port,
user: dbConfig.username, user: dbConfig.username,
password: dbConfig.password, password: dbConfig.password,
ssl: sslConfig
}); });
await connection.execute("CREATE DATABASE IF NOT EXISTS " + dbConfig.dbName + " CHARACTER SET utf8mb4"); await connection.execute("CREATE DATABASE IF NOT EXISTS " + dbConfig.dbName + " CHARACTER SET utf8mb4");
@ -278,6 +291,7 @@ class Database {
password: dbConfig.password, password: dbConfig.password,
database: dbConfig.dbName, database: dbConfig.dbName,
timezone: "Z", timezone: "Z",
ssl: sslConfig,
typeCast: function (field, next) { typeCast: function (field, next) {
if (field.type === "DATETIME") { if (field.type === "DATETIME") {
// Do not perform timezone conversion // Do not perform timezone conversion

@ -1,3 +1,4 @@
/* eslint-disable linebreak-style */
const express = require("express"); const express = require("express");
const { log } = require("../src/util"); const { log } = require("../src/util");
const expressStaticGzip = require("express-static-gzip"); const expressStaticGzip = require("express-static-gzip");
@ -6,6 +7,7 @@ const path = require("path");
const Database = require("./database"); const Database = require("./database");
const { allowDevAllOrigin } = require("./util-server"); const { allowDevAllOrigin } = require("./util-server");
const mysql = require("mysql2/promise"); const mysql = require("mysql2/promise");
const { mariaDbUseSSL, mariaDbSslCert } = require("./config");
/** /**
* A standalone express app that is used to setup a database * A standalone express app that is used to setup a database
@ -208,11 +210,22 @@ class SetupDatabase {
// Test connection // Test connection
try { try {
let sslConfig = null;
let serverCa = undefined;
if (mariaDbUseSSL) {
serverCa = [ fs.readFileSync(mariaDbSslCert, "utf8") ];
sslConfig = {
rejectUnauthorized: true,
ca: serverCa
};
}
const connection = await mysql.createConnection({ const connection = await mysql.createConnection({
host: dbConfig.hostname, host: dbConfig.hostname,
port: dbConfig.port, port: dbConfig.port,
user: dbConfig.username, user: dbConfig.username,
password: dbConfig.password, password: dbConfig.password,
ssl: sslConfig
}); });
await connection.execute("SELECT 1"); await connection.execute("SELECT 1");
connection.end(); connection.end();

Loading…
Cancel
Save