From 0261e875679f1bf63c8d689da7fc7e014597885d Mon Sep 17 00:00:00 2001 From: Stonewall Jackson Date: Sat, 4 Feb 2023 01:23:43 -0500 Subject: initial commit --- roles/vaultwarden/defaults/main.yml | 21 +++++ roles/vaultwarden/handlers/main.yml | 4 + roles/vaultwarden/tasks/database.yml | 18 ++++ roles/vaultwarden/tasks/freeipa.yml | 38 ++++++++ roles/vaultwarden/tasks/main.yml | 100 +++++++++++++++++++++ .../templates/etc/sysconfig/vaultwarden.j2 | 48 ++++++++++ .../etc/systemd/system/vaultwarden.service.j2 | 35 ++++++++ roles/vaultwarden/vars/main.yml | 54 +++++++++++ 8 files changed, 318 insertions(+) create mode 100644 roles/vaultwarden/defaults/main.yml create mode 100644 roles/vaultwarden/handlers/main.yml create mode 100644 roles/vaultwarden/tasks/database.yml create mode 100644 roles/vaultwarden/tasks/freeipa.yml create mode 100644 roles/vaultwarden/tasks/main.yml create mode 100644 roles/vaultwarden/templates/etc/sysconfig/vaultwarden.j2 create mode 100644 roles/vaultwarden/templates/etc/systemd/system/vaultwarden.service.j2 create mode 100644 roles/vaultwarden/vars/main.yml (limited to 'roles/vaultwarden') 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 }} + + ProxyPass http://127.0.0.1:{{ vaultwarden_port }}/ + ProxyPassReverse http://127.0.0.1:{{ vaultwarden_port }}/ + + + + 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] + + + + ProxyPass http://127.0.0.1:{{ vaultwarden_port }}/ + ProxyPassReverse http://127.0.0.1:{{ vaultwarden_port }}/ + + + + 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 }} + -- cgit