Установка и защита phpMyAdmin+Nginx на сервере Debian 9
Многим сайтам необходима база данных типа MySQL, но интерфейс командной строки СУБД не очень удобный и понятный, особенно для новичков.
Интерфейс phpMyAdmin призван устранить эту проблему. Это альтернативный веб-интерфейс для работы с СУБД. В данном мануале мы поговорим об установке и защите phpMyAdmin на сервере Debian 9. В качестве веб-сервера используется Nginx – производительный сервер, способный обрабатывать большие нагрузки. Также м поработаем над защитой сервера.
Примечание: Используя программы типа phpMyAdmin, следует обязательно соблюдать ряд правил безопасности – поскольку программа работает на сервере БД, она имеет доступ к учетным данным, а это позволяет злоумышленникам легко отправлять произвольные SQL-запросы. Поскольку phpMyAdmin – широко распространенное PHP-приложение, оно часто подвергается атакам. В этом мануале мы рассмотрим некоторые меры безопасности, которые могут вам пригодиться.
Требования
- Сервер Debian 9, настроенный по этому мануалу. Обязательно нужен пользователь с доступом к sudo.
- Предварительно установленный сервер LEMP (Linux, Nginx, MySQL и PHP). Все необходимые инструкции вы найдете в мануале Установка стека LEMP в Debian 9. Обязательно запишите или запомните пароль администратора MySQL.
Поскольку интерфейс phpMyAdmin напрямую связывается с установкой MySQL и обрабатывает аутентификацию с помощью учетных данных, запускать phpMyAdmin на удаленных системах по простому HTTP-соединению ни в коем случае нельзя. Если у вас нет домена, защищенного сертификатом SSL/TLS, обратитесь к руководству Создание сертификата Let’s Encrypt для Nginx в Debian 9.
Примечание: Если у вас нет SSL/TLS-сертификата, но вы хотите выполнить этот мануал, пожалуйста, рассмотрите варианты использования SSH-туннеля (об этом поговорим в разделе 5).
1: Установка phpMyAdmin
Предварительно установив стек LEMP, можно сразу приступать к установке phpMyAdmin. Пакеты этой программы можно найти в стандартных репозиториях Debian.
Сначала обновите индекс пакетов.
sudo apt update
Затем используйте менеджер apt, чтобы загрузить пакеты из репозитория и установить их:
sudo apt install phpmyadmin
Во время установки будут запрошены дополнительные данные, в том числе веб-сервер, который нужно автоматически настроить (Apache или Lighthttp). Поскольку среди предложенных вариантов нет нужного нам Nginx, просто нажмите Tab и Ok, чтобы продолжить.
Затем программа спросит, нужно ли настроить базу данных для phpMyAdmin с помощью dbconfig-common. Выберите Yes, чтобы продолжить. Это создаст внутреннюю БД и администратора для phpMyAdmin. После этого нужно ввести пароль для пользователя MySQL по имени phpmyadmin. Если вы оставите это поле пустым, phpMyAdmin создаст случайный пароль.
Установка завершена. Чтобы Nginx мог найти и корректно обработать файлы phpMyAdmin, нужно создать симлинк на каталог document root сервера Nginx:
sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
Теперь phpMyAdmin полностью готов к работе. Чтобы открыть интерфейс, введите в браузер домен или внешний IP-адрес и /phpmyadmin:
https://server_domain_or_IP/phpmyadmin
На экране появится стандартная страница входа phpMyAdmin.
Как мы уже говорили, phpMyAdmin обрабатывает аутентификацию по учетным данным MySQL: то есть вам нужно использовать то же имя пользователя и пароль, которые вы используете при доступе к БД через консоль или API. Чтобы войти, используйте учётные данные пользователя MySQL.
Читайте также: Краткий справочник по управлению базой данных SQL
Примечание: Входить в phpMyAdmin как root пользователь MySQL не рекомендуется – это представляет значительную угрозу безопасности. Немного позже мы расскажем, как заблокировать root-логин.
На этом этапе phpMyAdmin полностью готов к работе. Однако установка веб-интерфейса открыла публичный доступ к MySQL, а это серьёзный риск для безопасности сервера. Из-за большой популярности phpMyAdmin и объемов данных, к которым он имеет доступ, подобные программы часто становятся целью злоумышленников.
Далее мы рассмотрим несколько способов, которые помогут сделать установку phpMyAdmin более безопасной.
2: Изменение стандартного расположения phpMyAdmin
Один из основных способов защиты phpMyAdmin – усложнить поиск самой установки. Боты будут искать стандартные пути: phpmyadmin, pma, admin, mysql и тому подобное. Заменив стандартный URL-адрес интерфейса /phpmyadmin каким-то более сложным, неочевидным вариантом, вы усложните автоматизированный поиск и предотвратите brute-force атаки.
Ранее мы создали симлинк в /usr/share/phpmyadmin, чтобы веб-сервер Nginx находил и обслуживал файлы phpMyAdmin. Чтобы изменить URL-адрес интерфейса phpMyAdmin, нужно переименовать этот симлинк.
Перейдите в корневой каталог Nginx и посмотрите, какие в нем есть файлы (чтобы лучше понимать, как именно можно изменить расположение):
cd /var/www/html/
ls -l
Вы получите вывод:
total 8
-rw-r--r-- 1 root root 612 Apr 8 13:30 index.nginx-debian.html
lrwxrwxrwx 1 root root 21 Apr 8 15:36 phpmyadmin -> /usr/share/phpmyadmin
В выводе говорится, что в этом каталоге есть симлинк phpmyadmin. Измените имя этой ссылки; это изменит расположение phpMyAdmin, по которому его можно найти в браузере, благодаря чему автоматизированные боты для взлома не смогут получить к нему доступ.
Выберите нестандартное имя, которое не описывает конечной цели; для примера в этом мануале это расположение называется /nothingtosee. Переименуйте ссылку:
sudo mv phpmyadmin nothingtosee
ls -l
Теперь вы получите такой вывод:
total 8
-rw-r--r-- 1 root root 612 Apr 8 13:30 index.nginx-debian.html
lrwxrwxrwx 1 root root 21 Apr 8 15:36 nothingtosee -> /usr/share/phpmyadmin
Убедитесь, что старый URL не работает:
http://server_domain_or_IP/phpmyadmin
404 Not Found
Интерфейс phpMyAdmin теперь должен быть доступен по другому URL-адресу.
https://server_domain_or_IP/nothingtosee
3: Отключение root-логина
В MySQL, как и в обычных системах Linux, root является специальной учетной записью с неограниченным доступом к системе. Такой пользователь является очевидной целью для brute-force атак. Чтобы минимизировать риски, нужно отключить в phpMyAdmin любые попытки входа в систему с помощью этого аккаунта. То есть даже если вы укажете действительные учетные данные root, вы все равно получите ошибку «access denied» и не сможете войти в систему.
Поскольку ранее для настройки и хранения параметров phpMyAdmin мы решили использовать dbconfig-common, конфигурация по умолчанию в настоящее время хранится в базе данных. Сейчас нужно создать новый файл config.inc.php для определения пользовательских настроек.
Хотя PHP файлы phpMyAdmin находятся в /usr/share/phpmyadmin, приложение использует конфигурационные файлы, которые находятся в /etc/phpmyadmin. Создайте новый файл пользовательских настроек в /etc/phpmyadmin/conf.d и назовите его pma_secure.php:
sudo nano /etc/phpmyadmin/conf.d/pma_secure.php
Этот файл будет хранить все необходимые параметры, которые отключают беспарольный вход (AllowNoPassword имеет значение false) и root-логин (AllowRoot со значением false):
<?php
# PhpMyAdmin Settings
# This should be set to a random string of at least 32 chars
$cfg['blowfish_secret'] = '3!#32@3sa(+=_4?),5XP_:U%%8\34sdfSdg43yH#{o';
$i=0;
$i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['AllowNoPassword'] = false;
$cfg['Servers'][$i]['AllowRoot'] = false;
?>
Сохраните файл, когда закончите редактирование: нажмите Ctrl+X, y, чтобы подтвердить изменения, и Enter. Изменения автоматически вступят в силу. Если вы перезагрузите страницу входа и попытаетесь войти в систему как пользователь root, вы получите ошибку «Access Denied».
Теперь в вашей установке phpMyAdmin пользователю root запрещен вход в систему. Эта мера безопасности блокирует brute-force сценарии, которые пытаются угадать пароль root на вашем сервере. Более того, теперь для доступа к веб-интерфейсу phpMyAdmin можно использовать только учетные записи MySQL с пониженными привилегиями, что само по себе важно.
4: Настройка шлюза авторизации Nginx
Изменение стандартного расположения установки phpMyAdmin может сбить с толку некоторых автоматизированных ботов, сканирующих сеть, но при целевых атаках это не поможет. Чтобы надежнее защитить веб-приложение, нужно ограничить доступ к самой форме аутентификации – тогда злоумышленникам будет сложно добраться до приложения и они не смогут использовать общие эксплойты и brute-force атаки, чтобы угадать учетные данные.
Конкретно в случае phpMyAdmin очень важно держать интерфейс входа в систему заблокированным. Оставляя его открытым для всех пользователей, вы привлечете сотни злоумышленников, и кто-то рано или поздно сможет подобрать ваши учетные данные.
Потому сейчас нужно создать страницу авторизации сервера, которую необходимо будет пройти, чтобы получить доступ к самой странице входа в PhpMyAdmin.
Большинство веб-серверов, – Nginx в их числе, – по умолчанию поставляются с этой функцией.
Сначала нужно создать файл pma_pass для хранения учётных данных. Nginx требует, чтобы пароль был зашифрован с помощью функции crypt().
Криптографический пакет OpenSSL, который должен быть уже установлен на сервере, предоставляет эту функцию.
Чтобы создать зашифрованный пароль, введите:
openssl passwd
Затем укажите и подтвердите пароль, а после этого утилита выведет на экран его зашифрованную версию, которая будет иметь примерно такой вид:
O5az.RSPzd.HE
Скопируйте это значение и вставьте его в файл паролей.
Чтобы создать файл паролей, используйте эту команду (файл будет называться pma_pass и находиться в конфигурационном каталоге Nginx):
sudo nano /etc/nginx/pma_pass
В этом файле нужно указать имя пользователя и зашифрованный с помощью openssl пароль, который будет использоваться для входа в phpMyAdmin, разделив их символом двоеточия.
К примеру, если пользователя зовут demo, то файл будет выглядеть так:
demo:O5az.RSPzd.HE
Примечание: Ни в коем случае не используйте такое имя – его очень легко угадать.
Сохраните и закройте файл.
Теперь отредактируйте конфигурационный файл Nginx. Откройте его в редакторе:
sudo nano /etc/nginx/sites-available/example.com
В этот файл нужно внести новый раздел location для phpMyAdmin (в данном случае это /nothingtosee).
Создайте блок location в блоке server (и вне других блоков) и укажите в нём место установки:
server {
. . .
location / {
try_files $uri $uri/ =404;
}
location /nothingtosee {
# Settings for phpMyAdmin will go here
}
. . .
}
В этом блоке в директиве auth_basic нужно указать сообщение, которое будет отображаться в запросе учётных данных. Чтобы ограничить доступ неавторизованных пользователей, можно просто указать «Admin Login».
Затем нужно использовать директиву auth_basic_user_file, чтобы направить веб-сервер на файл паролей. Nginx запросит у пользователя учётные данные и проверит этот файл на наличие в нём этих данных.
В результате блок выглядит так:
server {
. . .
location /nothingtosee {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/pma_pass;
}
. . .
}
Сохраните и закройте файл. Проверьте ошибки:
sudo nginx -t
Команда должна вернуть:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Чтобы активировать шлюз авторизации, нужно перезапустить веб-сервер.
sudo systemctl reload nginx
Если вы сейчас посетите phpMyAdmin в веб-браузере, будет запрошено имя пользователя и пароль, внесённые в файл pma_pass.
https://server_domain_or_IP/nothingtosee
Примечание: Если после обновления браузера страница не появляется, попробуйте очистить кэш или открыть ее в другом браузере.
Получив учётные данные, браузер откроет страницу входа в phpMyAdmin. Теперь у вас есть дополнительный уровень безопасности, который сохранит логи MySQL в чистоте (в них не будет сотен записей о неудачных попытках входа).
5: Настройка доступа по зашифрованному туннелю (опционально)
Для повышения безопасности можно заблокировать установку phpMyAdmin для всех хостов, кроме авторизованных. Вы можете внести доверенные хосты в белый список (в конфигурации Nginx), и любой запрос, поступающий с IP-адреса, которого нет в этом списке, будет отклонен.
Хотя в отдельных случаях одной этой функции может быть достаточно, в долгосрочной перспективе она не всегда является лучшим решением. Главным образом это потому, что большинство людей получают доступ к интернету не со статических IP-адресов. Как только вы получите новый IP-адрес от интернет-провайдера, вы не сможете получить доступ к интерфейсу phpMyAdmin, пока не обновите конфигурационный файл Nginx и не укажете новый IP-адрес.
Более надежным решением является управление доступом на основе IP: пользователи будут иметь доступ к интерфейсу phpMyAdmin, только если они используют доверенный IP-адрес или входят с локального хоста через SSH-туннели. Здесь мы расскажем, как настроить такой туннель.
Сочетая управление доступом на основе IP с туннелированием SSH, вы серьезно повысите безопасность сервера, поскольку это полностью блокирует общий доступ из интернета (за исключением авторизованных IP-адресов). Кроме того, такой метод обеспечивает безопасный канал между пользователем и сервером посредством зашифрованных туннелей.
Настройка доступа по IP
В Nginx управление доступом на основе IP можно определить в соответствующем блоке location с помощью директив allow и deny. Например, если вы хотите разрешить запросы, поступающие только с определенного хоста, вы должны включить в соответствующий блок location следующие две строки в таком порядке:
allow hostname_or_IP;
deny all;
Вы можете добавить любое количество хостов, для этого вам необходимо только добавить строку allow для каждого авторизованного хоста или IP в соответствующий блок location. Директивы будут оцениваться в том порядке, в котором они перечислены в файле, пока веб-сервер не найдет нужный адрес. Если этого не случится, запрос будет отклонен из-за директивы deny all.
Теперь нужно настроить Nginx так, чтобы он поддерживал только запросы от localhost или вашего текущего IP-адреса. Во-первых, вам нужно знать внешний IP-адрес локального компьютера. Есть разные способы получить эту информацию; для простоты можно использовать сервис ipinfo.io. Вы можете открыть URL-адрес https://ipinfo.io/ip в своем браузере или выполнить следующую команду на локальном компьютере:
curl https://ipinfo.io/ip
В выводе вы увидите IP-адрес:
203.0.113.111
Это и есть текущий внешний адрес локальной машины. Настройте блок location phpMyAdmin так, чтобы в дополнение к localhost он разрешал только те запросы, которые поступают с этого IP. Для этого нужно еще раз отредактировать конфигурационный блок phpMyAdmin в файле /etc/nginx/sites-available/example.com.
Откройте файл Nginx:
sudo nano /etc/nginx/sites-available/example.com
Поскольку в текущей конфигурации уже есть правило доступа, вам нужно объединить его с управлением доступом по IP через директиву satisfy all. Таким образом можно защитить текущую строку HTTP-аутентификации.
Вот так должна выглядеть конфигурация phpMyAdmin Nginx, когда вы закончите редактирование:
server {
. . .
location /nothingtosee {
satisfy all; #requires both conditions
allow 203.0.113.111; #allow your IP
allow 127.0.0.1; #allow localhost via SSH tunnels
deny all; #deny all other sources
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/pma_pass;
}
. . .
}
Вместо nothingtosee нужно задать расположение вашей установки phpMyAdmin, а условный IP-адрес нужно заменить вашим текущим внешним IP.
Сохраните и закройте файл. Убедитесь, что конфигурация не содержит ошибок:
sudo nginx -t
Если ошибок нет, команда выведет:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Затем перезапустите веб-сервер:
sudo systemctl reload nginx
Поскольку ваш IP-адрес явно указан в качестве авторизованного хоста, вы не потеряете доступ к установке. Но любой, кто попытается получить доступ к вашей установке phpMyAdmin, получит ошибку 403 (Forbidden). Чтобы убедиться в этом, откройте страницу в браузере:
https://server_domain_or_IP/nothingtosee
В следующем разделе мы расскажем, как использовать SSH-туннелирование для доступа к веб-серверу через локальные запросы. Так вы все равно сможете получить доступ к интерфейсу phpMyAdmin даже после изменения вашего IP-адреса.
Доступ к phpMyAdmin по SSH-туннелю
Туннелирование SSH – это перенаправление сетевого трафика через зашифрованные каналы. Команда ssh, которую вы использовали бы для входа на сервер, может создать зашифрованный «туннель» между локальной машиной и удаленным сервером. Весь трафик, поступающий на этот локальный порт, теперь будет перенаправлен через туннель, а удаленный сервер будет работать в качестве прокси-сервера, прежде чем выйти в интернет. Это похоже на то, что происходит при использовании VPN (виртуальной частной сети), однако SSH-туннелирование гораздо проще настроить.
Мы будем использовать SSH-туннелирование для передачи запросов на удаленный веб-сервер, где работает phpMyAdmin. Создав туннель между локальной машиной и сервером phpMyAdmin, вы сможете перенаправить локальные запросы на удаленный веб-сервер, и, что более важно, зашифровать трафик. При этом запросы будут поступать в Nginx так, как если бы они исходили от localhost. Независимо от того, с какого IP-адреса вы подключаетесь, вы сможете получить безопасный доступ к интерфейсу phpMyAdmin.
Поскольку трафик между локальной машиной и удаленным веб-сервером будет зашифрован, этот метод очень хорошо подходит для серверов phpMyAdmin, у которых нет сертификатов SSL/TLS.
На локальной машине запустите такую команду, чтобы получить доступ к phpMyAdmin:
ssh user@server_domain_or_IP -L 8000:localhost:80 -L 8443:localhost:443 -N
Команда состоит из таких элементов:
- user: SSH пользователь для подключения к серверу, на котором работает phpMyAdmin.
- hostname_or_IP: хост SSH, на котором работает phpMyAdmin.
- -L 8000:localhost:80 перенаправляет HTTP-трафик на порт 8000.
- -L 8443:localhost:443 перенаправляет HTTPS трафик на порт 8443.
- -N: отключает выполнение удаленных команд.
Примечание: Эта команда блокирует терминал до тех пор, пока вы не остановите ее комбинацией клавиш Ctrl+C, в этом случае она прервет соединение SSH и прекратит перенаправление пакетов. Чтобы запускать эту команду в фоновом режиме, вы можете использовать опцию -f.
Теперь перейдите в браузер и замените server_domain_or_IP на localhost:PORT, где PORT – это 8000 для HTTP или 8443 для HTTPS:
http://localhost:8000/nothingtosee
https://localhost:443/nothingtosee
Примечание: Если вы обращаетесь к phpMyAdmin по https, вы можете получить сообщение о безопасности SSL-сертификата. Это происходит потому, что используемый вами домен (localhost) не совпадает с адресом в сертификате (домен, по которому фактически обслуживается phpMyAdmin). Это сообщение можно просто проигнорировать.
Все запросы на localhost:8000 (HTTP) и localhost:8443 (HTTPS) теперь перенаправляются к вашему удаленному интерфейсу phpMyAdmin через безопасный туннель. Вы не только повысили уровень безопасности данных, отключив публичный доступ к phpMyAdmin, но и защитили весь трафик между локальным компьютером и удаленным сервером через туннель.
Чтобы включить принудительное использование SSH-туннелирования для всех, кто хочет получить доступ к вашему интерфейсу phpMyAdmin (включая вас), вы можете удалить из конфигурации Nginx все доверенные IP-адреса. Для доступа нужно оставить в качестве разрешенного хоста только 127.0.0.1. Учитывая, что никто не сможет отправлять прямые запросы к phpMyAdmin, лучше отключить HTTP-аутентификацию, чтобы упростить настройку. Вот как будет выглядеть ваш файл конфигурации в таком сценарии:
server {
. . .
location /nothingtosee {
allow 127.0.0.1; #allow localhost only
deny all; #deny all other sources
}
. . .
}
Перезапустите Nginx с помощью команды sudo systemctl reload nginx. После этого установка phpMyAdmin будет доступна только по SSH-туннелю.
Заключение
Теперь можно управлять MySQL при помощи надёжного и относительно безопасного интерфейса. Он предоставляет основные функции, доступные из командной строки MySQL: пользователь может просматривать базы данных, схемы, создавать запросы и новые наборы и структуры данных.
После выполнения этого мануала вы сможете управлять базами данных MySQL с помощью достаточно безопасного веб-интерфейса. Этот пользовательский интерфейс предоставляет большую часть функциональности командной строки MySQL. Вы можете просматривать базы данных и схемы, выполнять запросы и создавать новые наборы и структуры данных.
Tags: Debian 9, MySQL, NGINX, phpMyAdmin