From 761bb67b5c6079665c08239344db63876e1a93b4 Mon Sep 17 00:00:00 2001 From: Bastian de Byl Date: Fri, 7 Feb 2025 19:39:32 -0500 Subject: [PATCH] noticket - add self-hosted bitwarden for skudak --- ansible/roles/podman/defaults/main.yml | 2 + .../tasks/containers/base/conf-nginx-http.yml | 2 + .../containers/base/conf-nginx-https.yml | 2 + .../tasks/containers/skudak/bitwarden.yml | 89 ++++++++++++++++++ .../podman/tasks/containers/skudak/wiki.yml | 8 +- ansible/roles/podman/tasks/main.yml | 6 ++ .../bitwarden.skudakrennsport.com.conf.j2 | 16 ++++ ...itwarden.skudakrennsport.com.https.conf.j2 | 44 +++++++++ ansible/roles/ssl/tasks/certbot.yml | 1 + ansible/vars/vault.yml | Bin 13337 -> 14244 bytes 10 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 ansible/roles/podman/tasks/containers/skudak/bitwarden.yml create mode 100644 ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.conf.j2 create mode 100644 ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.https.conf.j2 diff --git a/ansible/roles/podman/defaults/main.yml b/ansible/roles/podman/defaults/main.yml index b7b8ef4..d0d20f4 100644 --- a/ansible/roles/podman/defaults/main.yml +++ b/ansible/roles/podman/defaults/main.yml @@ -1,5 +1,6 @@ --- bookstack_path: "{{ podman_volumes }}/bookstack" +bitwarden_path: "{{ podman_volumes }}/bitwarden" cam2ip_path: "{{ podman_volumes }}/cam2ip" cloud_path: "{{ podman_volumes }}/cloud" cloud_skudak_path: "{{ podman_volumes }}/skudakcloud" @@ -25,6 +26,7 @@ drone_runner_capacity: "8" base_server_name: bdebyl.net assistant_server_name: assistant.bdebyl.net bookstack_server_name: wiki.skudakrennsport.com +bitwarden_server_name: bitwarden.skudakrennsport.com ci_server_name: ci.bdebyl.net cloud_server_name: cloud.bdebyl.net cloud_skudak_server_name: cloud.skudakrennsport.com diff --git a/ansible/roles/podman/tasks/containers/base/conf-nginx-http.yml b/ansible/roles/podman/tasks/containers/base/conf-nginx-http.yml index 8ea51aa..0f2bb6b 100644 --- a/ansible/roles/podman/tasks/containers/base/conf-nginx-http.yml +++ b/ansible/roles/podman/tasks/containers/base/conf-nginx-http.yml @@ -64,6 +64,7 @@ - "{{ base_server_name }}.conf" - "{{ assistant_server_name }}.conf" - "{{ bookstack_server_name }}.conf" + - "{{ bitwarden_server_name }}.conf" - "{{ ci_server_name }}.http.conf" - "{{ cloud_server_name }}.conf" - "{{ cloud_skudak_server_name }}.conf" @@ -89,6 +90,7 @@ - "{{ base_server_name }}.conf" - "{{ assistant_server_name }}.conf" - "{{ bookstack_server_name }}.conf" + - "{{ bitwarden_server_name }}.conf" - "{{ ci_server_name }}.http.conf" - "{{ cloud_server_name }}.conf" - "{{ cloud_skudak_server_name }}.conf" diff --git a/ansible/roles/podman/tasks/containers/base/conf-nginx-https.yml b/ansible/roles/podman/tasks/containers/base/conf-nginx-https.yml index acdc86c..3db0341 100644 --- a/ansible/roles/podman/tasks/containers/base/conf-nginx-https.yml +++ b/ansible/roles/podman/tasks/containers/base/conf-nginx-https.yml @@ -37,6 +37,7 @@ - "{{ base_server_name }}.https.conf" - "{{ assistant_server_name }}.https.conf" - "{{ bookstack_server_name }}.https.conf" + - "{{ bitwarden_server_name }}.https.conf" - "{{ ci_server_name }}.https.conf" - "{{ cloud_server_name }}.https.conf" - "{{ cloud_skudak_server_name }}.https.conf" @@ -60,6 +61,7 @@ - "{{ base_server_name }}.https.conf" - "{{ assistant_server_name }}.https.conf" - "{{ bookstack_server_name }}.https.conf" + - "{{ bitwarden_server_name }}.https.conf" - "{{ ci_server_name }}.https.conf" - "{{ cloud_server_name }}.https.conf" - "{{ cloud_skudak_server_name }}.https.conf" diff --git a/ansible/roles/podman/tasks/containers/skudak/bitwarden.yml b/ansible/roles/podman/tasks/containers/skudak/bitwarden.yml new file mode 100644 index 0000000..0239ff7 --- /dev/null +++ b/ansible/roles/podman/tasks/containers/skudak/bitwarden.yml @@ -0,0 +1,89 @@ +--- +- name: create required bitwarden volumes + become: true + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ podman_subuid.stdout }}" + group: "{{ podman_subuid.stdout }}" + mode: 0755 + notify: restorecon podman + loop: + - "{{ bitwarden_path }}/mysql" + - "{{ bitwarden_path }}/bitwarden" + +- name: flush handlers + ansible.builtin.meta: flush_handlers + +- import_tasks: podman/podman-check.yml + vars: + container_name: bitwarden-db + container_image: "{{ db_image }}" + +- name: create bitwarden-db container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: bitwarden-db + image: "{{ db_image }}" + restart_policy: on-failure:3 + log_driver: journald + network: + - shared + env: + MARIADB_RANDOM_ROOT_PASSWORD: "true" + MARIADB_DATABASE: bitwarden_vault + MARIADB_PASSWORD: "{{ bitwarden_db_pass }}" + MARIADB_USER: bitwarden + volumes: + - "{{ bitwarden_path }}/mysql:/var/lib/mysql" + +- name: create systemd startup job for bitwarden-db + include_tasks: podman/systemd-generate.yml + vars: + container_name: bitwarden-db + +- import_tasks: podman/podman-check.yml + vars: + container_name: bitwarden + container_image: "{{ image }}" + +- name: create bitwarden container + become: true + become_user: "{{ podman_user }}" + containers.podman.podman_container: + name: bitwarden + image: "{{ image }}" + restart_policy: on-failure:3 + log_driver: journald + network: + - shared + env: + BW_ENABLE_SSL: "false" + BW_ENABLE_SSL_CA: "false" + BW_PORT_HTTP: "8092" + BW_DOMAIN: "{{ bitwarden_server_name }}" + BW_DB_PROVIDER: mysql + BW_DB_SERVER: bitwarden-db + BW_DB_DATABASE: bitwarden_vault + BW_DB_USERNAME: bitwarden + BW_DB_PASSWORD: "{{ bitwarden_db_pass }}" + BW_INSTALLATION_ID: "{{ bitwarden_id }}" + BW_INSTALLATION_KEY: "{{ bitwarden_key }}" + globalSettings__mail__replyToEmail: "{{ skudaknoreply_mail_user }}" + globalSettings__mail__smtp__host: "{{ skudaknoreply_mail_host }}" + globalSettings__mail__smtp__port: 587 + globalSettings__mail__smtp__ssl: "true" + globalSettings__mail__smtp__username: "{{ skudaknoreply_mail_user }}" + globalSettings__mail__smtp__password: "{{ skudaknoreply_mail_pass }}" + globalSettings__disableUserRegistration: "true" + adminSettings__admins: "{{ bitwarden_admins }}" + volumes: + - "{{ bitwarden_path }}/bitwarden:/etc/bitwarden" + ports: + - "8092:8092" + +- name: create systemd startup job for bitwarden + include_tasks: podman/systemd-generate.yml + vars: + container_name: bitwarden diff --git a/ansible/roles/podman/tasks/containers/skudak/wiki.yml b/ansible/roles/podman/tasks/containers/skudak/wiki.yml index af069c8..c7ef08d 100644 --- a/ansible/roles/podman/tasks/containers/skudak/wiki.yml +++ b/ansible/roles/podman/tasks/containers/skudak/wiki.yml @@ -75,12 +75,12 @@ DB_DATABASE: "bookstack" DB_PASSWORD: "{{ bookstack_db_pass }}" MAIL_DRIVER: "smtp" - MAIL_HOST: "{{ bookstack_mail_host }}" + MAIL_HOST: "{{ skudaknoreply_mail_host }}" MAIL_PORT: 465 MAIL_ENCRYPTION: "ssl" - MAIL_USERNAME: "{{ bookstack_mail_user }}" - MAIL_PASSWORD: "{{ bookstack_mail_pass }}" - MAIL_FROM: "{{ bookstack_mail_user }}" + MAIL_USERNAME: "{{ skudaknoreply_mail_user }}" + MAIL_PASSWORD: "{{ skudaknoreply_mail_pass }}" + MAIL_FROM: "{{ skudaknoreply_mail_user }}" MAIL_FROM_NAME: "Skudak Wiki" ports: - "6875:8080" diff --git a/ansible/roles/podman/tasks/main.yml b/ansible/roles/podman/tasks/main.yml index 98098f6..d24bcf2 100644 --- a/ansible/roles/podman/tasks/main.yml +++ b/ansible/roles/podman/tasks/main.yml @@ -64,6 +64,12 @@ image: docker.io/library/nextcloud:30.0-apache tags: skudak, skudak-cloud +- import_tasks: containers/skudak/bitwarden.yml + vars: + db_image: docker.io/library/mariadb:10.6 + image: docker.io/bitwarden/self-host:2025.1.3-beta + tags: skudak, bitwarden + - import_tasks: containers/debyltech/fulfillr.yml vars: image: "{{ aws_ecr_endpoint }}/fulfillr:20241028.1847" diff --git a/ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.conf.j2 b/ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.conf.j2 new file mode 100644 index 0000000..3ee9972 --- /dev/null +++ b/ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.conf.j2 @@ -0,0 +1,16 @@ +server { + modsecurity on; + modsecurity_rules_file /etc/nginx/modsec_includes.conf; + + listen 80; + server_name {{ bitwarden_server_name }}; + + location '/.well-known/acme-challenge' { + default_type "text/plain"; + root /srv/http/letsencrypt; + } + + location / { + return 302 https://$host$request_uri; + } +} \ No newline at end of file diff --git a/ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.https.conf.j2 b/ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.https.conf.j2 new file mode 100644 index 0000000..75c39c7 --- /dev/null +++ b/ansible/roles/podman/templates/nginx/sites/bitwarden.skudakrennsport.com.https.conf.j2 @@ -0,0 +1,44 @@ +upstream bitwarden { + server 127.0.0.1:8092; +} + +server { + modsecurity on; + modsecurity_rules_file /etc/nginx/modsec_includes.conf; + + resolver 127.0.0.1 127.0.0.53 9.9.9.9 valid=60s; + + listen 443 ssl http2; + server_name {{ bitwarden_server_name }}; + client_max_body_size 500M; + + ssl_certificate /etc/letsencrypt/live/{{ bitwarden_server_name }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ bitwarden_server_name }}/privkey.pem; + ssl_trusted_certificate /etc/letsencrypt/live/{{ bitwarden_server_name }}/fullchain.pem; + ssl_dhparam /etc/nginx/ssl/dhparam.pem; + + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_session_timeout 1d; + ssl_stapling on; + ssl_stapling_verify on; + + location / { + add_header Referrer-Policy "same-origin" always; + add_header Strict-Transport-Security "max-age=630720000; includeSubDomains" always; + add_header X-Content-Type-Options "nosniff" always; + + proxy_set_header Host $host; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Real-IP $remote_addr; + + proxy_buffering off; + proxy_http_version 1.1; + proxy_pass http://bitwarden; + } +} \ No newline at end of file diff --git a/ansible/roles/ssl/tasks/certbot.yml b/ansible/roles/ssl/tasks/certbot.yml index 4d44d2a..ba2486c 100644 --- a/ansible/roles/ssl/tasks/certbot.yml +++ b/ansible/roles/ssl/tasks/certbot.yml @@ -10,6 +10,7 @@ loop: - "{{ base_server_name }}" - "{{ bookstack_server_name }}" + - "{{ bitwarden_server_name }}" - "{{ ci_server_name }}" - "{{ cloud_server_name }}" - "{{ cloud_skudak_server_name }}" diff --git a/ansible/vars/vault.yml b/ansible/vars/vault.yml index 961f15587c4c9a945712f063815d5dcf6d898cda..a3c4bae14a2055e7a4a624cd731a0062f91193b0 100644 GIT binary patch literal 14244 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 GX~&#?HLB78 literal 13337 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
P!f$oHah zhon3@Sh$t||1CaGptvjUWTygsAERzY2y=2&=3UoW7*Vy6K zpZ|4*wn0zpZ{55ebw^U>%wv7W7v`miibI|kEP8&Gj*WW$T;Z@zV=q&+_5?$=U3xzFB zACnHZ`!47vVzc{G!(e0SpQPlg5p%6{siK;(6^QJ^dxs5lN*9@F7Meg9#+UJ~$r7b? z&P%oB9L}_bM%3D2nL_gFM_M$nzynYeH1P!8_URV6 z^ra4l^hD;jjXCCx2X@}*r&~GRui3~|r9X#3JE(Y?RTnqUcnPU<8Fhn2k1_Os2d!^? zJ&%oYdDz9SN8=9H2iQV6f1NvEz|fUN8I_E=t*s(puqzU#K8Z7P$LN7prwF5`R!OB zQ_eJdS)#l`I(aN|8MBZZign8Ea9}m0>|Ds<479St?ynx^@v=|45XA>akV~PrD{D{) zAo35Nt6hNsgVFn|Jx!YD$9vR7Gkm<05c|Qc9pt$+dpP%yz{hXDU#XC**SA?A0XoBP z$R!IP&47x67Nx8VW|Vq2TGw>B4l<<=nbMTJvVf*?^z#e&2T(EN;xTs)<}9`FVuG>x5ng0+V6evy99E7RHiNbmo$RnMCPh~&*2*3dGKIU(gf`+9;!TeP~rU>e) zne#{f|4%wL;o=71v9E5xPGLSylC1kiV^U1>N>*`?DI>yxav+b?HSbVAYBcE9R|hu@ z9B9lhheMocPnTdaaOK)BJ&L6^_BuiFDkML>tbl4EBXdteY3C;Hf$`fd#In<>qe7n< zPI(b)xiIP0MQv3_C=PPJ;uMay6kp2P(=)Qk&QV0ZbAWG*e7 zohTS$Q6oXg2mq0sv*Pl_sZg&Uy^xPZMJ>E3qx3_K=Ar={6&t~^FhHiXbyO^7!pyEg zSZ9!Bf-Lx$af`AD+mv2U`%uUNcb)~dR?7e5Eg0rU|?ea<73o(^FivY!z_|k$jA`5zXR+T