fixed script new7
This commit is contained in:
parent
951a66417d
commit
03ba182fb8
|
|
@ -179,41 +179,23 @@ class EnrollmentManager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->reportProgress('INSTALL', 'Setting up OpenZiti package repository...');
|
$this->reportProgress('INSTALL', 'Installing OpenZiti CLI from pre-configured repository...');
|
||||||
|
|
||||||
// Add GPG key using enhanced method to handle PHP execution environment
|
// Verify repository is configured
|
||||||
if (!$this->addOpenZitiGpgKey()) {
|
if (!file_exists('/etc/apt/sources.list.d/openziti-release.list')) {
|
||||||
throw new Exception('Failed to add OpenZiti GPG key');
|
throw new Exception('OpenZiti repository not configured. Please run install.sh first to set up the system.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set proper permissions
|
if (!file_exists('/usr/share/keyrings/openziti.gpg')) {
|
||||||
if (!executeCommand('chmod a+r /usr/share/keyrings/openziti.gpg')) {
|
throw new Exception('OpenZiti GPG key not found. Please run install.sh first to set up the system.');
|
||||||
throw new Exception('Failed to set GPG key permissions');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add repository to sources list
|
// Install openziti-router package from pre-configured repository
|
||||||
$repoContent = 'deb [signed-by=/usr/share/keyrings/openziti.gpg] https://packages.openziti.org/zitipax-openziti-deb-stable debian main';
|
|
||||||
$tempFile = tempnam(sys_get_temp_dir(), 'openziti-repo');
|
|
||||||
file_put_contents($tempFile, $repoContent);
|
|
||||||
|
|
||||||
if (!executeCommand("cp '$tempFile' /etc/apt/sources.list.d/openziti-release.list")) {
|
|
||||||
unlink($tempFile);
|
|
||||||
throw new Exception('Failed to add OpenZiti repository');
|
|
||||||
}
|
|
||||||
unlink($tempFile);
|
|
||||||
|
|
||||||
// Update package list
|
|
||||||
$this->reportProgress('INSTALL', 'Updating package list...');
|
|
||||||
if (!executeCommand('apt-get update')) {
|
|
||||||
throw new Exception('Failed to update package list');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install openziti-router package
|
|
||||||
$this->reportProgress('INSTALL', 'Installing openziti-router package...');
|
$this->reportProgress('INSTALL', 'Installing openziti-router package...');
|
||||||
if (!executeCommand('apt-get install -y openziti-router')) {
|
if (!executeCommand('apt-get install -y openziti-router')) {
|
||||||
$this->reportProgress('INSTALL', 'Trying to install ziti CLI only...');
|
$this->reportProgress('INSTALL', 'Trying to install ziti CLI only...');
|
||||||
if (!executeCommand('apt-get install -y ziti')) {
|
if (!executeCommand('apt-get install -y ziti')) {
|
||||||
throw new Exception('Failed to install OpenZiti CLI');
|
throw new Exception('Failed to install OpenZiti CLI. Repository may not be properly configured. Please run install.sh first.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -528,191 +510,6 @@ EOF;
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add OpenZiti GPG key with enhanced error handling for CloudStack environments
|
|
||||||
*/
|
|
||||||
private function addOpenZitiGpgKey() {
|
|
||||||
$gpgKeyUrl = 'https://get.openziti.io/tun/package-repos.gpg';
|
|
||||||
$gpgKeyPath = '/usr/share/keyrings/openziti.gpg';
|
|
||||||
|
|
||||||
// First, check if GPG key already exists and is valid
|
|
||||||
if (file_exists($gpgKeyPath) && filesize($gpgKeyPath) > 0) {
|
|
||||||
$this->reportProgress('INSTALL', 'OpenZiti GPG key already exists (' . filesize($gpgKeyPath) . ' bytes), skipping installation');
|
|
||||||
logMessage('INFO', 'GPG key already exists at: ' . $gpgKeyPath);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->reportProgress('INSTALL', 'Installing OpenZiti GPG key...');
|
|
||||||
|
|
||||||
// Ensure keyrings directory exists with proper permissions
|
|
||||||
if (!$this->ensureKeyringsDirectory()) {
|
|
||||||
logMessage('ERROR', 'Failed to create keyrings directory');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method 1: CloudStack-optimized approach - download and process separately
|
|
||||||
$this->reportProgress('INSTALL', 'Downloading GPG key...');
|
|
||||||
$tempGpgFile = tempnam(sys_get_temp_dir(), 'openziti-gpg');
|
|
||||||
|
|
||||||
// Step 1: Download GPG key with detailed error reporting
|
|
||||||
$downloadCommand = 'curl -sSLf --connect-timeout 30 --max-time 60 ' . $gpgKeyUrl . ' -o ' . $tempGpgFile;
|
|
||||||
$output = '';
|
|
||||||
|
|
||||||
if (!executeCommand($downloadCommand, $output)) {
|
|
||||||
@unlink($tempGpgFile);
|
|
||||||
$errorMsg = 'Failed to download GPG key from ' . $gpgKeyUrl . '. Error: ' . $output;
|
|
||||||
logMessage('ERROR', $errorMsg);
|
|
||||||
$this->reportProgress('INSTALL', 'Download failed: ' . $output);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: Verify downloaded file
|
|
||||||
if (!file_exists($tempGpgFile) || filesize($tempGpgFile) == 0) {
|
|
||||||
@unlink($tempGpgFile);
|
|
||||||
$errorMsg = 'Downloaded GPG key file is empty or missing';
|
|
||||||
logMessage('ERROR', $errorMsg);
|
|
||||||
$this->reportProgress('INSTALL', $errorMsg);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$fileSize = filesize($tempGpgFile);
|
|
||||||
$this->reportProgress('INSTALL', "GPG key downloaded successfully ($fileSize bytes), processing...");
|
|
||||||
logMessage('INFO', "Downloaded GPG key: $fileSize bytes to $tempGpgFile");
|
|
||||||
|
|
||||||
// Step 3: Try multiple processing methods with detailed error reporting
|
|
||||||
$methods = [
|
|
||||||
'sudo_gpg_dearmor' => [
|
|
||||||
'name' => 'Sudo GPG dearmor',
|
|
||||||
'command' => "sudo /usr/bin/gpg --dearmor --output '$gpgKeyPath' '$tempGpgFile'"
|
|
||||||
],
|
|
||||||
'direct_gpg_dearmor' => [
|
|
||||||
'name' => 'Direct GPG dearmor',
|
|
||||||
'command' => "/usr/bin/gpg --dearmor --output '$gpgKeyPath' '$tempGpgFile'"
|
|
||||||
],
|
|
||||||
'sudo_cat_pipe' => [
|
|
||||||
'name' => 'Sudo cat pipe',
|
|
||||||
'command' => "sudo bash -c 'cat $tempGpgFile | /usr/bin/gpg --dearmor > $gpgKeyPath'"
|
|
||||||
],
|
|
||||||
'sudo_redirect' => [
|
|
||||||
'name' => 'Sudo redirect',
|
|
||||||
'command' => "sudo bash -c '/usr/bin/gpg --dearmor < $tempGpgFile > $gpgKeyPath'"
|
|
||||||
],
|
|
||||||
'python_base64' => [
|
|
||||||
'name' => 'Python base64 decode',
|
|
||||||
'command' => "sudo python3 -c \"import base64; open('$gpgKeyPath', 'wb').write(base64.b64decode(open('$tempGpgFile', 'rb').read()))\""
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($methods as $methodKey => $method) {
|
|
||||||
$this->reportProgress('INSTALL', "Trying method: {$method['name']}...");
|
|
||||||
logMessage('INFO', "Attempting GPG processing method: {$method['name']}");
|
|
||||||
|
|
||||||
$output = '';
|
|
||||||
if (executeCommand($method['command'], $output)) {
|
|
||||||
// Verify the processed file exists and has content
|
|
||||||
if (file_exists($gpgKeyPath) && filesize($gpgKeyPath) > 0) {
|
|
||||||
@unlink($tempGpgFile);
|
|
||||||
$processedSize = filesize($gpgKeyPath);
|
|
||||||
$this->reportProgress('INSTALL', "GPG key processed successfully using {$method['name']} ($processedSize bytes)");
|
|
||||||
logMessage('INFO', "GPG key successfully processed: $processedSize bytes at $gpgKeyPath");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
logMessage('WARNING', "Method {$method['name']} completed but output file is missing or empty");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logMessage('WARNING', "Method {$method['name']} failed: $output");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method 4: Last resort - try to use the raw file directly
|
|
||||||
$this->reportProgress('INSTALL', 'Trying raw file copy as last resort...');
|
|
||||||
logMessage('INFO', 'Attempting raw file copy as final fallback');
|
|
||||||
|
|
||||||
if (executeCommand("sudo cp '$tempGpgFile' '$gpgKeyPath'", $output)) {
|
|
||||||
if (file_exists($gpgKeyPath) && filesize($gpgKeyPath) > 0) {
|
|
||||||
@unlink($tempGpgFile);
|
|
||||||
$this->reportProgress('INSTALL', 'GPG key copied as raw file - apt will handle format conversion');
|
|
||||||
logMessage('INFO', 'GPG key copied as raw file for apt to process');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up and report final failure
|
|
||||||
@unlink($tempGpgFile);
|
|
||||||
$errorMsg = 'All GPG key installation methods failed. Check system permissions and network connectivity.';
|
|
||||||
logMessage('ERROR', $errorMsg);
|
|
||||||
$this->reportProgress('INSTALL', $errorMsg);
|
|
||||||
|
|
||||||
// Additional diagnostic information
|
|
||||||
$this->logDiagnosticInfo();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensure keyrings directory exists with proper permissions
|
|
||||||
*/
|
|
||||||
private function ensureKeyringsDirectory() {
|
|
||||||
$keyringsDir = '/usr/share/keyrings';
|
|
||||||
|
|
||||||
// Check if directory exists
|
|
||||||
if (is_dir($keyringsDir)) {
|
|
||||||
logMessage('INFO', 'Keyrings directory already exists');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to create directory
|
|
||||||
$output = '';
|
|
||||||
if (executeCommand("sudo mkdir -p '$keyringsDir'", $output)) {
|
|
||||||
if (executeCommand("sudo chmod 755 '$keyringsDir'", $output)) {
|
|
||||||
logMessage('INFO', 'Keyrings directory created successfully');
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
logMessage('ERROR', 'Failed to set keyrings directory permissions: ' . $output);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logMessage('ERROR', 'Failed to create keyrings directory: ' . $output);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log diagnostic information for troubleshooting
|
|
||||||
*/
|
|
||||||
private function logDiagnosticInfo() {
|
|
||||||
$diagnostics = [];
|
|
||||||
|
|
||||||
// Check basic commands
|
|
||||||
$commands = ['curl', 'gpg', 'python3', 'sudo'];
|
|
||||||
foreach ($commands as $cmd) {
|
|
||||||
$output = '';
|
|
||||||
$available = executeCommand("which $cmd", $output) ? 'available' : 'not found';
|
|
||||||
$diagnostics[] = "$cmd: $available";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check permissions
|
|
||||||
$output = '';
|
|
||||||
executeCommand('id', $output);
|
|
||||||
$diagnostics[] = "Current user: " . trim($output);
|
|
||||||
|
|
||||||
// Check sudo permissions
|
|
||||||
$output = '';
|
|
||||||
executeCommand('sudo -l | grep gpg', $output);
|
|
||||||
$diagnostics[] = "GPG sudo permissions: " . (empty(trim($output)) ? 'none found' : 'available');
|
|
||||||
|
|
||||||
// Check network connectivity
|
|
||||||
$output = '';
|
|
||||||
$networkOk = executeCommand('curl -I --connect-timeout 5 https://get.openziti.io', $output) ? 'working' : 'failed';
|
|
||||||
$diagnostics[] = "Network connectivity: $networkOk";
|
|
||||||
|
|
||||||
// Check disk space
|
|
||||||
$output = '';
|
|
||||||
executeCommand('df -h /usr/share', $output);
|
|
||||||
$diagnostics[] = "Disk space: " . trim($output);
|
|
||||||
|
|
||||||
logMessage('INFO', 'GPG Installation Diagnostics: ' . implode('; ', $diagnostics));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if command exists
|
* Check if command exists
|
||||||
|
|
|
||||||
103
UI/install.sh
103
UI/install.sh
|
|
@ -337,6 +337,106 @@ configure_php() {
|
||||||
log "SUCCESS" "PHP configured successfully"
|
log "SUCCESS" "PHP configured successfully"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Set up OpenZiti package repository
|
||||||
|
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 >/dev/null 2>&1; 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
|
||||||
|
}
|
||||||
|
|
||||||
# Set up sudo access
|
# Set up sudo access
|
||||||
setup_sudo() {
|
setup_sudo() {
|
||||||
log "INFO" "Setting up comprehensive sudo access for web server..."
|
log "INFO" "Setting up comprehensive sudo access for web server..."
|
||||||
|
|
@ -571,6 +671,9 @@ main() {
|
||||||
# Set up sudo access
|
# Set up sudo access
|
||||||
setup_sudo
|
setup_sudo
|
||||||
|
|
||||||
|
# Set up OpenZiti package repository
|
||||||
|
setup_openziti_repository
|
||||||
|
|
||||||
# Update hosts file
|
# Update hosts file
|
||||||
update_hosts
|
update_hosts
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,399 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pre-Enrollment Check Script
|
|
||||||
* Verifies system readiness before attempting router enrollment
|
|
||||||
*/
|
|
||||||
|
|
||||||
require_once 'includes/config.php';
|
|
||||||
|
|
||||||
// Set content type for web access
|
|
||||||
if (php_sapi_name() !== 'cli') {
|
|
||||||
header('Content-Type: text/html; charset=UTF-8');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute command and return detailed result
|
|
||||||
*/
|
|
||||||
function checkCommand($command, $description) {
|
|
||||||
$startTime = microtime(true);
|
|
||||||
$output = '';
|
|
||||||
$returnCode = 0;
|
|
||||||
|
|
||||||
exec($command . ' 2>&1', $outputLines, $returnCode);
|
|
||||||
$output = implode("\n", $outputLines);
|
|
||||||
$duration = round((microtime(true) - $startTime) * 1000, 2);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'command' => $command,
|
|
||||||
'description' => $description,
|
|
||||||
'success' => $returnCode === 0,
|
|
||||||
'returnCode' => $returnCode,
|
|
||||||
'output' => $output,
|
|
||||||
'duration' => $duration . 'ms'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check file/directory status
|
|
||||||
*/
|
|
||||||
function checkPath($path, $description, $expectedType = 'file') {
|
|
||||||
$exists = false;
|
|
||||||
$readable = false;
|
|
||||||
$writable = false;
|
|
||||||
$size = 0;
|
|
||||||
$permissions = '';
|
|
||||||
|
|
||||||
if (file_exists($path)) {
|
|
||||||
$exists = true;
|
|
||||||
$readable = is_readable($path);
|
|
||||||
$writable = is_writable($path);
|
|
||||||
|
|
||||||
if ($expectedType === 'file' && is_file($path)) {
|
|
||||||
$size = filesize($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
$permissions = substr(sprintf('%o', fileperms($path)), -4);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
'path' => $path,
|
|
||||||
'description' => $description,
|
|
||||||
'exists' => $exists,
|
|
||||||
'readable' => $readable,
|
|
||||||
'writable' => $writable,
|
|
||||||
'size' => $size,
|
|
||||||
'permissions' => $permissions,
|
|
||||||
'type' => $expectedType
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run all pre-enrollment checks
|
|
||||||
*/
|
|
||||||
function runPreEnrollmentChecks() {
|
|
||||||
$results = [
|
|
||||||
'timestamp' => date('Y-m-d H:i:s T'),
|
|
||||||
'environment' => [],
|
|
||||||
'commands' => [],
|
|
||||||
'permissions' => [],
|
|
||||||
'network' => [],
|
|
||||||
'files' => [],
|
|
||||||
'recommendations' => []
|
|
||||||
];
|
|
||||||
|
|
||||||
// Environment checks
|
|
||||||
$results['environment'] = [
|
|
||||||
'php_version' => PHP_VERSION,
|
|
||||||
'php_sapi' => php_sapi_name(),
|
|
||||||
'os' => PHP_OS,
|
|
||||||
'user' => get_current_user(),
|
|
||||||
'uid' => function_exists('posix_getuid') ? posix_getuid() : 'unknown',
|
|
||||||
'gid' => function_exists('posix_getgid') ? posix_getgid() : 'unknown',
|
|
||||||
'working_dir' => getcwd(),
|
|
||||||
'temp_dir' => sys_get_temp_dir()
|
|
||||||
];
|
|
||||||
|
|
||||||
// Command availability checks
|
|
||||||
$commands = [
|
|
||||||
'curl' => 'curl --version',
|
|
||||||
'gpg' => 'gpg --version',
|
|
||||||
'sudo' => 'sudo --version',
|
|
||||||
'systemctl' => 'systemctl --version',
|
|
||||||
'python3' => 'python3 --version',
|
|
||||||
'which' => 'which which',
|
|
||||||
'apt-get' => 'apt-get --version',
|
|
||||||
'jq' => 'jq --version'
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($commands as $name => $command) {
|
|
||||||
$results['commands'][$name] = checkCommand("which $name", "Check if $name is available");
|
|
||||||
if ($results['commands'][$name]['success']) {
|
|
||||||
$results['commands'][$name . '_version'] = checkCommand($command, "Get $name version");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sudo permissions check
|
|
||||||
$results['permissions']['sudo_test'] = checkCommand('sudo -n whoami', 'Test sudo access without password');
|
|
||||||
$results['permissions']['sudo_list'] = checkCommand('sudo -l', 'List sudo permissions');
|
|
||||||
|
|
||||||
// Network connectivity checks
|
|
||||||
$results['network']['dns_resolution'] = checkCommand('nslookup get.openziti.io', 'DNS resolution for OpenZiti');
|
|
||||||
$results['network']['ping_test'] = checkCommand('ping -c 1 get.openziti.io', 'Ping OpenZiti server');
|
|
||||||
$results['network']['https_test'] = checkCommand('curl -I --connect-timeout 10 https://get.openziti.io', 'HTTPS connectivity test');
|
|
||||||
$results['network']['gpg_key_download'] = checkCommand('curl -I --connect-timeout 10 https://get.openziti.io/tun/package-repos.gpg', 'GPG key URL accessibility');
|
|
||||||
|
|
||||||
// File system checks
|
|
||||||
$paths = [
|
|
||||||
'/usr/share/keyrings' => 'OpenZiti keyrings directory',
|
|
||||||
'/usr/share/keyrings/openziti.gpg' => 'OpenZiti GPG key file',
|
|
||||||
'/etc/apt/sources.list.d' => 'APT sources directory',
|
|
||||||
'/etc/apt/sources.list.d/openziti-release.list' => 'OpenZiti repository file',
|
|
||||||
'/tmp' => 'Temporary directory',
|
|
||||||
'/var/log' => 'Log directory'
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach ($paths as $path => $description) {
|
|
||||||
$expectedType = (substr($path, -1) === '/' || is_dir($path)) ? 'directory' : 'file';
|
|
||||||
$results['files'][$path] = checkPath($path, $description, $expectedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate recommendations
|
|
||||||
$results['recommendations'] = generateRecommendations($results);
|
|
||||||
|
|
||||||
return $results;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate recommendations based on check results
|
|
||||||
*/
|
|
||||||
function generateRecommendations($results) {
|
|
||||||
$recommendations = [];
|
|
||||||
|
|
||||||
// Check if running as www-data
|
|
||||||
if ($results['environment']['user'] === 'www-data') {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'info',
|
|
||||||
'message' => 'Running as www-data user (web server context)',
|
|
||||||
'action' => 'This is expected for web-based enrollment'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check sudo access
|
|
||||||
if (!$results['permissions']['sudo_test']['success']) {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'error',
|
|
||||||
'message' => 'Sudo access not working',
|
|
||||||
'action' => 'Run: sudo ./fix-permissions.sh or ensure www-data has proper sudo permissions'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check required commands
|
|
||||||
$requiredCommands = ['curl', 'gpg', 'sudo', 'systemctl'];
|
|
||||||
foreach ($requiredCommands as $cmd) {
|
|
||||||
if (!$results['commands'][$cmd]['success']) {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'error',
|
|
||||||
'message' => "Required command '$cmd' not found",
|
|
||||||
'action' => "Install $cmd: sudo apt-get update && sudo apt-get install -y $cmd"
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check network connectivity
|
|
||||||
if (!$results['network']['https_test']['success']) {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'error',
|
|
||||||
'message' => 'HTTPS connectivity to OpenZiti failed',
|
|
||||||
'action' => 'Check firewall settings and internet connectivity'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if GPG key already exists
|
|
||||||
if ($results['files']['/usr/share/keyrings/openziti.gpg']['exists']) {
|
|
||||||
$size = $results['files']['/usr/share/keyrings/openziti.gpg']['size'];
|
|
||||||
if ($size > 0) {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'success',
|
|
||||||
'message' => "OpenZiti GPG key already exists ($size bytes)",
|
|
||||||
'action' => 'GPG key installation should be skipped automatically'
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'warning',
|
|
||||||
'message' => 'OpenZiti GPG key file exists but is empty',
|
|
||||||
'action' => 'Remove the empty file: sudo rm /usr/share/keyrings/openziti.gpg'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check keyrings directory
|
|
||||||
if (!$results['files']['/usr/share/keyrings']['exists']) {
|
|
||||||
$recommendations[] = [
|
|
||||||
'type' => 'warning',
|
|
||||||
'message' => 'Keyrings directory does not exist',
|
|
||||||
'action' => 'Will be created automatically during enrollment'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $recommendations;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Output results in HTML format
|
|
||||||
*/
|
|
||||||
function outputHTML($results) {
|
|
||||||
?>
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Pre-Enrollment System Check</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); }
|
|
||||||
.section { margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }
|
|
||||||
.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; }
|
|
||||||
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; }
|
|
||||||
.status-ok { color: #28a745; font-weight: bold; }
|
|
||||||
.status-fail { color: #dc3545; font-weight: bold; }
|
|
||||||
.status-warn { color: #ffc107; font-weight: bold; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>🔍 Pre-Enrollment System Check</h1>
|
|
||||||
<p><strong>Purpose:</strong> Verify system readiness for ZitiNexus Router enrollment</p>
|
|
||||||
<p><strong>Time:</strong> <?php echo $results['timestamp']; ?></p>
|
|
||||||
|
|
||||||
<!-- Environment Information -->
|
|
||||||
<div class="section info">
|
|
||||||
<h3>📋 Environment Information</h3>
|
|
||||||
<table>
|
|
||||||
<?php foreach ($results['environment'] as $key => $value): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo ucwords(str_replace('_', ' ', $key)); ?></td>
|
|
||||||
<td><?php echo htmlspecialchars($value); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Command Availability -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>🔧 Command Availability</h3>
|
|
||||||
<table>
|
|
||||||
<tr><th>Command</th><th>Status</th><th>Details</th></tr>
|
|
||||||
<?php foreach ($results['commands'] as $name => $result): ?>
|
|
||||||
<?php if (strpos($name, '_version') !== false) continue; ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo htmlspecialchars($name); ?></td>
|
|
||||||
<td class="<?php echo $result['success'] ? 'status-ok' : 'status-fail'; ?>">
|
|
||||||
<?php echo $result['success'] ? '✅ Available' : '❌ Not Found'; ?>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<?php if ($result['success'] && isset($results['commands'][$name . '_version'])): ?>
|
|
||||||
<?php echo htmlspecialchars(trim(explode("\n", $results['commands'][$name . '_version']['output'])[0])); ?>
|
|
||||||
<?php else: ?>
|
|
||||||
<?php echo htmlspecialchars($result['output']); ?>
|
|
||||||
<?php endif; ?>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Permissions Check -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>🔐 Permissions Check</h3>
|
|
||||||
<?php foreach ($results['permissions'] as $name => $result): ?>
|
|
||||||
<div class="command"><?php echo htmlspecialchars($result['command']); ?></div>
|
|
||||||
<div class="<?php echo $result['success'] ? 'success' : 'error'; ?>">
|
|
||||||
<strong>Status:</strong> <?php echo $result['success'] ? '✅ SUCCESS' : '❌ FAILED'; ?><br>
|
|
||||||
<strong>Return Code:</strong> <?php echo $result['returnCode']; ?><br>
|
|
||||||
<strong>Duration:</strong> <?php echo $result['duration']; ?>
|
|
||||||
</div>
|
|
||||||
<?php if (!empty($result['output'])): ?>
|
|
||||||
<div class="output"><?php echo htmlspecialchars($result['output']); ?></div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Network Connectivity -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>🌐 Network Connectivity</h3>
|
|
||||||
<?php foreach ($results['network'] as $name => $result): ?>
|
|
||||||
<div class="command"><?php echo htmlspecialchars($result['command']); ?></div>
|
|
||||||
<div class="<?php echo $result['success'] ? 'success' : 'warning'; ?>">
|
|
||||||
<strong>Status:</strong> <?php echo $result['success'] ? '✅ SUCCESS' : '⚠️ FAILED'; ?><br>
|
|
||||||
<strong>Return Code:</strong> <?php echo $result['returnCode']; ?><br>
|
|
||||||
<strong>Duration:</strong> <?php echo $result['duration']; ?>
|
|
||||||
</div>
|
|
||||||
<?php if (!empty($result['output'])): ?>
|
|
||||||
<div class="output"><?php echo htmlspecialchars(substr($result['output'], 0, 500)) . (strlen($result['output']) > 500 ? '...' : ''); ?></div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- File System Status -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>📁 File System Status</h3>
|
|
||||||
<table>
|
|
||||||
<tr><th>Path</th><th>Status</th><th>Size</th><th>Permissions</th><th>Description</th></tr>
|
|
||||||
<?php foreach ($results['files'] as $path => $info): ?>
|
|
||||||
<tr>
|
|
||||||
<td><?php echo htmlspecialchars($path); ?></td>
|
|
||||||
<td class="<?php echo $info['exists'] ? 'status-ok' : 'status-warn'; ?>">
|
|
||||||
<?php echo $info['exists'] ? '✅ Exists' : '⚠️ Missing'; ?>
|
|
||||||
</td>
|
|
||||||
<td><?php echo $info['size'] > 0 ? number_format($info['size']) . ' bytes' : '-'; ?></td>
|
|
||||||
<td><?php echo $info['permissions'] ?: '-'; ?></td>
|
|
||||||
<td><?php echo htmlspecialchars($info['description']); ?></td>
|
|
||||||
</tr>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Recommendations -->
|
|
||||||
<div class="section">
|
|
||||||
<h3>💡 Recommendations</h3>
|
|
||||||
<?php if (empty($results['recommendations'])): ?>
|
|
||||||
<div class="success">
|
|
||||||
<strong>✅ System appears ready for enrollment!</strong><br>
|
|
||||||
No critical issues detected.
|
|
||||||
</div>
|
|
||||||
<?php else: ?>
|
|
||||||
<?php foreach ($results['recommendations'] as $rec): ?>
|
|
||||||
<div class="<?php echo $rec['type']; ?>">
|
|
||||||
<strong><?php echo ucfirst($rec['type']); ?>:</strong> <?php echo htmlspecialchars($rec['message']); ?><br>
|
|
||||||
<strong>Action:</strong> <?php echo htmlspecialchars($rec['action']); ?>
|
|
||||||
</div>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Next Steps -->
|
|
||||||
<div class="section info">
|
|
||||||
<h3>🚀 Next Steps</h3>
|
|
||||||
<ol>
|
|
||||||
<li><strong>Address any errors or warnings</strong> shown in the recommendations above</li>
|
|
||||||
<li><strong>Run fix-permissions.sh</strong> if sudo access is not working: <code>sudo ./fix-permissions.sh</code></li>
|
|
||||||
<li><strong>Try the enrollment process</strong> once all critical issues are resolved</li>
|
|
||||||
<li><strong>Check the logs</strong> in <code>/var/www/ziti-enrollment/logs/</code> if enrollment fails</li>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
<?php
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the checks and output results
|
|
||||||
$results = runPreEnrollmentChecks();
|
|
||||||
|
|
||||||
if (php_sapi_name() === 'cli') {
|
|
||||||
// CLI output
|
|
||||||
echo "Pre-Enrollment System Check\n";
|
|
||||||
echo "===========================\n\n";
|
|
||||||
|
|
||||||
echo "Environment: " . $results['environment']['php_sapi'] . " (PHP " . $results['environment']['php_version'] . ")\n";
|
|
||||||
echo "User: " . $results['environment']['user'] . " (UID: " . $results['environment']['uid'] . ")\n\n";
|
|
||||||
|
|
||||||
echo "Recommendations:\n";
|
|
||||||
foreach ($results['recommendations'] as $rec) {
|
|
||||||
echo "- [{$rec['type']}] {$rec['message']}\n";
|
|
||||||
echo " Action: {$rec['action']}\n\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Web output
|
|
||||||
outputHTML($results);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
Loading…
Reference in New Issue