#!/bin/bash # Function to show progress show_progress() { local pid=$1 local delay=0.1 local spinstr='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' local start_time=$(date +%s) printf " " while ps -p "$pid" > /dev/null 2>&1; do local temp=${spinstr#?} printf "\r[%c] " "$spinstr" local spinstr=$temp${spinstr%"$temp"} sleep $delay local current_time=$(date +%s) local elapsed=$((current_time - start_time)) printf "%02d:%02d" $((elapsed / 60)) $((elapsed % 60)) done printf "\r[✓] Done! \n" } # Function to print colored output print_color() { case $1 in "green") echo -e "\e[32m$2\e[0m" ;; "red") echo -e "\e[31m$2\e[0m" ;; "yellow") echo -e "\e[33m$2\e[0m" ;; esac sleep 0.1 } # Function to center text center_text() { local text="$1" local width width=$(tput cols) || return local padding=$(( (width - ${#text}) / 2 )) printf "%${padding}s%s\n" '' "$text" } # Function to install necessary packages install_dependencies() { print_color "yellow" "Installing dependencies..." (sudo apt update -q && sudo apt install -y -q wget curl sudo > /dev/null 2>&1) & show_progress $! print_color "green" "Dependencies installed successfully." } # Function to create vaultwarden user if it doesn't exist create_vaultwarden_user() { if ! command -v useradd &> /dev/null; then print_color "yellow" "useradd command not found. Installing..." (sudo apt install -y passwd > /dev/null 2>&1) & show_progress $! fi if ! id "vaultwarden" &>/dev/null; then print_color "yellow" "Creating vaultwarden user..." (sudo useradd -r -s /bin/false vaultwarden > /dev/null 2>&1) & show_progress $! print_color "green" "Vaultwarden user created successfully." else print_color "green" "Vaultwarden user already exists." fi } # Function to extract without Docker extract_without_docker() { print_color "yellow" "Extracting Vaultwarden binaries..." ( mkdir -p vw-image cd vw-image wget -q https://raw.githubusercontent.com/jjlin/docker-image-extract/main/docker-image-extract chmod +x docker-image-extract ./docker-image-extract vaultwarden/server:latest-alpine sudo mv output/vaultwarden /home/vaultwarden/ sudo mv output/web-vault /home/vaultwarden/ cd .. rm -rf vw-image sudo mkdir -p /home/vaultwarden/data ) &> /dev/null & show_progress $! if [ -f "/home/vaultwarden/vaultwarden" ] && [ -d "/home/vaultwarden/web-vault" ]; then print_color "green" "Extraction complete." else print_color "red" "Extraction failed. Please check the logs and try again." exit 1 fi } # Create systemd service file create_systemd_service() { print_color "yellow" "Creating systemd service file..." sudo tee /etc/systemd/system/vaultwarden.service > /dev/null << EOF [Unit] Description=Vaultwarden Server After=network.target [Service] User=vaultwarden Group=vaultwarden ExecStart=/home/vaultwarden/vaultwarden WorkingDirectory=/home/vaultwarden EnvironmentFile=/home/vaultwarden/.env [Install] WantedBy=multi-user.target EOF print_color "green" "Systemd service file created successfully." } # Function to create .env file create_env_file() { print_color "yellow" "Setting up Vaultwarden configuration..." read -p "Enter domain name for Vaultwarden (e.g., vault.example.com): " DOMAIN print_color "yellow" "Creating .env file..." sudo tee /home/vaultwarden/.env > /dev/null << EOF DOMAIN=https://$DOMAIN ROCKET_PORT=8000 DATA_FOLDER=/home/vaultwarden/data WEB_VAULT_FOLDER=/home/vaultwarden/web-vault EOF (sudo chown vaultwarden:vaultwarden /home/vaultwarden/.env && sudo chmod 600 /home/vaultwarden/.env) & show_progress $! print_color "green" "Vaultwarden configuration file created successfully." } # Function to set up Nginx setup_nginx() { if ! command -v nginx &> /dev/null; then print_color "yellow" "Nginx not found. Installing..." (sudo apt update && sudo apt install -y nginx > /dev/null 2>&1) & show_progress $! fi print_color "yellow" "Configuring Nginx for Vaultwarden..." sudo tee /etc/nginx/sites-available/vaultwarden > /dev/null << EOF server { listen 80; server_name $DOMAIN; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host \$host; 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; } } EOF sudo ln -sf /etc/nginx/sites-available/vaultwarden /etc/nginx/sites-enabled/ print_color "yellow" "Testing Nginx configuration..." if sudo nginx -t; then (sudo systemctl reload nginx > /dev/null 2>&1) & show_progress $! print_color "green" "Nginx configured and reloaded successfully." else print_color "red" "Nginx configuration test failed. Please check your configuration." fi } # Function to install Certbot install_certbot() { print_color "yellow" "Installing Certbot..." (sudo apt update && sudo apt install -y snapd && sudo snap install core && sudo snap refresh core && sudo snap install --classic certbot && sudo ln -s /snap/bin/certbot /usr/bin/certbot) & show_progress $! print_color "green" "Certbot installed successfully." } # Function to set up admin panel setup_admin_panel() { print_color "yellow" "Setting up admin panel..." # Install argon2 if not already installed if ! command -v argon2 &> /dev/null; then print_color "yellow" "Installing argon2..." (sudo apt update && sudo apt install -y argon2 > /dev/null 2>&1) & show_progress $! fi # Prompt for admin password read -sp "Enter the admin password: " admin_password echo print_color "yellow" "Generating admin token..." # Generate argon2 hash admin_token=$(echo -n "$admin_password" | argon2 $(openssl rand -base64 32) -e -id -k 65540 -t 3 -p 4) # Append admin token to .env file print_color "yellow" "Updating .env file with admin token..." (echo "ENABLE_ADMIN=true" | sudo tee -a /home/vaultwarden/.env > /dev/null echo "ADMIN_TOKEN='$admin_token'" | sudo tee -a /home/vaultwarden/.env > /dev/null) & show_progress $! print_color "green" "Admin panel has been enabled successfully." } #------------- # Main script #------------- # Check if script is run as root if [ "$EUID" -ne 0 ]; then echo "This script must be run as root. Please use sudo or run as root." exit 1 fi # Welcome Message cat <<"EOF" ██╗ ██╗ █████╗ ██╗ ██╗██╗ ████████╗██╗ ██╗ █████╗ ██████╗ ██████╗ ███████╗███╗ ██╗ ██║ ██║██╔══██╗██║ ██║██║ ╚══██╔══╝██║ ██║██╔══██╗██╔══██╗██╔══██╗██╔════╝████╗ ██║ ██║ ██║███████║██║ ██║██║ ██║ ██║ █╗ ██║███████║██████╔╝██║ ██║█████╗ ██╔██╗ ██║ ╚██╗ ██╔╝██╔══██║██║ ██║██║ ██║ ██║███╗██║██╔══██║██╔══██╗██║ ██║██╔══╝ ██║╚██╗██║ ╚████╔╝ ██║ ██║╚██████╔╝███████╗██║ ╚███╔███╔╝██║ ██║██║ ██║██████╔╝███████╗██║ ╚████║ ╚═══╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═══╝ ███████╗███████╗████████╗██╗ ██╗██████╗ ██╔════╝██╔════╝╚══██╔══╝██║ ██║██╔══██╗ ███████╗█████╗ ██║ ██║ ██║██████╔╝ ╚════██║██╔══╝ ██║ ██║ ██║██╔═══╝ ███████║███████╗ ██║ ╚██████╔╝██║ ╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═╝ EOF echo center_text "Created by Enki" center_text "Thanks for using this Vaultwarden installation script" center_text "This script will install Vaultwarden server and configure it to start at boot." center_text "It can also set up the Vaultwarden web server on your domain." echo print_color "yellow" "Make sure you have pointed your domain to this server's IP address before proceeding if you are not installing localy." if [ -t 0 ]; then print_color "green" "Press any key to continue..." read -n 1 -s -r -p "" fi echo print_color "green" "Starting Vaultwarden installation..." install_dependencies create_vaultwarden_user sudo mkdir -p /home/vaultwarden extract_without_docker # Create .env file create_env_file # Create systemd service create_systemd_service # Set correct permissions print_color "yellow" "Setting correct permissions..." (sudo chown -R vaultwarden:vaultwarden /home/vaultwarden) & show_progress $! print_color "green" "Permissions set successfully." # Offer to set up Nginx read -p "Would you like to set up Nginx as a reverse proxy? (y/n) " setup_nginx_answer if [[ $setup_nginx_answer =~ ^[Yy]$ ]]; then setup_nginx install_certbot print_color "yellow" "You can set up SSL later by running: sudo certbot --nginx -d $DOMAIN" fi # Enable and start Vaultwarden service print_color "yellow" "Enabling and starting Vaultwarden service..." (sudo systemctl enable vaultwarden && sudo systemctl start vaultwarden) & show_progress $! print_color "green" "Vaultwarden service enabled and started." print_color "green" "Vaultwarden has been installed and configured." print_color "yellow" "Please ensure your firewall allows traffic on ports 80 and 443 (if using HTTPS)." print_color "yellow" "If you didn't set up Nginx, make sure to allow traffic on port 8000 as well." # Offer to set up admin panel read -p "Would you like to enable the admin panel? (y/n) " setup_admin_answer if [[ $setup_admin_answer =~ ^[Yy]$ ]]; then setup_admin_panel # Restart Vaultwarden to apply changes print_color "yellow" "Restarting Vaultwarden to apply changes..." (sudo systemctl restart vaultwarden) & show_progress $! print_color "green" "Vaultwarden restarted successfully." fi print_color "green" "Vaultwarden installation complete!" if [[ $DOMAIN ]]; then print_color "yellow" "You can access your Vaultwarden instance at: https://$DOMAIN" if [[ $setup_admin_answer =~ ^[Yy]$ ]]; then print_color "yellow" "Admin panel is available at: https://$DOMAIN/admin" fi fi