Каталог статей
Прекратите устанавливать Adminer вручную! Один скрипт может выполнить всю настройку безопасности.
Несколько дней назад мой друг, который тоже работает системным администратором, пожаловался мне, что установка Adminer на его сервер занимает у него большую часть дня. Дело не в том, что сам Adminer сложно установить; это всего лишь PHP-файл, его можно просто загрузить, и он будет работать. Проблема в том, что нельзя просто загрузить PHP-файл и на этом закончить.
Вам необходимо настроить поддомены, загрузить плагины, настроить аутентификацию Nginx и сконфигурировать Fail2Ban для предотвращения атак методом перебора паролей. Каждый шаг несложен, но вместе они образуют набор разрозненных команд и конфигурационных файлов.
Ещё более неприятно то, что настройки безопасности, такие как аутентификация и брандмауэры, особенно подвержены ошибкам. Небольшая оплошность может привести к тому, что интерфейс управления базой данных станет доступен из общедоступного интернета, сделав его доступным для любого желающего.
Тогда я посмеялся, потому что сам делал то же самое. Позже я больше не мог этого терпеть, поэтому написал скрипт развертывания в один клик, чтобы автоматизировать все эти шаги.

为什么不用PHPMYADMIN
Вы можете спросить, почему бы не использовать 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 минут, он будет заблокирован на 1 час.
Что касается восстановления прав доступа и перезагрузки служб, скрипт автоматически установит правильные права доступа к файлам и перезагрузит PHP-FPM, Nginx и Fail2Ban.
Я серьёзно отношусь к безопасности.
Честно говоря, безопасность инструментов управления базами данных — это то, что для меня важнее всего.
Подумайте сами, администратор может напрямую управлять всеми базами данных на вашем сервере. Если они окажутся в открытом доступе в интернете и кто-то их просканирует, последствия будут невообразимыми.
Этот скрипт имеет тройную защиту.
Первый уровень — это базовая HTTP-аутентификация Nginx. При доступе к Adminer в вашем браузере появится диалоговое окно с запросом на ввод имени пользователя и пароля. Только после ввода корректной информации вы сможете увидеть страницу входа в Adminer.
Второй уровень — это хэширование пароля администратора. Я настроил хэширование паролей в файле index.php, поэтому даже если кто-то обойдет аутентификацию Nginx, он не узнает пароль администратора.
Третий уровень защиты — это защита от подбора паролей методом перебора. Если кто-то попытается подобрать ваш пароль методом перебора, 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 вручную. Скрипт не оставит никаких других следов в системе.
Напишите в конце
Я всегда считал, что эксплуатация и техническое обслуживание не должны быть такими сложными.
Многие задачи, выполняемые вручную, можно автоматизировать с помощью скриптов. Это позволит вам потратить время на более важные дела, такие как оптимизация производительности серверов, мониторинг состояния приложений и изучение новых технологий.
Это напоминает мне одну историческую историю. В 1880-х годах электричество начало распространяться в Соединенных Штатах. Многие владельцы заводов потратили большие деньги на покупку генераторов и электродвигателей и установили их на своих предприятиях. Однако после установки многие обнаружили, что эффективность производства существенно не улучшилась. Это произошло потому, что они заменили только паровые двигатели электродвигателями, а общая планировка, процессы и методы управления заводом остались неизменными.
Те, кто действительно извлек выгоду из энергетического бума, первыми поняли, что на самом деле означает электричество. Они перепроектировали производственные линии, реорганизовали цеха и изменили методы работы рабочих.
То же самое относится и к автоматизации операций и технического обслуживания. Многие знают, что можно использовать скрипты, но всё же предпочитают ручное управление, подобно тем владельцам заводов в прошлом, которые знали об электродвигателях, но всё ещё использовали подход, аналогичный паровым двигателям. Скрипты не призваны заменить ваше собственное суждение, а автоматизировать повторяющиеся, механические и подверженные ошибкам задачи, позволяя вам сосредоточить свою энергию на том, что действительно требует обдуманного подхода.
Вот так и появился этот скрипт. Он решил мою проблему, и я надеюсь, что он поможет и вам.
Если вы используете HestiaCP и Adminer, возможно, вам стоит попробовать этот скрипт. Он может сэкономить вам много времени.
Раз уж вы дочитали до этого места, если вам это показалось полезным, пожалуйста, поставьте лайк и поделитесь этим постом. Если вы хотите получать обновления первыми, вы также можете подписаться на меня!
Спасибо за прочтение моей статьи. До встречи в следующий раз.
Надеюсь, статья "Скрипт администратора развертывания HestiaCP в один клик (включая аутентификацию Nginx + двойную защиту Fail2Ban)", опубликованная в блоге Чен Вэйляна ( https://www.chenweiliang.com/ ), окажется для вас полезной.
Не стесняйтесь делиться ссылкой на эту статью: https://www.chenweiliang.com/cwl-34395.html
