Security: Add PHOTOPRISM_DEFAULT_TLS config option #3509

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2023-07-15 12:01:06 +02:00
parent 5fb9e95217
commit 651782eb4d
18 changed files with 71 additions and 19 deletions

View file

@ -48,7 +48,12 @@ func (c *Config) TLSCert() string {
}
// Find default TLS certificate.
return find("photoprism" + PublicCertExt)
if c.DefaultTLS() {
return find("photoprism" + PublicCertExt)
}
// Not found.
return ""
}
// TLSKey returns the private key required to enable TLS.
@ -78,7 +83,12 @@ func (c *Config) TLSKey() string {
}
// Find default key file.
return find("photoprism" + PrivateKeyExt)
if c.DefaultTLS() {
return find("photoprism" + PrivateKeyExt)
}
// Not found.
return ""
}
// TLS returns the HTTPS certificate and private key file name.
@ -90,7 +100,7 @@ func (c *Config) TLS() (publicCert, privateKey string) {
return c.TLSCert(), c.TLSKey()
}
// DisableTLS checks if HTTPS should be disabled.
// DisableTLS checks if HTTPS should be disabled even if the site URL starts with https:// and a certificate is available.
func (c *Config) DisableTLS() bool {
if c.options.DisableTLS {
return true
@ -100,3 +110,8 @@ func (c *Config) DisableTLS() bool {
return c.TLSCert() == "" || c.TLSKey() == ""
}
// DefaultTLS checks if a self-signed certificate should be used to enable HTTPS if no other certificate is available.
func (c *Config) DefaultTLS() bool {
return c.options.DefaultTLS
}

View file

@ -31,13 +31,23 @@ func TestConfig_TLSEmail(t *testing.T) {
func TestConfig_TLSCert(t *testing.T) {
c := NewConfig(CliTestContext())
c.options.DefaultTLS = false
assert.Equal(t, "", c.TLSCert())
c.options.DefaultTLS = true
assert.True(t, strings.HasSuffix(c.TLSCert(), "photoprism.crt"))
c.options.DefaultTLS = false
assert.Equal(t, "", c.TLSCert())
}
func TestConfig_TLSKey(t *testing.T) {
c := NewConfig(CliTestContext())
c.options.DefaultTLS = false
assert.Equal(t, "", c.TLSKey())
c.options.DefaultTLS = true
assert.True(t, strings.HasSuffix(c.TLSKey(), "photoprism.key"))
c.options.DefaultTLS = false
assert.Equal(t, "", c.TLSKey())
}
func TestConfig_TLS(t *testing.T) {
@ -54,3 +64,9 @@ func TestConfig_DisableTLS(t *testing.T) {
assert.True(t, c.DisableTLS())
}
func TestConfig_DefaultTLS(t *testing.T) {
c := NewConfig(CliTestContext())
assert.False(t, c.DefaultTLS())
}

View file

@ -456,9 +456,14 @@ var Flags = CliFlags{
}}, {
Flag: cli.BoolFlag{
Name: "disable-tls",
Usage: "disable HTTPS even if a certificate is available",
Usage: "disable HTTPS/TLS even if the site URL starts with https:// and a certificate is available",
EnvVar: EnvVar("DISABLE_TLS"),
}}, {
Flag: cli.BoolFlag{
Name: "default-tls",
Usage: "default to a self-signed HTTPS/TLS certificate if no other certificate is available",
EnvVar: EnvVar("DEFAULT_TLS"),
}}, {
Flag: cli.StringFlag{
Name: "tls-email",
Usage: "`EMAIL` address to enable automatic HTTPS via Let's Encrypt",

View file

@ -107,6 +107,7 @@ type Options struct {
ProxyProtoHeaders []string `yaml:"ProxyProtoHeaders" json:"-" flag:"proxy-proto-header"`
ProxyProtoHttps []string `yaml:"ProxyProtoHttps" json:"-" flag:"proxy-proto-https"`
DisableTLS bool `yaml:"DisableTLS" json:"DisableTLS" flag:"disable-tls"`
DefaultTLS bool `yaml:"DefaultTLS" json:"DefaultTLS" flag:"default-tls"`
TLSEmail string `yaml:"TLSEmail" json:"TLSEmail" flag:"tls-email"`
TLSCert string `yaml:"TLSCert" json:"TLSCert" flag:"tls-cert"`
TLSKey string `yaml:"TLSKey" json:"TLSKey" flag:"tls-key"`

View file

@ -155,6 +155,7 @@ func (c *Config) Report() (rows [][]string, cols []string) {
// Web Server.
{"disable-tls", fmt.Sprintf("%t", c.DisableTLS())},
{"default-tls", fmt.Sprintf("%t", c.DefaultTLS())},
{"tls-email", c.TLSEmail()},
{"tls-cert", c.TLSCert()},
{"tls-key", c.TLSKey()},

View file

@ -13,7 +13,7 @@ clean:
rm -rf /var/lib/apt/lists/*
https: install-https
install-https:
/scripts/install-https.sh
@/scripts/install-https.sh
mariadb: mariadb-client
mariadb-client: install-mariadb-client
install-mariadb-client:

View file

@ -51,6 +51,9 @@ fi
# do nothing if PHOTOPRISM_INIT was not set
if [[ -z ${PHOTOPRISM_INIT} ]]; then
if [[ ${PHOTOPRISM_DEFAULT_TLS} = "true" ]]; then
make --no-print-directory -C "$INIT_SCRIPTS" "https"
fi
exit
fi
@ -60,7 +63,7 @@ INIT_LOCK="/scripts/.init-lock"
if [[ ! -e ${INIT_LOCK} ]]; then
for INIT_TARGET in $PHOTOPRISM_INIT; do
echo "init: $INIT_TARGET"
make -C "$INIT_SCRIPTS" "$INIT_TARGET"
make --no-print-directory -C "$INIT_SCRIPTS" "$INIT_TARGET"
done
echo 1 >${INIT_LOCK}

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Generates local HTTPS keys and certificates on Linux.
# Creates a default TLS certificate that can be used to enable HTTPS if no other certificate is available.
# bash <(curl -s https://raw.githubusercontent.com/photoprism/photoprism/develop/scripts/dist/install-https.sh)
PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/scripts:$PATH"
@ -19,11 +19,11 @@ KEY_PATH="/etc/ssl/private"
# Abort if files already exist.
if [ -f "$CERTS_PATH/photoprism.issuer.crt" ] && [ -f "$KEY_PATH/photoprism.pfx" ]; then
echo "Certificate already exists in ${KEY_PATH} and ${CERTS_PATH}."
echo "Default HTTPS/TLS certificate already exists."
exit 0
fi
echo "Creating keys and certificates in ${KEY_PATH} and ${CERTS_PATH}."
echo "Creating a default HTTPS/TLS certificate."
mkdir -p "${CERTS_PATH}" "${KEY_PATH}"
groupadd -f -r -g 116 ssl-cert 1>&2

View file

@ -55,7 +55,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "none" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_WORKERS: 2 # limits the number of indexing workers to reduce system load

View file

@ -50,7 +50,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "none" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_WORKERS: 1 # Limits the number of indexing workers to reduce system load

View file

@ -142,14 +142,15 @@ services:
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic
PHOTOPRISM_READONLY: "false" # do not modify originals directory (reduced functionality)
PHOTOPRISM_EXPERIMENTAL: "false" # enables experimental features
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS even if a certificate is available
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_DISABLE_CHOWN: "false" # disables updating storage permissions via chmod and chown on startup
PHOTOPRISM_DISABLE_WEBDAV: "false" # disables built-in WebDAV server
PHOTOPRISM_DISABLE_SETTINGS: "false" # disables Settings in Web UI
PHOTOPRISM_DISABLE_TENSORFLOW: "false" # disables all features depending on TensorFlow
PHOTOPRISM_DISABLE_FACES: "false" # disables face detection and recognition (requires TensorFlow)
PHOTOPRISM_DISABLE_CLASSIFICATION: "false" # disables image classification (requires TensorFlow)
PHOTOPRISM_DISABLE_VECTORS: "false" # disables vector graphics support
PHOTOPRISM_DISABLE_VECTORS: "false" # disables vector graphics support
PHOTOPRISM_DISABLE_RAW: "false" # disables indexing and conversion of RAW images
PHOTOPRISM_RAW_PRESETS: "false" # enables applying user presets when converting RAW images (reduces performance)
PHOTOPRISM_JPEG_QUALITY: 85 # a higher value increases the quality and file size of JPEG images and thumbnails (25-100)

View file

@ -47,7 +47,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic

View file

@ -43,7 +43,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic

View file

@ -51,7 +51,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic

View file

@ -45,6 +45,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic

View file

@ -43,7 +43,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic

View file

@ -49,7 +49,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_DEBUG: "false" # run in debug mode, shows additional log messages

View file

@ -51,7 +51,8 @@ services:
PHOTOPRISM_ADMIN_PASSWORD: "insecure" # initial admin password (8-72 characters)
PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password)
PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)"
PHOTOPRISM_DISABLE_TLS: "true" # disables HTTPS/TLS even if the site URL starts with https://
PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available
PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available
PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video)
PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip)
PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic