fixed script new3
This commit is contained in:
parent
8e225fdedd
commit
49f0aa8498
|
|
@ -0,0 +1,300 @@
|
|||
# ZitiNexus Router Enrollment UI - Troubleshooting Guide
|
||||
|
||||
This guide helps resolve common issues with the ZitiNexus Router Enrollment UI, particularly the GPG key installation failure on CloudStack instances.
|
||||
|
||||
## Quick Fix Steps
|
||||
|
||||
### 1. Fix File Permissions and Configuration
|
||||
|
||||
On your CloudStack instance, run these commands as root:
|
||||
|
||||
```bash
|
||||
# Navigate to the UI directory
|
||||
cd /path/to/your/UI/directory
|
||||
|
||||
# Make the fix script executable
|
||||
chmod +x fix-permissions.sh
|
||||
|
||||
# Run the fix script
|
||||
sudo ./fix-permissions.sh
|
||||
```
|
||||
|
||||
### 2. Access the Diagnostic Script
|
||||
|
||||
After running the fix script, access the diagnostic tool:
|
||||
|
||||
```
|
||||
http://your-server-ip/debug-command-execution.php
|
||||
```
|
||||
|
||||
This will show you exactly what's failing and provide specific recommendations.
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue 1: "File not found" when accessing diagnostic script
|
||||
|
||||
**Cause**: The web server document root is not configured correctly, or files are in the wrong location.
|
||||
|
||||
**Solution**:
|
||||
1. Check if the installation was completed properly
|
||||
2. Ensure files are in `/var/www/ziti-enrollment/public/`
|
||||
3. Run the fix-permissions script
|
||||
|
||||
### Issue 2: "Failed to add OpenZiti GPG key"
|
||||
|
||||
**Cause**: PHP execution environment differences between manual execution and web server execution.
|
||||
|
||||
**Root Causes**:
|
||||
- PHP-FPM has restricted execution permissions
|
||||
- Sudo configuration issues for www-data user
|
||||
- Environment variables not properly set
|
||||
- GPG command execution context problems
|
||||
|
||||
**Solutions**:
|
||||
|
||||
#### Option A: Fix Web Server Execution (Recommended)
|
||||
```bash
|
||||
# 1. Fix sudo permissions
|
||||
sudo visudo -f /etc/sudoers.d/ziti-enrollment
|
||||
|
||||
# Add these lines:
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/curl
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/gpg
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/mkdir
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/chmod
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/cp
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/apt-get
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/systemctl
|
||||
|
||||
# 2. Test sudo access
|
||||
sudo -u www-data sudo -n whoami
|
||||
|
||||
# 3. Create keyrings directory
|
||||
sudo mkdir -p /usr/share/keyrings
|
||||
sudo chmod 755 /usr/share/keyrings
|
||||
|
||||
# 4. Test GPG key download manually
|
||||
sudo -u www-data curl -sSLf https://get.openziti.io/tun/package-repos.gpg -o /tmp/test-gpg.key
|
||||
sudo -u www-data sudo gpg --dearmor --output /usr/share/keyrings/test.gpg /tmp/test-gpg.key
|
||||
```
|
||||
|
||||
#### Option B: Use CLI Instead of Web Interface
|
||||
```bash
|
||||
# Run the enrollment script directly via SSH
|
||||
cd /path/to/Router-enrollment-script/
|
||||
sudo ./enroll-router.sh
|
||||
```
|
||||
|
||||
#### Option C: Manual GPG Key Installation
|
||||
```bash
|
||||
# Download and install GPG key manually
|
||||
curl -sSLf https://get.openziti.io/tun/package-repos.gpg | sudo gpg --dearmor --output /usr/share/keyrings/openziti.gpg
|
||||
sudo chmod a+r /usr/share/keyrings/openziti.gpg
|
||||
|
||||
# Add repository
|
||||
echo 'deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main' | sudo tee /etc/apt/sources.list.d/openziti-release.list
|
||||
|
||||
# Update and install
|
||||
sudo apt update
|
||||
sudo apt install -y openziti-router
|
||||
```
|
||||
|
||||
### Issue 3: PHP-FPM Execution Restrictions
|
||||
|
||||
**Symptoms**: Commands work manually but fail through web interface
|
||||
|
||||
**Cause**: PHP-FPM runs with restricted permissions and environment
|
||||
|
||||
**Solutions**:
|
||||
|
||||
1. **Configure PHP-FPM for better command execution**:
|
||||
```bash
|
||||
# Edit PHP-FPM pool configuration
|
||||
sudo nano /etc/php/8.x/fpm/pool.d/www.conf
|
||||
|
||||
# Add these lines:
|
||||
env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
env[HOME] = /var/www
|
||||
env[SHELL] = /bin/bash
|
||||
```
|
||||
|
||||
2. **Restart PHP-FPM**:
|
||||
```bash
|
||||
sudo systemctl restart php8.x-fpm
|
||||
```
|
||||
|
||||
### Issue 4: Network Connectivity Issues
|
||||
|
||||
**Symptoms**: Cannot reach get.openziti.io
|
||||
|
||||
**Solutions**:
|
||||
```bash
|
||||
# Test connectivity
|
||||
ping get.openziti.io
|
||||
curl -I https://get.openziti.io
|
||||
|
||||
# Check DNS resolution
|
||||
nslookup get.openziti.io
|
||||
|
||||
# Check firewall rules
|
||||
sudo ufw status
|
||||
sudo iptables -L
|
||||
```
|
||||
|
||||
### Issue 5: Missing Dependencies
|
||||
|
||||
**Symptoms**: Commands not found (curl, gpg, jq)
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
sudo apt update
|
||||
sudo apt install -y curl gnupg jq
|
||||
```
|
||||
|
||||
## Diagnostic Commands
|
||||
|
||||
Run these commands to diagnose issues:
|
||||
|
||||
```bash
|
||||
# Check web server status
|
||||
sudo systemctl status apache2 # or nginx
|
||||
sudo systemctl status php8.x-fpm # for Nginx
|
||||
|
||||
# Check file permissions
|
||||
ls -la /var/www/ziti-enrollment/
|
||||
ls -la /var/www/ziti-enrollment/public/
|
||||
|
||||
# Check sudo configuration
|
||||
sudo -u www-data sudo -l
|
||||
|
||||
# Test GPG key download
|
||||
curl -sSLf https://get.openziti.io/tun/package-repos.gpg -o /tmp/test.gpg
|
||||
file /tmp/test.gpg
|
||||
|
||||
# Test GPG dearmor
|
||||
gpg --dearmor --output /tmp/test.gpg.dearmored /tmp/test.gpg
|
||||
ls -la /tmp/test.gpg*
|
||||
```
|
||||
|
||||
## Environment-Specific Issues
|
||||
|
||||
### CloudStack Instances
|
||||
|
||||
CloudStack instances often have:
|
||||
- Restrictive security policies
|
||||
- Different network configurations
|
||||
- Limited sudo access for web server users
|
||||
|
||||
**CloudStack-specific fixes**:
|
||||
1. Ensure the instance has outbound internet access
|
||||
2. Check security groups allow HTTPS traffic
|
||||
3. Verify DNS resolution works properly
|
||||
4. Consider using the CLI enrollment method instead
|
||||
|
||||
### Ubuntu 24.04 Specific
|
||||
|
||||
Ubuntu 24.04 may have:
|
||||
- Different PHP-FPM configurations
|
||||
- Updated security policies
|
||||
- Different package versions
|
||||
|
||||
**Ubuntu 24.04 fixes**:
|
||||
```bash
|
||||
# Install specific PHP version
|
||||
sudo apt install -y php8.3 php8.3-fpm php8.3-curl
|
||||
|
||||
# Update sudoers with full paths
|
||||
which curl gpg apt-get systemctl
|
||||
# Use the full paths in sudoers configuration
|
||||
```
|
||||
|
||||
## Alternative Solutions
|
||||
|
||||
### 1. Use Docker Container
|
||||
```bash
|
||||
# Run enrollment in a container with proper permissions
|
||||
docker run -it --rm -v /etc/zitirouter:/etc/zitirouter ubuntu:24.04 bash
|
||||
# Then run enrollment commands inside container
|
||||
```
|
||||
|
||||
### 2. Create Wrapper Script
|
||||
```bash
|
||||
# Create a wrapper script that runs with proper permissions
|
||||
sudo tee /usr/local/bin/ziti-enroll-wrapper.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
export HOME="/root"
|
||||
export GNUPGHOME="/root/.gnupg"
|
||||
exec "$@"
|
||||
EOF
|
||||
|
||||
sudo chmod +x /usr/local/bin/ziti-enroll-wrapper.sh
|
||||
|
||||
# Update sudoers to use wrapper
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/local/bin/ziti-enroll-wrapper.sh
|
||||
```
|
||||
|
||||
### 3. Use systemd Service
|
||||
```bash
|
||||
# Create a systemd service for enrollment
|
||||
sudo tee /etc/systemd/system/ziti-enrollment.service << 'EOF'
|
||||
[Unit]
|
||||
Description=Ziti Router Enrollment
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/path/to/enrollment/script
|
||||
User=root
|
||||
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Trigger enrollment via systemd
|
||||
sudo systemctl start ziti-enrollment
|
||||
```
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you continue to experience issues:
|
||||
|
||||
1. **Run the diagnostic script** and save the results
|
||||
2. **Check the log files**:
|
||||
- `/var/www/ziti-enrollment/logs/ui-enrollment.log`
|
||||
- `/var/log/apache2/error.log` (or nginx equivalent)
|
||||
- `/var/log/syslog`
|
||||
|
||||
3. **Gather system information**:
|
||||
```bash
|
||||
# System info
|
||||
uname -a
|
||||
lsb_release -a
|
||||
php -v
|
||||
systemctl status apache2 # or nginx
|
||||
|
||||
# Network info
|
||||
ip addr show
|
||||
cat /etc/resolv.conf
|
||||
|
||||
# Permission info
|
||||
id www-data
|
||||
sudo -u www-data sudo -l
|
||||
```
|
||||
|
||||
4. **Contact support** with the diagnostic results and system information
|
||||
|
||||
## Prevention
|
||||
|
||||
To prevent similar issues in the future:
|
||||
|
||||
1. **Use the CLI enrollment method** for production deployments
|
||||
2. **Test the web interface** in a development environment first
|
||||
3. **Document your specific environment** requirements and configurations
|
||||
4. **Keep backups** of working configurations
|
||||
5. **Monitor logs** regularly for early detection of issues
|
||||
|
||||
---
|
||||
|
||||
**Note**: This troubleshooting guide is specifically designed for the GPG key installation failure issue on CloudStack instances, but the solutions apply to similar environments with restricted execution contexts.
|
||||
|
|
@ -0,0 +1,320 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Fix Permissions Script for ZitiNexus Router Enrollment UI
|
||||
# This script fixes common permission and configuration issues
|
||||
|
||||
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"
|
||||
WEB_USER="www-data"
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
local level=$1
|
||||
shift
|
||||
local message="$*"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# Check if running as root
|
||||
check_root() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
log "ERROR" "This script must be run as root (use sudo)"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Fix file permissions
|
||||
fix_permissions() {
|
||||
log "INFO" "Fixing file permissions..."
|
||||
|
||||
if [[ ! -d "$WEB_DIR" ]]; then
|
||||
log "ERROR" "Web directory $WEB_DIR not found. Please run install.sh first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set proper ownership
|
||||
chown -R "$WEB_USER:$WEB_USER" "$WEB_DIR"
|
||||
log "SUCCESS" "Set ownership to $WEB_USER:$WEB_USER"
|
||||
|
||||
# Set directory permissions
|
||||
find "$WEB_DIR" -type d -exec chmod 755 {} \;
|
||||
log "SUCCESS" "Set directory permissions to 755"
|
||||
|
||||
# Set file permissions
|
||||
find "$WEB_DIR" -type f -exec chmod 644 {} \;
|
||||
log "SUCCESS" "Set file permissions to 644"
|
||||
|
||||
# Set special permissions for logs and temp
|
||||
if [[ -d "$WEB_DIR/logs" ]]; then
|
||||
chmod -R 777 "$WEB_DIR/logs"
|
||||
log "SUCCESS" "Set logs directory permissions to 777"
|
||||
fi
|
||||
|
||||
if [[ -d "$WEB_DIR/temp" ]]; then
|
||||
chmod -R 777 "$WEB_DIR/temp"
|
||||
log "SUCCESS" "Set temp directory permissions to 777"
|
||||
fi
|
||||
|
||||
# Make PHP files executable if needed
|
||||
find "$WEB_DIR" -name "*.php" -exec chmod 644 {} \;
|
||||
log "SUCCESS" "Set PHP file permissions"
|
||||
}
|
||||
|
||||
# Fix sudo configuration
|
||||
fix_sudo() {
|
||||
log "INFO" "Checking sudo configuration..."
|
||||
|
||||
if [[ -f "/etc/sudoers.d/ziti-enrollment" ]]; then
|
||||
log "INFO" "Sudo configuration already exists"
|
||||
|
||||
# Test sudo access
|
||||
if sudo -u www-data sudo -n whoami >/dev/null 2>&1; then
|
||||
log "SUCCESS" "Sudo access is working"
|
||||
else
|
||||
log "WARNING" "Sudo access may not be working properly"
|
||||
log "INFO" "Recreating sudo configuration..."
|
||||
|
||||
# Recreate 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
|
||||
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/wc
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/nslookup
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/ping
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/id
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/pwd
|
||||
www-data ALL=(ALL) NOPASSWD: /usr/bin/date
|
||||
EOF
|
||||
|
||||
# Validate sudoers file
|
||||
if visudo -c -f "/etc/sudoers.d/ziti-enrollment"; then
|
||||
log "SUCCESS" "Sudo configuration updated successfully"
|
||||
else
|
||||
log "ERROR" "Invalid sudoers configuration"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log "WARNING" "Sudo configuration not found. Please run install.sh first."
|
||||
fi
|
||||
}
|
||||
|
||||
# Fix web server configuration
|
||||
fix_web_server() {
|
||||
log "INFO" "Checking web server configuration..."
|
||||
|
||||
# Check if Apache is running
|
||||
if systemctl is-active --quiet apache2 2>/dev/null; then
|
||||
log "INFO" "Apache is running"
|
||||
|
||||
# Check if site is enabled
|
||||
if [[ -f "/etc/apache2/sites-enabled/ziti-enrollment.conf" ]]; then
|
||||
log "SUCCESS" "Apache site is enabled"
|
||||
else
|
||||
log "WARNING" "Apache site not enabled"
|
||||
if [[ -f "/etc/apache2/sites-available/ziti-enrollment.conf" ]]; then
|
||||
a2ensite ziti-enrollment.conf
|
||||
systemctl reload apache2
|
||||
log "SUCCESS" "Enabled Apache site"
|
||||
else
|
||||
log "ERROR" "Apache site configuration not found. Please run install.sh first."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if Nginx is running
|
||||
elif systemctl is-active --quiet nginx 2>/dev/null; then
|
||||
log "INFO" "Nginx is running"
|
||||
|
||||
# Check if site is enabled
|
||||
if [[ -L "/etc/nginx/sites-enabled/ziti-enrollment" ]]; then
|
||||
log "SUCCESS" "Nginx site is enabled"
|
||||
else
|
||||
log "WARNING" "Nginx site not enabled"
|
||||
if [[ -f "/etc/nginx/sites-available/ziti-enrollment" ]]; then
|
||||
ln -sf "/etc/nginx/sites-available/ziti-enrollment" "/etc/nginx/sites-enabled/"
|
||||
nginx -t && systemctl reload nginx
|
||||
log "SUCCESS" "Enabled Nginx site"
|
||||
else
|
||||
log "ERROR" "Nginx site configuration not found. Please run install.sh first."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check PHP-FPM
|
||||
PHP_VERSION=$(php -v | head -n1 | cut -d' ' -f2 | cut -d'.' -f1,2)
|
||||
if systemctl is-active --quiet "php${PHP_VERSION}-fpm" 2>/dev/null; then
|
||||
log "SUCCESS" "PHP-FPM is running"
|
||||
else
|
||||
log "WARNING" "PHP-FPM not running"
|
||||
systemctl start "php${PHP_VERSION}-fpm" || log "ERROR" "Failed to start PHP-FPM"
|
||||
fi
|
||||
|
||||
else
|
||||
log "ERROR" "No web server (Apache or Nginx) is running"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install missing packages
|
||||
install_missing_packages() {
|
||||
log "INFO" "Checking for missing packages..."
|
||||
|
||||
# Update package list
|
||||
apt update >/dev/null 2>&1
|
||||
|
||||
# Check for curl
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
log "INFO" "Installing curl..."
|
||||
apt install -y curl
|
||||
fi
|
||||
|
||||
# Check for GPG
|
||||
if ! command -v gpg >/dev/null 2>&1; then
|
||||
log "INFO" "Installing gnupg..."
|
||||
apt install -y gnupg
|
||||
fi
|
||||
|
||||
# Check for jq
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
log "INFO" "Installing jq..."
|
||||
apt install -y jq
|
||||
fi
|
||||
|
||||
log "SUCCESS" "All required packages are installed"
|
||||
}
|
||||
|
||||
# Create missing directories
|
||||
create_missing_directories() {
|
||||
log "INFO" "Creating missing directories..."
|
||||
|
||||
# Create logs directory
|
||||
if [[ ! -d "$WEB_DIR/logs" ]]; then
|
||||
mkdir -p "$WEB_DIR/logs"
|
||||
chown "$WEB_USER:$WEB_USER" "$WEB_DIR/logs"
|
||||
chmod 777 "$WEB_DIR/logs"
|
||||
log "SUCCESS" "Created logs directory"
|
||||
fi
|
||||
|
||||
# Create temp directory
|
||||
if [[ ! -d "$WEB_DIR/temp" ]]; then
|
||||
mkdir -p "$WEB_DIR/temp"
|
||||
chown "$WEB_USER:$WEB_USER" "$WEB_DIR/temp"
|
||||
chmod 777 "$WEB_DIR/temp"
|
||||
log "SUCCESS" "Created temp directory"
|
||||
fi
|
||||
|
||||
# Create keyrings directory
|
||||
if [[ ! -d "/usr/share/keyrings" ]]; then
|
||||
mkdir -p "/usr/share/keyrings"
|
||||
chmod 755 "/usr/share/keyrings"
|
||||
log "SUCCESS" "Created keyrings directory"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test the installation
|
||||
test_installation() {
|
||||
log "INFO" "Testing installation..."
|
||||
|
||||
# Test web server access
|
||||
if curl -s -o /dev/null -w "%{http_code}" "http://localhost" | grep -q "200\|301\|302"; then
|
||||
log "SUCCESS" "Web server is accessible"
|
||||
else
|
||||
log "WARNING" "Web server may not be accessible"
|
||||
fi
|
||||
|
||||
# Test PHP
|
||||
if php -v >/dev/null 2>&1; then
|
||||
log "SUCCESS" "PHP is working"
|
||||
else
|
||||
log "ERROR" "PHP is not working"
|
||||
fi
|
||||
|
||||
# Test sudo access
|
||||
if sudo -u www-data sudo -n whoami >/dev/null 2>&1; then
|
||||
log "SUCCESS" "Sudo access is working"
|
||||
else
|
||||
log "WARNING" "Sudo access may not be working"
|
||||
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
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
echo "=============================================="
|
||||
echo " ZitiNexus UI Permission Fix Script"
|
||||
echo "=============================================="
|
||||
echo
|
||||
|
||||
check_root
|
||||
install_missing_packages
|
||||
create_missing_directories
|
||||
fix_permissions
|
||||
fix_sudo
|
||||
fix_web_server
|
||||
test_installation
|
||||
|
||||
echo
|
||||
log "SUCCESS" "Permission fix completed!"
|
||||
echo
|
||||
echo "Next steps:"
|
||||
echo "1. Access the diagnostic script: http://your-server-ip/debug-command-execution.php"
|
||||
echo "2. Review the diagnostic results"
|
||||
echo "3. Try the enrollment process again"
|
||||
echo
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
|
|
@ -0,0 +1,360 @@
|
|||
<?php
|
||||
/**
|
||||
* Command Execution Diagnostic Script
|
||||
* Tests various aspects of command execution, permissions, and environment
|
||||
* to identify issues with GPG key installation on CloudStack instances
|
||||
*/
|
||||
|
||||
// Include config for logging functions
|
||||
require_once '../includes/config.php';
|
||||
|
||||
// Start output buffering for clean HTML output
|
||||
ob_start();
|
||||
|
||||
// Set content type
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Command Execution Diagnostics</title>
|
||||
<style>
|
||||
body { font-family: monospace; margin: 20px; background: #f5f5f5; }
|
||||
.container { max-width: 1200px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
||||
.test-section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
|
||||
.test-section h3 { margin-top: 0; color: #333; border-bottom: 2px solid #007bff; padding-bottom: 5px; }
|
||||
.success { background-color: #d4edda; border-color: #c3e6cb; color: #155724; }
|
||||
.warning { background-color: #fff3cd; border-color: #ffeaa7; color: #856404; }
|
||||
.error { background-color: #f8d7da; border-color: #f5c6cb; color: #721c24; }
|
||||
.info { background-color: #d1ecf1; border-color: #bee5eb; color: #0c5460; }
|
||||
.command { background: #f8f9fa; padding: 10px; border-left: 4px solid #007bff; margin: 10px 0; font-family: 'Courier New', monospace; }
|
||||
.output { background: #2d3748; color: #e2e8f0; padding: 10px; border-radius: 4px; margin: 10px 0; white-space: pre-wrap; font-family: 'Courier New', monospace; }
|
||||
.summary { background: #e3f2fd; padding: 15px; border-radius: 5px; margin: 20px 0; }
|
||||
table { width: 100%; border-collapse: collapse; margin: 10px 0; }
|
||||
th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
|
||||
th { background-color: #f2f2f2; }
|
||||
.btn { display: inline-block; padding: 10px 20px; background: #007bff; color: white; text-decoration: none; border-radius: 4px; margin: 5px; }
|
||||
.btn:hover { background: #0056b3; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔍 Command Execution Diagnostics</h1>
|
||||
<p><strong>Purpose:</strong> Diagnose why GPG key installation fails on CloudStack instance</p>
|
||||
<p><strong>Time:</strong> <?php echo date('Y-m-d H:i:s T'); ?></p>
|
||||
|
||||
<?php
|
||||
|
||||
// Initialize results array
|
||||
$results = [];
|
||||
$issues = [];
|
||||
$recommendations = [];
|
||||
|
||||
/**
|
||||
* Helper function to execute command and capture detailed output
|
||||
*/
|
||||
function testCommand($description, $command, $expectSuccess = true) {
|
||||
global $results, $issues;
|
||||
|
||||
echo "<div class='test-section'>";
|
||||
echo "<h3>$description</h3>";
|
||||
echo "<div class='command'>Command: $command</div>";
|
||||
|
||||
$startTime = microtime(true);
|
||||
|
||||
// Test using our executeCommand function
|
||||
$output = '';
|
||||
$returnCode = null;
|
||||
$success = executeCommand($command, $output, $returnCode);
|
||||
|
||||
$endTime = microtime(true);
|
||||
$duration = round(($endTime - $startTime) * 1000, 2);
|
||||
|
||||
$result = [
|
||||
'description' => $description,
|
||||
'command' => $command,
|
||||
'success' => $success,
|
||||
'return_code' => $returnCode,
|
||||
'output' => $output,
|
||||
'duration_ms' => $duration,
|
||||
'expected_success' => $expectSuccess
|
||||
];
|
||||
|
||||
$results[] = $result;
|
||||
|
||||
// Display result
|
||||
$statusClass = $success ? 'success' : 'error';
|
||||
if ($success && !$expectSuccess) $statusClass = 'warning';
|
||||
if (!$success && !$expectSuccess) $statusClass = 'info';
|
||||
|
||||
echo "<div class='$statusClass'>";
|
||||
echo "<strong>Status:</strong> " . ($success ? "✅ SUCCESS" : "❌ FAILED") . "<br>";
|
||||
echo "<strong>Return Code:</strong> $returnCode<br>";
|
||||
echo "<strong>Duration:</strong> {$duration}ms<br>";
|
||||
echo "</div>";
|
||||
|
||||
if ($output) {
|
||||
echo "<div class='output'>$output</div>";
|
||||
}
|
||||
|
||||
// Track issues
|
||||
if ($expectSuccess && !$success) {
|
||||
$issues[] = "$description failed: $output";
|
||||
}
|
||||
|
||||
echo "</div>";
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test PHP environment information
|
||||
*/
|
||||
echo "<div class='test-section info'>";
|
||||
echo "<h3>📋 PHP Environment Information</h3>";
|
||||
echo "<table>";
|
||||
echo "<tr><th>Property</th><th>Value</th></tr>";
|
||||
echo "<tr><td>PHP Version</td><td>" . PHP_VERSION . "</td></tr>";
|
||||
echo "<tr><td>PHP SAPI</td><td>" . php_sapi_name() . "</td></tr>";
|
||||
echo "<tr><td>Operating System</td><td>" . PHP_OS . "</td></tr>";
|
||||
echo "<tr><td>Current User (PHP)</td><td>" . get_current_user() . "</td></tr>";
|
||||
echo "<tr><td>Process UID</td><td>" . (function_exists('posix_getuid') ? posix_getuid() : 'N/A') . "</td></tr>";
|
||||
echo "<tr><td>Process GID</td><td>" . (function_exists('posix_getgid') ? posix_getgid() : 'N/A') . "</td></tr>";
|
||||
echo "<tr><td>Process PID</td><td>" . getmypid() . "</td></tr>";
|
||||
echo "<tr><td>Memory Limit</td><td>" . ini_get('memory_limit') . "</td></tr>";
|
||||
echo "<tr><td>Max Execution Time</td><td>" . ini_get('max_execution_time') . "s</td></tr>";
|
||||
echo "<tr><td>Disable Functions</td><td>" . (ini_get('disable_functions') ?: 'None') . "</td></tr>";
|
||||
echo "<tr><td>Document Root</td><td>" . $_SERVER['DOCUMENT_ROOT'] . "</td></tr>";
|
||||
echo "<tr><td>Script Filename</td><td>" . $_SERVER['SCRIPT_FILENAME'] . "</td></tr>";
|
||||
echo "<tr><td>Current Working Dir</td><td>" . getcwd() . "</td></tr>";
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
/**
|
||||
* Test environment variables
|
||||
*/
|
||||
echo "<div class='test-section info'>";
|
||||
echo "<h3>🌍 Environment Variables</h3>";
|
||||
$envVars = ['PATH', 'HOME', 'USER', 'SHELL', 'TERM', 'PWD', 'SUDO_USER', 'SUDO_UID', 'SUDO_GID'];
|
||||
echo "<table>";
|
||||
echo "<tr><th>Variable</th><th>Value</th></tr>";
|
||||
foreach ($envVars as $var) {
|
||||
$value = getenv($var) ?: $_SERVER[$var] ?? 'Not Set';
|
||||
echo "<tr><td>$var</td><td>$value</td></tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
/**
|
||||
* Test basic command execution
|
||||
*/
|
||||
echo "<h2>🔧 Basic Command Tests</h2>";
|
||||
testCommand("Current Working Directory", "pwd");
|
||||
testCommand("Current User Identity", "whoami");
|
||||
testCommand("Detailed User Info", "id");
|
||||
testCommand("Hostname", "hostname");
|
||||
testCommand("Date/Time", "date");
|
||||
|
||||
/**
|
||||
* Test sudo access
|
||||
*/
|
||||
echo "<h2>🔐 Sudo Access Tests</h2>";
|
||||
testCommand("Sudo Version", "sudo --version");
|
||||
testCommand("Sudo Non-Interactive Test", "sudo -n whoami");
|
||||
testCommand("Sudo List Permissions", "sudo -l", false); // May fail, that's ok
|
||||
testCommand("Test Sudo Echo", "sudo echo 'sudo test successful'");
|
||||
|
||||
/**
|
||||
* Test network connectivity
|
||||
*/
|
||||
echo "<h2>🌐 Network Connectivity Tests</h2>";
|
||||
testCommand("Curl Version", "curl --version");
|
||||
testCommand("Test DNS Resolution", "nslookup get.openziti.io", false);
|
||||
testCommand("Test Ping to OpenZiti", "ping -c 1 get.openziti.io", false);
|
||||
testCommand("Test HTTPS Connection", "curl -I https://get.openziti.io", false);
|
||||
testCommand("Test GPG Key URL", "curl -sSLf https://get.openziti.io/tun/package-repos.gpg -o /dev/null");
|
||||
|
||||
/**
|
||||
* Test GPG functionality
|
||||
*/
|
||||
echo "<h2>🔑 GPG Functionality Tests</h2>";
|
||||
testCommand("GPG Version", "gpg --version");
|
||||
testCommand("Which GPG", "which gpg");
|
||||
testCommand("GPG List Keys", "gpg --list-keys", false);
|
||||
testCommand("Test GPG Dearmor", "echo 'test' | gpg --dearmor", false);
|
||||
|
||||
/**
|
||||
* Test file system permissions
|
||||
*/
|
||||
echo "<h2>📁 File System Permission Tests</h2>";
|
||||
testCommand("Test /tmp Write", "touch /tmp/test-write-" . uniqid() . " && echo 'Write test successful'");
|
||||
testCommand("Test /usr/share Access", "ls -la /usr/share/", false);
|
||||
testCommand("Test /usr/share/keyrings Directory", "ls -la /usr/share/keyrings/", false);
|
||||
testCommand("Test Create Keyrings Directory", "sudo mkdir -p /usr/share/keyrings && echo 'Directory creation successful'");
|
||||
testCommand("Test Write to Keyrings", "sudo touch /usr/share/keyrings/test-" . uniqid() . " && echo 'Keyring write test successful'");
|
||||
|
||||
/**
|
||||
* Test the specific failing GPG command step by step
|
||||
*/
|
||||
echo "<h2>🎯 Specific GPG Key Installation Tests</h2>";
|
||||
|
||||
$tempFile = '/tmp/openziti-gpg-test-' . uniqid();
|
||||
$keyringFile = '/usr/share/keyrings/openziti-test.gpg';
|
||||
|
||||
testCommand("Step 1: Download GPG Key", "curl -sSLf https://get.openziti.io/tun/package-repos.gpg -o $tempFile");
|
||||
testCommand("Step 2: Verify Downloaded File", "ls -la $tempFile && wc -c $tempFile");
|
||||
testCommand("Step 3: Test GPG Dearmor on File", "sudo gpg --dearmor --output $keyringFile $tempFile");
|
||||
testCommand("Step 4: Verify Output File", "ls -la $keyringFile", false);
|
||||
testCommand("Step 5: Test Original Piped Command", "curl -sSLf https://get.openziti.io/tun/package-repos.gpg | sudo gpg --dearmor --output /usr/share/keyrings/openziti-test2.gpg");
|
||||
|
||||
// Clean up test files
|
||||
testCommand("Cleanup: Remove Test Files", "sudo rm -f $tempFile $keyringFile /usr/share/keyrings/openziti-test2.gpg", false);
|
||||
|
||||
/**
|
||||
* Test alternative execution methods
|
||||
*/
|
||||
echo "<h2>🔄 Alternative Execution Method Tests</h2>";
|
||||
|
||||
// Test direct proc_open
|
||||
echo "<div class='test-section'>";
|
||||
echo "<h3>Direct proc_open Test</h3>";
|
||||
$cmd = "curl -sSLf https://get.openziti.io/tun/package-repos.gpg | head -c 100";
|
||||
$descriptorspec = [
|
||||
0 => ['pipe', 'r'],
|
||||
1 => ['pipe', 'w'],
|
||||
2 => ['pipe', 'w']
|
||||
];
|
||||
$process = proc_open($cmd, $descriptorspec, $pipes);
|
||||
if (is_resource($process)) {
|
||||
fclose($pipes[0]);
|
||||
$stdout = stream_get_contents($pipes[1]);
|
||||
$stderr = stream_get_contents($pipes[2]);
|
||||
fclose($pipes[1]);
|
||||
fclose($pipes[2]);
|
||||
$return_value = proc_close($process);
|
||||
|
||||
echo "<div class='command'>Command: $cmd</div>";
|
||||
echo "<div class='" . ($return_value === 0 ? 'success' : 'error') . "'>";
|
||||
echo "<strong>Return Code:</strong> $return_value<br>";
|
||||
echo "</div>";
|
||||
echo "<div class='output'>STDOUT: " . substr($stdout, 0, 200) . "\nSTDERR: $stderr</div>";
|
||||
}
|
||||
echo "</div>";
|
||||
|
||||
/**
|
||||
* Summary and recommendations
|
||||
*/
|
||||
echo "<div class='summary'>";
|
||||
echo "<h2>📊 Diagnostic Summary</h2>";
|
||||
|
||||
$totalTests = count($results);
|
||||
$successfulTests = count(array_filter($results, function($r) { return $r['success']; }));
|
||||
$failedTests = $totalTests - $successfulTests;
|
||||
|
||||
echo "<p><strong>Total Tests:</strong> $totalTests</p>";
|
||||
echo "<p><strong>Successful:</strong> $successfulTests</p>";
|
||||
echo "<p><strong>Failed:</strong> $failedTests</p>";
|
||||
|
||||
if (!empty($issues)) {
|
||||
echo "<h3>🚨 Issues Identified:</h3>";
|
||||
echo "<ul>";
|
||||
foreach ($issues as $issue) {
|
||||
echo "<li>$issue</li>";
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
|
||||
// Generate recommendations based on results
|
||||
$phpSapi = php_sapi_name();
|
||||
$currentUser = get_current_user();
|
||||
$processUid = function_exists('posix_getuid') ? posix_getuid() : null;
|
||||
|
||||
echo "<h3>💡 Recommendations:</h3>";
|
||||
echo "<ul>";
|
||||
|
||||
if ($phpSapi === 'fpm-fcgi') {
|
||||
echo "<li><strong>PHP-FPM Detected:</strong> You're running PHP-FPM which has restricted execution permissions. Consider running the enrollment script via CLI instead.</li>";
|
||||
}
|
||||
|
||||
if ($processUid !== 0 && $currentUser !== 'root') {
|
||||
echo "<li><strong>Non-Root Execution:</strong> PHP is running as user '$currentUser' (UID: $processUid). Ensure sudo permissions are properly configured for this user.</li>";
|
||||
}
|
||||
|
||||
$sudoTest = array_filter($results, function($r) { return strpos($r['command'], 'sudo -n whoami') !== false; });
|
||||
if (!empty($sudoTest) && !reset($sudoTest)['success']) {
|
||||
echo "<li><strong>Sudo Configuration:</strong> Non-interactive sudo failed. Configure passwordless sudo for the web server user or run enrollment via CLI.</li>";
|
||||
}
|
||||
|
||||
$curlTest = array_filter($results, function($r) { return strpos($r['command'], 'curl') !== false && strpos($r['command'], 'openziti') !== false; });
|
||||
if (!empty($curlTest) && !reset($curlTest)['success']) {
|
||||
echo "<li><strong>Network Issues:</strong> Cannot reach OpenZiti servers. Check firewall, proxy settings, or DNS resolution.</li>";
|
||||
}
|
||||
|
||||
$gpgTest = array_filter($results, function($r) { return strpos($r['command'], 'gpg --version') !== false; });
|
||||
if (!empty($gpgTest) && !reset($gpgTest)['success']) {
|
||||
echo "<li><strong>GPG Missing:</strong> GPG is not installed or not accessible. Install gnupg package.</li>";
|
||||
}
|
||||
|
||||
echo "<li><strong>Alternative Solution:</strong> Consider running the enrollment script directly via SSH as root user instead of through the web interface.</li>";
|
||||
echo "<li><strong>Web Server Configuration:</strong> If you must use the web interface, configure your web server to run with appropriate permissions or use a different execution method.</li>";
|
||||
echo "</ul>";
|
||||
|
||||
echo "</div>";
|
||||
|
||||
// Export results to log file
|
||||
$logData = [
|
||||
'timestamp' => date('c'),
|
||||
'php_sapi' => $phpSapi,
|
||||
'current_user' => $currentUser,
|
||||
'process_uid' => $processUid,
|
||||
'total_tests' => $totalTests,
|
||||
'successful_tests' => $successfulTests,
|
||||
'failed_tests' => $failedTests,
|
||||
'issues' => $issues,
|
||||
'detailed_results' => $results
|
||||
];
|
||||
|
||||
$logFile = UI_LOG_DIR . '/command-execution-diagnostics-' . date('Y-m-d-H-i-s') . '.json';
|
||||
if (!is_dir(UI_LOG_DIR)) {
|
||||
mkdir(UI_LOG_DIR, 0755, true);
|
||||
}
|
||||
file_put_contents($logFile, json_encode($logData, JSON_PRETTY_PRINT));
|
||||
|
||||
echo "<div class='info'>";
|
||||
echo "<h3>📄 Detailed Results Saved</h3>";
|
||||
echo "<p>Complete diagnostic results saved to: <code>$logFile</code></p>";
|
||||
echo "<a href='?download_log=" . basename($logFile) . "' class='btn'>Download Log File</a>";
|
||||
echo "</div>";
|
||||
|
||||
?>
|
||||
|
||||
<div style="margin-top: 30px; text-align: center;">
|
||||
<a href="dashboard.php" class="btn">← Back to Dashboard</a>
|
||||
<a href="?refresh=1" class="btn">🔄 Run Diagnostics Again</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
|
||||
// Handle log file download
|
||||
if (isset($_GET['download_log'])) {
|
||||
$logFileName = basename($_GET['download_log']);
|
||||
$logFilePath = UI_LOG_DIR . '/' . $logFileName;
|
||||
|
||||
if (file_exists($logFilePath) && strpos($logFileName, 'command-execution-diagnostics-') === 0) {
|
||||
header('Content-Type: application/json');
|
||||
header('Content-Disposition: attachment; filename="' . $logFileName . '"');
|
||||
header('Content-Length: ' . filesize($logFilePath));
|
||||
readfile($logFilePath);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// Flush output
|
||||
ob_end_flush();
|
||||
?>
|
||||
Loading…
Reference in New Issue