فهرست مقاله
نصب دستی ادمین را متوقف کنید! یک اسکریپت میتواند کل پیکربندی امنیتی را مدیریت کند.
چند روز پیش، یکی از دوستانم که او هم در بخش مدیریت سیستم کار میکند، از من شکایت کرد که نصب Adminer روی سرورش بیشتر روز طول میکشد. نصب خود Adminer سخت نیست؛ فقط یک فایل PHP است، میتوانید آن را اجرا کنید و کار میکند. اما مشکل این است که نمیتوانید فقط یک فایل PHP را اجرا کنید و کارتان تمام شود.
شما باید زیر دامنهها را پیکربندی کنید، افزونهها را بارگذاری کنید، احراز هویت Nginx را تنظیم کنید و Fail2Ban را برای جلوگیری از حملات brute-force پیکربندی کنید. هر مرحله پیچیده نیست، اما در مجموع منجر به مجموعهای از دستورات و فایلهای پیکربندی پراکنده میشود.
چیزی که حتی آزاردهندهتر است این است که پیکربندیهای مربوط به امنیت مانند احراز هویت و فایروالها به طور خاص مستعد خطا هستند. یک غفلت جزئی میتواند رابط مدیریت پایگاه داده را در معرض اینترنت عمومی قرار دهد و آن را برای هر کسی قابل دسترسی کند.
آن موقع خندیدم چون خودم هم قبلاً همین کار را میکردم. بعداً دیگر نتوانستم تحمل کنم، بنابراین یک اسکریپت استقرار با یک کلیک نوشتم تا تمام این مراحل را خودکار کند.

