From d95bb1b94b0546ea52342d8045d30928e991f21e Mon Sep 17 00:00:00 2001
From: baldnerd
Date: Thu, 10 Jul 2025 14:25:13 -0400
Subject: [PATCH] First [not yet working] version
---
README.md | 120 +++++++++++++++-
installer.sh | 374 ++++++++++++++++++++++++++++++++++++++++++++++++
setup/index.php | 54 +++++++
3 files changed, 547 insertions(+), 1 deletion(-)
create mode 100755 installer.sh
create mode 100644 setup/index.php
diff --git a/README.md b/README.md
index 47a7994..5566976 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,120 @@
-# password-manager
+# Password Management Appliance
+
+**An Open Source Appliance from Robbie Ferguson**
+
+A hardened, self-hosted password manager appliance based on Vaultwarden. Designed for secure deployment in business or personal environments.
+
+---
+
+## ✅ Features
+
+- 🛡️ Fully self-hosted on Debian 12
+- 🔐 Vaultwarden (Bitwarden-compatible)
+- 💾 MariaDB backend
+- 🧠 Supports .env override system via web-based setup
+- 🌐 NGINX reverse proxy + PHP-based first-time setup wizard
+- 🔑 Multi-user access, browser extensions, mobile app compatibility
+
+---
+
+## 📂 Important File Paths
+
+| Path | Purpose |
+|------|---------|
+| `/opt/vaultwarden/.env` | Core Vaultwarden environment settings |
+| `/var/lib/vaultwarden/.env.user` | User-defined config written via the setup wizard |
+| `/var/lib/vaultwarden/.setup-complete` | Flag file that disables the setup wizard after first-time config |
+| `/opt/vaultwarden/.env.merged` | Combined environment used by the wrapper |
+| `/usr/local/bin/vaultwarden` | Vaultwarden binary |
+| `/usr/local/bin/vaultwarden-wrapper` | Wrapper that merges .env and .env.user |
+| `/etc/systemd/system/vaultwarden.service` | Systemd unit to manage Vaultwarden as a service |
+| `/var/www/html/setup/` | First-time setup wizard served via PHP |
+| `/var/www/html/vaultinfo/index.html` | Installer-complete welcome page served on `/` |
+
+---
+
+## 🚀 Installation
+
+On a fresh Debian 12 system, clone the password-manager repository and then run:
+
+```bash
+./installer.sh
+```
+
+After installation:
+- Access the appliance at `http:///`
+- Go to `/setup` to complete first-time configuration
+- After submitting the form, Vaultwarden will use your custom settings
+
+---
+
+## 🧠 Configuration Flow
+
+1. Installer creates `/opt/vaultwarden/.env` (default config)
+2. User config is stored via `/setup` in `/var/lib/vaultwarden/.env.user`
+3. `vaultwarden-wrapper` merges both files into `.env.merged`
+4. Systemd launches Vaultwarden using the wrapper
+
+---
+
+## 🔁 To Re-run Setup
+
+To prevent a bad actor from modifying your configuration by re-running the /setup tool, a file `.setup-complete` is created to tell the system to no longer allow the configuration to be saved. You can, if needed, delete the `.setup-complete` file to re-run the configuration:
+
+```bash
+rm /var/lib/vaultwarden/.setup-complete
+```
+
+Then visit `/setup` in your browser again.
+
+---
+
+## 🖥️ System Requirements
+
+To successfully build and run the Password Management Appliance, your system must meet the following minimum requirements:
+
+### Minimum Requirements (suitable for testing and light use)
+
+* **Operating System**: Debian 12 (Bookworm) x86\_64
+* **CPU**: Dual-core processor (2 vCPUs)
+* **RAM**: 4 GB
+* **Disk Space**: 5 GB free disk space
+* **Network**: Internet access for package installation and updates
+* **Privileges**: Root access required to run the installer
+
+### Recommended Requirements (for smoother experience and production use)
+
+* **CPU**: Quad-core processor (4 vCPUs)
+* **RAM**: 8 GB or more
+* **Disk Space**: 10 GB+ free disk space
+* **Swap**: At least 2 GB swap space to prevent build crashes
+* **Persistent Hostname/IP**: Recommended for SSL setup and accessibility
+
+> ⚠️ Note: The Vaultwarden build process is **resource-intensive** and may fail on underpowered systems or single-core CPUs. Be sure to allocate enough CPU and RAM, or use the `--purge` option to clean up failed attempts before retrying.
+
+---
+
+### 🔁 `--purge` Option
+
+If you need to reset your environment to retry installing after a failed installation, run the installer with the `--purge` flag:
+
+```bash
+./installer.sh --purge
+```
+
+This will:
+
+* Remove Vaultwarden and its related system user
+* Delete configuration files and setup data
+* Uninstall MariaDB and clear its databases
+* Remove any sudo rules added by the installer
+
+Use this to clean the system before running a fresh install. **Note:** This does not perform a complete system rollback - only what's necessary to allow a successful reinstallation.
+
+---
+
+## 📜 License
+
+This project is licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0).
+© Robbie Ferguson – Open Source Appliance Project
diff --git a/installer.sh b/installer.sh
new file mode 100755
index 0000000..608392a
--- /dev/null
+++ b/installer.sh
@@ -0,0 +1,374 @@
+#!/bin/bash
+#
+# Password Management Appliance Installer
+# An Open Source Appliance from Robbie Ferguson
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# You may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+set -e
+
+if [[ "$EUID" -ne 0 ]]; then
+ echo "Please run as root."
+ exit 1
+fi
+
+generate_token() {
+ local length=${1:-64}
+ head -c $((length / 2)) /dev/urandom | xxd -p | tr -d '\n'
+}
+
+# Save the directory where the script was started
+INSTALLER_DIR="$(pwd)"
+
+echo "=== Password Management Appliance Installer ==="
+echo "An Open Source Appliance from Robbie Ferguson"
+echo
+
+
+if [[ "$1" == "--purge" ]]; then
+ echo "PURGE command passed on the command line."
+ echo
+ echo "WARNING: This will permanently remove Vaultwarden and all its data."
+ read -r -p "Are you sure you want to delete everything? [y/N]: " confirm
+
+ # Default to "No" if input is empty or not 'y' or 'Y'
+ if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
+ echo "Purge aborted."
+ exit 0
+ fi
+
+ echo "Purging previous Vaultwarden installation..."
+
+ set +e
+ echo "Removing MariaDB (server + client + common)..."
+ systemctl stop mariadb 2>/dev/null
+ apt purge -y mariadb-server mariadb-client mariadb-common mariadb-backup
+ apt autoremove -y
+ rm -rf /var/lib/mysql /etc/mysql
+
+ if id "vaultwarden" &>/dev/null; then
+ echo "Attempting to stop and remove vaultwarden user..."
+
+ echo "Killing any processes owned by vaultwarden..."
+ pkill -u vaultwarden 2>/dev/null || true
+
+ echo "Stopping Vaultwarden service if running..."
+ systemctl stop vaultwarden 2>/dev/null || true
+ systemctl disable vaultwarden 2>/dev/null || true
+ rm -f /etc/systemd/system/vaultwarden.service
+
+ echo "Unmounting or clearing home directory if needed..."
+ umount /opt/vaultwarden 2>/dev/null || true
+ rm -rf /opt/vaultwarden /var/lib/vaultwarden
+
+ rm -f /usr/local/bin/vaultwarden-wrapper
+
+ echo "Deleting vaultwarden user..."
+ userdel vaultwarden && echo "vaultwarden user removed." || echo "Failed to remove vaultwarden user."
+ else
+ echo "vaultwarden user does not exist. Skipping."
+ fi
+
+ echo "Purging the vaultgroup gruop"
+ groupdel vaultgroup
+ getent group vaultgroup
+
+ echo "Cleaning www-data writable config and setup..."
+ rm -f /var/lib/vaultwarden/.env.user
+ rm -f /var/lib/vaultwarden/.setup-complete
+ rm -rf /var/www/html/setup/
+
+ echo "Removing sudoers config for www-data..."
+ rm -f /etc/sudoers.d/vaultwarden-www-restart
+
+ echo "Purge complete. You can now re-run installer.sh safely."
+ exit 0
+fi
+
+
+# Update system and install dependencies
+echo "Installing dependencies..."
+apt update && apt upgrade -y
+apt install -y curl gnupg2 software-properties-common apt-transport-https lsb-release mariadb-server mariadb-client nginx unzip ufw git build-essential pkg-config libssl-dev libmariadb-dev libmariadb-dev-compat sudo xxd
+
+ufw allow OpenSSH
+ufw allow 'Nginx Full'
+ufw --force enable
+
+DB_NAME="vaultwarden"
+DB_USER="vaultuser"
+#DB_PASS=$(openssl rand -base64 24)
+DB_PASS=$(generate_token 64)
+
+echo "Creating MariaDB database and user..."
+mysql -u root </dev/null 2>&1 || {
+ echo "ERROR: Cannot verify MariaDB access."
+ exit 1
+}
+echo "MariaDB credentials verified."
+
+echo "Installing Rust and Vaultwarden..."
+curl https://sh.rustup.rs -sSf | sh -s -- -y
+export PATH="$HOME/.cargo/bin:$PATH"
+
+useradd -r -d /opt/vaultwarden -s /usr/sbin/nologin vaultwarden || true
+mkdir -p /opt/vaultwarden
+chown vaultwarden:vaultwarden /opt/vaultwarden
+
+cd /opt
+git clone https://github.com/dani-garcia/vaultwarden.git
+cd vaultwarden
+
+echo "Building Vaultwarden with MySQL support..."
+if ! cargo build --release --locked --features mysql; then
+ echo "Cargo build failed."
+ exit 1
+fi
+
+echo "Verifying that Vaultwarden binary was built..."
+if [[ ! -x target/release/vaultwarden ]]; then
+ echo "Vaultwarden binary not found after build."
+ exit 1
+fi
+
+echo "Checking for MySQL support in the built binary..."
+if ldd target/release/vaultwarden | grep -qE 'libmysqlclient|libmariadb'; then
+ echo "Vaultwarden binary is linked with MySQL/MariaDB support."
+ if [[ -e /usr/local/bin/vaultwarden ]]; then
+ rm -f /usr/local/bin/vaultwarden
+ fi
+ echo "Placing binary in /usr/local/bin"
+ cp target/release/vaultwarden /usr/local/bin/
+ chown vaultwarden:vaultwarden /usr/local/bin/vaultwarden
+else
+ echo "Built Vaultwarden binary does not link MySQL/MariaDB. Something went wrong."
+ exit 1
+fi
+
+# Ensure vaultwarden data directory exists
+if [ ! -d /var/lib/vaultwarden ]; then
+ echo "Creating /var/lib/vaultwarden directory..."
+ mkdir -p /var/lib/vaultwarden
+ chown www-data:www-data /var/lib/vaultwarden
+fi
+
+# Ensure .env.user file exists
+if [ ! -f /var/lib/vaultwarden/.env.user ]; then
+ echo "Creating .env.user file..."
+ touch /var/lib/vaultwarden/.env.user
+ chown www-data:www-data /var/lib/vaultwarden/.env.user
+fi
+
+mkdir -p /opt/vaultwarden/data
+chown -R vaultwarden:vaultwarden /opt/vaultwarden
+
+cat < /opt/vaultwarden/.env
+DATABASE_URL=mysql://${DB_USER}:${DB_PASS}@localhost:3306/${DB_NAME}
+DATA_FOLDER=/opt/vaultwarden/data
+DOMAIN=https://localhost
+ROCKET_PORT=8080
+ROCKET_ADDRESS=0.0.0.0
+WEBSOCKET_ENABLED=true
+WEB_VAULT_FOLDER=/opt/vaultwarden/web-vault
+EOF
+
+chown vaultwarden:vaultwarden /opt/vaultwarden/.env
+chmod 600 /opt/vaultwarden/.env
+
+# Create vaultwarden-wrapper to support layered .env config
+cat <<"EOF" > /usr/local/bin/vaultwarden-wrapper
+#!/bin/bash
+ENV_MAIN="/opt/vaultwarden/.env"
+ENV_USER="/var/lib/vaultwarden/.env.user"
+ENV_MERGED="/opt/vaultwarden/.env.merged"
+
+cat "$ENV_MAIN" > "$ENV_MERGED"
+[ -f "$ENV_USER" ] && cat "$ENV_USER" >> "$ENV_MERGED"
+
+# Load environment variables from merged file
+set -a
+source "$ENV_MERGED"
+set +a
+
+exec /usr/local/bin/vaultwarden
+EOF
+
+chmod +x /usr/local/bin/vaultwarden-wrapper
+
+cat < /etc/systemd/system/vaultwarden.service
+[Unit]
+Description=Vaultwarden Password Server
+After=network.target mariadb.service
+
+[Service]
+User=vaultwarden
+Group=vaultwarden
+WorkingDirectory=/opt/vaultwarden
+ExecStart=/usr/local/bin/vaultwarden-wrapper
+Restart=always
+RestartSec=5s
+
+[Install]
+WantedBy=multi-user.target
+EOF
+
+systemctl daemon-reexec
+systemctl enable --now vaultwarden
+
+echo "Checking Vaultwarden service..."
+systemctl is-active --quiet vaultwarden || {
+ echo "Vaultwarden service failed to start."
+ journalctl -u vaultwarden --no-pager | tail -n 10
+ exit 1
+}
+echo "Vaultwarden service is active."
+
+# Remove default nginx site if it exists to avoid duplicate default_server errors
+if [ -f /etc/nginx/sites-enabled/default ]; then
+ echo "Removing default Nginx site to avoid conflict..."
+ rm -f /etc/nginx/sites-enabled/default
+fi
+
+# Basic NGINX placeholder config
+cat <<"EOF" > /etc/nginx/sites-available/vaultwarden
+server {
+ listen 80 default_server;
+ server_name _;
+
+ root /var/www/html/vaultinfo;
+ index index.php;
+
+ # Main landing page
+ location / {
+ try_files $uri $uri/ /index.php?$args;
+ }
+
+ # Serve PHP files
+ location ~ \.php$ {
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/run/php/php8.2-fpm.sock;
+ }
+
+ # Setup interface
+ location /setup {
+ root /var/www/html;
+ index index.php;
+
+ location ~ ^/setup/.*\.php$ {
+ include snippets/fastcgi-php.conf;
+ fastcgi_pass unix:/run/php/php8.2-fpm.sock;
+ }
+ }
+
+ # Vaultwarden Admin Panel
+ location ^~ /admin/ {
+ proxy_pass http://127.0.0.1:8080/admin/;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+
+ # Vaultwarden static files (referenced from root!)
+ location ~ ^/(bootstrap|admin|vaultwarden|.*\.(css|js|png|ico|woff2?)$) {
+ proxy_pass http://127.0.0.1:8080;
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ }
+
+ # WebSocket
+ location /notifications/hub {
+ proxy_pass http://127.0.0.1:3012;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ }
+}
+EOF
+
+ln -sf /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/vaultwarden
+
+echo "Testing Nginx configuration..."
+if nginx -t; then
+ echo "Reloading Nginx..."
+ systemctl reload nginx
+else
+ echo "Nginx config test failed. Please check manually."
+fi
+
+
+mkdir -p /var/www/html/vaultinfo
+chown -R www-data:www-data /var/www/html/vaultinfo
+
+# Setup a group that allows Vaultwarden and www-data to share configs
+groupadd vaultgroup
+usermod -aG vaultgroup vaultwarden
+usermod -aG vaultgroup www-data
+
+# Allow web interface to save initial config
+touch /var/lib/vaultwarden/.env.user
+chown www-data:vaultgroup /var/lib/vaultwarden/.env.user
+chmod 640 /var/lib/vaultwarden/.env.user
+
+# Download and deploy setup wizard
+echo "Installing PHP and deploying setup page..."
+apt install -y php php-fpm php-cli php-common php-mbstring php-json php-curl php-xml php-zip php-gd
+cd "$INSTALLER_DIR"
+cp -R ./setup /var/www/html/
+chown -R www-data:www-data /var/www/html/setup
+
+# Welcome page with /setup condition check
+cat <<"EOF" > /var/www/html/vaultinfo/index.php
+
+
+
+
+ Password Management Appliance
+
+
+
+ Password Management Appliance
+ This server is running Vaultwarden on a Password Management Appliance.
+ ✓ Installation Complete
+
+ Access the admin panel at: /admin
'; } else { echo 'Continue to activation.
'; } ?>
+ An Open Source Appliance from Robbie Ferguson
+
+
+EOF
+
+echo "Setup system ready. Visit http:///setup to begin configuration."
+
+# Allow www-data to restart Vaultwarden without password
+echo "www-data ALL=NOPASSWD: /bin/systemctl restart vaultwarden" > /etc/sudoers.d/vaultwarden-www-restart
+chmod 440 /etc/sudoers.d/vaultwarden-www-restart
+
+echo "Configuring default web-vault."
+cd /opt/vaultwarden
+curl -L https://github.com/dani-garcia/bw_web_builds/releases/download/v2025.6.0/bw_web_v2025.6.0.tar.gz | tar xz
+chown -R vaultwarden:vaultwarden web-vault
+chmod -R 755 web-vault
+systemctl restart vaultwarden
+
+echo
+echo "Installation complete!"
+echo "Visit http:///setup to begin configuration."
+
diff --git a/setup/index.php b/setup/index.php
new file mode 100644
index 0000000..1ec9a60
--- /dev/null
+++ b/setup/index.php
@@ -0,0 +1,54 @@
+
+
+
+
+
+ Vaultwarden Setup Complete
+
+
+
+
+
Vaultwarden Setup Complete
+
+
Your admin token has been generated and securely hashed. Please copy and store this token:
+
= htmlspecialchars($adminToken) ?>
+
To access the Vaultwarden admin interface, click below:
+
Open Admin Panel
+
Note: If you ever need to reset this setup, delete /opt/vaultwarden/.setup-complete
and reload this page.
+
+
Error: Unable to generate or save the admin token. Please check permissions or disk space.
+
+
+
+