Vaultwarden bundle

This commit is contained in:
Daniel Berteaud 2023-11-01 22:51:13 +01:00
parent e841b2c48a
commit 36412c2768
9 changed files with 253 additions and 0 deletions

4
bundles.yml Normal file
View File

@ -0,0 +1,4 @@
---
dependencies:
- url: ../common.git

View File

@ -0,0 +1,3 @@
Kind = "service-defaults"
Name = "[[ .vaultwarden.instance ]][[ .consul.suffix ]]"
Protocol = "http"

View File

@ -0,0 +1,16 @@
[[ $c := merge .vaultwarden . -]]
Kind = "service-intentions"
Name = "[[ $c.instance ]][[ $c.consul.suffix ]]"
Sources = [
{
Name = "[[ $c.traefik.instance ]]"
Permissions = [
{
Action = "allow"
HTTP {
Methods = ["GET", "HEAD", "POST", "PUT", "DELETE"]
}
}
]
}
]

View File

@ -0,0 +1,72 @@
FROM rust:alpine AS build
ARG VAULTWARDEN_FEATURES=[[ join .vaultwarden.server.features "," ]] \
VAULTWARDEN_SERVER_VERSION=1.29.2 \
VAULTWARDEN_WEB_VERSION=2023.9.1
RUN set -euxo pipefail &&\
apk --no-cache upgrade &&\
apk --no-cache add \
curl \
ca-certificates \
tar \
musl-dev \
[[- if has .vaultwarden.server.features "postgresql" ]]
postgresql15-dev \
[[- end ]]
[[- if has .vaultwarden.server.features "mysql" ]]
mariadb-dev \
[[- end ]]
[[- if has .vaultwarden.server.features "sqlite" ]]
sqlite-dev \
[[- end ]]
&&\
cd /tmp &&\
curl -sSLO https://github.com/dani-garcia/vaultwarden/archive/refs/tags/${VAULTWARDEN_SERVER_VERSION}.tar.gz &&\
tar xvzf ${VAULTWARDEN_SERVER_VERSION}.tar.gz &&\
cd vaultwarden-${VAULTWARDEN_SERVER_VERSION} &&\
rustup target add x86_64-unknown-linux-musl &&\
cargo build --features=${VAULTWARDEN_FEATURES} --profile "release" --target "x86_64-unknown-linux-musl" &&\
find ./target -type f -name vaultwarden &&\
# Move vaultwarden bin to copy it easily in the runtime stage \
mv ./target/x86_64-unknown-linux-musl/release/vaultwarden / &&\
chown root:root /vaultwarden &&\
chmod 755 /vaultwarden &&\
cd ../ &&\
curl -sSLO https://github.com/dani-garcia/bw_web_builds/releases/download/v${VAULTWARDEN_WEB_VERSION}/bw_web_v${VAULTWARDEN_WEB_VERSION}.tar.gz &&\
tar xvzf bw_web_v${VAULTWARDEN_WEB_VERSION}.tar.gz &&\
mv web-vault / &&\
chown -R root:root /web-vault
FROM [[ .docker.repo ]][[ .docker.base_images.alpine.image ]]
MAINTAINER [[ .docker.maintainer ]]
ENV ROCKET_PROFILE=release \
ROCKET_ADDRESS=0.0.0.0 \
ROCKET_PORT=8234 \
DATA_FOLDER=/data \
DATABASE_URL=/data/db.sqlite3
COPY --from=build /vaultwarden /usr/local/bin/
COPY --from=build /web-vault /opt/vaultwarden/web-vault
RUN set -euxo pipefail &&\
apk --no-cache upgrade &&\
apk --no-cache add \
ca-certificates \
curl \
openssl \
tzdata \
&&\
addgroup -g 8234 vaultwarden &&\
adduser --system --ingroup vaultwarden --disabled-password --uid 8234 --home /opt/vaultwarden --shell /sbin/nologin vaultwarden &&\
mkdir /data &&\
chown vaultwarden:vaultwarden /data
WORKDIR /opt/vaultwarden
USER vaultwarden
EXPOSE 8234
CMD ["vaultwarden"]

8
init/vault-vaultwarden Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
set -euo pipefail
[[- template "common/vault.mkpgrole.sh.tpl"
dict "ctx" .
"config" (dict "role" .vaultwarden.instance "database" "postgres")
]]

1
prep.d/10-mv_conf.sh Executable file
View File

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

42
variables.yml Normal file
View File

@ -0,0 +1,42 @@
---
vaultwarden:
instance: vaultwarden
server:
count: 1
image: vaultwarden/server:1.29.2
#image: danielberteaud/vaultwarden:latest
features:
- postgresql
resources:
cpu: 80
memory: 128
consul:
connect:
upstreams:
- service_name: '[[ .mail.smtp_service_name ]]'
local_bind_port: 25
env:
ORG_EVENTS_ENABLED: 'true'
EVENTS_DAYS_RETAIN: 720
SIGNUPS_VERIFY: 'true'
SMTP_HOST: localhost
SMTP_PORT: 25
SMTP_FROM: vaultwarden-no-reply@[[ .consul.domain ]]
SMTP_SECURITY: off
TRASH_AUTO_DELETE_DAYS: 7
INCOMPLETE_2FA_TIME_LIMIT: 5
USER_ATTACHMENT_LIMIT: 204800
public_url: https://vaultwarden.example.org/
traefik:
middlewares: []
admin:
traefik:
middlewares: []
volumes:
data:
type: csi
source: vaultwarden-data

