Повышаем безопасность стека web-приложений (виртуализация LAMP, шаг 2/6)

Original author: Vivek Gite
  • Translation

Linux: Настройка сервера баз данных MySQL


Перейдем ко второму практическому уроку серии и поговорим о настройке виртуального окружения выделенного сервера – подготовим  узел (VM) предназначенный для хранения и обслуживания доступа к БД MySQL/PostgreSQL.

В этой установке, мы будем использовать сервер баз данных MySQL. Все настройки этого урока будут проводится исключительно на vm04 с IP-адресом 192.168.1.13

Установка сервера MySQL


Введите следующую команду yum-менеджера, что бы установить MySQL сервера баз данных на RHEL/CentOS Linux систему:

# yum install mysql mysql-server

Настройка сервера MySQL

Отредактируем файл /etc/my.cnf:

# vi /etc/my.cnf

Убедитесь, что MySQL сервер доступен с виртуальных машин vm01 и vm02 с установленными на нем Apache+php5. Найдите раздел [mysqld] и добавте/исправьте следующие параматеры, что бы mysqld служба БД стала доступна удаленно:

# Убедитесь, что директива skip-networking закомментирована (или удалена)
# skip-networking
# Включение удаленный доступ
bind-address=192.168.1.13


Оптимизация параметров MySQL-сервера

Необходимо оптимизировать сервер MySQL, иначе он отъест весомую часть ресурсов виртуальной машины vm04. Вы можете добавить или исправить настройки следующим образом (подробнее — в руководстве по MySQL).

########################################################################
# Внимание!!!
# Параметры безопасности и производительности
# Читайте манны mysqld и my.cnf для получения подробной информации
# т.к. следующие параметры зависят от установленного оборудования и
# конкретных требований к системе
########################################################################
# Из соображений безопасности рекомендуется отключить использование
# symbolic-links
symbolic-links=0

## Идем дальше, пропуская ряд прописанных параметров, YMMV
skip-name-resolve
skip-slave-start
skip-external-locking

# ИНДИВИДУАЛЬНЫЕ КЛИЕНТСКИЕ НАСТРОЙКИ              #
# Завышенные параметры, но мои ресурсы позволяют   #
sort_buffer_size           = 2M
read_buffer_size           = 2M
binlog_cache_size          = 1M
wait_timeout               = 200
interactive_timeout        = 300
max_allowed_packet         = 12M
thread_stack               = 128K
table_cache                = 1024
myisam_sort_buffer_size    = 1M
tmp_table_size             = 12M
max_heap_table_size        = 12M

# ПРОТОКОЛИРОВАНИЕ #
log_queries_not_using_indexes  = 1
slow_query_log                 = 1
slow_query_log_file            = /var/lib/mysql/slowquery.log

# Кэши и предельные значения #
tmp_table_size                 = 12M
max_heap_table_size            = 12M
query_cache_type               = 1
query_cache_limit              = 2M
query_cache_size               = 32M
max_connections                = 500
thread_cache_size              = 50
open_files_limit               = 65535
table_definition_cache         = 4096
table_open_cache               = 1024

# MyISAM #
key_buffer_size                = 32M
myisam_recover                 = FORCE,BACKUP

# БЕЗОПАСНОСТЬ #
max_allowed_packet = 16M
max_connect_errors = 1000000

# Бинарный лог #
log_bin                        = /var/lib/mysql/mysql-bin
expire_logs_days               = 14
sync_binlog                    = 1

# InnoDB #
innodb_flush_method            = O_DIRECT
innodb_log_files_in_group      = 2
innodb_log_file_size           = 256M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table          = 1
innodb_buffer_pool_size        = 10G

Сохраним изменения и закроем файл. Перезагрузим/перезапустим  сервер MySQL:

# chkconfig mysqld on
# service mysqld start
# service mysqld reload
# service mysqld restart

Убедимся, что на TCP-порту #3306 работает mysqld:

# netstat -tulpn | grep :3306


MySQL сервера баз данных конфигурации брандмауэра


Отредактируем конфигурацию брандмауэра /etc/sysconfig/iptables:

# vi /etc/sysconfig/iptables

Убедитесь, что виртуальные машины vm01 и vm02 могут получить доступ к серверу баз данных:

