Установка и защита phpMyAdmin+Nginx на сервере Ubuntu 18.04

Многим сайтам необходима база данных типа MySQL, однако интерфейс командной строки СУБД не очень дружественный и понятный, особенно для новичков.

Интерфейс phpMyAdmin был разработан, чтобы устранить эту проблему. Это альтернативный веб-интерфейс для работы с СУБД. В данном мануале речь пойдёт об установке и защите phpMyAdmin на сервере Ubuntu 18.04. В качестве веб-сервера используется Nginx – производительный сервер, способный обрабатывать большие нагрузки.

Примечание: Используя программы типа phpMyAdmin, следует соблюдать ряд правил безопасности – поскольку программа работает на сервере БД, она имеет доступ к учетным данным БД, что позволяет злоумышленникам легко отправлять произвольные SQL-запросы. Поскольку phpMyAdmin — это широко распространенное PHP-приложение, оно часто подвергается атакам. В этом мануале мы рассмотрим некоторые меры безопасности, которые могут вам пригодиться.

Требования

  • Сервер Ubuntu 18.04, настроенный по этому мануалу. Обязательно нужен пользователь с доступом к sudo.
  • Предварительно установленный сервер LEMP (Linux, Nginx, MySQL и PHP). Все необходимые инструкции вы найдете в мануале Установка стека LEMP в Ubuntu 18.04. Обязательно запишите или запомните пароль администратора MySQL.

Поскольку интерфейс phpMyAdmin напрямую связывается с вашей установкой MySQL и обрабатывает аутентификацию с использованием учетных данных, запускать phpMyAdmin на удаленных системах по простому HTTP-соединению ни в коем случае нельзя. Если у вас нет домена, защищенного сертификатом SSL/TLS, обратитесь к руководству Создание сертификата Let’s Encrypt для Nginx в Ubuntu 18.04.

Примечание: Если у вас нет SSL/TLS-сертификата, но вы хотите выполнить этот мануал, пожалуйста, рассмотрите варианты использования SSH-туннеля (об этом поговорим в разделе 5).

1: Установка phpMyAdmin

Предварительно установив платформу LEMP, можно сразу приступать к инсталляции phpMyAdmin. Пакеты этой программы можно найти в стандартных репозиториях Ubuntu.

Сначала обновите индекс пакетов системы.

sudo apt update

Затем используйте инструмент apt, чтобы загрузить пакеты из репозитория и установить их:

sudo apt install phpmyadmin

Во время установки будут запрошены дополнительные данные, например, веб-сервер, который нужно автоматически настроить (Apache или Lighthttp). Поскольку среди предложенных вариантов нет Nginx, просто нажмите Tab и Ok, чтобы продолжить.

Затем программа спросит, нужно ли настроить базу данных для phpMyAdmin при помощи dbconfig-common. Выберите Yes, чтобы продолжить. Это создаст внутреннюю БД и администратора для phpMyAdmin. Теперь нужно ввести пароль для пользователя MySQL по имени phpmyadmin. Если вы оставите это поле пустым, phpMyAdmin создаст случайный пароль.

Установка phpMyAdmin завершена. Чтобы Nginx мог найти и корректно обработать файлы phpMyAdmin, нужно создать симлинк на каталог document root сервера Nginx:

sudo ln -s /usr/share/phpmyadmin /var/www/html

Теперь phpMyAdmin полностью готов к работе. Чтобы открыть интерфейс, введите в браузер доменное имя или внешний IP-адрес и /phpmyadmin:

http://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» и не сможете войти в систему.

Поскольку ранее мы решили использовать dbconfig-common для настройки и хранения параметров phpMyAdmin, конфигурация по умолчанию в настоящее время хранится в базе данных. Сейчас нужно будет создать новый файл 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/default

В этот файл нужно внести новый раздел 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: пользователь может просматривать базы данных, схемы, создавать запросы и новые наборы и структуры данных.

Tags: , , , , ,