diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bec2c5..4c81443 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,12 +10,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### 🚀 Distribution Detection Enhancement Release #### Added -- **Robust Distribution Detection System** - - 5-method fallback detection (/etc/os-release, /etc/redhat-release, /etc/debian_version, lsb_release, manual file checks) - - Container environment detection (Docker, Podman, LXC, WSL) with user warnings - - Advanced version normalization with regex parsing and bc calculator - - Comprehensive unit testing (66+ test cases, 98.5% success rate) - - Enterprise-grade error handling with detailed logging +- **Webmin Integration** + - Web-based system administration interface + - Automatic firewall configuration for port 10000 + - SSL configuration and session timeout optimization + - Multi-distribution support (Ubuntu/Debian, Fedora, openSUSE) + +- **Advanced Memory Optimization** + - vm.swappiness=10 for reduced aggressive swapping + - vm.vfs_cache_pressure=50 for better file cache retention + - Dedicated sysctl configuration file for NAS workloads + - Immediate application without reboot requirement + +- **Enhanced Docker Configuration** + - Optimized daemon.json with overlay2 storage driver + - Log rotation (10MB max size, 3 files) + - Performance tuning (live-restore, userland-proxy=false) + - Resource limits and metrics endpoint configuration - **Enhanced Security Documentation** - New SECURITY.md with comprehensive security policy diff --git a/README.md b/README.md index 7efd2d6..d79d3b7 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file - **Netdata** for real-time system monitoring - **Jellyfin** media server for multimedia content - **Vaultwarden** for secure password management +- **Webmin** web-based system administration interface - **System Performance Tracking** with automatic reports - **Comprehensive Unit Testing** framework with extensive test coverage @@ -130,6 +131,7 @@ The script guides you through an interactive configuration: - **Vaultwarden:** Password manager with security hardening - **Jellyfin:** Media server with modern GPG keys - **Portainer:** Docker management with HTTPS +- **Webmin:** Web-based system administration interface ### Security Configuration - **Firewall Rules:** IPv4/IPv6 automatic based on selected services @@ -158,6 +160,7 @@ nas/ │ ├── vaultwarden.sh # Vaultwarden password manager │ ├── jellyfin.sh # Jellyfin media server │ ├── portainer.sh # Portainer Docker management +│ ├── webmin.sh # Webmin web interface │ ├── unattended-upgrades.sh # Automatic system updates │ └── performance.sh # Performance optimization ├── tests/ @@ -182,6 +185,7 @@ nas/ | Jellyfin | 1900 | UDP | DLNA Discovery | ✅ | | Portainer | 9000 | TCP | Docker Management (HTTPS) | ✅ | | Vaultwarden | 8080 | TCP | Password Manager | ✅ | +| Webmin | 10000 | TCP | Web Administration Interface | ✅ | | Docker API | 2375, 2376 | TCP | Docker Remote API | ✅ | ## 🛡️ Security Features diff --git a/config/defaults.sh b/config/defaults.sh index 9698da6..31b1b38 100644 --- a/config/defaults.sh +++ b/config/defaults.sh @@ -121,6 +121,7 @@ INSTALL_NETDATA=${INSTALL_NETDATA:-false} INSTALL_VAULTWARDEN=${INSTALL_VAULTWARDEN:-false} INSTALL_JELLYFIN=${INSTALL_JELLYFIN:-false} INSTALL_PORTAINER=${INSTALL_PORTAINER:-false} +INSTALL_WEBMIN=${INSTALL_WEBMIN:-false} # Configuration validation validate_config() { diff --git a/lib/docker.sh b/lib/docker.sh index 7fed8d1..db2519a 100644 --- a/lib/docker.sh +++ b/lib/docker.sh @@ -52,14 +52,15 @@ install_docker() { handle_error sudo systemctl enable docker handle_error sudo systemctl start docker - # Configure Docker data directory + # Configure Docker data directory and optimization 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 - + + # Create optimized Docker daemon configuration + configure_docker_daemon + export DOCKER_CONTENT_TRUST=1 log_info "Docker installed successfully." @@ -75,3 +76,44 @@ install_docker() { echo "5. Enable linger for the user:" echo " sudo loginctl enable-linger \$(whoami)" } + +# Configure optimized Docker daemon +configure_docker_daemon() { + log_info "Configuring optimized Docker daemon..." + + sudo mkdir -p /etc/docker + + # Create optimized daemon.json + cat << EOF | sudo tee /etc/docker/daemon.json +{ + "storage-driver": "overlay2", + "log-driver": "json-file", + "log-opts": { + "max-size": "10m", + "max-file": "3" + }, + "exec-opts": ["native.cgroupdriver=systemd"], + "live-restore": true, + "userland-proxy": false, + "experimental": false, + "metrics-addr": "0.0.0.0:9323", + "default-ulimits": { + "nofile": { + "Hard": 64000, + "Name": "nofile", + "Soft": 64000 + } + } +EOF + + # Add data-root if custom directory is specified + if [[ "$DOCKER_DATA_DIR" != "$DEFAULT_DOCKER_DATA_DIR" ]]; then + # Modify the daemon.json to include data-root + sudo sed -i "s|{|{\n \"data-root\": \"$DOCKER_DATA_DIR\",|" /etc/docker/daemon.json + fi + + # Restart Docker to apply configuration + handle_error sudo systemctl restart docker + + log_success "Docker daemon optimized" +} diff --git a/lib/performance.sh b/lib/performance.sh index f1ffe0b..3aef88f 100644 --- a/lib/performance.sh +++ b/lib/performance.sh @@ -6,6 +6,9 @@ optimize_system_performance() { log_info "Optimizing system performance..." + # Memory optimization for NAS workloads + configure_memory_optimization + # Optimize kernel parameters sudo tee -a /etc/sysctl.conf > /dev/null < /dev/null <<'EOF' diff --git a/lib/webmin.sh b/lib/webmin.sh new file mode 100644 index 0000000..247ecf8 --- /dev/null +++ b/lib/webmin.sh @@ -0,0 +1,118 @@ +#!/bin/bash + +# Webmin installation and configuration + +install_webmin() { + if [[ "${INSTALL_WEBMIN:-false}" != "true" ]]; then + return 0 + fi + + log_info "Installing Webmin web interface..." + + case $DISTRO in + ubuntu|debian) + # Download and run Webmin setup script + handle_error curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh + handle_error sudo bash setup-repos.sh + + # Install Webmin + handle_error sudo apt update + handle_error sudo apt install -y webmin + + # Clean up setup script + rm -f setup-repos.sh + ;; + fedora) + # Add Webmin repository + handle_error sudo curl -o /etc/yum.repos.d/webmin.repo https://raw.githubusercontent.com/webmin/webmin/master/webmin.repo + handle_error sudo dnf install -y webmin + ;; + opensuse) + # Add Webmin repository + handle_error sudo zypper addrepo -f https://download.webmin.com/download/yum/webmin-suse.repo + handle_error sudo zypper refresh + handle_error sudo zypper install -y webmin + ;; + arch) + # Webmin is available in AUR + log_warning "Webmin installation on Arch Linux requires manual AUR installation" + log_info "Please install Webmin manually from AUR: yay -S webmin" + log_info "Then run: sudo systemctl enable webmin && sudo systemctl start webmin" + return 0 + ;; + *) + log_error "Webmin installation not supported for $DISTRO" + return 1 + ;; + esac + + # Enable and start Webmin service + handle_error sudo systemctl enable webmin + handle_error sudo systemctl start webmin + + # Configure firewall for Webmin (port 10000) + configure_webmin_firewall + + # Get IP address for access information + local ip_address=$(hostname -I | awk '{print $1}') + + log_success "Webmin installed and configured" + log_info "Webmin is available at: https://${ip_address}:10000" + log_info "Default login: root / your root password" + log_warning "Important: Change the default password after first login!" + log_info "Note: Webmin uses self-signed SSL certificate - accept the security warning" + + # Add to rollback + add_rollback_action "sudo systemctl disable webmin && sudo systemctl stop webmin && sudo apt remove -y webmin" +} + +# Configure firewall for Webmin access +configure_webmin_firewall() { + log_info "Configuring firewall for Webmin access..." + + case $DISTRO in + ubuntu|debian|arch) + # UFW firewall + if command -v ufw &> /dev/null; then + handle_error sudo ufw allow 10000/tcp + log_info "UFW rule added: allow port 10000/tcp for Webmin" + fi + ;; + fedora|opensuse) + # Firewalld + if command -v firewall-cmd &> /dev/null; then + handle_error sudo firewall-cmd --permanent --add-port=10000/tcp + handle_error sudo firewall-cmd --reload + log_info "Firewalld rule added: allow port 10000/tcp for Webmin" + fi + ;; + esac +} + +# Webmin configuration optimization +configure_webmin() { + if [[ "${INSTALL_WEBMIN:-false}" != "true" ]]; then + return 0 + fi + + log_info "Configuring Webmin optimizations..." + + # Webmin configuration file + local webmin_config="/etc/webmin/miniserv.conf" + + if [[ -f "$webmin_config" ]]; then + # Increase session timeout + sudo sed -i 's/^session_timeout=.*/session_timeout=3600/' "$webmin_config" + + # Configure SSL settings + sudo sed -i 's/^ssl=.*/ssl=1/' "$webmin_config" + sudo sed -i 's/^ssl_redirect=.*/ssl_redirect=1/' "$webmin_config" + + # Restart Webmin to apply changes + handle_error sudo systemctl restart webmin + + log_success "Webmin configuration optimized" + else + log_warning "Webmin configuration file not found - skipping optimization" + fi +} \ No newline at end of file diff --git a/setup.sh b/setup.sh index ee0e2fc..efd2d86 100644 --- a/setup.sh +++ b/setup.sh @@ -46,6 +46,7 @@ source "${SCRIPT_DIR}/lib/unattended-upgrades.sh" source "${SCRIPT_DIR}/lib/vaultwarden.sh" source "${SCRIPT_DIR}/lib/jellyfin.sh" source "${SCRIPT_DIR}/lib/portainer.sh" +source "${SCRIPT_DIR}/lib/webmin.sh" source "${SCRIPT_DIR}/lib/performance.sh" # Initialize logging @@ -306,6 +307,7 @@ create_interactive_config() { save_config "INSTALL_VAULTWARDEN" "$(ask_yes_no "Install Vaultwarden password manager?" "n" && echo "true" || echo "false")" save_config "INSTALL_JELLYFIN" "$(ask_yes_no "Install Jellyfin media server?" "n" && echo "true" || echo "false")" save_config "INSTALL_PORTAINER" "$(ask_yes_no "Install Portainer Docker management?" "n" && echo "true" || echo "false")" + save_config "INSTALL_WEBMIN" "$(ask_yes_no "Install Webmin web interface?" "n" && echo "true" || echo "false")" log_success "Configuration created and saved to ${CONFIG_FILE}" } @@ -339,7 +341,7 @@ update_system() { # Main installation orchestrator run_installation() { - local total_steps=12 + local total_steps=13 local current_step=0 log_info "Starting NAS installation process..." @@ -410,6 +412,14 @@ run_installation() { else ((current_step++)) fi + + if [[ "${INSTALL_WEBMIN:-false}" == "true" ]]; then + ((current_step++)); show_progress $current_step $total_steps "Installing Webmin" + install_webmin + configure_webmin + else + ((current_step++)) + fi } # Installation summary @@ -442,6 +452,9 @@ show_installation_summary() { if [[ "${INSTALL_PORTAINER:-false}" == "true" ]]; then echo " ✓ Portainer Docker management: http://$(hostname -I | awk '{print $1}'):9000" fi + if [[ "${INSTALL_WEBMIN:-false}" == "true" ]]; then + echo " ✓ Webmin web interface: https://$(hostname -I | awk '{print $1}'):10000" + fi echo log_info "Next steps:"