diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..917bdb5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,57 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [3.4.0] - 2025-01-01 +### Added +- Support for multiple Linux distributions (Ubuntu, Debian, Fedora, Arch Linux, openSUSE) +- Installation of Docker, NFS, and Netdata +- Improved network configuration + +### Changed +- Modularization of the script by moving functions to separate files + +### Fixed +- Improved error handling and logging + +## [3.0.0] - 2024-01-28 +### Added +- Initial public release of the NAS Setup Script version 3.0 +- Compatibility with Ubuntu 22.04 and later versions +- SSH configuration with custom port and user +- Samba file sharing setup +- Docker installation and configuration +- Basic security measures including: + - Firewall setup (ufw) + - fail2ban installation + - Secure shared memory configuration +- Automatic system updates configuration (unattended-upgrades) +- Optional installation of additional components: + - Vaultwarden + - Jellyfin + - Portainer + - Netdata +- System requirements check (disk space, RAM) +- Network configuration with static IP option +- Time Machine backup support for macOS +- Comprehensive logging functionality +- Enhanced error handling and progress display +- Configuration file (config.sh) for easy customization +- Backup functionality for configuration files +- Basic system monitoring tools (htop, iotop) + +### Changed +- Improved script structure and modularity +- Enhanced user interaction with more informative prompts + +### Documentation +- Comprehensive README with usage instructions +- Contribution guidelines (CONTRIBUTING.md) +- MIT License +- This CHANGELOG file + +[3.0.0]: https://github.com/noordjonge/nas-setup-script/releases/tag/v3.0.0 +[3.4.0]: https://github.com/noordjonge/nas-setup-script/releases/tag/v3.4.0 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..99387c4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing + +Thank you for considering contributing to this project! Here are some guidelines to help you contribute. + +## How to Contribute + +1. Fork the repository. +2. Create a new branch (`git checkout -b feature-branch`). +3. Make your changes and commit them (`git commit -am 'Add new feature'`). +4. Push the branch (`git push origin feature-branch`). +5. Create a new Pull Request. + +## Code Guidelines + +- Ensure your code is well-documented. +- Follow the existing code style. +- Write tests for your changes if possible. + +## Reporting Issues + +If you find a bug, please report it in the [Issue Tracker](https://github.com/noordjonge/nasscript/issues). + +## License + +By contributing, you agree that your contributions will be licensed under the MIT License. \ No newline at end of file diff --git a/LICENSE b/LICENSE index 66fd900..159f73f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Sebastian Palencsár +Copyright (c) 2024 Sebastian Palencsár Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index b88f9b1..21745e9 100644 --- a/README.md +++ b/README.md @@ -204,4 +204,4 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file - Thanks to all contributors - Inspired by best practices in NAS setup and administration -- Built with and for the open source community +- Built with and for the open source community \ No newline at end of file diff --git a/config/defaults.sh b/config/defaults.sh new file mode 100644 index 0000000..22bb022 --- /dev/null +++ b/config/defaults.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Default configuration values for NAS setup script + +# Log file location +LOG_FILE="/var/log/nas_setup.log" + +# New user to be created +NEW_USER="nasadmin" + +# Samba configuration +SAMBA_CONFIG="/etc/samba/smb.conf" + +# Configuration variables +CONFIG_FILE="/etc/nas_setup.conf" +DEFAULT_SSH_PORT=39000 +DEFAULT_USER="nas_user" +DEFAULT_DOCKER_DATA_DIR="/var/lib/docker" +DEBUG=${DEBUG:-false} + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[0;33m' +NC='\033[0m' # No Color + +# Network configuration +NETWORK_INTERFACE="eth0" + +# Docker configuration +DOCKER_COMPOSE_VERSION="1.29.2" + +# NFS configuration +NFS_EXPORT_DIR="/srv/nfs" + +# Netdata configuration +NETDATA_PORT="19999" + +# Vaultwarden configuration +VAULTWARDEN_DATA_DIR="/opt/vaultwarden" + +# Jellyfin configuration +JELLYFIN_DATA_DIR="/var/lib/jellyfin" + +# Portainer configuration +PORTAINER_DATA_DIR="/opt/portainer" diff --git a/lib/docker.sh b/lib/docker.sh new file mode 100644 index 0000000..348368d --- /dev/null +++ b/lib/docker.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +install_docker() { + log_info "Installing Docker..." + + # Update package index and install prerequisites + handle_error sudo apt-get update + handle_error sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common + + # Add Docker's official GPG key + handle_error curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - + + # Add Docker's official APT repository + handle_error sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" + + # Update package index again + handle_error sudo apt-get update + + # Install Docker CE + handle_error sudo apt-get install -y docker-ce + + # Add user to the docker group + handle_error sudo usermod -aG docker "$NEW_USER" + + case $DISTRO in + ubuntu|debian) + handle_error sudo apt-get install -y docker.io + ;; + fedora) + handle_error sudo dnf install -y docker + ;; + arch) + handle_error sudo pacman -S --noconfirm docker + ;; + opensuse) + handle_error sudo zypper install -y docker + ;; + *) + log_error "Unsupported Linux distribution: $DISTRO" + exit 1 + ;; + esac + handle_error sudo systemctl enable docker + handle_error sudo systemctl start docker + + # Configure Docker data directory + if [[ "$DOCKER_DATA_DIR" != "$DEFAULT_DOCKER_DATA_DIR" ]]; then + log_info "Configuring Docker data directory to $DOCKER_DATA_DIR..." + handle_error sudo mkdir -p "$DOCKER_DATA_DIR" + echo "{\"data-root\": \"$DOCKER_DATA_DIR\"}" | sudo tee /etc/docker/daemon.json > /dev/null + handle_error sudo systemctl restart docker + fi + + export DOCKER_CONTENT_TRUST=1 + + log_info "Docker installed successfully." + log_info "Instructions for installing Docker in rootless mode:" + echo "1. Ensure required packages are installed: uidmap" + echo "2. Run Docker rootless installation script: curl -fsSL https://get.docker.com/rootless | sh" + echo "3. Set the following environment variables in your shell profile (e.g., ~/.bashrc):" + echo " export PATH=/usr/bin:\$PATH" + echo " export DOCKER_HOST=unix:///run/user/\$(id -u)/docker.sock" + echo "4. Start and enable Docker service in user mode:" + echo " systemctl --user start docker" + echo " systemctl --user enable docker" + echo "5. Enable linger for the user:" + echo " sudo loginctl enable-linger \$(whoami)" +} diff --git a/lib/firewall.sh b/lib/firewall.sh new file mode 100644 index 0000000..514b4ca --- /dev/null +++ b/lib/firewall.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +# Function to set up firewall rules for Fedora +setup_firewall_fedora() { + echo "Setting up firewall for Fedora..." + sudo firewall-cmd --permanent --add-service=http + sudo firewall-cmd --permanent --add-service=https + sudo firewall-cmd --reload + echo "Firewall setup complete for Fedora." +} + +# Function to set up firewall rules for Arch Linux +setup_firewall_arch() { + echo "Setting up firewall for Arch Linux..." + sudo ufw allow http + sudo ufw allow https + sudo ufw enable + echo "Firewall setup complete for Arch Linux." +} + +# Function to set up firewall rules for openSUSE +setup_firewall_opensuse() { + echo "Setting up firewall for openSUSE..." + sudo firewall-cmd --permanent --add-service=http + sudo firewall-cmd --permanent --add-service=https + sudo firewall-cmd --reload + echo "Firewall setup complete for openSUSE." +} + +# Detect the operating system and call the appropriate function +if [ -f /etc/fedora-release ]; then + setup_firewall_fedora +elif [ -f /etc/arch-release ]; then + setup_firewall_arch +elif [ -f /etc/SuSE-release ]; then + setup_firewall_opensuse +else + echo "Unsupported operating system." + exit 1 +fi + +configure_firewall() { + log_info "Configuring firewall..." + + # Allow SSH + ufw allow "${DEFAULT_SSH_PORT}/tcp" + + # Allow Samba + ufw allow from any to any port 137,138 proto udp + ufw allow from any to any port 139,445 proto tcp + + # Allow NFS + ufw allow from any to any port 2049 proto tcp + + # Allow Netdata + ufw allow "${NETDATA_PORT}/tcp" + + # Allow Docker + ufw allow 2375/tcp + ufw allow 2376/tcp + + # Enable UFW + ufw --force enable + + log_info "Firewall configuration completed." +} \ No newline at end of file diff --git a/lib/internet.sh b/lib/internet.sh new file mode 100644 index 0000000..718cad8 --- /dev/null +++ b/lib/internet.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +check_internet_connection() { + log_info "Checking internet connection..." + if ping -c 1 google.com &> /dev/null; then + log_info "Internet connection is active." + else + log_error "No internet connection. Please check your network settings." + exit 1 + fi +} diff --git a/lib/jellyfin.sh b/lib/jellyfin.sh new file mode 100644 index 0000000..3728e9d --- /dev/null +++ b/lib/jellyfin.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Jellyfin installation and configuration script + +log_info() { + echo "[INFO] $1" +} + +log_error() { + echo "[ERROR] $1" >&2 +} + +handle_error() { + "$@" + local status=$? + if [ $status -ne 0 ]; then + log_error "Error with $1" + exit 1 + fi +} + +install_jellyfin() { + log_info "Installing Jellyfin..." + + case $DISTRO in + ubuntu|debian) + handle_error sudo apt-get update + handle_error sudo apt-get install -y apt-transport-https software-properties-common + handle_error wget -O - https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add - + handle_error sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://repo.jellyfin.org/$(lsb_release -cs) main" + handle_error sudo apt-get update + handle_error sudo apt-get install -y jellyfin + ;; + fedora) + handle_error sudo dnf install -y https://repo.jellyfin.org/releases/server/fedora/releases/jellyfin-server.rpm + ;; + arch) + handle_error sudo pacman -S --noconfirm jellyfin + ;; + opensuse) + handle_error sudo zypper addrepo https://repo.jellyfin.org/releases/server/opensuse/jellyfin.repo + handle_error sudo zypper refresh + handle_error sudo zypper install -y jellyfin + ;; + *) + log_error "Unsupported Linux distribution: $DISTRO" + exit 1 + ;; + esac + + handle_error sudo systemctl enable jellyfin + handle_error sudo systemctl start jellyfin + + log_info "Jellyfin installation completed." +} + +# Detect the distribution and call the appropriate function +if [ -f /etc/os-release ]; then + . /etc/os-release + DISTRO=$ID + install_jellyfin +else + log_error "Cannot detect the operating system." + exit 1 +fi \ No newline at end of file diff --git a/lib/logging.sh b/lib/logging.sh new file mode 100644 index 0000000..d01550c --- /dev/null +++ b/lib/logging.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +log_info() { + echo -e "${GREEN}[INFO] $1${NC}" +} + +log_warning() { + echo -e "${YELLOW}[WARNING] $1${NC}" +} + +log_error() { + echo -e "${RED}[ERROR] $1${NC}" >&2 +} + +backup_config() { + local config_file=$1 + if [ -f "$config_file" ]; then + local backup_file="${config_file}.$(date +%F-%T).bak" + handle_error sudo cp "$config_file" "$backup_file" + log_info "Backup of $config_file created at $backup_file" + fi +} diff --git a/lib/netdata.sh b/lib/netdata.sh new file mode 100644 index 0000000..fb968fb --- /dev/null +++ b/lib/netdata.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Netdata installation and configuration script + +install_netdata() { + log_info "Installing Netdata..." + + # Install dependencies + handle_error sudo apt-get update + handle_error sudo apt-get install -y curl git + + # Install Netdata from GitHub + handle_error bash <(curl -Ss https://my-netdata.io/kickstart.sh) --stable-channel --disable-telemetry + + handle_error sudo systemctl enable netdata + handle_error sudo systemctl start netdata + + log_info "Netdata installation completed." +} diff --git a/lib/network.sh b/lib/network.sh new file mode 100644 index 0000000..71d32f1 --- /dev/null +++ b/lib/network.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +configure_network() { + log_info "Configuring network..." + + local interface=$(ip route | awk '/default/ {print $5}') + local current_ip=$(ip addr show $interface | awk '/inet / {print $2}' | cut -d/ -f1) + + read -p "Enter static IP address [$current_ip]: " static_ip + static_ip=${static_ip:-$current_ip} + + read -p "Enter gateway IP: " gateway_ip + read -p "Enter DNS server IP: " dns_ip + + backup_config "/etc/netplan/01-netcfg.yaml" + + case $DISTRO in + ubuntu|debian) + cat < /dev/null +network: + version: 2 + renderer: networkd + ethernets: + $interface: + addresses: [$static_ip/24] + routes: + - to: default + via: $gateway_ip + nameservers: + addresses: [$dns_ip] +EOL + sudo netplan apply + ;; + fedora|arch|opensuse) + cat < /dev/null +DEVICE=$interface +BOOTPROTO=none +ONBOOT=yes +IPADDR=$static_ip +PREFIX=24 +GATEWAY=$gateway_ip +DNS1=$dns_ip +EOL + sudo systemctl restart NetworkManager + ;; + *) + log_error "Unsupported Linux distribution: $DISTRO" + exit 1 + ;; + esac + + log_info "Network configuration applied." +} + +# ...existing code... diff --git a/lib/nfs.sh b/lib/nfs.sh new file mode 100644 index 0000000..bb6fdf5 --- /dev/null +++ b/lib/nfs.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +install_nfs() { + log_info "Installing NFS..." + case $DISTRO in + ubuntu|debian) + handle_error sudo apt-get install -y nfs-kernel-server + ;; + fedora) + handle_error sudo dnf install -y nfs-utils + ;; + arch) + handle_error sudo pacman -S --noconfirm nfs-utils + ;; + opensuse) + handle_error sudo zypper install -y nfs-kernel-server + ;; + *) + log_error "Unsupported Linux distribution: $DISTRO" + exit 1 + ;; + esac + log_info "NFS installation completed." +} diff --git a/lib/portainer.sh b/lib/portainer.sh new file mode 100644 index 0000000..e75c6ea --- /dev/null +++ b/lib/portainer.sh @@ -0,0 +1,82 @@ +#!/bin/bash + +# portainer.sh - Script to install Portainer on various Linux distributions + +# Function to install Portainer on Ubuntu +install_portainer_ubuntu() { + sudo apt-get update + sudo apt-get install -y docker.io + sudo systemctl start docker + sudo systemctl enable docker + sudo docker volume create portainer_data + sudo docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce +} + +# Function to install Portainer on Debian +install_portainer_debian() { + sudo apt-get update + sudo apt-get install -y docker.io + sudo systemctl start docker + sudo systemctl enable docker + sudo docker volume create portainer_data + sudo docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce +} + +# Function to install Portainer on Fedora +install_portainer_fedora() { + sudo dnf -y update + sudo dnf -y install docker + sudo systemctl start docker + sudo systemctl enable docker + sudo docker volume create portainer_data + sudo docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce +} + +# Function to install Portainer on Arch Linux +install_portainer_arch() { + sudo pacman -Syu --noconfirm + sudo pacman -S --noconfirm docker + sudo systemctl start docker + sudo systemctl enable docker + sudo docker volume create portainer_data + sudo docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce +} + +# Function to install Portainer on openSUSE +install_portainer_opensuse() { + sudo zypper refresh + sudo zypper install -y docker + sudo systemctl start docker + sudo systemctl enable docker + sudo docker volume create portainer_data + sudo docker run -d -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce +} + +# Main script logic to detect the distribution and call the appropriate function +if [ -f /etc/os-release ]; then + . /etc/os-release + case "$ID" in + ubuntu) + install_portainer_ubuntu + ;; + debian) + install_portainer_debian + ;; + fedora) + install_portainer_fedora + ;; + arch) + install_portainer_arch + ;; + opensuse) + install_portainer_opensuse + ;; + *) + echo "Unsupported distribution: $ID" + exit 1 + ;; + esac +else + echo "Cannot detect the operating system." + exit 1 +fi \ No newline at end of file diff --git a/lib/security.sh b/lib/security.sh new file mode 100644 index 0000000..b4bcd86 --- /dev/null +++ b/lib/security.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Security configuration script + +secure_shared_memory() { + log_info "Securing shared memory..." + handle_error sudo cp /etc/fstab /etc/fstab.bak + echo "tmpfs /run/shm tmpfs defaults,noexec,nosuid 0 0" | sudo tee -a /etc/fstab + handle_error sudo mount -o remount /run/shm + log_info "Shared memory secured." +} + +install_fail2ban() { + log_info "Installing Fail2Ban..." + case $DISTRO in + ubuntu|debian) + handle_error sudo apt-get update + handle_error sudo apt-get install -y fail2ban + ;; + fedora) + handle_error sudo dnf install -y fail2ban + ;; + arch) + handle_error sudo pacman -S --noconfirm fail2ban + ;; + opensuse) + handle_error sudo zypper install -y fail2ban + ;; + *) + log_error "Unsupported Linux distribution: $DISTRO" + exit 1 + ;; + esac + handle_error sudo systemctl enable fail2ban + handle_error sudo systemctl start fail2ban + log_info "Fail2Ban installation completed." +} diff --git a/lib/ufw.sh b/lib/ufw.sh new file mode 100644 index 0000000..e69de29 diff --git a/lib/unattended-upgrades.sh b/lib/unattended-upgrades.sh new file mode 100644 index 0000000..aff3b40 --- /dev/null +++ b/lib/unattended-upgrades.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# unattended-upgrades.sh +# This script sets up unattended upgrades for various Linux distributions + +set -e + +DISTRO=$(lsb_release -is) + +case "$DISTRO" in + Ubuntu|Debian) + echo "Setting up unattended upgrades for $DISTRO..." + sudo apt-get update + sudo apt-get install -y unattended-upgrades + sudo dpkg-reconfigure --priority=low unattended-upgrades + ;; + Fedora) + echo "Setting up unattended upgrades for Fedora..." + sudo dnf install -y dnf-automatic + sudo systemctl enable --now dnf-automatic-install.timer + ;; + "Arch Linux") + echo "Setting up unattended upgrades for Arch Linux..." + sudo pacman -Syu --noconfirm + sudo systemctl enable --now paccache.timer + ;; + openSUSE) + echo "Setting up unattended upgrades for openSUSE..." + sudo zypper install -y yast2-online-update-configuration + sudo yast2 online_update_configuration + ;; + *) + echo "Unsupported distribution: $DISTRO" + exit 1 + ;; +esac + +echo "Unattended upgrades setup complete." \ No newline at end of file diff --git a/lib/vaultwarden.sh b/lib/vaultwarden.sh new file mode 100644 index 0000000..dad0035 --- /dev/null +++ b/lib/vaultwarden.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Vaultwarden installation and configuration script + +install_vaultwarden() { + log_info "Installing Vaultwarden..." + + if [ -f /etc/os-release ]; then + . /etc/os-release + OS=$ID + else + echo "Unsupported OS" + exit 1 + fi + + case $OS in + ubuntu|debian) + sudo apt update + sudo apt install -y docker.io docker-compose + ;; + fedora) + sudo dnf install -y docker docker-compose + ;; + arch) + sudo pacman -Syu --noconfirm docker docker-compose + ;; + opensuse) + sudo zypper install -y docker docker-compose + ;; + *) + echo "Unsupported OS" + exit 1 + ;; + esac + + sudo systemctl start docker + sudo systemctl enable docker + + mkdir -p ~/vaultwarden + cd ~/vaultwarden + + cat < docker-compose.yml +version: '3' +services: + vaultwarden: + image: vaultwarden/server:latest + container_name: vaultwarden + restart: unless-stopped + volumes: + - ./vw-data:/data + ports: + - 80:80 +EOF + + # Pull the Vaultwarden image + handle_error sudo docker pull vaultwarden/server:latest + + # Create the Vaultwarden container + handle_error sudo docker run -d --name vaultwarden -v /vw-data/:/data/ -p 80:80 --restart always vaultwarden/server:latest + + log_info "Vaultwarden installation completed." +} + +install_vaultwarden \ No newline at end of file diff --git a/setup.sh b/setup.sh new file mode 100644 index 0000000..0b094de --- /dev/null +++ b/setup.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +# NAS Setup Script - Version 3.4 +# +# This script automates the setup of a NAS system with various services. +# It is designed to run on multiple Linux distributions, including: +# - Ubuntu +# - Debian +# - Fedora +# - Arch Linux +# - openSUSE +# +# Disclaimer: +# This script is provided "as is", without warranty of any kind, express or implied, +# including but not limited to the warranties of merchantability, fitness for a particular purpose, +# and noninfringement. In no event shall the authors or copyright holders be liable for any claim, +# damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, +# out of, or in connection with the software or the use or other dealings in the software. +# +# Usage: +# Run this script with root privileges on a fresh installation of a supported Linux distribution. +# Ensure you have an active internet connection before starting the setup. +# +# Author: Sebastian Palencsár +# License: MIT License +# (c) 2025 Sebastian Palencsár + +# Import configuration and functions +source "$(dirname "$0")/config/defaults.sh" +source "$(dirname "$0")/lib/logging.sh" +source "$(dirname "$0")/lib/network.sh" +source "$(dirname "$0")/lib/docker.sh" +source "$(dirname "$0")/lib/security.sh" +source "$(dirname "$0")/lib/internet.sh" +source "$(dirname "$0")/lib/nfs.sh" +source "$(dirname "$0")/lib/netdata.sh" +source "$(dirname "$0")/lib/firewall.sh" +source "$(dirname "$0")/lib/unattended-upgrades.sh" +source "$(dirname "$0")/lib/vaultwarden.sh" +source "$(dirname "$0")/lib/jellyfin.sh" +source "$(dirname "$0")/lib/portainer.sh" + +# Logging configuration +exec > >(tee -a "${LOG_FILE}") 2>&1 + +# Improved error handling +handle_error() { + "$@" + local status=$? + if [ $status -ne 0 ]; then + log_error "Error executing $* (exit code: $status)" + exit 1 + fi +} + +# Detect Linux distribution +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + DISTRO=$ID + else + log_error "Unsupported Linux distribution." + exit 1 + fi +} + +# Main script execution +log_info "NAS Setup Script started." + +detect_distro +check_internet_connection + +case $DISTRO in + ubuntu|debian) + check_ubuntu_version + ;; + fedora|arch|opensuse) + # Add specific checks here if needed + ;; + *) + log_error "Unsupported Linux distribution: $DISTRO" + exit 1 + ;; +esac + +check_system_requirements + +load_or_create_config + +update_system + +configure_network +configure_ssh +setup_samba +configure_firewall + +secure_shared_memory +install_fail2ban +configure_automatic_updates +setup_basic_monitoring + +if ask_yes_no "Do you want to install Docker?"; then + install_docker +fi + +if ask_yes_no "Do you want to install additional components?"; then + install_additional_components +else + log_info "Installation of additional components skipped." +fi + +if ask_yes_no "Do you want to install NFS?"; then + install_nfs +fi + +if ask_yes_no "Do you want to install Netdata for advanced monitoring?"; then + install_netdata +fi + +if ask_yes_no "Do you want to install Vaultwarden?"; then + install_vaultwarden +fi + +if ask_yes_no "Do you want to install Jellyfin?"; then + install_jellyfin +fi + +if ask_yes_no "Do you want to install Portainer?"; then + install_portainer +fi + +cleanup + +log_info "Setup completed. User $NEW_USER has been created with sudo and Samba access. Installation of optional components completed." +show_progress 100 100 "Setup completed" + +log_info "Please reboot your system to ensure all changes take effect." +if ask_yes_no "Do you want to reboot now?"; then + sudo reboot +fi