چرا استفاده نکنیم؟از phpMyAdmin
شاید بپرسید، چرا از phpMyAdmin که رایجتر است استفاده نمیکنید؟
در واقع، phpMyAdmin کاربران و جامعهی بزرگتری دارد. اما من فکر میکنم Adminer در چند زمینه عملکرد بهتری دارد.
اول اینکه سبک است؛ Adminer فقط یک فایل PHP است، در حالی که phpMyAdmin مجموعهای کامل از فایلها است. دوم اینکه امن است؛ فلسفه طراحی Adminer «به طور پیشفرض غیرقابل اعتماد» است، به این معنی که برای کار با پایگاه داده باید اطلاعات اتصال را به صراحت پیکربندی کنید.
جنبه دیگر، عملکرد است؛ Adminer هنگام مدیریت پایگاههای داده بزرگ، به طور قابل توجهی سریعتر از phpMyAdmin است.
البته، هیچکدام از اینها مهمترین چیزها نیستند. مهمترین چیز این است که این اسکریپت باعث میشود دیگر مجبور نباشم آن موارد امنیتی را بهصورت دستی پیکربندی کنم.
فیلمنامه دقیقاً چه کاری انجام میداد؟
ایده پشت این اسکریپت در واقع بسیار ساده است: خودکارسازی تمام مراحلی که معمولاً به صورت دستی انجام میدهید.
برای ورودی تعاملی، اسکریپت از شما چند سوال میپرسد: نام کاربری HestiaCP ، نام دامنه، نام کاربری احراز هویت و رمز عبور. شما فقط باید این موارد را وارد کنید و اسکریپت بقیه کارها را انجام خواهد داد.
این اسکریپت به طور خودکار دایرکتوری ریشه وب را ایجاد میکند، بررسی میکند که آیا apache2-utils (که برای تولید فایلهای رمز عبور استفاده میشود) و محیط PHP نصب شدهاند یا خیر، و ایجاد دایرکتوری و نصب وابستگیها را مدیریت میکند.
هنگام دانلود ادمین، اسکریپت ابتدا سعی میکند آخرین نسخه را از مخزن رسمی دانلود کند. اگر مخزن رسمی در دسترس نباشد، به طور خودکار به مخزن پایدار GitHub Releases منتقل میشود. من فکر میکنم این بسیار مهم است، زیرا مخزن رسمی گاهی اوقات میتواند ناپایدار باشد؛ من قبلاً با وقفههای اتصال مواجه شدهام.
در مورد دانلود افزونهها، این اسکریپت سه افزونه اصلی را دانلود خواهد کرد: plugin.php فایل بارگذاری افزونه است، fc-sqlite-connection-without-credentials.php برای مدیریت اتصالات بدون رمز عبور استفاده میشود و login-password-less.php از ورود با رمز عبور هش شده پشتیبانی میکند.
در مورد تولید هش رمز عبور و index.php، یک نکته کوچک وجود دارد: اسکریپت به جای استفاده مستقیم از $_ENV، از getenv() برای بازیابی رمز عبور استفاده میکند. این کار از مشکل پیکربندی php.ini که باعث خالی شدن محاسبه هش میشود، جلوگیری میکند. من خودم با این مشکل مواجه شدم و مدت زیادی را صرف فهمیدن این کردم که دامنه 'E' در php.ini فعال نیست.
برای پیکربندی احراز هویت Nginx، اسکریپت به جای تغییر مستقیم فایل پیکربندی اصلی Nginx، از مکانیزم بومی HestiaCP برای include کردن استفاده میکند. مزیت این رویکرد این است که حتی اگر پیکربندی دامنه را از نو بسازید، احراز هویت با شکست مواجه نخواهد شد.
در پیکربندی Fail2Ban، اسکریپت یک قانون فیلترینگ برای نظارت بر خطاهای ۴۰۱ ایجاد میکند. اگر یک IP در عرض ۱۰ دقیقه ۳ بار نتواند وارد سیستم شود، به مدت ۱ ساعت مسدود خواهد شد.
در مورد تعمیر مجوزها و بارگذاری مجدد سرویس، اسکریپت به طور خودکار مجوزهای صحیح فایل را تنظیم کرده و 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)
این اسکریپت به طور خودکار کل فرآیند پیکربندی را بدون جا گذاشتن هیچ چیزی انجام میدهد.
کل این فرآیند حدود یک یا دو دقیقه طول میکشد. اسکریپت همه چیز را به طور خودکار انجام میدهد و نیازی به اجرای دستی هیچ دستوری نیست.
بعد از اتمام کار، میتوانید از طریق https://yourdomain/index.php به ادمین دسترسی پیدا کنید.
برخی از سوالاتی که ممکن است نگران آنها باشید
شاید بعضی از دوستان بپرسند، آیا این اسکریپت از چندین نسخه PHP پشتیبانی میکند؟
بله، پشتیبانی میشود. این اسکریپت به طور خودکار تمام سرویسهای PHP-FPM در حال اجرا روی سیستم را شناسایی کرده و آنها را یکی یکی بارگذاری مجدد میکند. بنابراین چه از PHP 7.4 استفاده کنید و چه از PHP 8.2، به خوبی کار میکند.
شاید بعضی از دوستان بپرسند، اگر بخواهم رمز عبورم را عوض کنم، چه کار کنم؟
خیلی ساده است؛ فقط اسکریپت را دوباره اجرا کنید. اسکریپت هش رمز عبور را دوباره تولید میکند، احراز هویت Nginx و Fail2Ban را دوباره پیکربندی میکند. پیکربندی قدیمی بازنویسی خواهد شد.
اگه بخوام حذف نصبش کنم چیکار کنم؟
شما میتوانید به سادگی دایرکتوری ریشه وب، فایل رمز عبور و پیکربندی Fail2Ban را به صورت دستی حذف کنید. این اسکریپت هیچ ردپای دیگری روی سیستم باقی نخواهد گذاشت.
در پایان بنویسید
من همیشه احساس میکردم که عملیات و نگهداری نباید خیلی پیچیده باشد.
بسیاری از کارهای دستی را میتوان با استفاده از اسکریپتها خودکار کرد. این به شما امکان میدهد وقت خود را صرف موارد مهمتری مانند بهینهسازی عملکرد سرور، نظارت بر وضعیت برنامه و تحقیق در مورد فناوریهای جدید کنید.
این موضوع مرا به یاد یک داستان تاریخی میاندازد. در دهه ۱۸۸۰، برق در ایالات متحده شروع به گسترش کرد. بسیاری از صاحبان کارخانهها پول زیادی را صرف خرید ژنراتورها و موتورهای الکتریکی و نصب آنها در کارخانههای خود کردند. با این حال، پس از نصب، بسیاری متوجه شدند که راندمان تولید به طور قابل توجهی بهبود نیافته است. این به این دلیل بود که آنها فقط موتورهای بخار را با موتورهای الکتریکی جایگزین کرده بودند، اما طرح کلی، فرآیندها و روشهای مدیریت کارخانه بدون تغییر باقی مانده بود.
کسانی که واقعاً از رونق برق بهرهمند شدند، اولین کسانی بودند که فهمیدند برق واقعاً به چه معناست. آنها خطوط تولید را دوباره طراحی کردند، کارگاهها را بازسازی کردند و نحوهی کار کارگران را از نو سازماندهی کردند.
همین امر در مورد اتوماسیون عملیات و نگهداری نیز صدق میکند. بسیاری از مردم میدانند که میتوان از اسکریپتها استفاده کرد، اما هنوز عملیات دستی را ترجیح میدهند، درست مانند صاحبان کارخانه در گذشته که در مورد موتورهای الکتریکی میدانستند اما همچنان از طرز فکر موتورهای بخار برای استفاده از آنها استفاده میکردند. اسکریپتها قرار نیست جایگزین قضاوت شما شوند، بلکه برای خودکارسازی کارهای تکراری، مکانیکی و مستعد خطا هستند و به شما این امکان را میدهند که انرژی خود را روی آنچه واقعاً به فکر نیاز دارد متمرکز کنید.
این اسکریپت به این شکل خلق شد. این اسکریپت یک مشکل اساسی برای من را حل کرد و امیدوارم به شما هم کمک کند.
اگر از HestiaCP و Adminer استفاده میکنید، شاید بخواهید این اسکریپت را امتحان کنید. این کار میتواند در زمان شما صرفهجویی زیادی کند.
از آنجایی که تا اینجا را خواندهاید، اگر برایتان مفید بود، لطفاً آن را لایک کنید و به اشتراک بگذارید. اگر میخواهید زودتر از بقیه از بهروزرسانیها مطلع شوید، میتوانید من را دنبال کنید!
ممنون که مقاله من را خواندید. دفعه بعد میبینمتان.
امیدوارم مقاله "اسکریپت استقرار خودکار HestiaCP با یک کلیک برای ادمین (شامل احراز هویت Nginx + محافظت دوگانه Fail2Ban)" که در وبلاگ چن ویلیانگ ( https://www.chenweiliang.com/ ) به اشتراک گذاشته شده است، برای شما مفید باشد.
لینک این مقاله را به اشتراک بگذارید: https://www.chenweiliang.com/cwl-34395.html