## Откройте порты mysqld для web-сервера Apache и Lighttpd #
-A INPUT -m state --state NEW -s 192.168.1.10 -m tcp -p tcp --dport 3306 -j ACCEPT
-A INPUT -m state --state NEW -s 192.168.1.11 -m tcp -p tcp --dport 3306 -j ACCEPT

Сохраните и закройте файл. Перезапустим службу iptables:

# service iptables restart


Увеличение дисковых квот и диапазона портов сервера БД


Для нагруженных серверов СУБД следует увеличить предельное количество дескрипторов файлов (FD limits) и увеличить число доступных IP-портов

# Увеличим предельное число  дескрипторов файловой системы
fs.file-max = 50000
# Увеличим число доступных портов
net.ipv4. ip_local_port_range = 2000 65000

Активируем изменения, введя следующую sysctl-команду, изменяющую параметры ядра Linux исходя из указанных нами настроек:

# sysctl -p


Создание баз данных MySQL и учетных записей пользователей


В данном разделе приводятся основные параметры ручного создания базы данных MySQL.Для наглятности нашей задачи мы создадим базу данных MySQL и пользователя со следующими параметрами:
  • ИМЯ БД: foo
  • ИМЯ ПОЛЬЗОВАТЕЛЯ БД: bar
  • ПАРОЛЬ БД: mypassword
  • КОМУ РАЗРЕШЕН ДОСТУП К БД: localhost, vm01, vm02 со следующими IP-адресами — 192.168.1.10 и 192.168.1.11


Введите следующую команду для создания БД и требующихся пользователей:

# /usr/bin/mysql -u root -h localhost -p

Чтобы создать БД с именем foo, введите следующую команду в строке терминала mysql:

mysql > CREATE DATABASE foo;


Необходимо предоставить права доступа к этой БД пользователю MySQL с именем bar, под которым сервера приложений Apache + php5 будут подключаться к БД.

mysql > GRANT ALL ON foo.* TO bar@localhost IDENTIFIED BY 'mypassword';
mysql > GRANT ALL ON foo.* TO bar@192.168.1.10 IDENTIFIED BY 'mypassword';
mysql > GRANT ALL ON foo.* TO bar@192.168.1.11 IDENTIFIED BY 'mypassword';

Что бы выйти из консоли MySQL, введите следующую команду:

mysql > quit

Теперь можно создавать таблицы или загрузить данные, используя SQL-файл. Вы можете автоматизировать эту процедуру, написав шелл- или Perl-скрипт добавления пользователей MySQL и баз данных.

Проверьте вашу новенькую БД и пользовательские настройки с «удаленных» vm01 и vm02


Подключитесь через ssh к виртуальному узлу vm01 или узлу vm03 и введите следующую команду, чтобы проверить связь с Apache/Lighttpd web-сервером:

$ mysql -u bar -h 192.168.1.13 -p'mypassword' foo

или так:

$ mysql -u bar -h vm04 -p'mypassword' foo


PhpMyAdmin


PhpMyAdmin – известный web-интерфейс к БД MySQL. Этот серверный скрипт используется для удаленного администрирования MySQL с помощью одного лишь браузера. PhpMyAdmin может администрировать как весь сервер MySQL, так и одну базу данных. Этот пакет рекомендуется для всех новых пользователей базы данных MySQL и администраторов.



