This commit is contained in:
Daniel Berteaud 2024-01-31 15:20:01 +01:00
parent 0ac78089a4
commit 2bd87ad6e7
10 changed files with 42 additions and 76 deletions

View File

@ -2,7 +2,7 @@
set -euo pipefail set -euo pipefail
vault write database/roles/paperless \ vault write /database/roles/paperless \
db_name="postgres" \ db_name="postgres" \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \ creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT \"paperless\" TO \"{{name}}\"; \ GRANT \"paperless\" TO \"{{name}}\"; \

View File

@ -61,10 +61,10 @@ job "paperless" {
tags = [ tags = [
"traefik.enable=true", "traefik.enable=true",
"traefik.http.routers.paperless.rule=Host(`paperless.example.org`)",
"traefik.http.routers.paperless.entrypoints=https", "traefik.http.routers.paperless.entrypoints=https",
"traefik.http.middlewares.paperless-csp.headers.contentsecuritypolicy=default-src 'self';font-src 'self' data:;img-src 'self' data:;script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';", "traefik.http.routers.paperless.rule=Host(`paperless.example.org`)",
"traefik.http.routers.paperless.middlewares=security-headers@file,rate-limit-std@file,forward-proto@file,inflight-std@file,hsts@file,compression@file,paperless-csp", "traefik.http.middlewares.csp-paperless.headers.contentsecuritypolicy=default-src 'self';font-src 'self' data:;img-src 'self' data:;script-src 'self' 'unsafe-inline' 'unsafe-eval';style-src 'self' 'unsafe-inline';",
"traefik.http.routers.paperless.middlewares=security-headers@file,rate-limit-std@file,forward-proto@file,inflight-std@file,hsts@file,compression@file,csp-paperless",
] ]
} }
@ -166,7 +166,7 @@ PAPERLESS_CONVERT_TMPDIR=/alloc/data
PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org
PAPERLESS_ENABLE_COMPRESSION=false PAPERLESS_ENABLE_COMPRESSION=false
PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]' PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]'
PAPERLESS_SECRET_KEY={{ with secret "kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }} PAPERLESS_SECRET_KEY={{ with secret "/kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }}
PAPERLESS_TRUSTED_PROXIES=127.0.0.1 PAPERLESS_TRUSTED_PROXIES=127.0.0.1
PAPERLESS_URL=https://paperless.example.org PAPERLESS_URL=https://paperless.example.org
PAPERLESS_USE_X_FORWARD_HOST=true PAPERLESS_USE_X_FORWARD_HOST=true
@ -182,8 +182,8 @@ _EOT
data = <<_EOT data = <<_EOT
PAPERLESS_DBHOST=127.0.0.1 PAPERLESS_DBHOST=127.0.0.1
PAPERLESS_DBPORT=5432 PAPERLESS_DBPORT=5432
PAPERLESS_DBUSER={{ with secret "database/creds/paperless" }}{{ .Data.username }}{{ end }} PAPERLESS_DBUSER={{ with secret "/database/creds/paperless" }}{{ .Data.username }}{{ end }}
PAPERLESS_DBPASS={{ with secret "database/creds/paperless" }}{{ .Data.password }}{{ end }} PAPERLESS_DBPASS={{ with secret "/database/creds/paperless" }}{{ .Data.password }}{{ end }}
_EOT _EOT
destination = "secrets/.db.env" destination = "secrets/.db.env"
perms = 400 perms = 400
@ -243,7 +243,7 @@ PAPERLESS_CONVERT_TMPDIR=/alloc/data
PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org
PAPERLESS_ENABLE_COMPRESSION=false PAPERLESS_ENABLE_COMPRESSION=false
PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]' PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]'
PAPERLESS_SECRET_KEY={{ with secret "kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }} PAPERLESS_SECRET_KEY={{ with secret "/kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }}
PAPERLESS_TRUSTED_PROXIES=127.0.0.1 PAPERLESS_TRUSTED_PROXIES=127.0.0.1
PAPERLESS_URL=https://paperless.example.org PAPERLESS_URL=https://paperless.example.org
PAPERLESS_USE_X_FORWARD_HOST=true PAPERLESS_USE_X_FORWARD_HOST=true
@ -259,8 +259,8 @@ _EOT
data = <<_EOT data = <<_EOT
PAPERLESS_DBHOST=127.0.0.1 PAPERLESS_DBHOST=127.0.0.1
PAPERLESS_DBPORT=5432 PAPERLESS_DBPORT=5432
PAPERLESS_DBUSER={{ with secret "database/creds/paperless" }}{{ .Data.username }}{{ end }} PAPERLESS_DBUSER={{ with secret "/database/creds/paperless" }}{{ .Data.username }}{{ end }}
PAPERLESS_DBPASS={{ with secret "database/creds/paperless" }}{{ .Data.password }}{{ end }} PAPERLESS_DBPASS={{ with secret "/database/creds/paperless" }}{{ .Data.password }}{{ end }}
_EOT _EOT
destination = "secrets/.db.env" destination = "secrets/.db.env"
perms = 400 perms = 400
@ -322,7 +322,7 @@ PAPERLESS_CONVERT_TMPDIR=/alloc/data
PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org
PAPERLESS_ENABLE_COMPRESSION=false PAPERLESS_ENABLE_COMPRESSION=false
PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]' PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]'
PAPERLESS_SECRET_KEY={{ with secret "kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }} PAPERLESS_SECRET_KEY={{ with secret "/kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }}
PAPERLESS_TRUSTED_PROXIES=127.0.0.1 PAPERLESS_TRUSTED_PROXIES=127.0.0.1
PAPERLESS_URL=https://paperless.example.org PAPERLESS_URL=https://paperless.example.org
PAPERLESS_USE_X_FORWARD_HOST=true PAPERLESS_USE_X_FORWARD_HOST=true
@ -338,8 +338,8 @@ _EOT
data = <<_EOT data = <<_EOT
PAPERLESS_DBHOST=127.0.0.1 PAPERLESS_DBHOST=127.0.0.1
PAPERLESS_DBPORT=5432 PAPERLESS_DBPORT=5432
PAPERLESS_DBUSER={{ with secret "database/creds/paperless" }}{{ .Data.username }}{{ end }} PAPERLESS_DBUSER={{ with secret "/database/creds/paperless" }}{{ .Data.username }}{{ end }}
PAPERLESS_DBPASS={{ with secret "database/creds/paperless" }}{{ .Data.password }}{{ end }} PAPERLESS_DBPASS={{ with secret "/database/creds/paperless" }}{{ .Data.password }}{{ end }}
_EOT _EOT
destination = "secrets/.db.env" destination = "secrets/.db.env"
perms = 400 perms = 400
@ -401,7 +401,7 @@ PAPERLESS_CONVERT_TMPDIR=/alloc/data
PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org PAPERLESS_CORS_ALLOWED_HOSTS=https://paperless.example.org
PAPERLESS_ENABLE_COMPRESSION=false PAPERLESS_ENABLE_COMPRESSION=false
PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]' PAPERLESS_PROXY_SSL_HEADER='["HTTP_X_FORWARDED_PROTO", "https"]'
PAPERLESS_SECRET_KEY={{ with secret "kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }} PAPERLESS_SECRET_KEY={{ with secret "/kv/service/paperless" }}{{ .Data.data.secret_key }}{{ end }}
PAPERLESS_TRUSTED_PROXIES=127.0.0.1 PAPERLESS_TRUSTED_PROXIES=127.0.0.1
PAPERLESS_URL=https://paperless.example.org PAPERLESS_URL=https://paperless.example.org
PAPERLESS_USE_X_FORWARD_HOST=true PAPERLESS_USE_X_FORWARD_HOST=true
@ -417,8 +417,8 @@ _EOT
data = <<_EOT data = <<_EOT
PAPERLESS_DBHOST=127.0.0.1 PAPERLESS_DBHOST=127.0.0.1
PAPERLESS_DBPORT=5432 PAPERLESS_DBPORT=5432
PAPERLESS_DBUSER={{ with secret "database/creds/paperless" }}{{ .Data.username }}{{ end }} PAPERLESS_DBUSER={{ with secret "/database/creds/paperless" }}{{ .Data.username }}{{ end }}
PAPERLESS_DBPASS={{ with secret "database/creds/paperless" }}{{ .Data.password }}{{ end }} PAPERLESS_DBPASS={{ with secret "/database/creds/paperless" }}{{ .Data.password }}{{ end }}
_EOT _EOT
destination = "secrets/.db.env" destination = "secrets/.db.env"
perms = 400 perms = 400

View File

@ -1,19 +0,0 @@
#!/bin/sh
set -eu
if [ "paperless" != "paperless" ]; then
for DIR in vault consul nomad; do
if [ -d output/${DIR} ]; then
for FILE in $(find output/${DIR} -name "*paperless*.hcl" -type f); do
NEW_FILE=$(echo "${FILE}" | sed -E "s/paperless/paperless/g")
mv "${FILE}" "${NEW_FILE}"
done
fi
done
fi

View File

@ -2,16 +2,21 @@
set -euo pipefail set -euo pipefail
# Initialize random passwords if needed # vim: syntax=sh
export LC_ALL=C
VAULT_KV_PATH=/kv/service/paperless
RAND_CMD="tr -dc A-Za-z0-9\-_\/=~\.+ < /dev/urandom | head -c 50"
if ! vault kv list $(dirname ${VAULT_KV_PATH}) 2>/dev/null | grep -q -E "^$(basename ${VAULT_KV_PATH})\$"; then
vault kv put ${VAULT_KV_PATH} \
secret_key="$(sh -c "${RAND_CMD}")" \
if ! vault kv list kv/service 2>/dev/null | grep -q -E '^paperless$'; then
vault kv put kv/service/paperless \
secret_key=$(pwgen -s -n 50 1)
fi fi
for SECRET in secret_key; do
for PWD in secret_key; do if ! vault kv get -field ${SECRET} ${VAULT_KV_PATH} >/dev/null 2>&1; then
if ! vault kv get -field ${PWD} kv/service/paperless >/dev/null 2>&1; then vault kv patch ${VAULT_KV_PATH} \
vault kv patch kv/service/paperless \ ${SECRET}=$(sh -c "${RAND_CMD}")
${PWD}=$(pwgen -s -n 50 1)
fi fi
done done

View File

@ -1,7 +1,7 @@
path "kv/data/service/paperless" { path "/kv/data/service/paperless" {
capabilities = ["read"] capabilities = ["read"]
} }
path "database/creds/paperless" { path "/database/creds/paperless" {
capabilities = ["read"] capabilities = ["read"]
} }

View File

@ -2,7 +2,4 @@
set -euo pipefail set -euo pipefail
[[- template "common/vault.mkpgrole.sh" [[ template "common/vault.mkpgrole.sh" merge .paperless . ]]
dict "ctx" .
"config" (dict "role" .instance "database" "postgres")
]]

View File

@ -1 +0,0 @@
[[ template "common/mv_conf.sh" dict "ctx" . "services" (dict "paperless" .instance) ]]

View File

@ -2,16 +2,4 @@
set -euo pipefail set -euo pipefail
# Initialize random passwords if needed [[ template "common/vault.rand_secrets" merge .paperless . ]]
if ! vault kv list [[ .vault.prefix ]]kv/service 2>/dev/null | grep -q -E '^[[ .instance ]]$'; then
vault kv put [[ .vault.prefix ]]kv/service/[[ .instance ]] \
secret_key=$(pwgen -s -n 50 1)
fi
for PWD in secret_key; do
if ! vault kv get -field ${PWD} [[ .vault.prefix ]]kv/service/[[ .instance ]] >/dev/null 2>&1; then
vault kv patch [[ .vault.prefix ]]kv/service/[[ .instance ]] \
${PWD}=$(pwgen -s -n 50 1)
fi
done

View File

@ -15,23 +15,19 @@ paperless:
- destination_name: postgres[[ .consul.suffix ]] - destination_name: postgres[[ .consul.suffix ]]
local_bind_port: 5432 local_bind_port: 5432
# Vault policies to add to the containers
vault: vault:
# Vault policies to add to the containers
policies: policies:
- '[[ .instance ]][[ .consul.suffix ]]' - '[[ .instance ]][[ .consul.suffix ]]'
# Random secrets to generate and store in vault KV
# Parameters for the postgres database rand_secrets:
postgres: fields:
host: 127.0.0.1 - secret_key
port: 5432
database: '[[ .instance ]]'
user: '{{ with secret "[[ .vault.prefix ]]database/creds/[[ .instance ]]" }}{{ .Data.username }}{{ end }}'
password: '{{ with secret "[[ .vault.prefix ]]database/creds/[[ .instance ]]" }}{{ .Data.password }}{{ end }}'
# Env var to set in the containers # Env var to set in the containers
# The ones here will be inherited by all containers # The ones here will be inherited by all containers
env: env:
PAPERLESS_SECRET_KEY: '{{ with secret "[[ .vault.prefix ]]kv/service/[[ .instance ]]" }}{{ .Data.data.secret_key }}{{ end }}' PAPERLESS_SECRET_KEY: '{{ with secret "[[ .vault.root ]]kv/service/[[ .instance ]]" }}{{ .Data.data.secret_key }}{{ end }}'
PAPERLESS_CORS_ALLOWED_HOSTS: '[[ .paperless.webserver.public_url ]]' PAPERLESS_CORS_ALLOWED_HOSTS: '[[ .paperless.webserver.public_url ]]'
PAPERLESS_URL: '[[ .paperless.webserver.public_url ]]' PAPERLESS_URL: '[[ .paperless.webserver.public_url ]]'
PAPERLESS_CONVERT_TMPDIR: /alloc/data PAPERLESS_CONVERT_TMPDIR: /alloc/data

View File

@ -1,7 +1,7 @@
path "[[ .vault.prefix ]]kv/data/service/[[ .instance ]]" { path "[[ .vault.root ]]kv/data/service/[[ .instance ]]" {
capabilities = ["read"] capabilities = ["read"]
} }
path "[[ .vault.prefix ]]database/creds/[[ .instance ]]" { path "[[ .vault.root ]]database/creds/[[ .instance ]]" {
capabilities = ["read"] capabilities = ["read"]
} }