769 lines
25 KiB
Bash
769 lines
25 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 OpenZiti package repository and install packages
|
|
setup_openziti_repository() {
|
|
log "INFO" "Setting up OpenZiti package repository..."
|
|
|
|
local gpgKeyUrl='https://get.openziti.io/tun/package-repos.gpg'
|
|
local gpgKeyPath='/usr/share/keyrings/openziti.gpg'
|
|
|
|
# Check if GPG key already exists and is valid
|
|
if [[ -f "$gpgKeyPath" && -s "$gpgKeyPath" ]]; then
|
|
local keySize=$(wc -c < "$gpgKeyPath")
|
|
log "SUCCESS" "OpenZiti GPG key already exists ($keySize bytes), skipping installation"
|
|
else
|
|
log "INFO" "Installing OpenZiti GPG key..."
|
|
|
|
# Ensure keyrings directory exists
|
|
mkdir -p /usr/share/keyrings || error_exit "Failed to create keyrings directory"
|
|
chmod 755 /usr/share/keyrings || error_exit "Failed to set keyrings directory permissions"
|
|
|
|
# Download GPG key to temporary file
|
|
local tempGpgFile=$(mktemp)
|
|
log "INFO" "Downloading GPG key from $gpgKeyUrl..."
|
|
|
|
if curl -sSLf --connect-timeout 30 --max-time 60 "$gpgKeyUrl" -o "$tempGpgFile"; then
|
|
local fileSize=$(wc -c < "$tempGpgFile")
|
|
log "SUCCESS" "GPG key downloaded successfully ($fileSize bytes)"
|
|
|
|
# Try multiple methods to process the GPG key
|
|
local methods=(
|
|
"gpg --dearmor --output '$gpgKeyPath' '$tempGpgFile'"
|
|
"cat '$tempGpgFile' | gpg --dearmor > '$gpgKeyPath'"
|
|
"gpg --dearmor < '$tempGpgFile' > '$gpgKeyPath'"
|
|
)
|
|
|
|
local success=false
|
|
for method in "${methods[@]}"; do
|
|
log "INFO" "Trying GPG processing method: $method"
|
|
if eval "$method" 2>/dev/null; then
|
|
if [[ -f "$gpgKeyPath" && -s "$gpgKeyPath" ]]; then
|
|
local processedSize=$(wc -c < "$gpgKeyPath")
|
|
log "SUCCESS" "GPG key processed successfully ($processedSize bytes)"
|
|
success=true
|
|
break
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Fallback: copy raw file and let apt handle it
|
|
if [[ "$success" != true ]]; then
|
|
log "WARNING" "GPG processing failed, trying raw file copy..."
|
|
if cp "$tempGpgFile" "$gpgKeyPath"; then
|
|
log "SUCCESS" "GPG key copied as raw file - apt will handle format conversion"
|
|
success=true
|
|
fi
|
|
fi
|
|
|
|
rm -f "$tempGpgFile"
|
|
|
|
if [[ "$success" != true ]]; then
|
|
error_exit "Failed to install OpenZiti GPG key"
|
|
fi
|
|
else
|
|
rm -f "$tempGpgFile"
|
|
error_exit "Failed to download OpenZiti GPG key from $gpgKeyUrl"
|
|
fi
|
|
fi
|
|
|
|
# Set proper permissions on GPG key
|
|
chmod a+r "$gpgKeyPath" || error_exit "Failed to set GPG key permissions"
|
|
|
|
# Configure OpenZiti repository
|
|
local repoFile='/etc/apt/sources.list.d/openziti-release.list'
|
|
local repoContent='deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main'
|
|
|
|
if [[ -f "$repoFile" ]]; then
|
|
log "INFO" "OpenZiti repository already configured"
|
|
else
|
|
log "INFO" "Configuring OpenZiti repository..."
|
|
echo "$repoContent" > "$repoFile" || error_exit "Failed to create repository file"
|
|
log "SUCCESS" "OpenZiti repository configured"
|
|
fi
|
|
|
|
# Update package list
|
|
log "INFO" "Updating package list..."
|
|
if apt update; then
|
|
log "SUCCESS" "Package list updated successfully"
|
|
else
|
|
log "WARNING" "Package list update had issues, but continuing..."
|
|
fi
|
|
|
|
# Verify repository is accessible
|
|
log "INFO" "Verifying OpenZiti repository accessibility..."
|
|
if apt-cache show openziti-router >/dev/null 2>&1; then
|
|
log "SUCCESS" "OpenZiti repository is accessible and openziti-router package is available"
|
|
elif apt-cache show ziti >/dev/null 2>&1; then
|
|
log "SUCCESS" "OpenZiti repository is accessible and ziti package is available"
|
|
else
|
|
log "WARNING" "OpenZiti packages not found in repositories, but repository is configured"
|
|
fi
|
|
}
|
|
|
|
# Install OpenZiti packages
|
|
install_openziti_packages() {
|
|
log "INFO" "Installing OpenZiti packages..."
|
|
|
|
# Check if OpenZiti CLI is already installed
|
|
if command -v ziti &> /dev/null; then
|
|
local ziti_version=$(ziti version 2>/dev/null | head -n1 || echo "unknown")
|
|
log "INFO" "OpenZiti CLI already installed: $ziti_version"
|
|
|
|
# Check if we also have the router package
|
|
if dpkg -l | grep -q openziti-router; then
|
|
log "SUCCESS" "OpenZiti router package already installed"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
log "INFO" "Installing OpenZiti packages using package repository..."
|
|
|
|
# Try to install openziti-router package first (includes ziti CLI)
|
|
log "INFO" "Installing openziti-router package..."
|
|
if apt install -y openziti-router; then
|
|
log "SUCCESS" "OpenZiti router package installed successfully"
|
|
else
|
|
log "WARNING" "Failed to install openziti-router package, trying ziti CLI only..."
|
|
|
|
# Fallback: Try to install just the ziti CLI
|
|
log "INFO" "Attempting to install ziti CLI only..."
|
|
if apt install -y ziti; then
|
|
log "SUCCESS" "OpenZiti CLI installed successfully"
|
|
else
|
|
error_exit "Failed to install OpenZiti packages from repository"
|
|
fi
|
|
fi
|
|
|
|
# Verify installation
|
|
if command -v ziti &> /dev/null; then
|
|
local ziti_version=$(ziti version 2>/dev/null | head -n1 || echo "unknown")
|
|
log "SUCCESS" "OpenZiti CLI installed and working: $ziti_version"
|
|
else
|
|
error_exit "OpenZiti CLI installation failed - command not found after installation"
|
|
fi
|
|
|
|
# Additional verification - test basic ziti commands
|
|
log "INFO" "Testing OpenZiti CLI functionality..."
|
|
if ziti --help >/dev/null 2>&1; then
|
|
log "SUCCESS" "OpenZiti CLI is functional"
|
|
else
|
|
log "WARNING" "OpenZiti CLI may not be fully functional"
|
|
fi
|
|
|
|
# Check for router-specific functionality
|
|
if ziti router --help >/dev/null 2>&1; then
|
|
log "SUCCESS" "OpenZiti router commands are available"
|
|
else
|
|
log "WARNING" "OpenZiti router commands may not be available"
|
|
fi
|
|
|
|
log "SUCCESS" "OpenZiti package installation completed"
|
|
}
|
|
|
|
# Set up sudo access
|
|
setup_sudo() {
|
|
log "INFO" "Setting up comprehensive sudo access for web server..."
|
|
log "INFO" "This configuration works on both normal Ubuntu and CloudStack instances"
|
|
|
|
# Create comprehensive sudoers file
|
|
cat > "/etc/sudoers.d/ziti-enrollment" << 'EOF'
|
|
# Allow www-data to run system commands for Ziti enrollment
|
|
# Comprehensive permissions for all environments (normal Ubuntu + CloudStack)
|
|
|
|
# Core system commands
|
|
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/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
|
|
|
|
# Network and download commands
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/curl
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/wget
|
|
|
|
# GPG and security commands
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/gpg
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/ziti
|
|
|
|
# Information gathering commands
|
|
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/whoami
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/id
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/pwd
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/date
|
|
|
|
# File operations
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/tee
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/cat
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/test
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/ls
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/touch
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/echo
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/head
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/tail
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/wc
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/grep
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/sed
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/awk
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/cut
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/sort
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/uniq
|
|
|
|
# Network diagnostic commands
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/nslookup
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/ping
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/dig
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/host
|
|
|
|
# Process and system monitoring
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/ps
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/top
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/htop
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/free
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/df
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/du
|
|
|
|
# Text processing and utilities
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/find
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/xargs
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/basename
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/dirname
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/realpath
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/readlink
|
|
|
|
# Archive and compression
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/tar
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/gzip
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/gunzip
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/zip
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/unzip
|
|
|
|
# Shell and environment
|
|
www-data ALL=(ALL) NOPASSWD: /bin/bash
|
|
www-data ALL=(ALL) NOPASSWD: /bin/sh
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/env
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/sleep
|
|
www-data ALL=(ALL) NOPASSWD: /usr/bin/timeout
|
|
EOF
|
|
|
|
# Validate sudoers file
|
|
if visudo -c -f "/etc/sudoers.d/ziti-enrollment"; then
|
|
log "SUCCESS" "Comprehensive sudo access configured successfully"
|
|
log "INFO" "Configuration includes all permissions needed for any environment"
|
|
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
|
|
|
|
# Test OpenZiti installation
|
|
if command -v ziti &> /dev/null; then
|
|
local ziti_version=$(ziti version 2>/dev/null | head -n1 || echo "unknown")
|
|
log "SUCCESS" "OpenZiti CLI is installed and working: $ziti_version"
|
|
|
|
# Test ziti router command
|
|
if ziti router --help >/dev/null 2>&1; then
|
|
log "SUCCESS" "OpenZiti router commands are functional"
|
|
else
|
|
log "WARNING" "OpenZiti router commands may not be available"
|
|
fi
|
|
else
|
|
log "ERROR" "OpenZiti CLI is not installed or not working"
|
|
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. OpenZiti packages are now pre-installed and ready for enrollment"
|
|
echo " 2. Change the default password in production"
|
|
echo " 3. Consider setting up HTTPS for production use"
|
|
echo " 4. Review security settings in $WEB_DIR/includes/config.php"
|
|
echo " 5. The UI will now focus only on enrollment using hash keys"
|
|
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
|
|
|
|
# Set up OpenZiti package repository
|
|
setup_openziti_repository
|
|
|
|
# Install OpenZiti packages
|
|
install_openziti_packages
|
|
|
|
# Update hosts file
|
|
update_hosts
|
|
|
|
# Test installation
|
|
test_installation
|
|
|
|
# Show final information
|
|
show_final_info
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|