2025-08-26 16:26:33 +00:00
|
|
|
|
#!/bin/bash
|
|
|
|
|
|
# ==============================================================================
|
|
|
|
|
|
# Script: create_pma_gateway.sh
|
|
|
|
|
|
# Purpose: Create a time-limited gateway URL for phpMyAdmin on Virtuozzo LLSMP.
|
|
|
|
|
|
# Usage: create_pma_gateway.sh --validity=30 [--slug=myalias]
|
|
|
|
|
|
# Outputs: Prints the generated URL.
|
|
|
|
|
|
# ==============================================================================
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
|
|
SLUG=""
|
|
|
|
|
|
VALIDITY=30 # minutes
|
|
|
|
|
|
|
|
|
|
|
|
for arg in "$@"; do
|
|
|
|
|
|
case $arg in
|
|
|
|
|
|
--slug=*) SLUG="${arg#*=}" ;;
|
|
|
|
|
|
--validity=*) VALIDITY="${arg#*=}" ;;
|
|
|
|
|
|
*) echo "Unknown argument $arg"; exit 1 ;;
|
|
|
|
|
|
esac
|
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
|
|
if [[ -z "$SLUG" ]]; then
|
|
|
|
|
|
SLUG=$(openssl rand -hex 4) # 8-char random
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
# Determine environment public host (no node prefix)
|
|
|
|
|
|
if [[ -n "${JELASTIC_ENV_DOMAIN:-}" ]]; then
|
|
|
|
|
|
ENV_HOST="$JELASTIC_ENV_DOMAIN"
|
|
|
|
|
|
else
|
|
|
|
|
|
ENV_HOST=$(hostname -f)
|
|
|
|
|
|
ENV_HOST=${ENV_HOST#node*-} # strip nodeXXXX-
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
|
|
PMADB_DIR="/usr/share/phpMyAdmin"
|
|
|
|
|
|
GATEWAY_FILE="$PMADB_DIR/access-db-$SLUG.php"
|
|
|
|
|
|
|
|
|
|
|
|
SECRET_FILE="/var/lib/jelastic/keys/mbadmin_secret"
|
|
|
|
|
|
sudo mkdir -p "$(dirname $SECRET_FILE)"
|
|
|
|
|
|
if [[ ! -f "$SECRET_FILE" ]]; then
|
|
|
|
|
|
sudo sh -c "openssl rand -hex 32 > $SECRET_FILE"
|
|
|
|
|
|
fi
|
2025-08-26 17:27:43 +00:00
|
|
|
|
sudo chown litespeed:litespeed "$SECRET_FILE"
|
|
|
|
|
|
sudo chmod 644 "$SECRET_FILE"
|
|
|
|
|
|
SECRET=$(sudo cat "$SECRET_FILE" | xargs)
|
2025-08-26 16:26:33 +00:00
|
|
|
|
|
|
|
|
|
|
now=$(date +%s)
|
|
|
|
|
|
expires=$((now + VALIDITY*60))
|
|
|
|
|
|
# token = base64("$SLUG:$expires") . '.' . HMAC_SHA256(secret, data)
|
|
|
|
|
|
data="$SLUG:$expires"
|
2025-08-26 17:27:43 +00:00
|
|
|
|
base=$(printf "%s" "$data" | base64 | tr -d '\n')
|
|
|
|
|
|
mac=$(php -r "echo hash_hmac('sha256', '$data', '$SECRET');")
|
2025-08-26 16:26:33 +00:00
|
|
|
|
token="$base.$mac"
|
|
|
|
|
|
|
2025-08-26 17:46:27 +00:00
|
|
|
|
# Secure the phpMyAdmin vhost with Rewrite Rules to block direct access
|
|
|
|
|
|
VHOST_CONFIG="/usr/share/phpMyAdmin/vhost.conf"
|
|
|
|
|
|
NEEDS_RESTART=0
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
# Remove any existing rewrite block to ensure a clean state.
|
|
|
|
|
|
sudo sed -i '/\s*<rewrite>/,/<\/rewrite>/d' "$VHOST_CONFIG"
|
|
|
|
|
|
|
|
|
|
|
|
# Define the new rewrite block using a temporary file to avoid escaping issues.
|
|
|
|
|
|
REWRITE_TMP=$(mktemp)
|
|
|
|
|
|
cat > "$REWRITE_TMP" <<'EOF'
|
|
|
|
|
|
<rewrite>
|
|
|
|
|
|
<enable>1</enable>
|
|
|
|
|
|
<logLevel>0</logLevel>
|
|
|
|
|
|
<rules>
|
|
|
|
|
|
# PMA Gateway Security Rules
|
|
|
|
|
|
# Allow access to the gateway scripts themselves
|
|
|
|
|
|
RewriteCond %{REQUEST_URI} ^/access-db-.*\.php$
|
|
|
|
|
|
RewriteRule .* - [L]
|
|
|
|
|
|
# For all other requests, block if the security cookie is not present
|
|
|
|
|
|
RewriteCond %{HTTP_COOKIE} !pma_access_granted
|
|
|
|
|
|
RewriteRule .* - [F,L]
|
|
|
|
|
|
</rules>
|
|
|
|
|
|
</rewrite>
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
|
|
# Use awk to insert the new block before the </vhssl> tag for robustness
|
|
|
|
|
|
sudo awk -v r="$(cat $REWRITE_TMP)" '{if (/\s*<vhssl>/) print r} {print}' "$VHOST_CONFIG" | sudo tee "$VHOST_CONFIG" > /dev/null
|
|
|
|
|
|
|
|
|
|
|
|
rm -f "$REWRITE_TMP"
|
|
|
|
|
|
NEEDS_RESTART=1
|
|
|
|
|
|
fi
|
|
|
|
|
|
else
|
|
|
|
|
|
echo "Warning: phpMyAdmin vhost config not found at $VHOST_CONFIG. Cannot apply security rules." >&2
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
2025-08-26 17:27:43 +00:00
|
|
|
|
sudo tee "$GATEWAY_FILE" >/dev/null <<'PHP'
|
2025-08-26 16:26:33 +00:00
|
|
|
|
<?php
|
2025-08-26 17:27:43 +00:00
|
|
|
|
// Secure phpMyAdmin gateway – auto-generated, do NOT edit manually.
|
|
|
|
|
|
|
2025-08-26 16:26:33 +00:00
|
|
|
|
ini_set('session.cookie_httponly', 1);
|
2025-08-26 17:27:43 +00:00
|
|
|
|
$param = 'token';
|
|
|
|
|
|
|
|
|
|
|
|
function deny() {
|
|
|
|
|
|
http_response_code(403);
|
|
|
|
|
|
echo 'Access denied';
|
|
|
|
|
|
exit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!isset($_GET[$param])) {
|
|
|
|
|
|
deny();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$token = $_GET[$param];
|
|
|
|
|
|
if (strpos($token, '.') === false) {
|
|
|
|
|
|
deny();
|
|
|
|
|
|
}
|
2025-08-26 16:26:33 +00:00
|
|
|
|
|
2025-08-26 17:27:43 +00:00
|
|
|
|
list($base, $sig) = explode('.', $token, 2);
|
2025-08-26 16:26:33 +00:00
|
|
|
|
$data = base64_decode($base, true);
|
2025-08-26 17:27:43 +00:00
|
|
|
|
if ($data === false) {
|
|
|
|
|
|
deny();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (strpos($data, ':') === false) {
|
|
|
|
|
|
deny();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
list($slug, $exp) = explode(':', $data, 2);
|
|
|
|
|
|
if (time() > intval($exp)) {
|
2025-08-26 17:46:27 +00:00
|
|
|
|
unlink(__FILE__); // Self-destruct if expired
|
2025-08-26 17:27:43 +00:00
|
|
|
|
deny();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$secret = trim(file_get_contents('/var/lib/jelastic/keys/mbadmin_secret'));
|
|
|
|
|
|
if (!hash_equals($sig, hash_hmac('sha256', $data, $secret))) {
|
|
|
|
|
|
deny();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-26 17:46:27 +00:00
|
|
|
|
// Issue a short-lived cookie that the rewrite rule looks for.
|
|
|
|
|
|
// This cookie acts as the temporary pass.
|
|
|
|
|
|
setcookie('pma_access_granted', $sig, intval($exp), '/', '', true, true);
|
2025-08-26 16:26:33 +00:00
|
|
|
|
header('Location: /');
|
|
|
|
|
|
exit;
|
|
|
|
|
|
?>
|
|
|
|
|
|
PHP
|
|
|
|
|
|
|
2025-08-26 17:27:43 +00:00
|
|
|
|
sudo chown litespeed:litespeed "$GATEWAY_FILE"
|
|
|
|
|
|
sudo chmod 644 "$GATEWAY_FILE"
|
2025-08-26 16:26:33 +00:00
|
|
|
|
|
2025-08-26 17:46:27 +00:00
|
|
|
|
# Restart LiteSpeed if we modified the config
|
|
|
|
|
|
if [[ "${NEEDS_RESTART:-0}" -eq 1 ]]; then
|
|
|
|
|
|
echo "Applying security rules and restarting LiteSpeed..." >&2
|
|
|
|
|
|
if ! sudo systemctl restart lsws; then
|
|
|
|
|
|
echo "Warning: LiteSpeed restart failed. Manual restart may be required." >&2
|
|
|
|
|
|
fi
|
|
|
|
|
|
fi
|
|
|
|
|
|
|
2025-08-26 16:26:33 +00:00
|
|
|
|
URL="https://$ENV_HOST:8443/access-db-$SLUG.php?token=$token"
|
|
|
|
|
|
echo "$URL"
|