523 lines
16 KiB
Bash
523 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 the enrollment script to a system location
|
|
if [[ -f "../Router-enrollment-script/enroll-router.sh" ]]; then
|
|
cp "../Router-enrollment-script/enroll-router.sh" "/usr/local/bin/" || error_exit "Failed to copy enrollment script"
|
|
chmod +x "/usr/local/bin/enroll-router.sh" || error_exit "Failed to make enrollment script executable"
|
|
log "SUCCESS" "Copied enrollment script to /usr/local/bin/enroll-router.sh"
|
|
else
|
|
log "WARNING" "Enrollment script not found at ../Router-enrollment-script/enroll-router.sh"
|
|
fi
|
|
|
|
# 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/local/bin/enroll-router.sh
|
|
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 "$@"
|