zitinexus-router-script/UI/install.sh

520 lines
16 KiB
Bash

#!/bin/bash
# ZitiNexus Router Enrollment UI Installation Script
# For Ubuntu 22.04/24.04 LTS
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
WEB_DIR="/var/www/ziti-enrollment"
DOMAIN="ziti-enrollment.local"
WEB_USER="www-data"
PHP_VERSION=""
# Logging function
log() {
local level=$1
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
case $level in
"ERROR")
echo -e "${RED}[ERROR]${NC} $message" >&2
;;
"SUCCESS")
echo -e "${GREEN}[SUCCESS]${NC} $message"
;;
"WARNING")
echo -e "${YELLOW}[WARNING]${NC} $message"
;;
"INFO")
echo -e "${BLUE}[INFO]${NC} $message"
;;
*)
echo "$message"
;;
esac
}
# Error handling
error_exit() {
log "ERROR" "$1"
exit 1
}
# Check if running as root
check_root() {
if [[ $EUID -ne 0 ]]; then
error_exit "This script must be run as root (use sudo)"
fi
}
# Detect available PHP version
detect_php_version() {
log "INFO" "Detecting available PHP version..."
# Update package cache first
apt update >/dev/null 2>&1
# Check for available PHP versions in order of preference
for version in "8.3" "8.2" "8.1" "8.0"; do
log "INFO" "Checking for PHP $version..."
# Check multiple ways to ensure package availability
if apt-cache show "php${version}" >/dev/null 2>&1 || \
apt-cache show "php${version}-cli" >/dev/null 2>&1 || \
apt list "php${version}" 2>/dev/null | grep -q "php${version}"; then
# Double-check that the FPM package exists for Nginx
if apt-cache show "php${version}-fpm" >/dev/null 2>&1 || \
apt list "php${version}-fpm" 2>/dev/null | grep -q "php${version}-fpm"; then
PHP_VERSION="$version"
log "SUCCESS" "Found PHP $PHP_VERSION with FPM support"
break
else
log "WARNING" "PHP $version found but FPM package not available"
fi
else
log "INFO" "PHP $version not available"
fi
done
if [[ -z "$PHP_VERSION" ]]; then
log "ERROR" "No compatible PHP version found. Available packages:"
apt list --installed | grep php 2>/dev/null || echo "No PHP packages found"
log "INFO" "Trying to install default PHP..."
# Fallback: try to install default php package
if apt-cache show "php" >/dev/null 2>&1; then
log "INFO" "Found default PHP package, will use system default"
# Get the default PHP version
PHP_VERSION=$(apt-cache show php | grep "^Depends:" | grep -o "php[0-9]\+\.[0-9]\+" | head -1 | sed 's/php//')
if [[ -n "$PHP_VERSION" ]]; then
log "SUCCESS" "Will use system default PHP $PHP_VERSION"
else
error_exit "Could not determine PHP version from default package"
fi
else
error_exit "No PHP packages available. Please install PHP manually first."
fi
fi
log "SUCCESS" "Selected PHP version: $PHP_VERSION"
}
# Detect web server preference
detect_web_server() {
echo
log "INFO" "Which web server would you like to use?"
echo "1) Apache (recommended)"
echo "2) Nginx"
read -p "Enter your choice (1-2): " choice
case $choice in
1)
WEB_SERVER="apache"
;;
2)
WEB_SERVER="nginx"
;;
*)
log "WARNING" "Invalid choice, defaulting to Apache"
WEB_SERVER="apache"
;;
esac
log "INFO" "Selected web server: $WEB_SERVER"
}
# Install web server and PHP
install_web_server() {
log "INFO" "Installing web server and PHP $PHP_VERSION..."
# Update package list
apt update || error_exit "Failed to update package list"
# Determine required PHP packages
PHP_PACKAGES="php${PHP_VERSION} php${PHP_VERSION}-curl"
# JSON support is bundled in modern PHP versions (php-cli, php-fpm, etc.)
log "INFO" "Skipping php${PHP_VERSION}-json as it's bundled in php${PHP_VERSION}-cli"
if [[ "$WEB_SERVER" == "apache" ]]; then
# Install Apache and PHP
apt install -y apache2 $PHP_PACKAGES libapache2-mod-php${PHP_VERSION} || error_exit "Failed to install Apache and PHP"
# Enable and start Apache
systemctl enable apache2 || error_exit "Failed to enable Apache"
systemctl start apache2 || error_exit "Failed to start Apache"
log "SUCCESS" "Apache and PHP $PHP_VERSION installed successfully"
elif [[ "$WEB_SERVER" == "nginx" ]]; then
# Install Nginx and PHP-FPM
apt install -y nginx php${PHP_VERSION}-fpm $PHP_PACKAGES || error_exit "Failed to install Nginx and PHP"
# Enable and start services
systemctl enable nginx php${PHP_VERSION}-fpm || error_exit "Failed to enable Nginx and PHP-FPM"
systemctl start nginx php${PHP_VERSION}-fpm || error_exit "Failed to start Nginx and PHP-FPM"
log "SUCCESS" "Nginx and PHP $PHP_VERSION installed successfully"
fi
}
# Deploy UI files
deploy_ui() {
log "INFO" "Deploying UI files..."
# Create web directory
mkdir -p "$WEB_DIR" || error_exit "Failed to create web directory"
# Check for required directories
log "INFO" "Current directory: $(pwd)"
log "INFO" "Directory contents: $(ls -la)"
if [[ ! -d "public" ]]; then
error_exit "public directory not found. Current directory: $(pwd)"
fi
if [[ ! -d "includes" ]]; then
error_exit "includes directory not found. Current directory: $(pwd)"
fi
log "INFO" "Found required directories: public and includes"
# Copy main UI files (assets are now inside public)
cp -r public includes "$WEB_DIR/" || error_exit "Failed to copy UI files"
# Copy root-level PHP files for direct access (when document root is main directory)
if [[ -f "index.php" ]]; then
cp index.php "$WEB_DIR/" || log "WARNING" "Failed to copy root index.php"
fi
if [[ -f "dashboard.php" ]]; then
cp dashboard.php "$WEB_DIR/" || log "WARNING" "Failed to copy root dashboard.php"
fi
# Copy optional files if they exist
if [[ -f "README.md" ]]; then
cp README.md "$WEB_DIR/" || log "WARNING" "Failed to copy README.md"
fi
if [[ -f ".htaccess" ]]; then
cp .htaccess "$WEB_DIR/" || log "WARNING" "Failed to copy .htaccess"
fi
# Create logs and temp directories if they don't exist
if [[ -d "logs" ]]; then
cp -r logs "$WEB_DIR/" || log "WARNING" "Failed to copy logs directory"
else
mkdir -p "$WEB_DIR/logs" || error_exit "Failed to create logs directory"
log "INFO" "Created logs directory"
fi
if [[ -d "temp" ]]; then
cp -r temp "$WEB_DIR/" || log "WARNING" "Failed to copy temp directory"
else
mkdir -p "$WEB_DIR/temp" || error_exit "Failed to create temp directory"
log "INFO" "Created temp directory"
fi
# Set proper permissions
chown -R "$WEB_USER:$WEB_USER" "$WEB_DIR" || error_exit "Failed to set ownership"
chmod -R 755 "$WEB_DIR" || error_exit "Failed to set permissions"
chmod -R 777 "$WEB_DIR/logs" "$WEB_DIR/temp" || error_exit "Failed to set log/temp permissions"
log "SUCCESS" "UI files deployed successfully"
}
# Configure Apache
configure_apache() {
log "INFO" "Configuring Apache virtual host..."
# Create virtual host configuration
cat > "/etc/apache2/sites-available/ziti-enrollment.conf" << EOF
<VirtualHost *:80>
ServerName $DOMAIN
DocumentRoot $WEB_DIR/public
<Directory $WEB_DIR/public>
AllowOverride All
Require all granted
DirectoryIndex index.php
</Directory>
ErrorLog \${APACHE_LOG_DIR}/ziti-enrollment_error.log
CustomLog \${APACHE_LOG_DIR}/ziti-enrollment_access.log combined
</VirtualHost>
EOF
# Enable site and modules
a2ensite ziti-enrollment.conf || error_exit "Failed to enable site"
a2enmod rewrite || error_exit "Failed to enable rewrite module"
# Disable default site
a2dissite 000-default.conf || log "WARNING" "Failed to disable default site"
# Reload Apache
systemctl reload apache2 || error_exit "Failed to reload Apache"
log "SUCCESS" "Apache configured successfully"
}
# Configure Nginx
configure_nginx() {
log "INFO" "Configuring Nginx virtual host..."
# Create virtual host configuration
cat > "/etc/nginx/sites-available/ziti-enrollment" << EOF
server {
listen 80;
server_name $DOMAIN;
root $WEB_DIR/public;
index index.php;
location / {
try_files \$uri \$uri/ /index.php?\$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php${PHP_VERSION}-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME \$realpath_root\$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\. {
deny all;
}
}
EOF
# Enable site
ln -sf "/etc/nginx/sites-available/ziti-enrollment" "/etc/nginx/sites-enabled/" || error_exit "Failed to enable site"
# Remove default site
rm -f "/etc/nginx/sites-enabled/default" || log "WARNING" "Failed to remove default site"
# Test and reload Nginx
nginx -t || error_exit "Nginx configuration test failed"
systemctl reload nginx || error_exit "Failed to reload Nginx"
log "SUCCESS" "Nginx configured successfully"
}
# Configure PHP
configure_php() {
log "INFO" "Configuring PHP..."
# Find PHP configuration file
if [[ "$WEB_SERVER" == "apache" ]]; then
PHP_INI="/etc/php/${PHP_VERSION}/apache2/php.ini"
else
PHP_INI="/etc/php/${PHP_VERSION}/fpm/php.ini"
fi
# Check if exec functions are disabled
if grep -q "disable_functions.*exec" "$PHP_INI"; then
log "WARNING" "PHP exec functions may be disabled. Please check $PHP_INI"
log "INFO" "Ensure exec, shell_exec, proc_open are NOT in disable_functions"
fi
# Restart web server to apply PHP changes
if [[ "$WEB_SERVER" == "apache" ]]; then
systemctl restart apache2 || error_exit "Failed to restart Apache"
else
systemctl restart php${PHP_VERSION}-fpm || error_exit "Failed to restart PHP-FPM"
fi
log "SUCCESS" "PHP configured successfully"
}
# Set up sudo access
setup_sudo() {
log "INFO" "Setting up sudo access for web server..."
# Create sudoers file
cat > "/etc/sudoers.d/ziti-enrollment" << 'EOF'
# Allow www-data to run system commands for Ziti enrollment
www-data ALL=(ALL) NOPASSWD: /usr/bin/apt-get
www-data ALL=(ALL) NOPASSWD: /usr/bin/systemctl
www-data ALL=(ALL) NOPASSWD: /usr/bin/mkdir
www-data ALL=(ALL) NOPASSWD: /usr/bin/chmod
www-data ALL=(ALL) NOPASSWD: /usr/bin/chown
www-data ALL=(ALL) NOPASSWD: /usr/bin/curl
www-data ALL=(ALL) NOPASSWD: /usr/bin/gpg
www-data ALL=(ALL) NOPASSWD: /usr/bin/ziti
www-data ALL=(ALL) NOPASSWD: /usr/bin/which
www-data ALL=(ALL) NOPASSWD: /usr/bin/hostname
www-data ALL=(ALL) NOPASSWD: /usr/bin/uname
www-data ALL=(ALL) NOPASSWD: /usr/bin/lsb_release
www-data ALL=(ALL) NOPASSWD: /usr/bin/cp
www-data ALL=(ALL) NOPASSWD: /usr/bin/mv
www-data ALL=(ALL) NOPASSWD: /usr/bin/rm
www-data ALL=(ALL) NOPASSWD: /usr/bin/ln
www-data ALL=(ALL) NOPASSWD: /usr/bin/whoami
www-data ALL=(ALL) NOPASSWD: /usr/bin/tee
www-data ALL=(ALL) NOPASSWD: /usr/bin/cat
EOF
# Validate sudoers file
if visudo -c -f "/etc/sudoers.d/ziti-enrollment"; then
log "SUCCESS" "Sudo access configured successfully"
else
error_exit "Invalid sudoers configuration"
fi
}
# Update hosts file
update_hosts() {
log "INFO" "Updating hosts file..."
# Check if entry already exists
if ! grep -q "$DOMAIN" /etc/hosts; then
echo "127.0.0.1 $DOMAIN" >> /etc/hosts
log "SUCCESS" "Added $DOMAIN to hosts file"
else
log "INFO" "Domain already exists in hosts file"
fi
}
# Test installation
test_installation() {
log "INFO" "Testing installation..."
# Test web server
if [[ "$WEB_SERVER" == "apache" ]]; then
if systemctl is-active --quiet apache2; then
log "SUCCESS" "Apache is running"
else
log "ERROR" "Apache is not running"
fi
else
if systemctl is-active --quiet nginx && systemctl is-active --quiet php${PHP_VERSION}-fpm; then
log "SUCCESS" "Nginx and PHP-FPM are running"
else
log "ERROR" "Nginx or PHP-FPM is not running"
fi
fi
# Test PHP
if php -v > /dev/null 2>&1; then
log "SUCCESS" "PHP is working"
# Test JSON support
if php -r 'var_dump(function_exists("json_encode"));' 2>/dev/null | grep -q "bool(true)"; then
log "SUCCESS" "PHP JSON support is available"
else
log "WARNING" "PHP JSON support may not be available"
fi
else
log "ERROR" "PHP is not working"
fi
# Test sudo access
if sudo -u www-data sudo -n systemctl --version > /dev/null 2>&1; then
log "SUCCESS" "Sudo access is working"
else
log "WARNING" "Sudo access may not be working properly"
fi
# Test file permissions
if [[ -r "$WEB_DIR/public/index.php" ]]; then
log "SUCCESS" "File permissions are correct"
else
log "ERROR" "File permissions may be incorrect"
fi
}
# Show final information
show_final_info() {
echo
echo "=============================================="
echo " INSTALLATION COMPLETED"
echo "=============================================="
echo
log "SUCCESS" "ZitiNexus Router Enrollment UI installed successfully!"
echo
echo "Access Information:"
echo " URL: http://$DOMAIN"
echo " Username: admin"
echo " Password: admin123"
echo
echo "Important Notes:"
echo " 1. Change the default password in production"
echo " 2. Consider setting up HTTPS for production use"
echo " 3. Review security settings in $WEB_DIR/includes/config.php"
echo
echo "File Locations:"
echo " Web Directory: $WEB_DIR"
echo " Configuration: $WEB_DIR/includes/config.php"
echo " Logs: $WEB_DIR/logs/"
echo
echo "Useful Commands:"
if [[ "$WEB_SERVER" == "apache" ]]; then
echo " Check status: systemctl status apache2"
echo " View logs: tail -f /var/log/apache2/ziti-enrollment_error.log"
else
echo " Check status: systemctl status nginx php${PHP_VERSION}-fpm"
echo " View logs: tail -f /var/log/nginx/error.log"
fi
echo " Test sudo: sudo -u www-data sudo -l"
echo
}
# Main installation function
main() {
echo "=============================================="
echo " ZitiNexus Router Enrollment UI Installer"
echo "=============================================="
echo
# Check if running as root
check_root
# Detect available PHP version
detect_php_version
# Detect web server preference
detect_web_server
# Install web server and PHP
install_web_server
# Deploy UI files
deploy_ui
# Configure web server
if [[ "$WEB_SERVER" == "apache" ]]; then
configure_apache
else
configure_nginx
fi
# Configure PHP
configure_php
# Set up sudo access
setup_sudo
# Update hosts file
update_hosts
# Test installation
test_installation
# Show final information
show_final_info
}
# Run main function
main "$@"