Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions backend/internal/certificate.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ const internalCertificate = {
* @param {String} privateKey This is the entire key contents as a string
*/
checkPrivateKey: async (privateKey) => {
const filepath = await tempWrite(privateKey, "/tmp");
const filepath = await tempWrite(privateKey);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems like a fair bug fix. The second parameter is optional, although lib does not specify where the temp file will be created. Reference: https://www.npmjs.com/package/temp-write

const failTimeout = setTimeout(() => {
throw new error.ValidationError(
"Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.",
Expand Down Expand Up @@ -660,7 +660,7 @@ const internalCertificate = {
* @param {Boolean} [throwExpired] Throw when the certificate is out of date
*/
getCertificateInfo: async (certificate, throwExpired) => {
const filepath = await tempWrite(certificate, "/tmp");
const filepath = await tempWrite(certificate);
try {
const certData = await internalCertificate.getCertificateInfoFromFile(filepath, throwExpired);
fs.unlinkSync(filepath);
Expand Down
1 change: 1 addition & 0 deletions backend/internal/host.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const internalHost = {
if (!combinedData.certificate_id) {
combinedData.ssl_forced = false;
combinedData.http2_support = false;
combinedData.http3_support = false;
}

if (!combinedData.ssl_forced) {
Expand Down
45 changes: 43 additions & 2 deletions backend/internal/nginx.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import fs from "node:fs";
import { dirname } from "node:path";
import { fileURLToPath } from "node:url";
import _ from "lodash";
import db from "../db.js";
import errs from "../lib/error.js";
import utils from "../lib/utils.js";
import { debug, nginx as logger } from "../logger.js";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const HTTP_HOST_TABLES = ["proxy_host", "redirection_host", "dead_host"];

const internalNginx = {
/**
* This will:
Expand Down Expand Up @@ -158,6 +161,7 @@ const internalNginx = {
{ block_exploits: host.block_exploits },
{ allow_websocket_upgrade: host.allow_websocket_upgrade },
{ http2_support: host.http2_support },
{ http3_support: host.http3_support },
{ hsts_enabled: host.hsts_enabled },
{ hsts_subdomains: host.hsts_subdomains },
{ access_list: host.access_list },
Expand Down Expand Up @@ -241,7 +245,16 @@ const internalNginx = {
// Set the IPv6 setting for the host
host.ipv6 = internalNginx.ipv6Enabled();

locationsPromise.then(() => {
locationsPromise
.then(async () => {
const friendlyHostType = internalNginx.getFileFriendlyHostType(host_type);
if (HTTP_HOST_TABLES.includes(friendlyHostType) && (host.http3_support === 1 || host.http3_support === true)) {
host.http3_first = await internalNginx.isFirstHttp3Host(friendlyHostType, host.id);
} else {
host.http3_first = false;
}
})
.then(() => {
renderEngine
.parseAndRender(template, host)
.then((config_text) => {
Expand All @@ -257,10 +270,38 @@ const internalNginx = {
debug(logger, `Could not write ${filename}:`, err.message);
reject(new errs.ConfigurationError(err.message));
});
});
})
.catch((err) => {
reject(new errs.ConfigurationError(err.message));
});
});
},

/**
* @param {String} hostType
* @param {Number} hostId
* @returns {Promise<boolean>}
*/
isFirstHttp3Host: async (hostType, hostId) => {
const knex = db();
const rows = await Promise.all(
HTTP_HOST_TABLES.map((table) =>
knex(table)
.select("id")
.where("is_deleted", 0)
.andWhere("enabled", 1)
.andWhere("http3_support", 1)
.andWhere("certificate_id", ">", 0),
),
);

const all = rows
.flatMap((tableRows, index) => tableRows.map((row) => ({ host_type: HTTP_HOST_TABLES[index], id: row.id })))
.sort((a, b) => (a.id === b.id ? a.host_type.localeCompare(b.host_type) : a.id - b.id));

return all.length > 0 && all[0].host_type === hostType && all[0].id === hostId;
},

/**
* This generates a temporary nginx config listening on port 80 for the domain names listed
* in the certificate setup. It allows the letsencrypt acme challenge to be requested by letsencrypt
Expand Down
50 changes: 50 additions & 0 deletions backend/migrations/20251112090000_http3_support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { migrate as logger } from "../logger.js";

const migrateName = "http3_support";

/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @returns {Promise}
*/
const up = (knex) => {
logger.info(`[${migrateName}] Migrating Up...`);

return knex.schema
.table("proxy_host", (proxy_host) => {
proxy_host.integer("http3_support").notNull().unsigned().defaultTo(0);
})
.then(() => {
logger.info(`[${migrateName}] proxy_host Table altered`);

return knex.schema.table("redirection_host", (redirection_host) => {
redirection_host.integer("http3_support").notNull().unsigned().defaultTo(0);
});
})
.then(() => {
logger.info(`[${migrateName}] redirection_host Table altered`);

return knex.schema.table("dead_host", (dead_host) => {
dead_host.integer("http3_support").notNull().unsigned().defaultTo(0);
});
})
.then(() => {
logger.info(`[${migrateName}] dead_host Table altered`);
});
};

/**
* Undo Migrate
*
* @param {Object} knex
* @returns {Promise}
*/
const down = (_knex) => {
logger.warn(`[${migrateName}] You can't migrate down this one.`);
return Promise.resolve(true);
};

export { up, down };
2 changes: 1 addition & 1 deletion backend/models/dead_host.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import User from "./user.js";

Model.knex(db());

const boolFields = ["is_deleted", "ssl_forced", "http2_support", "enabled", "hsts_enabled", "hsts_subdomains"];
const boolFields = ["is_deleted", "ssl_forced", "http2_support", "http3_support", "enabled", "hsts_enabled", "hsts_subdomains"];

class DeadHost extends Model {
$beforeInsert() {
Expand Down
1 change: 1 addition & 0 deletions backend/models/proxy_host.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const boolFields = [
"block_exploits",
"allow_websocket_upgrade",
"http2_support",
"http3_support",
"enabled",
"hsts_enabled",
"hsts_subdomains",
Expand Down
1 change: 1 addition & 0 deletions backend/models/redirection_host.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const boolFields = [
"hsts_enabled",
"hsts_subdomains",
"http2_support",
"http3_support",
];

class RedirectionHost extends Model {
Expand Down
5 changes: 5 additions & 0 deletions backend/schema/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@
"type": "boolean",
"example": true
},
"http3_support": {
"description": "HTTP3 Protocol Support",
"type": "boolean",
"example": true
},
"block_exploits": {
"description": "Should we block common exploits",
"type": "boolean",
Expand Down
20 changes: 19 additions & 1 deletion backend/schema/components/dead-host-object.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,22 @@
{
"type": "object",
"description": "404 Host object",
"required": ["id", "created_on", "modified_on", "owner_user_id", "domain_names", "certificate_id", "ssl_forced", "hsts_enabled", "hsts_subdomains", "http2_support", "advanced_config", "enabled", "meta"],
"required": [
"id",
"created_on",
"modified_on",
"owner_user_id",
"domain_names",
"certificate_id",
"ssl_forced",
"hsts_enabled",
"hsts_subdomains",
"http2_support",
"http3_support",
"advanced_config",
"enabled",
"meta"
],
"additionalProperties": false,
"properties": {
"id": {
Expand Down Expand Up @@ -34,6 +49,9 @@
"http2_support": {
"$ref": "../common.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../common.json#/properties/http3_support"
},
"advanced_config": {
"type": "string",
"example": ""
Expand Down
4 changes: 4 additions & 0 deletions backend/schema/components/proxy-host-object.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"meta",
"allow_websocket_upgrade",
"http2_support",
"http3_support",
"forward_scheme",
"enabled",
"locations",
Expand Down Expand Up @@ -87,6 +88,9 @@
"http2_support": {
"$ref": "../common.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../common.json#/properties/http3_support"
},
"forward_scheme": {
"type": "string",
"enum": ["http", "https"],
Expand Down
4 changes: 4 additions & 0 deletions backend/schema/components/redirection-host-object.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"hsts_enabled",
"hsts_subdomains",
"http2_support",
"http3_support",
"block_exploits",
"advanced_config",
"enabled",
Expand Down Expand Up @@ -80,6 +81,9 @@
"http2_support": {
"$ref": "../common.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../common.json#/properties/http3_support"
},
"block_exploits": {
"$ref": "../common.json#/properties/block_exploits"
},
Expand Down
1 change: 1 addition & 0 deletions backend/schema/paths/nginx/dead-hosts/get.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"nginx_err": null
},
"http2_support": false,
"http3_support": false,
"enabled": true,
"hsts_enabled": false,
"hsts_subdomains": false
Expand Down
1 change: 1 addition & 0 deletions backend/schema/paths/nginx/dead-hosts/hostID/get.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"nginx_err": null
},
"http2_support": false,
"http3_support": false,
"enabled": true,
"hsts_enabled": false,
"hsts_subdomains": false
Expand Down
4 changes: 4 additions & 0 deletions backend/schema/paths/nginx/dead-hosts/hostID/put.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
"http2_support": {
"$ref": "../../../../components/dead-host-object.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../../../../components/dead-host-object.json#/properties/http3_support"
},
"advanced_config": {
"$ref": "../../../../components/dead-host-object.json#/properties/advanced_config"
},
Expand Down Expand Up @@ -80,6 +83,7 @@
"nginx_err": null
},
"http2_support": false,
"http3_support": false,
"enabled": true,
"hsts_enabled": false,
"hsts_subdomains": false,
Expand Down
5 changes: 5 additions & 0 deletions backend/schema/paths/nginx/dead-hosts/post.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
"http2_support": {
"$ref": "../../../components/dead-host-object.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../../../components/dead-host-object.json#/properties/http3_support"
},
"advanced_config": {
"$ref": "../../../components/dead-host-object.json#/properties/advanced_config"
},
Expand All @@ -55,6 +58,7 @@
"ssl_forced": false,
"advanced_config": "",
"http2_support": false,
"http3_support": false,
"hsts_enabled": false,
"hsts_subdomains": false,
"meta": {}
Expand Down Expand Up @@ -82,6 +86,7 @@
"advanced_config": "",
"meta": {},
"http2_support": false,
"http3_support": false,
"enabled": true,
"hsts_enabled": false,
"hsts_subdomains": false,
Expand Down
1 change: 1 addition & 0 deletions backend/schema/paths/nginx/proxy-hosts/get.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
},
"allow_websocket_upgrade": false,
"http2_support": false,
"http3_support": false,
"forward_scheme": "http",
"enabled": true,
"locations": [],
Expand Down
1 change: 1 addition & 0 deletions backend/schema/paths/nginx/proxy-hosts/hostID/get.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
},
"allow_websocket_upgrade": false,
"http2_support": false,
"http3_support": false,
"forward_scheme": "http",
"enabled": true,
"locations": [],
Expand Down
4 changes: 4 additions & 0 deletions backend/schema/paths/nginx/proxy-hosts/hostID/put.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@
"http2_support": {
"$ref": "../../../../components/proxy-host-object.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../../../../components/proxy-host-object.json#/properties/http3_support"
},
"block_exploits": {
"$ref": "../../../../components/proxy-host-object.json#/properties/block_exploits"
},
Expand Down Expand Up @@ -120,6 +123,7 @@
},
"allow_websocket_upgrade": false,
"http2_support": false,
"http3_support": false,
"forward_scheme": "http",
"enabled": true,
"locations": [],
Expand Down
4 changes: 4 additions & 0 deletions backend/schema/paths/nginx/proxy-hosts/post.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
"http2_support": {
"$ref": "../../../components/proxy-host-object.json#/properties/http2_support"
},
"http3_support": {
"$ref": "../../../components/proxy-host-object.json#/properties/http3_support"
},
"block_exploits": {
"$ref": "../../../components/proxy-host-object.json#/properties/block_exploits"
},
Expand Down Expand Up @@ -117,6 +120,7 @@
"meta": {},
"allow_websocket_upgrade": false,
"http2_support": false,
"http3_support": false,
"forward_scheme": "http",
"enabled": true,
"locations": [],
Expand Down
1 change: 1 addition & 0 deletions backend/schema/paths/nginx/redirection-hosts/get.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"nginx_err": null
},
"http2_support": false,
"http3_support": false,
"enabled": true,
"hsts_enabled": false,
"hsts_subdomains": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"nginx_err": null
},
"http2_support": false,
"http3_support": false,
"enabled": true,
"hsts_enabled": false,
"hsts_subdomains": false,
Expand Down
Loading