View File

@ -0,0 +1,4 @@
[[ $c := merge .vaultwarden . ]]
path "[[ $c.vault.prefix ]]database/creds/[[ $c.instance ]]" {
capabilities = ["read"]
}

103
vaultwarden.nomad.hcl Normal file
View File

@ -0,0 +1,103 @@
[[ $c := merge .vaultwarden.server . -]]
job "[[ .vaultwarden.instance ]]" {
[[ template "common/job_start.tpl" $c ]]
group "vaultwarden" {
count = [[ $c.count ]]
network {
mode = "bridge"
}
volume "data" {
type = [[ .vaultwarden.volumes.data.type | toJSON ]]
source = [[ .vaultwarden.volumes.data.source | toJSON ]]
attachment_mode = "file-system"
access_mode = "multi-node-multi-writer"
}
service {
name = "[[ .vaultwarden.instance ]][[ $c.consul.suffix ]]"
port = 8234
[[ template "common/connect.tpl" $c ]]
check {
type = "http"
path = "/alive"
expose = true
interval = "5s"
timeout = "3s"
check_restart {
limit = 20
grace = "20s"
}
}
tags = [
[[- $a := merge .vaultwarden.admin . ]]
"[[ $c.traefik.instance ]].enable=true",
[[- if ne $c.traefik.instance $a.traefik.instance ]]
"[[ $a.traefik.instance ]].enable=true",
[[- end ]]
# Admin interface
"[[ $a.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $a.consul.suffix ]]-admin.rule=Host(`[[ (urlParse $c.public_url).Hostname ]]`) && PathPrefix(`[[ (urlParse $c.public_url).Path | regexp.Replace "/$" "" ]]/admin`)",
"[[ $a.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $a.consul.suffix ]]-admin.entrypoints=[[ join $a.traefik.entrypoints "," ]]",
"[[ $a.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $a.consul.suffix ]]-admin.priority=200",
"[[ $a.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $a.consul.suffix ]].middlewares=[[ template "common/traefik_middlewares.tpl" $a.traefik ]]",
# Main interface
"[[ $c.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $c.consul.suffix ]].rule=Host(`[[ (urlParse $c.public_url).Hostname ]]`)
[[- if not ((urlParse $c.public_url).Path | regexp.Match "^/?$") ]] && PathPrefix(`[[ (urlParse $c.public_url).Path ]]`)[[ end ]]",
"[[ $c.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $c.consul.suffix ]].entrypoints=[[ join $c.traefik.entrypoints "," ]]",
"[[ $c.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $c.consul.suffix ]].priority=100",
"[[ $c.traefik.instance ]].http.middlewares.[[ .vaultwarden.instance ]]-csp[[ $c.consul.suffix ]].headers.contentSecurityPolicy=default-src 'self'; img-src 'self' data: https://www.gravatar.com; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; font-src 'self' data:; connect-src 'self' https://api.pwnedpasswords.com https://api.2fa.directory",
[[- if not ((urlParse $c.public_url).Path | regexp.Match "^/?$") ]]
"[[ $c.traefik.instance ]].http.middlewares.[[ .vaultwarden.instance ]][[ $c.consul.suffix ]]-prefix.stripprefix.prefixes=[[ (urlParse $c.public_url).Path ]]",
"[[ $c.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $c.consul.suffix ]].middlewares=[[ .vaultwarden.instance ]]-csp[[ $c.consul.suffix ]],[[ template "common/traefik_middlewares.tpl" $c.traefik ]],[[ .vaultwarden.instance ]][[ $c.consul.suffix ]]-prefix",
[[- else ]]
"[[ $c.traefik.instance ]].http.routers.[[ .vaultwarden.instance ]][[ $c.consul.suffix ]].middlewares=[[ .vaultwarden.instance ]]-csp[[ $c.consul.suffix ]],[[ template "common/traefik_middlewares.tpl" $c.traefik ]]",
[[- end ]]
]
}
[[ template "common/task.wait_for.tpl" $c ]]
task "vaultwarden" {
driver = [[ $c.nomad.driver | toJSON ]]
user = 8234
config {
image = [[ $c.image | toJSON ]]
pids_limit = 100
readonly_rootfs = true
}
vault {
policies = ["[[ .vaultwarden.instance ]][[ $c.consul.suffix ]]"]
env = false
disable_file = true
}
env {
ROCKET_ADDRESS = "127.0.0.1"
ROCKET_PORT = 8234
IP_HEADER = "X-Forwarded-for"
DOMAIN = [[ $c.public_url | toJSON ]]
DB_CONNECTION_RETRIES = 0
[[ template "common/proxy_env.tpl" $c ]]
}
[[ template "common/file_env.tpl" $c.env ]]
volume_mount {
volume = "data"
destination = "/data"
}
[[ template "common/resources.tpl" $c.resources ]]
}
}
}