diff --git a/config/default.yaml b/config/default.yaml index dce95440c8b..691431e6d57 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -80,6 +80,20 @@ trust_proxy: database: hostname: '127.0.0.1' port: 5432 + # ssl options: + # false - no ssl + # true - ssl without cert validation + # object - full control over tls + # + # Note: + # Each file path (ca, cert, key) MUST be absolute path + # + # Example: + # ssl: + # reject_unauthorized: false + # ca: '/abs/path/to/server-certificates/root.crt' + # cert: '/abs/path/to/client-certificates/postgresql.crt' + # key: '/abs/path/to/client-key/postgresql.key' ssl: false suffix: '_dev' username: 'peertube' diff --git a/config/production.yaml.example b/config/production.yaml.example index 908f6f41d09..e0127e6ea85 100644 --- a/config/production.yaml.example +++ b/config/production.yaml.example @@ -78,6 +78,20 @@ trust_proxy: database: hostname: '127.0.0.1' port: 5432 + # ssl options: + # false - no ssl + # true - ssl without cert validation + # object - full control over tls + # + # Note: + # Each file path (ca, cert, key) MUST be absolute path + # + # Example: + # ssl: + # reject_unauthorized: false + # ca: '/abs/path/to/server-certificates/root.crt' + # cert: '/abs/path/to/client-certificates/postgresql.crt' + # key: '/abs/path/to/client-key/postgresql.key' ssl: false suffix: '_prod' username: 'peertube' diff --git a/server/core/initializers/config.ts b/server/core/initializers/config.ts index 21a788921fd..99f1c931837 100644 --- a/server/core/initializers/config.ts +++ b/server/core/initializers/config.ts @@ -37,7 +37,19 @@ const CONFIG = { DBNAME: config.has('database.name') ? config.get('database.name') : 'peertube' + config.get('database.suffix'), HOSTNAME: config.get('database.hostname'), PORT: config.get('database.port'), - SSL: config.get('database.ssl'), + SSL: (() => { + if (!config.has('database.ssl')) return false + + const ssl = config.get('database.ssl') + if (typeof ssl === 'boolean') return ssl + + return { + REJECT_UNAUTHORIZED: ssl.reject_unauthorized ?? null, + CA: ssl.ca ?? null, + CERT: ssl.cert ?? null, + KEY: ssl.key ?? null, + } + })(), USERNAME: config.get('database.username'), PASSWORD: config.get('database.password'), POOL: { diff --git a/server/core/initializers/database.ts b/server/core/initializers/database.ts index 9efb01731b0..9483589ac38 100644 --- a/server/core/initializers/database.ts +++ b/server/core/initializers/database.ts @@ -33,6 +33,7 @@ import { LocalVideoViewerWatchSectionModel } from '@server/models/view/local-vid import { LocalVideoViewerModel } from '@server/models/view/local-video-viewer.js' import { WatchedWordsListModel } from '@server/models/watched-words/watched-words-list.js' import pg from 'pg' +import { readFileSync } from 'fs' import { QueryTypes, Transaction } from 'sequelize' import { Sequelize as SequelizeTypescript } from 'sequelize-typescript' import { logger } from '../helpers/logger.js' @@ -85,10 +86,17 @@ const poolMax = CONFIG.DATABASE.POOL.MAX let dialectOptions: any = {} -if (CONFIG.DATABASE.SSL) { +// Backward compatibility +if (CONFIG.DATABASE.SSL === true) { + dialectOptions = { ssl: { rejectUnauthorized: false } } +} else if (CONFIG.DATABASE.SSL) { dialectOptions = { + // For reference: https://node-postgres.com/features/ssl ssl: { - rejectUnauthorized: false + ...(CONFIG.DATABASE.SSL.REJECT_UNAUTHORIZED != null && { rejectUnauthorized: CONFIG.DATABASE.SSL.REJECT_UNAUTHORIZED }), + ...(CONFIG.DATABASE.SSL.CA && { ca: readFileSync(CONFIG.DATABASE.SSL.CA, { encoding: 'utf8' }) }), + ...(CONFIG.DATABASE.SSL.CERT && { cert: readFileSync(CONFIG.DATABASE.SSL.CERT, { encoding: 'utf8' }) }), + ...(CONFIG.DATABASE.SSL.KEY && { key: readFileSync(CONFIG.DATABASE.SSL.KEY, { encoding: 'utf8' }) }), } } }