diff --git a/scripts/pma-gateway/create_pma_gateway.sh b/scripts/pma-gateway/create_pma_gateway.sh index ac3546c..97fb7ff 100644 --- a/scripts/pma-gateway/create_pma_gateway.sh +++ b/scripts/pma-gateway/create_pma_gateway.sh @@ -187,64 +187,155 @@ fi token="$base.$mac" -# Create symlinks for phpMyAdmin and gateway in main document root -# This serves both through the main domain (port 443) with valid SSL certificate -sudo mkdir -p "$MAIN_DOCROOT" +# phpMyAdmin vhost configuration will be handled below -# Symlink entire phpMyAdmin directory for full access -sudo ln -sf "/usr/share/phpMyAdmin" "$MAIN_DOCROOT/phpmyadmin" - -# Symlink the gateway script for public access -sudo ln -sf "$GATEWAY_FILE" "$PUBLIC_GATEWAY_FILE" - -# Remove the phpMyAdmin vhost to avoid exposing port 8443 publicly +# ============================================================================== +# Step 4: Configure phpMyAdmin vhost with SSL certificate detection +# ============================================================================== VHOST_CONFIG="/usr/share/phpMyAdmin/vhost.conf" -if [[ -f "$VHOST_CONFIG" ]]; then - echo "Removing phpMyAdmin vhost configuration to prevent public exposure on port 8443..." >&2 - sudo rm -f "$VHOST_CONFIG" +NEEDS_RESTART=0 + +# If vhost config is missing or empty, recreate it from a known-good default. +if [ ! -s "$VHOST_CONFIG" ]; then + echo "Warning: $VHOST_CONFIG is empty or missing. Recreating from default." >&2 + sudo tee "$VHOST_CONFIG" > /dev/null <<'EOF' + + + /usr/share/phpMyAdmin/ + 1 + + + 0 + $SERVER_ROOT/logs/error.log + DEBUG + 10M + + + 0 + $SERVER_ROOT/logs/access.log + 10M + 30 + 0 + + + + 0 + index.php, index.html + 0 + /_autoindex/default.php + + + + 404 + /error404.html + + + + 31 + .htaccess + + + 1 + + + 0 + + 0 + gif, jpeg, jpg + 1 + 1 + + + * + + 10 + + + /tmp/lscache/vhosts/$VH_NAME + + + + 0 + 0 + RewriteCond %{HTTP_USER_AGENT} ^NameOfBadRobot +RewriteRule ^/nospider/ - [F] + + + __KEY_FILE_PLACEHOLDER__ + __CERT_FILE_PLACEHOLDER__ + 1 + + + 0 + 0 + + + 0 + $VH_ROOT/awstats + /awstats/ + localhost + 127.0.0.1 localhost + 86400 + 0 + + +EOF + + # Inject the discovered certificate paths using sed + # Escape special characters (/, $, &, \, ') in paths for use with sed + ESCAPED_KEY_PATH=$(printf '%s\n' "$KEY_FILE_PATH" | sed 's/[\/&$\\'"'"']/\\&/g') + ESCAPED_CERT_PATH=$(printf '%s\n' "$CERT_FILE_PATH" | sed 's/[\/&$\\'"'"']/\\&/g') + + # Replace placeholders with actual certificate paths + sudo sed -i "s|__KEY_FILE_PLACEHOLDER__|$ESCAPED_KEY_PATH|g" "$VHOST_CONFIG" + sudo sed -i "s|__CERT_FILE_PLACEHOLDER__|$ESCAPED_CERT_PATH|g" "$VHOST_CONFIG" + + echo "SSL certificate paths injected into vhost configuration." >&2 NEEDS_RESTART=1 fi -# ============================================================================== -# Step 4: Automatically inject security rules into main vhost configuration -# ============================================================================== -MAIN_VHOST_CONFIG="/var/www/conf/vhosts/$PUBLIC_HOST/vhconf.xml" +if [ -f "$VHOST_CONFIG" ]; then + MARKER="# PMA Gateway Security Rules" + + # If rules are not already in place, add them. + if ! sudo grep -qF "$MARKER" "$VHOST_CONFIG"; then + + # Ensure xmlstarlet is installed, as it's the safest way to edit XML. + if ! command -v xmlstarlet &> /dev/null; then + echo "xmlstarlet not found. Installing for safe XML editing..." >&2 + if ! sudo dnf install -y xmlstarlet; then + echo "FATAL: Failed to install xmlstarlet. Cannot safely modify vhost." >&2 + exit 1 + fi + fi -# Ensure main vhost config exists (critical for automation) -if [[ ! -f "$MAIN_VHOST_CONFIG" ]]; then - echo "FATAL: Main vhost config not found at $MAIN_VHOST_CONFIG" >&2 - echo "Expected location: /var/www/conf/vhosts/$PUBLIC_HOST/vhconf.xml" >&2 - exit 1 -fi - -MARKER="# PMA Gateway Security Rules" -if ! sudo grep -qF "$MARKER" "$MAIN_VHOST_CONFIG"; then - echo "Injecting PMA gateway security rules into main vhost..." >&2 - - # Define comprehensive security rules for phpMyAdmin protection - NEW_RULES=$(cat <<'EOF' + # Define the new rules content. Note the lack of indentation. + # xmlstarlet will handle the formatting. + NEW_RULES_CONTENT=$(cat <<'EOF' # PMA Gateway Security Rules # Allow access to the gateway scripts themselves RewriteCond %{REQUEST_URI} ^/access-db-.*\.php$ RewriteRule .* - [L] -# Block all phpMyAdmin paths unless security cookie is present +# For all other requests, block if the security cookie is not present RewriteCond %{HTTP_COOKIE} !pma_access_granted -RewriteCond %{REQUEST_URI} ^/(phpmyadmin/|index\.php|url\.php|js/|css/|libraries/|themes/|favicon\.ico) RewriteRule .* - [F,L] EOF - ) +) + + # Use xmlstarlet to atomically update the rewrite block in-place. + # This is far safer than sed/awk for structured XML. + if ! sudo xmlstarlet ed -L \ + -u "//virtualHostConfig/rewrite/enable" -v "1" \ + -u "//virtualHostConfig/rewrite/rules" -v "$NEW_RULES_CONTENT" \ + "$VHOST_CONFIG"; then + echo "FATAL: xmlstarlet failed to update $VHOST_CONFIG." >&2 + exit 1 + fi - # Enable rewrite and inject comprehensive rules - if ! sudo xmlstarlet ed -L \ - -u "//virtualHostConfig/rewrite/enable" -v "1" \ - -u "//virtualHostConfig/rewrite/rules" -v "$(sudo xmlstarlet sel -t -v "//virtualHostConfig/rewrite/rules" "$MAIN_VHOST_CONFIG" 2>/dev/null)$NEW_RULES" \ - "$MAIN_VHOST_CONFIG"; then - echo "FATAL: Failed to update main vhost rewrite rules." >&2 - exit 1 + NEEDS_RESTART=1 fi - - echo "✅ PMA security rules injected into main vhost configuration" >&2 - NEEDS_RESTART=1 +else + echo "Warning: phpMyAdmin vhost config not found at $VHOST_CONFIG. Cannot apply security rules." >&2 fi sudo tee "$GATEWAY_FILE" >/dev/null <<'PHP' @@ -302,13 +393,7 @@ PHP sudo chown litespeed:litespeed "$GATEWAY_FILE" sudo chmod 644 "$GATEWAY_FILE" -# Set proper permissions on the public symlink as well -if [[ -L "$PUBLIC_GATEWAY_FILE" ]]; then - sudo chown --no-dereference litespeed:litespeed "$PUBLIC_GATEWAY_FILE" - sudo chmod 644 "$PUBLIC_GATEWAY_FILE" -else - echo "WARNING: Public symlink $PUBLIC_GATEWAY_FILE does not exist. Skipping chown/chmod." >&2 -fi +# Gateway file permissions are already set above # Restart LiteSpeed if we modified the config if [[ "${NEEDS_RESTART:-0}" -eq 1 ]]; then @@ -318,9 +403,8 @@ if [[ "${NEEDS_RESTART:-0}" -eq 1 ]]; then fi fi -# Generate URL using public hostname (port 443) with valid SSL certificate -# This bypasses CDN protections and uses the trusted certificate -URL="https://$PUBLIC_HOST/access-db-$SLUG.php?token=$token" +# Generate URL using phpMyAdmin vhost (port 8443) with detected SSL certificate +URL="https://$PUBLIC_HOST:8443/access-db-$SLUG.php?token=$token" # Output JSON response for Cloud Scripting compatibility # Cloud Scripting expects structured JSON output from custom actions @@ -344,9 +428,9 @@ EOF # Display security information to stderr (not part of JSON response) echo "🔐 SECURITY NOTICE:" >&2 -echo " • Gateway URL uses valid Let's Encrypt certificate" >&2 -echo " • Served through main domain (port 443) with CDN protection" >&2 -echo " • Port 8443 exposure has been removed for security" >&2 -echo " • phpMyAdmin symlinked to /phpmyadmin/ with full protection" >&2 -echo " • Security rules automatically injected into main vhost" >&2 +echo " • Gateway URL uses detected SSL certificate: $CERT_FILE_PATH" >&2 +echo " • Served through phpMyAdmin vhost (port 8443)" >&2 +echo " • SSL certificate automatically detected and configured" >&2 +echo " • Security rules automatically injected into vhost" >&2 +echo " • Time-limited access with HMAC-signed tokens" >&2 echo "" >&2 \ No newline at end of file