fixed script new3

This commit is contained in:
Edmund Tan 2025-07-22 22:24:44 +08:00
parent 8e225fdedd
commit 49f0aa8498
3 changed files with 980 additions and 0 deletions

300
UI/TROUBLESHOOTING.md Normal file
View File

@ -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.

320
UI/fix-permissions.sh Normal file
View File

@ -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 "$@"

View File

@ -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();
?>