دليل المادة
توقف عن تثبيت Adminer يدويًا! يمكن لبرنامج نصي واحد التعامل مع إعدادات الأمان بالكامل.
قبل يومين، اشتكى لي صديق يعمل أيضاً في إدارة الأنظمة من أن تثبيت برنامج Adminer على خادمه يستغرق منه معظم اليوم. ليس تثبيت Adminer نفسه صعباً؛ فهو مجرد ملف PHP، يمكنك تشغيله وسيعمل. لكن المشكلة تكمن في أنه لا يمكنك ببساطة تشغيل ملف PHP والانتهاء من الأمر.
تحتاج إلى تهيئة النطاقات الفرعية، وتحميل الإضافات، وإعداد مصادقة Nginx، وتكوين Fail2Ban لمنع هجمات القوة الغاشمة. كل خطوة ليست معقدة، ولكنها مجتمعة تشكل مجموعة من الأوامر وملفات التكوين المتفرقة.
الأمر الأكثر إزعاجاً هو أن إعدادات الأمان، كالمصادقة وجدران الحماية، عرضةٌ للأخطاء بشكل خاص. فأي إهمال بسيط قد يكشف واجهة إدارة قاعدة البيانات للإنترنت العام، مما يجعلها متاحة لأي شخص.
ضحكت حينها لأني كنت أفعل الشيء نفسه من قبل. لاحقاً، لم أعد أطيق الأمر، فكتبت برنامجاً نصياً للنشر بنقرة واحدة لأتمتة كل هذه الخطوات.

