суБД — Безопасность Данных

    В ходе реализации нового проекта заказчик часто задаёт вопрос о том, каким образом защищена внедряемая СУБД. Один из вероятных ответов (неправильный на мой взгляд): «БД находится во внутреннем периметре вычислительной сети и недоступна для злоумышленника». По статистике инсайдеры более опасны, так как у них есть возможность легитимно исследовать уязвимости в предоставленных сервисах.

    Предлагаю попробовать самостоятельно настроить уже имеющийся функционал, позволяющий повысить уровень защищённости вашей системы.

    Предисловие: мне поручили задачу по написанию утилитки, которая должна проверять настройки PostgreSQL. В этой статье я хочу поделиться аналитикой возможностей данной СУБД, используемых для предотвращения несанкционированного доступа.

    1. Обновление программного обеспечения.


    Однозначно нужно стараться ставить последнюю версию софта или специальных патчей для закрытия обнаруженных интернет-сообществом уязвимостей. На момент написания стати это — 9.5.4. Далее мы будем изменять параметры в файле postgresql.conf из каталога PGDATA, так как все из них требуют перезапуска службы СУБД.

    2. Установка нестандартных настроек


    Изменим порт подключения:

    port = '5333'

    Конечно nmap обнаружит сервис postgres, однако детектировать активное сканирование в сети легче, чем точечное обращение к целевому хосту. При желании можно задействовать port knocking.

    3. Ограничение числа возможных подключений


    Явно указываем ip-пользователей. Пользователям не часто выдают доступ к написанию SQL-запросов, поэтому ограничиваем количество продуктивных серверов:

    listen_addresses = 'ip_1, ip_2, ip_3'

    Изменяем максимальное количество одновременных подключений (+1 для суперюзера или репликации). По умолчанию стоит значение 100 (видимо исходя из работы с web-сервером), но если у вас стандартная связка с пулом 1С, то устанавливаем:

    max_connections = '4'

    В файле pg_hba.conf убираем записи host, hostnossl и local (последний — если не используются доменные сокеты Unix). Оставляем\устанавливаем только hostssl.

    Убираем стандартную учётную запись postgres и параметры all: для DATABASE указываем конкретное имя БД, а для USER — имя пользователя, которому разрешено подключение.

    В поле METHOD записываем тип аутентификации пользователя + дополнительные опции. В моём примере проверяем валидность пользователей по сертификатам SSL, то есть добавляем параметр cert. У нас получаются строчки вида:

    hostssl    test_database             test_user             192.168.23.2/24           cert 

    Вообще здесь много свободы для фантазии, так как в postgres реализовали совместимость с GSS, SSPI, IDENT, LDAP, RADIUS и PAM.

    4. Усложнение подбора пароля.


    Ограниченим время для аутентификации на СУБД:

    authentication_timeout = '1s'

    Если не используется прямой доступ человеков, то я бы поставил значение «1s» — достаточно для ввода корректной парольной информации роботом, но недостаточно для полноценного брутфорса. Скрываем при помощи MD5 пароли пользователей PostgreSQL:

    password_encryption = 'on'

    Требуем, чтобы в случае успешного подключения СУБД проводила проверку доступа пользователя к БД. В случае активации этой настройки пользователей придётся создавать в формате <имя_пользователя>@<имя_рабочей_БД>.

    db_user_namespace = 'on'

    Если хотим использовать аутентификацию GSSAPI — устанавливаем:

    krb_server_keyfile = 'файл_гсcапи'
    krb_caseins_users = 'on' 
    

    Примечание: Имена становятся регистрозависимыми. При использовании этой настройки пользователям нужно создавать имена в формате <имя_пользователя>@<имя_домена>. Соответственно db_user_namespace нужно переключить в режим off.

    5. Использование архитектурных особенностей


    Если у вас используется репликация, то можно ограничить количество репликантов при помощи параметров max_wal_senders = 2 и max_replication_slots = 2. Потенциальный злоумышленник даже если и получит доступ к БД, то не сможет сразу скачать все данные бэкапом при условии, что ваши реплики находятся в рабочем состоянии.

    Хотя дефолтный уровень изоляции REPEATABLE READ в Postgres более строгий, чем того требует ISO/IEC 9075, тот же стандарт SQL рекомендует использовать:

    default_transaction_isolation = 'serializable'

    Можно задать default_transaction_read_only = on, а затем создать триггер, который будет срабатывать на изменение уровня транзакций в сессии. Таким образом можно вести журнал вносимых изменений в СУБД.

    6. Шифрование канала передачи данных


    Включаем ssl — защищаем КПД между PostgreSQL и клиентом:

    ssl = 'on'
    ssl_ciphers = 'HIGH:+3DES:!aNULL'
    

    Параметр !aNULL запрещает вход анонимных юзеров. На всякий случай явно указываем, что наш сервер будет диктовать свои правила при установлении защищённого соединения (по дефолту так и работает):

    ssl_prefer_server_ciphers = 'on'

    Генерим сертификаты для SSL — можно по этой инструкции. Учитываем что Postgres требует идентичности имени выданного сертификата и имени пользователя, который производит подключение. Если используем винду, то на неё можно поставить OpenSSL и выполнять те же команды. Сертификаты по умолчанию должны находиться в PGDATA:

    • сертификат нашей СУБД (без ключа):

      ssl_cert_file = 'серт.crt'	
      

    • ключ для СУБД:

      ssl_key_file = 'ключ.key'
      

    • если хотим отслеживать цепочки сертификатов, то добавляем сертификат удостоверяющего центра (УЦ):

      ssl_ca_file = 'ваш_са.crt'	
      

    • при активации предыдущего пункта можно отслеживать список отозванных сертификатов (СОС):

      ssl_crl_file = 'ваш_сос.crl'
      

    Перезапускаем службу postgresql, проверяем отсутствие ошибок. На стороне пользователя устанавливаем цепочку сертификатов. Проверить корректность подключения можно при помощи утилиты psql с параметрами:

    psql -U test_user sslcert=test_user.crt
    

    Вывод в случае успешного подключения:

    SSL-соединение (протокол: TLSv1.2, шифр: ECDHE-RSA-AES256-GCM-SHA384, бит: 256)
    

    Послесловие: Начиная с версии 9.5 была добавлена политика безопасности строк. Про неё и использование нативного шифрования данных в БД надеюсь у меня получиться написать отдельный текст.
    • +10
    • 9.1k
    • 3
    Share post

    Comments 3

      0
      Не смотрели hardening STIG для EDB Postgres Advanced Server на http://iase.disa.mil/stigs/Pages/a-z.aspx?
      Если бы я был клиентом, я бы спросил о соответствии ему.
        0
        шикарно — если бы все клиенты были столь осведомлены, то я б работал на вас почти за даром)). Попробую прикрутить PEM Thick Client к посгресу. Первое, что вручную нашёл: Verify that pg_hba.conf is not using: “trust”, “md5”,… (пошёл парсить xml))).
          0

          Set all rows to have TYPE of "hostssl" and METHOD of "cert" и будет вам счастье))...

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