Ссылки на продолжение в конце поста будут проставлены в течение недели, по мере перевода и при вашем желании слушать дальше этот перевод.

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 15

    0
    Ну о какой безопасности можно говорить, если:
    GRANT ALL ON foo.* TO bar@192.168.1.10 IDENTIFIED BY 'mypassword'
      0
      Вот-вот. Уж хотя бы на каждую БД по юзеру выделили.
        0
        А тут одна БД с одним пользователем. Просто этот пользователь будет прописан в конфигах, а у него права нераеально избыточные. Надеюсь дальше задумка автора как-то себя обнаружит. У нас ведь с БД собирается общаться не фронт-энд. Может есть тут какая-то логика, хоть и не очень ясная.
        0
        Сам в шоке. Главное-то не понятно «зачем». Сейчас поищу вменяемый текст по правам доступа
        SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES
        

        Или ссылку вменяемую.
        0
        Вообще-то если уж на то пошло, то я бы сделал следующее:

        1 — Перевесить Mysql на другой порт. При этом все, что ломиться на стандартный — в лог iptables.
        2 — Права на БД — сразу минимальные. Потом поднимать в случае возникновения ошибок.
        3 — Убрал бы вообще mysql с 127.0.0.1 — у меня на всех серверах стоит лог+дроп всего, что идет на localhost.
        4 — Ну и да — саму базу я бы перенес на отдельный раздел(проще всего и удобнее всего — симлинком) + изменение имени пользователя.
          0
          Интересное замечание. Можно уточнить?
          У нас БД висит на виртуалке 192.168.1.13/vm04,
          доступ к ней есть у пользователя foo с трех машин:

          192.168.1.13 - сам сервер БД
          192.168.1.10 - LightHTTPD/Nginx под статику
          192.168.1.11 - бэкенд Apache+php+...
          

          В iptables забит доступ к машине с БД

          -A INPUT -m state --state NEW -s 192.168.1.10 -m tcp -p tcp --dport 3306 -j ACCEPT
          -A INPUT -m state --state NEW -s 192.168.1.11 -m tcp -p tcp --dport 3306 -j ACCEPT
          

          1. В самих конфигах приложения (допустим установлен WPress) порт/логин/пароль будут фигурировать явным образом. Т.е. не понятно, от кого/чего мы защитимся, перевесив порты. Я вот пока не понимаю, зачем серверу статики доступ к БД, но это видимо станет ясно по ходу перевода. Ну или вернемся сюда позднее и внесем дополнительные примечания. Ваш коммент будет свидетелем. ;)

          Логирование — предложение более чем интересное. Я бы добавил к ссылке в статье об iptables, предложенной авторами оригинального материала, свой перевод. Как вам? Замечания/предложения?

          2. По поводу минимальных прав. Если пользователь foo — админ, то может быть пусть будут у него эти права? Он у нас удаленно может зайти только через phpMyAdmin на фронт/бэкэнд серверах апача и Nginx.
          Можно внести это в примечание к статье и дать ссылку или перевод на доп.статьи о правах. Авторы оригинального перевода тупо отослали к доками MySQL. А на хабре по этой теме ничего нет, вроде бы. Или я не нашел. Может вы какой-то материал/ссылку на эту тему видели? Или из перечисленного что-то хотелось бы иметь в переводном виде?

          www.greensql.com/articles/mysql-security-best-practices
          dev.mysql.com/doc/mysql-security-excerpt/5.6/en/index.html
          dev.mysql.com/doc/mysql-security-excerpt/5.6/en/topic-mysql-security-faq.html

          3. Вы предлагаете запретить доступ к БД с сервера БД? Уточните, я не совсем понимаю.

          4. Я так понял, вы предлагаете сделать так, как это описано в 7-м пункте приведенной чуть выше ссылки?
            0
            1 — Ну с одной стороны да — вроде бы перевешивание портов — дело крайне не обязательное, но в плане безопасности все просто:
            В случае каких-то косяков — первым делом ломиться будут по стандартным портам. В купе с логированием трафика — очень просто отследить, кто и откуда ломиться посмотреть нашу базу(пару раз я вылавливал таких интересующихся в совершенно неожиданных местах).

            2 — Тут тоже спорный вопрос по поводу прав — лично я видел довольно мало приложений, которым требуется дроп итд. Я предпочитаю забирать права на удаление, и отлавливать ошибки в логах — если есть ошибки и они по делу — тогда да — можно разрешить.(абсолютно аналогично я поступаю и с правами на файлы — давая минимальные права на группу, забирая право владения у пользователя).

            3 — Немного не так — я просмотрел в статье, что настраивается биндинг на ip. Просто к этому я бы еще добавил лог на 127.0.0.1 на необходимый порт, тк правильная ситуация — когда подключение идет с внешнего Ip, а не через шелл на сервере :)

            4 — Грубо говоря да. Тут еще довольно неосвещенный момент — обычно для баз, лично я использую отдельную хранилку, лун, раздел и прочее чтобы разделять I/O системы и базы.

            P.S. Вообще спасибо за проявленный интерес — я думаю, если добавить вышеприведенные ссылки, ваш топик будет крайне содержателен и полезен.
              0
              1. Если не скомпрометирован сервер приложения, то маловероятно, что мы дадим ломиться на машину с БД человеку извне. Если наше приложение — «говно дыряво», то пиши-пропало, на каком бы оно порту не весело. Либо делать пользователя БД «SELECT-only» с репликацией из сторонней админской базы. Ну это вообще я от балды сейчас говорю, так как не вижу вариантов защиты.
              2. Не представляю организации подобного в рамках классических open-source движков CMS. Или же это получится бредовариант из пункта №1 с зеркалированием «тайного сервера из бункера гитлера».
              3. Интересное замечание. Надо думать, как это провернуть с «динамическими разработчиками».
              4. Мне уже страшно подумать о том, какой оверхед и latency обретет такая система. А какие-то best-practics на эту тему есть почитать?

              Вы только не прощайтесь, разговор-то какой получился положительный. ;) А то я уже на шизофреника стал похож, рассуждая сам с собой, как можно это все поломать и защитить. «Сам себе пентест». ))

              Цитирую одного пользователя, очень он из интернета похож на приличного администратора, я потревожил его вопросом о качестве «построяемой» авторами туториала системы:

              «В статье фигня какая то, ну скомпроментировал я ваш сервер с исходниками сайта и апачем, ну посмотрел я пароли к mysql и кешу, ну написал простой скрипт и сделал дамп все себе на почту, какой-то защиты я там не вижу.

              Разделение на виртуальные машины хороший прием, так как позволяет распределять нагрузку, и более четко контролировать сервисы, а защитой от компрометации это не является, хотя и является шагом для её реализации. А вообще сложные пароли, хороший код, обновление по и защита по ip довольно хорошо защищают».

              Первый шаг. Хорошо, что не «последнее дело». Значит нужно искать второй шаг. 8) Хорошим топиком считаю те, где есть хорошие комментарии. Так что затея уже удалась и спасибо за участие, 0Lexx0.
                0
                1 — А вот это кстати довольно спорный момент — во время работы на одном белорусском сотовом операторе я был вынужден проводить аудит юниксовых серверов. Так вот был там один такой оракловый кластер, к которому кто-то снатил 22 порт. И в итоге раз в минуту туда шел коннект по ssh откуда-то из-за великого китайского файрволла. Я думаю, что никто не застрахован от такой ошибки.
                Или же допустим внутри dmz была сломана машинка на которой крутился VHCS для каких-то там хостинговых целей — если бы не снорт, думаю можно было огрести реальных проблем.

                2 — Из последнего — настраивал я с пол-года назад atlassian стек для одной конторы. Эти продукты использовали mysql. Ставил как было написано в мануале. После завершения инсталяции я там радостно ревоукнул половину прав(вот счас уже и не вспомню, что именно). Ругалась соотвественно только jira, а всякие fisheye, confluence и прочее — радостно продолжили работать. С одной стороны это все черевато проблемами и кучей потраченого времени на тюнинг, но с другой стороны — насколько приятнее на душе, когда ты знаешь, что у тебя все вылизано до предела.

                По поводу лэтенси — сложно сказать для малых баз это может быть безразлично, но на нагруженых — это не так. В любом случае — база должна висеть на быстром диске(очень быстром :) )Навряд ли целесообразно заниматься страйпингом для /var что-то там. Опять же — если это nas, das или еще -то что внешнее — скорее всего есть возможность адаптивной оптимизации либо же снапшотов и прочих вкусностей, что также бывает очень полезно. (ну это уже совсем не безопасность).

                А вообще — нет предела совершенству: Если есть время и есть деньги — виртуалки с разделением по сервисам + dmz с IDS или уже стразу IPS, но это уже совсем другая история, и такие телодвижения требуют значительно больших трудозатрат, чем перенос сервиса на другие порты.

                Для меня было очень познавательным выкидывание виртуальной машинки со снортом в интернет с днс записью admin.xxx.com. Божымой — чего я там насмотрелся.
            0
              0
              И еще с хабры момент один прощелкан: ~/mysql_history и безопасность
                0
                  0
                  Буду кэпом… Зачем в iptables эти правила, если в конце нет правила с -j DROP?
                    0
                    Аналогично — rhel и CentOS имеют дефолт полиси — DROP(либо же имеют вконце инпута явный дроп.)

                  Only users with full accounts can post comments. Log in, please.