لماذا لا تستخدمبريس
قد تسأل، لماذا لا تستخدم phpMyAdmin، وهو الأكثر شيوعًا؟
صحيح أن phpMyAdmin لديه عدد أكبر من المستخدمين ومجتمع أوسع، لكنني أعتقد أن Adminer يتفوق عليه في بعض الجوانب.
أولاً، يتميز بصغر حجمه؛ فـ Adminer عبارة عن ملف PHP واحد فقط، بينما phpMyAdmin عبارة عن مجموعة من الملفات. ثانياً، يتميز بالأمان؛ إذ تعتمد فلسفة تصميم Adminer على مبدأ "عدم الثقة افتراضياً"، مما يعني أنك تحتاج إلى ضبط معلومات الاتصال بشكل صريح لتشغيل قاعدة البيانات.
جانب آخر هو الأداء؛ فبرنامج Adminer أسرع بكثير من phpMyAdmin عند التعامل مع قواعد البيانات الكبيرة.
بالطبع، لا شيء من هذا هو الأهم. الأهم هو أن هذا البرنامج النصي يعني أنني لم أعد مضطراً إلى ضبط تلك الإعدادات الأمنية يدوياً.
ما الذي فعله النص البرمجي بالضبط؟
إن الفكرة الكامنة وراء هذا البرنامج النصي بسيطة للغاية: وهي أتمتة جميع الخطوات التي تقوم بها عادةً يدويًا.
لإدخال البيانات بشكل تفاعلي، سيطرح عليك البرنامج النصي بعض الأسئلة: اسم مستخدم HestiaCP ، واسم النطاق، واسم مستخدم المصادقة، وكلمة المرور. ما عليك سوى إدخال هذه البيانات، وسيتولى البرنامج النصي الباقي.
يقوم البرنامج النصي تلقائيًا بإنشاء دليل جذر الويب، ويتحقق مما إذا كانت apache2-utils (المستخدمة لإنشاء ملفات كلمات المرور) وبيئة PHP مثبتة، ويتعامل مع إنشاء الدليل وتثبيت التبعيات.
عند تنزيل برنامج Adminer، يحاول البرنامج أولاً تنزيل أحدث إصدار من المستودع الرسمي. إذا كان المستودع الرسمي غير متاح، فإنه ينتقل تلقائيًا إلى مستودع GitHub Releases المستقر. أعتقد أن هذا مهم للغاية، لأن المستودع الرسمي قد يكون غير مستقر أحيانًا؛ فقد واجهتُ انقطاعات في الاتصال من قبل.
فيما يتعلق بتنزيلات المكونات الإضافية، سيقوم البرنامج النصي بتنزيل ثلاثة مكونات إضافية أساسية: plugin.php هو محمل المكونات الإضافية، و fc-sqlite-connection-without-credentials.php يستخدم للتعامل مع الاتصالات بدون كلمة مرور، و login-password-less.php يدعم تسجيل الدخول باستخدام تجزئة كلمة المرور.
فيما يتعلق بتوليد تجزئة كلمة المرور وملف index.php، هناك تفصيل بسيط: يستخدم البرنامج النصي الدالة getenv() لاسترجاع كلمة المرور بدلاً من استخدام $_ENV مباشرةً. هذا يتجنب مشكلة في إعدادات ملف php.ini قد تتسبب في أن تكون عملية حساب التجزئة فارغة. لقد واجهتُ هذه المشكلة بنفسي، وقضيتُ وقتًا طويلاً في اكتشاف أن نطاق 'E' لم يكن مُفعّلاً في ملف php.ini.
لإعداد مصادقة Nginx، يستخدم البرنامج النصي آلية التضمين الأصلية لـ HestiaCP بدلاً من تعديل ملف التكوين الرئيسي لـ Nginx مباشرةً. وتكمن ميزة هذه الطريقة في أن المصادقة لن تفشل حتى في حال إعادة بناء تكوين النطاق.
في إعدادات Fail2Ban، يقوم البرنامج النصي بإنشاء قاعدة تصفية لمراقبة أخطاء 401. إذا فشل عنوان IP في تسجيل الدخول 3 مرات خلال 10 دقائق، فسيتم حظره لمدة ساعة واحدة.
فيما يتعلق بإصلاح الأذونات وإعادة تحميل الخدمة، سيقوم البرنامج النصي تلقائيًا بتعيين أذونات الملفات الصحيحة وإعادة تحميل PHP-FPM و Nginx و Fail2Ban.
أنا جاد بشأن السلامة.
بصراحة، إن أمان أدوات إدارة قواعد البيانات هو أكثر ما يهمني.
تخيّل الأمر، بإمكان المسؤول التلاعب مباشرةً بجميع قواعد البيانات على خادمك. إذا كانت هذه القواعد مكشوفة للإنترنت العام وقام أحدهم بفحصها، فستكون العواقب وخيمة للغاية.
هذا النص البرمجي محمي بثلاث طبقات من الحماية.
الطبقة الأولى هي مصادقة HTTP الأساسية لـ Nginx. عند دخولك إلى Adminer، سيظهر لك مربع حوار في متصفحك يطلب منك إدخال اسم المستخدم وكلمة المرور. لن تتمكن من رؤية صفحة تسجيل الدخول إلى Adminer إلا بعد إدخال المعلومات الصحيحة.
الطبقة الثانية هي تسجيل دخول المدير باستخدام تجزئة كلمة المرور. لقد قمتُ بضبط تجزئة كلمة المرور في ملف index.php، لذا حتى لو تمكن أحدهم من تجاوز مصادقة Nginx، فلن يتمكن من معرفة كلمة مرور تسجيل دخول المدير.
الطبقة الثالثة هي حماية Fail2Ban من هجمات التخمين العشوائي. إذا حاول أحدهم تخمين كلمة مرورك، سيقوم Fail2Ban تلقائيًا بحظر عنوان IP الخاص به.
بفضل هذه الطبقات الثلاث من الحماية مجتمعة، يمكنك أساسًا وضع المسؤول على الإنترنت العام براحة بال.
عملية بنقرة واحدة، إنها فعلاً بنقرة واحدة.
عملية النشر بسيطة للغاية.
#!/bin/bash
# ==============================================================================
# Adminer + 插件 + Nginx Auth + Fail2Ban 一键自动化部署脚本 (HestiaCP 完美版)
# ==============================================================================
set -e
# 必须以 root 权限运行
if [ "$EUID" -ne 0 ]; then
echo "❌ 错误:请使用 root 或 sudo 运行此脚本!"
exit 1
fi
# ------------------------------------------------------------------------------
# 1. 交互式输入配置参数
# ------------------------------------------------------------------------------
read -p "请输入 HestiaCP 用户名 [默认: admin]: " HESTIA_USER
HESTIA_USER=${HESTIA_USER:-admin}
read -p "请输入 Adminer 部署域名 [例如: adminer.example.com]: " DOMAIN
if [ -z "$DOMAIN" ]; then
echo "❌ 错误:域名不能为空!"
exit 1
fi
read -p "请输入 Nginx 网页认证用户名 [默认: adminuser]: " AUTH_USER
AUTH_USER=${AUTH_USER:-adminuser}
read -sp "请输入防护密码 (用于 Nginx 认证与 Adminer 登录): " AUTH_PASS
echo ""
if [ -z "$AUTH_PASS" ]; then
echo "❌ 错误:密码不能为空!"
exit 1
fi
# 核心路径变量定义
WEBROOT="/home/$HESTIA_USER/web/$DOMAIN/public_html"
ADMINER_FILE="$WEBROOT/adminer.php"
PLUGIN_DIR="$WEBROOT/plugins"
HTPASSWD_FILE="/etc/nginx/.htpasswd-$DOMAIN"
echo -e "\n🚀 开始部署 Adminer 到域名: $DOMAIN ..."
# ------------------------------------------------------------------------------
# 2. 创建目录与安装基础依赖
# ------------------------------------------------------------------------------
if [ ! -d "$WEBROOT" ]; then
echo "📁 创建 Web 根目录: $WEBROOT"
mkdir -p "$WEBROOT"
fi
mkdir -p "$PLUGIN_DIR"
echo "🔍 检查基础依赖环境..."
if ! command -v htpasswd >/dev/null 2>&1; then
echo "📦 安装 apache2-utils 工具包..."
apt-get update -qq && apt-get install -y -qq apache2-utils
fi
if ! command -v php >/dev/null 2>&1; then
echo "❌ 错误:未检测到系统的 PHP 环境!"
exit 1
fi
# ------------------------------------------------------------------------------
# 3. 安全下载 Adminer 核心程序
# ------------------------------------------------------------------------------
echo "📥 正在下载最新版 Adminer..."
curl -sL -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)" \
-o "$ADMINER_FILE" "https://www.adminer.org/latest.php"
# 校验下载有效性
if ! grep -q "<?php" "$ADMINER_FILE"; then
echo "⚠️ 官方源连接异常,正在切换至 GitHub Releases 稳定源..."
curl -sL -o "$ADMINER_FILE" \
"https://github.com/vrana/adminer/releases/download/v4.8.1/adminer-4.8.1.php"
fi
# ------------------------------------------------------------------------------
# 4. 下载官方核心插件与加载器
# ------------------------------------------------------------------------------
echo "🧩 正在下载插件组件..."
curl -sL -o "$PLUGIN_DIR/plugin.php" \
https://raw.githubusercontent.com/vrana/adminer/master/plugins/plugin.php
curl -sL -o "$PLUGIN_DIR/fc-sqlite-connection-without-credentials.php" \
https://raw.githubusercontent.com/vrana/adminer/master/plugins/fc-sqlite-connection-without-credentials.php
curl -sL -o "$PLUGIN_DIR/login-password-less.php" \
https://raw.githubusercontent.com/vrana/adminer/master/plugins/login-password-less.php
# ------------------------------------------------------------------------------
# 5. 安全生成密码 Hash 并构建入口文件 index.php
# ------------------------------------------------------------------------------
echo "⚙️ 生成密码 Hash 与 index.php 配置..."
# 使用 getenv() 替代 $_ENV,防止 php.ini 未开启 E 作用域导致 Hash 计算为空
HASHED_PASSWORD=$(AUTH_PASS="$AUTH_PASS" php -r 'echo password_hash(getenv("AUTH_PASS"), PASSWORD_DEFAULT);')
cat > "$WEBROOT/index.php" <<EOF
<?php
function adminer_object() {
include_once "./plugins/plugin.php";
include_once "./plugins/fc-sqlite-connection-without-credentials.php";
include_once "./plugins/login-password-less.php";
return new AdminerPlugin([
new AdminerFCSqliteConnectionWithoutCredentials(),
new AdminerLoginPasswordLess('$HASHED_PASSWORD'),
]);
}
include "./adminer.php";
EOF
# ------------------------------------------------------------------------------
# 6. 配置 Nginx 基础认证 (完全依赖 HestiaCP 原生 Include 机制)
# ------------------------------------------------------------------------------
echo "🔒 配置 Nginx HTTP Basic Auth..."
htpasswd -b -c "$HTPASSWD_FILE" "$AUTH_USER" "$AUTH_PASS"
chmod 644 "$HTPASSWD_FILE"
HESTIA_CONF_DIR="/home/$HESTIA_USER/conf/web/$DOMAIN"
if [ -d "$HESTIA_CONF_DIR" ]; then
# HestiaCP 原生包含文件名格式:nginx.conf_* 与 nginx.ssl.conf_*
# 这样无需 sed 修改主配置文件,重建域名配置时也不会失效
cat > "$HESTIA_CONF_DIR/nginx.conf_adminer" <<EOF
auth_basic "Restricted Adminer Access";
auth_basic_user_file $HTPASSWD_FILE;
EOF
cat > "$HESTIA_CONF_DIR/nginx.ssl.conf_adminer" <<EOF
auth_basic "Restricted Adminer Access";
auth_basic_user_file $HTPASSWD_FILE;
EOF
fi
# ------------------------------------------------------------------------------
# 7. 配置 Fail2Ban 防护规则
# ------------------------------------------------------------------------------
echo "🛡️ 配置 Fail2Ban 规则..."
cat > /etc/fail2ban/filter.d/nginx-adminer.conf <<'EOF'
[Definition]
failregex = ^<HOST> - .* "GET /.* HTTP/.*" 401
ignoreregex =
EOF
cat > /etc/fail2ban/jail.d/nginx-adminer.conf <<EOF
[nginx-adminer]
enabled = true
filter = nginx-adminer
port = http,https
logpath = /var/log/nginx/domains/$DOMAIN.log
maxretry = 3
findtime = 600
bantime = 3600
EOF
# ------------------------------------------------------------------------------
# 8. 修复权限、刷新缓存与重载服务
# ------------------------------------------------------------------------------
echo "🧹 修复权限并重载服务..."
chown -R $HESTIA_USER:$HESTIA_USER "$WEBROOT"
find "$WEBROOT" -type d -exec chmod 755 {} +
find "$WEBROOT" -type f -exec chmod 644 {} +
# 平滑重载 PHP-FPM(兼容多版本 PHP 环境)
for service in $(systemctl list-units --type=service --state=running --no-legend | awk '{print $1}' | grep -E 'php.*fpm'); do
systemctl reload "$service" || true
done
# 重载 Web 与防护服务
nginx -t && systemctl reload nginx
if systemctl is-active --quiet fail2ban; then
systemctl restart fail2ban
fi
echo -e "\n=================================================="
echo -e "✅ Adminer 一键部署成功!"
echo -e "--------------------------------------------------"
echo -e "🌐 访问地址 : https://$DOMAIN/index.php"
echo -e "👤 Nginx 认证账号 : $AUTH_USER"
echo -e "🔑 Nginx 认证密码 : [你输入的防护密码]"
echo -e "--------------------------------------------------"
echo -e "💡 Adminer 登录说明:"
echo -e " 数据库用户名填写:root(或你的数据库账号)"
echo -e " 数据库密码填写:[你输入的防护密码]"
echo -e "=================================================="كيفية تشغيل البرنامج النصي: امنح البرنامج النصي أذونات التنفيذ:
sudo chmod +x /usr/local/bin/deploy-adminer.sh
قم بتشغيل البرنامج النصي باستخدام sudo:
sudo /usr/local/bin/deploy-adminer.sh
أدخل معلومات التكوين عند الطلب:
- أدخل اسم المستخدم الخاص بك في HestiaCP (على سبيل المثال، admin).
- أدخل النطاق الفرعي الكامل المُجهز (على سبيل المثال، adminer.example.com).
- أدخل كلمة مرور الأمان الخاصة بك (على سبيل المثال، MySuperPassword123)
سيقوم البرنامج النصي بإكمال عملية التكوين بأكملها تلقائيًا دون إغفال أي شيء.
تستغرق العملية برمتها حوالي دقيقة أو دقيقتين. سيتولى البرنامج النصي كل شيء تلقائيًا، ولن تحتاج إلى تنفيذ أي أوامر يدويًا.
بعد الانتهاء، يمكنك الوصول إلى Adminer عبر الرابط التالي: https://yourdomain/index.php
بعض الأسئلة التي قد تثير قلقك
قد يسأل بعض الأصدقاء: هل يدعم هذا البرنامج النصي إصدارات متعددة من لغة PHP؟
نعم، هذه الميزة مدعومة. سيقوم البرنامج النصي تلقائيًا باكتشاف جميع خدمات PHP-FPM العاملة على النظام وإعادة تحميلها واحدة تلو الأخرى. لذا فهو يعمل بشكل جيد سواء كنت تستخدم PHP 7.4 أو PHP 8.2.
قد يسأل بعض الأصدقاء: ماذا لو أردت تغيير كلمة المرور الخاصة بي؟
الأمر بسيط للغاية؛ ما عليك سوى إعادة تشغيل البرنامج النصي. سيقوم البرنامج بإعادة إنشاء تجزئة كلمة المرور، وإعادة تهيئة مصادقة Nginx، وإعادة تهيئة Fail2Ban. سيتم استبدال الإعدادات القديمة.
ماذا لو أردت إلغاء تثبيته؟
يمكنك ببساطة حذف مجلد الموقع الرئيسي وملف كلمات المرور وإعدادات Fail2Ban يدويًا. لن يترك البرنامج النصي أي آثار أخرى على النظام.
اكتب في النهاية
لطالما شعرت أن عمليات التشغيل والصيانة لا ينبغي أن تكون معقدة للغاية.
يمكن أتمتة العديد من المهام اليدوية باستخدام البرامج النصية. وهذا يتيح لك قضاء وقتك في أمور أكثر أهمية، مثل تحسين أداء الخادم، ومراقبة حالة التطبيقات، والبحث في التقنيات الجديدة.
هذا يذكرني بقصة تاريخية. في ثمانينيات القرن التاسع عشر، بدأ انتشار الكهرباء في الولايات المتحدة. أنفق العديد من أصحاب المصانع مبالغ طائلة لشراء المولدات والمحركات الكهربائية وتركيبها في مصانعهم. مع ذلك، بعد التركيب، وجد الكثيرون أن كفاءة الإنتاج لم تتحسن بشكل ملحوظ. والسبب في ذلك هو أنهم استبدلوا محركات البخار بمحركات كهربائية فقط، بينما بقي التصميم العام للمصنع وعملياته وأساليب إدارته على حالها.
أولئك الذين استفادوا حقاً من طفرة الكهرباء كانوا أول من فهم المعنى الحقيقي للكهرباء. لقد أعادوا تصميم خطوط الإنتاج، وأعادوا هيكلة ورش العمل، وأعادوا تنظيم طريقة عمل العمال.
وينطبق الأمر نفسه على أتمتة عمليات التشغيل والصيانة. يعلم الكثيرون بإمكانية استخدام البرامج النصية، لكنهم ما زالوا يفضلون التشغيل اليدوي، تمامًا كما كان أصحاب المصانع في الماضي على دراية بالمحركات الكهربائية، لكنهم ظلوا يستخدمون عقلية محركات البخار في تشغيلها. لا تهدف البرامج النصية إلى استبدال حكمك، بل إلى أتمتة المهام المتكررة والميكانيكية والمعرضة للأخطاء، مما يتيح لك تركيز طاقتك على ما يتطلب تفكيرًا عميقًا.
هكذا ظهر هذا النص البرمجي. لقد حلّ مشكلةً كنت أعاني منها، وآمل أن يفيدك أنت أيضاً.
إذا كنت تستخدم HestiaCP و Adminer، فقد ترغب في تجربة هذا البرنامج النصي. قد يوفر لك الكثير من الوقت.
بما أنك قرأت حتى هذه النقطة، إذا وجدت هذا المحتوى مفيدًا، يُرجى الإعجاب به ومشاركته. وإذا كنت ترغب في تلقي التحديثات أولًا، يمكنك أيضًا متابعتي!
شكراً لكم على قراءة مقالتي. أراكم في المرة القادمة.
نأمل أن تكون المقالة "HestiaCP One-Click Automated Deployment Adminer Script (بما في ذلك مصادقة Nginx + Fail2Ban Dual Protection)" التي تمت مشاركتها على مدونة Chen Weiliang ( https://www.chenweiliang.com/ ) مفيدة لك.
لا تتردد في مشاركة رابط هذه المقالة: https://www.chenweiliang.com/cwl-34395.html
