aboutsummaryrefslogtreecommitdiffstats
path: root/roles/vaultwarden
diff options
context:
space:
mode:
Diffstat (limited to 'roles/vaultwarden')
-rw-r--r--roles/vaultwarden/defaults/main.yml21
-rw-r--r--roles/vaultwarden/handlers/main.yml4
-rw-r--r--roles/vaultwarden/tasks/database.yml18
-rw-r--r--roles/vaultwarden/tasks/freeipa.yml38
-rw-r--r--roles/vaultwarden/tasks/main.yml100
-rw-r--r--roles/vaultwarden/templates/etc/sysconfig/vaultwarden.j248
-rw-r--r--roles/vaultwarden/templates/etc/systemd/system/vaultwarden.service.j235
-rw-r--r--roles/vaultwarden/vars/main.yml54
8 files changed, 318 insertions, 0 deletions
diff --git a/roles/vaultwarden/defaults/main.yml b/roles/vaultwarden/defaults/main.yml
new file mode 100644
index 0000000..8652adc
--- /dev/null
+++ b/roles/vaultwarden/defaults/main.yml
@@ -0,0 +1,21 @@
+vaultwarden_version: 1.27.0
+vaultwarden_web_version: 2023.1.0
+
+vaultwarden_port: 8008
+vaultwarden_websocket_port: 8009
+
+vaultwarden_server_name: '{{ ansible_fqdn }}'
+vaultwarden_url: https://{{ vaultwarden_server_name }}
+
+vaultwarden_user: s-vaultwarden
+vaultwarden_db_name: vaultwarden
+vaultwarden_db_host: '{{ postgresql_host }}'
+vaultwarden_verify_signups: true
+vaultwarden_signup_domain_whitelist: ['{{ email_domain }}']
+vaultwarden_invitations_allowed: false
+vaultwarden_user_attachment_limit_kb: 1048576 # 1 GB
+vaultwarden_admin_group: role-bitwarden-admin
+
+vaultwarden_smtp_host: '{{ mail_host }}'
+vaultwarden_smtp_from: bitwarden-noreply@{{ email_domain }}
+vaultwarden_smtp_from_name: Bitwarden
diff --git a/roles/vaultwarden/handlers/main.yml b/roles/vaultwarden/handlers/main.yml
new file mode 100644
index 0000000..6f8f7ec
--- /dev/null
+++ b/roles/vaultwarden/handlers/main.yml
@@ -0,0 +1,4 @@
+- name: restart vaultwarden
+ systemd:
+ name: vaultwarden
+ state: restarted
diff --git a/roles/vaultwarden/tasks/database.yml b/roles/vaultwarden/tasks/database.yml
new file mode 100644
index 0000000..313232e
--- /dev/null
+++ b/roles/vaultwarden/tasks/database.yml
@@ -0,0 +1,18 @@
+- name: create database
+ postgresql_db:
+ name: '{{ vaultwarden_db_name }}'
+ state: present
+ delegate_to: "{{ postgresql_inventory_host }}"
+ become: yes
+ become_user: postgres
+ register: vaultwarden_db
+
+- name: create database user
+ postgresql_user:
+ name: '{{ vaultwarden_user }}'
+ db: '{{ vaultwarden_db_name }}'
+ priv: ALL
+ state: present
+ delegate_to: "{{ postgresql_inventory_host }}"
+ become: yes
+ become_user: postgres
diff --git a/roles/vaultwarden/tasks/freeipa.yml b/roles/vaultwarden/tasks/freeipa.yml
new file mode 100644
index 0000000..aea52e6
--- /dev/null
+++ b/roles/vaultwarden/tasks/freeipa.yml
@@ -0,0 +1,38 @@
+- name: create user
+ ipauser:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ vaultwarden_user }}'
+ loginshell: /sbin/nologin
+ homedir: '{{ vaultwarden_home }}'
+ givenname: Vaultwarden
+ sn: Service Account
+ state: present
+ run_once: yes
+
+- name: retrieve user keytab
+ include_role:
+ name: freeipa_keytab
+ vars:
+ keytab_principal: '{{ vaultwarden_user }}'
+ keytab_path: '{{ vaultwarden_keytab }}'
+
+- name: configure gssproxy for kerberized postgres
+ include_role:
+ name: gssproxy_client
+ vars:
+ gssproxy_name: vaultwarden
+ gssproxy_section: service/vaultwarden
+ gssproxy_client_keytab: '{{ vaultwarden_keytab }}'
+ gssproxy_cred_usage: initiate
+ gssproxy_euid: '{{ vaultwarden_user }}'
+
+- name: create admin group
+ ipagroup:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ vaultwarden_admin_group }}'
+ description: Bitwarden Administrators
+ nonposix: yes
+ state: present
+ run_once: yes
diff --git a/roles/vaultwarden/tasks/main.yml b/roles/vaultwarden/tasks/main.yml
new file mode 100644
index 0000000..a4ad144
--- /dev/null
+++ b/roles/vaultwarden/tasks/main.yml
@@ -0,0 +1,100 @@
+- name: install packages
+ dnf:
+ name: '{{ vaultwarden_packages }}'
+ state: present
+
+- import_tasks: freeipa.yml
+ tags: freeipa
+
+- name: create home directory
+ file:
+ path: '{{ vaultwarden_home }}'
+ owner: '{{ vaultwarden_user }}'
+ group: '{{ vaultwarden_user }}'
+ mode: 0755
+ state: directory
+
+- name: download rustup
+ get_url:
+ url: https://sh.rustup.rs
+ dest: '{{ vaultwarden_home }}/rustup.sh'
+ mode: 0555
+ become: yes
+ become_user: '{{ vaultwarden_user }}'
+ register: rustup
+
+- name: install rust
+ command: '{{ vaultwarden_home }}/rustup.sh -y'
+ when: rustup.changed
+ become: yes
+ become_user: '{{ vaultwarden_user }}'
+
+- name: clone git repository
+ git:
+ repo: '{{ vaultwarden_git_repo }}'
+ dest: '{{ vaultwarden_source_dir }}'
+ version: '{{ vaultwarden_version }}'
+ force: yes
+ update: yes
+ become: yes
+ become_user: '{{ vaultwarden_user }}'
+ register: vaultwarden_git
+ notify: restart vaultwarden
+
+- name: build vaultwarden
+ shell:
+ cmd: 'source ${HOME}/.cargo/env && cargo build --features postgresql --release'
+ chdir: '{{ vaultwarden_source_dir }}'
+ become: yes
+ become_user: '{{ vaultwarden_user }}'
+ when: vaultwarden_git.changed
+
+- name: create web vault directory
+ file:
+ path: '{{ vaultwarden_web_dir }}'
+ owner: '{{ vaultwarden_user }}'
+ group: '{{ vaultwarden_user }}'
+ mode: 0755
+ state: directory
+
+- name: extract web vault
+ unarchive:
+ src: '{{ vaultwarden_web_url }}'
+ dest: '{{ vaultwarden_web_dir }}'
+ remote_src: yes
+ extra_opts: --strip-components=1
+ become: yes
+ become_user: '{{ vaultwarden_user }}'
+
+- name: create data directory
+ file:
+ path: '{{ vaultwarden_data_dir }}'
+ owner: '{{ vaultwarden_user }}'
+ group: '{{ vaultwarden_user }}'
+ mode: 0700
+ state: directory
+
+- name: create systemd unit
+ template:
+ src: etc/systemd/system/vaultwarden.service.j2
+ dest: /etc/systemd/system/vaultwarden.service
+ notify: restart vaultwarden
+
+- name: reload systemd daemons
+ systemd:
+ daemon_reload: yes
+
+- name: generate environment file
+ template:
+ src: etc/sysconfig/vaultwarden.j2
+ dest: /etc/sysconfig/vaultwarden
+ notify: restart vaultwarden
+
+- import_tasks: database.yml
+ tags: database
+
+- name: enable systemd unit
+ systemd:
+ name: vaultwarden
+ enabled: yes
+ state: started
diff --git a/roles/vaultwarden/templates/etc/sysconfig/vaultwarden.j2 b/roles/vaultwarden/templates/etc/sysconfig/vaultwarden.j2
new file mode 100644
index 0000000..61d50e7
--- /dev/null
+++ b/roles/vaultwarden/templates/etc/sysconfig/vaultwarden.j2
@@ -0,0 +1,48 @@
+ROCKET_CLI_COLORS=false
+
+LOG_LEVEL=warn
+EXTENDED_LOGGING=true
+
+IP_HEADER=X-Forwarded-For
+
+DATABASE_URL=postgresql://{{ vaultwarden_user }}@{{ vaultwarden_db_host }}/{{ vaultwarden_db_name }}
+
+WEBSOCKET_ENABLED=true
+WEBSOCKET_ADDRESS=127.0.0.1
+WEBSOCKET_PORT={{ vaultwarden_websocket_port }}
+
+SIGNUPS_ALLOWED={{ 'false' if vaultwarden_signup_domain_whitelist else 'true' }}
+SIGNUPS_VERIFY={{ vaultwarden_verify_signups }}
+
+{% if vaultwarden_signup_domain_whitelist %}
+SIGNUPS_DOMAINS_WHITELIST={{ vaultwarden_signup_domain_whitelist | join(',') }}
+{% endif %}
+
+DISABLE_ADMIN_TOKEN=true
+
+INVITATIONS_ALLOWED={{ vaultwarden_invitations_allowed }}
+
+{% if vaultwarden_user_attachment_limit_kb %}
+USER_ATTACHMENT_LIMIT={{ vaultwarden_user_attachment_limit_kb }}
+{% endif %}
+
+DOMAIN={{ vaultwarden_url }}
+
+{% if vaultwarden_yubico_client_id is defined %}
+YUBICO_CLIENT_ID={{ vaultwarden_yubico_client_id }}
+YUBICO_SECRET_KEY={{ vaultwarden_yubico_secret_key }}
+{% endif %}
+
+ROCKET_ADDRESS=127.0.0.1
+ROCKET_PORT={{ vaultwarden_port }}
+
+SMTP_HOST=localhost
+SMTP_FROM={{ vaultwarden_smtp_from }}
+SMTP_FROM_NAME={{ vaultwarden_smtp_from_name }}
+SMTP_SECURITY=off
+SMTP_SSL=false
+SMTP_PORT=25
+
+{% if vaultwarden_haveibeenpwned_api_key is defined %}
+HIBP_API_KEY={{ vaultwarden_haveibeenpwned_api_key }}
+{% endif %}
diff --git a/roles/vaultwarden/templates/etc/systemd/system/vaultwarden.service.j2 b/roles/vaultwarden/templates/etc/systemd/system/vaultwarden.service.j2
new file mode 100644
index 0000000..883359b
--- /dev/null
+++ b/roles/vaultwarden/templates/etc/systemd/system/vaultwarden.service.j2
@@ -0,0 +1,35 @@
+[Unit]
+Description=Vaultwarden Server
+Documentation=https://github.com/dani-garcia/vaultwarden
+Wants=gssproxy.service
+After=network-online.target nss-user-lookup.target gssproxy.service
+
+[Service]
+NoNewPrivileges=yes
+PrivateTmp=yes
+PrivateDevices=yes
+DevicePolicy=closed
+ProtectSystem=strict
+ProtectHome=yes
+ProtectControlGroups=yes
+ProtectKernelModules=yes
+ProtectKernelTunables=yes
+RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
+RestrictNamespaces=yes
+RestrictRealtime=yes
+RestrictSUIDSGID=yes
+LockPersonality=yes
+ReadWritePaths={{ vaultwarden_data_dir }}
+
+User={{ vaultwarden_user }}
+Group={{ vaultwarden_user }}
+
+Environment=DATA_FOLDER={{ vaultwarden_data_dir }}
+Environment=WEB_VAULT_FOLDER={{ vaultwarden_web_dir }}
+Environment=GSS_USE_PROXY=yes
+EnvironmentFile=/etc/sysconfig/vaultwarden
+
+ExecStart={{ vaultwarden_source_dir }}/target/release/vaultwarden
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/vaultwarden/vars/main.yml b/roles/vaultwarden/vars/main.yml
new file mode 100644
index 0000000..5c232ad
--- /dev/null
+++ b/roles/vaultwarden/vars/main.yml
@@ -0,0 +1,54 @@
+vaultwarden_packages:
+ - mariadb-connector-c
+ - libpq
+ - libpq-devel
+ - openssl-devel
+ - git
+ - npm
+ - nodejs
+ - gcc
+
+vaultwarden_home: /opt/vaultwarden
+
+vaultwarden_git_repo: https://github.com/dani-garcia/vaultwarden
+vaultwarden_source_dir: '{{ vaultwarden_home }}/vaultwarden'
+
+vaultwarden_web_url: https://github.com/dani-garcia/bw_web_builds/releases/download/v{{ vaultwarden_web_version }}/bw_web_v{{ vaultwarden_web_version }}.tar.gz
+vaultwarden_web_dir: '{{ vaultwarden_home }}/web-vault'
+
+vaultwarden_data_dir: /var/lib/vaultwarden
+vaultwarden_keytab: /var/lib/gssproxy/clients/{{ vaultwarden_user }}.keytab
+
+vaultwarden_admin_hbac_hostgroup: bitwarden_servers
+vaultwarden_admin_hbac_service: bitwarden-admin
+
+vaultwarden_apache_config: |
+ {{ apache_proxy_config }}
+ <Location />
+ ProxyPass http://127.0.0.1:{{ vaultwarden_port }}/
+ ProxyPassReverse http://127.0.0.1:{{ vaultwarden_port }}/
+ </Location>
+
+ <Location /notifications/hub>
+ ProxyPass http://127.0.0.1:{{ vaultwarden_websocket_port }}/
+ ProxyPassReverse http://127.0.0.1:{{ vaultwarden_websocket_port }}/
+
+ RewriteEngine on
+ RewriteCond %{HTTP:Upgrade} websocket [NC]
+ RewriteCond %{HTTP:Connection} upgrade [NC]
+ RewriteRule ^/?(.*) "ws://127.0.0.1:{{ vaultwarden_websocket_port }}/$1" [P,L]
+ </Location>
+
+ <Location /notifications/hub/negotiate>
+ ProxyPass http://127.0.0.1:{{ vaultwarden_port }}/
+ ProxyPassReverse http://127.0.0.1:{{ vaultwarden_port }}/
+ </Location>
+
+ <Location /admin>
+ AuthType GSSAPI
+ AuthName "FreeIPA Single Sign-On"
+ GssapiLocalName On
+ {{ apache_gssapi_session_config }}
+ {{ apache_ldap_config }}
+ Require ldap-attribute memberof=cn={{ vaultwarden_admin_group }},{{ freeipa_group_basedn }}
+ </Location>