як забезпечити відкритий порт PostgreSQL


29

Отже, така ситуація. Здається, нам потрібен відкритий TCP-порт 5432 у світі, де клієнт має доступ до своєї бази даних PostgreSQL.

З очевидних причин, ми не можемо сказати просто «ні», лише як останній захід.

Які найбільші неприємності? Як я можу захистити нашу інфраструктуру?

У будь-якому разі: чому б його не відкрити світові? Я думаю, можливо, це більш безпечно, ніж якийсь 20-річний, непідтримуваний FTP-сервер.

PS VPN не в порядку. Можливо, якесь шифрування (якщо я можу дати йому URL-адресу з'єднання JDBC, який працює ).


4
SSH тунелі - це не варіант? У цій статті про фактично використовується PostgreSQL як приклад. Ви можете надати клієнту заздалегідь налаштований клієнт SSH для полегшення підключення.
Люцифер Сем

@LuciferSam. Ні. Db буде використовуватися власним розробленим додатком java на близько 100 машин компанії. Наш єдиний спосіб налаштувати їх - надати URL-адресу з'єднання jdbc їх адміністрації локальної мережі, будь-який інший дуже-дуже проблематичний.

@milkman що робить додаток? можливо, він може замість цього запросити сервер RESTful? Очевидно, що передача SQL в REST нічого не отримує, але якщо припустити, що це CRUD ..
tedder42

@ tedder42 Він маніпулює базою даних CMS користувачів, яка розміщується і нами. У нас немає дозволу змінювати джерело.

Відповіді:


41

Потрібна SSL, увімкніть SELinux, стежте за журналами та використовуйте поточну версію PostgreSQL .

Сторона сервера

Потрібна SSL

У postgresql.confнаборі ssl=onі переконайтеся , що у вас є файл_ключа і CERTFILE встановлені належним чином (див документації та коментарі в postgresql.conf).

Можливо, вам доведеться придбати сертифікат у ЦА, якщо ви хочете, щоб клієнти йому довіряли без спеціальних налаштувань на клієнта.

У pg_hba.confвикористанні щось на кшталт:

hostssl theuser thedatabase 1.2.3.4/32 md5

... можливо, з "всім" для користувача та / або бази даних та, можливо, із ширшим фільтром IP-адреси джерела.

Обмежте користувачів, які можуть увійти, відмовити у віддаленому вході в систему суперпользователя

Не дозволяйте "все" для користувачів, якщо можливо; ви не хочете віддаляти дозвіл на вхід суперпользователя, якщо ви можете уникнути необхідності.

Обмежте права користувачів

Обмежте права користувачів (користувачів), які можуть увійти. Не дайте їм CREATEDBчи CREATEUSERправ.

REVOKECONNECTправо з PUBLICусіх баз даних, а потім повернути його назад тільки користувач / ролі , які повинні бути в змозі отримати доступ до цієї бази даних. (Групуйте користувачів на ролі та надайте права на ролі, а не безпосередньо окремим користувачам).

Переконайтеся, що користувачі з віддаленим доступом можуть підключатися лише до необхідних БД і мати лише права на схеми, таблиці та стовпці в межах, які вони насправді потребують. Це хороша практика і для місцевих користувачів, це просто розумна безпека.

Налаштування клієнта

У PgJDBC передайте параметрssl=true :

Щоб доручити драйверу JDBC спробувати встановити SSL-з'єднання, потрібно додати параметр URL-адреси підключення ssl = true.

... і встановіть серверний сертифікат у довіре клієнта або використовуйте сертифікат сервера, якому довіряється один із ЦС у вбудованому довіреному сховищі Java, якщо ви не хочете, щоб користувач мав встановити cert.

Постійні дії

Тепер переконайтесь, що ви постійно оновлюєте PostgreSQL . У PostgreSQL було лише декілька попередніх аукціонів, але це більше ніж нуль, тому будьте в курсі. У будь-якому випадку, ви повинні виправити помилки.

Додайте брандмауер попереду, якщо є великі мережеві блоки / регіони, до яких ви знаєте, що вам ніколи не потрібен доступ.

Підключення та відключення журналу (див. postgresql.conf). Запитуйте журнал, якщо це практично. Запустити систему виявлення вторгнень або несправність2ban або подібне попереду, якщо це можливо. Для fail2ban з postgres тут є зручне керівництво

Контроль файлів журналу.

Бонусна параноїя

Додаткові кроки для роздумів ...

Потрібні клієнтські сертифікати

Якщо ви хочете, ви також pg_hba.confможете вимагати, щоб клієнт представив клієнтський сертифікат X.509, якому довіряє сервер. Тут не потрібно використовувати той самий CA, що і сервер cert, ви можете зробити це за допомогою homebrew openssl CA. Користувачеві JDBC потрібно імпортувати клієнтський сертифікат у keytoolсвою сховище Java за допомогою та, можливо, налаштувати деякі властивості системи JSSE, щоб вказати Java на їхній сховище клавіш, тому це не зовсім прозоро.

Карантинний примірник

Якщо ви хочете бути дійсно параноїком, запустіть екземпляр для клієнта в окремому контейнері / VM або, принаймні, під іншим обліковим записом користувача, лише з потрібними базами даних.

Таким чином, якщо вони скомпрометують екземпляр PostgreSQL, вони більше не отримають.

Використовуйте SELinux

Я не повинен був цього говорити, але ...

Запустіть машину з підтримкою SELinux, наприклад RHEL 6 або 7, і не вимикайте SELinux і не перемикайте його на дозвільний режим . Тримайте його в режимі примусового виконання.

Використовуйте порт, який не використовується за замовчуванням

Безпека лише незрозумілістю - це дурість. Безпека, яка використовує трохи невідомості, як тільки ви зробите розумні речі, ймовірно, не зашкодить.

Запустіть Pg на порт, який не використовується за замовчуванням, щоб зробити життя трохи важчим для автоматизованих нападників.

Поставте проксі спереду

Ви також можете запустити PgBouncer або PgPool-II перед PostgreSQL, виконуючи функції пулу з'єднань та проксі. Таким чином ви можете дозволити проксі обробляти SSL, а не справжній хост бази даних. Проксі-сервер може бути на окремому ВМ або на машині.

Використання проксі-серверів для об'єднання підключень, як правило, хороша ідея з PostgreSQL, якщо тільки у клієнтського додатка вже немає вбудованого пулу. Більшість серверів додатків Java, Rails тощо мають вбудований пул. Навіть тоді проксі-сервер об'єднання на стороні сервера в гіршому випадку нешкідливий.


3
Якщо у клієнта є статичний $ IP, дозвольте це також пройти через брандмауер до $ port.
user9517 підтримує GoFundMonica

Велике спасибі! У Pgjdbc є цей парам, але я можу надати йому лише URL-адресу з'єднання jdbc, і я не впевнений, чи він буде працювати з його додатком java (захищеним, невиправленим). Гаразд, якщо ні, я поставлю нове запитання. Дякую за детальну відповідь!

1
@lesto Власне, я думаю, що показ VPN значно збільшує поверхню атаки порівняно з однією службою з обмеженим доступом. Люди забувають, що VPN потім стає каналом атаки для будь-якого зловмисного програмного забезпечення на віддалених машинах, щоб пробити всю безпеку периметра і потрапити до кишок мережі. Я вважаю їх прийнятними лише в тому випадку, якщо вони підключаються до DMZ, який вважає їх такими ж токсичними, як і Інтернет-господарі.
Крейг Рінгер

1
@CraigRinger Я не кажу, щоб зняти іншу частину захисту, а щоб інкапсулювати службу у VPN
Lesto

1
@lesto Звичайно, погоджено, VPN може бути корисним додатковим шаром, якщо він не трактується як Magic Security Sauce, як це роблять багато адміністраторів.
Крейг Рінгер

2

Просте розширення до вражаючого плану дій Крейга:

Можливо, користувач користується лише відносно невеликим набором мережевих провайдерів (наприклад, його провайдер мобільної мережі під час переїзду, його кабельна мережа з дому та на робочому місці, що виходить з роботи на робочому місці).

Більшість постачальників мереж мають багато IP-адрес, але насправді не багато підмереж. Отже, ви можете надати фільтр iptables, який обмежує доступ postgresql до мережевих сегментів, які використовує ваш клієнт. Це значно зменшило можливості атаки випадково вибраних джерел проблем мережі.

Простий сценарій підтримки:

  1. Ваш клієнт закликає вас: "Не можу ввійти" .
  2. З tcpdump -i eth0 -p tcp port 5432командою ви дізнаєтесь , звідки він походить.
  3. За допомогою whois 1.2.3.4ви можете отримати ip-адресу, використану цим ip. Наприклад, це може бути 1.2.3.0/24.
  4. За допомогою iptables -A INPUT -s 1.2.3.0/24 -p tcp --dport 5432 -j ACCEPT(або якогось подібного) ви дозволяєте tcp з'єднатись із його новою підмережею.

Існує дуже хороший сценарій Perl, який називається uifпостійним та інтуїтивно зрозумілим набором правил iptables. (Google для "uif iptables").


1
Цікава ідея, але це здається трохи крихким.
nishantjr

@nishantjr Звичайно, це не окреме рішення, а лише можливість покращити справи.
Peterh каже відновити Моніку

Більш практичним підходом може бути білий список окремих Інтернет-провайдерів та / або країн, наприклад, як це зробити, наприклад, stackoverflow.com/questions/16617607/…
Йосип Родін,

1

Ось досить проста конфігурація Fail2ban для PostgreSQL, що базується на зв’язаному вище HOWTO, але налагоджена для фактичної роботи з пакетами Ubuntu, вкажіть ще одну умову помилки та пропустіть різні повідомлення про налагодження, щоб зробити це швидше:

/etc/fail2ban/filter.d/local-postgresql.conf:

[Definition]

failregex = <HOST>\(\d+\) FATAL:  password authentication failed for .+$
            <HOST>\(\d+\) FATAL:  no pg_hba.conf entry for host .+$

ignoreregex = duration:

/etc/fail2ban/jail.d/local-postgresql.conf:

[local-postgresql]
enabled  = true
filter   = local-postgresql
action   = iptables[name=PostgreSQL, port=5432, protocol=tcp]
           sendmail-whois[name=PostgreSQL, dest=root@localhost]
logpath  = /var/log/postgresql/postgresql-9.3-main.log
maxretry = 3

1

Fail2ban - це потужний інструмент, але не варто вірити, що фільтр працюватиме як є. Тестуйте будь-які фільтри за допомогою інструмента failregex і пам’ятайте, щоб уникнути будь-яких лапок (тобто «адміністратор» був би \ «адміністратор \»). Як приклад, тестування наступного рядка відключення фільтра з мого /etc/log/postgresql/postgresql-9.3-main.log не працювало для мене.

fail2ban-regex '2016-09-20 14:30:09 PDT FATAL:  password authentication failed for user "admin"' '<HOST>\(\d+\) FATAL:  password authentication failed for .+$'

Сказане мені дало

Failregex: 0 всього

Мені довелося оновити файл failregex, щоб він відповідав формату журналу.

fail2ban-regex '2016-09-20 14:30:09 PDT FATAL:  password authentication failed for user "admin"' 'FATAL:  password authentication failed for user \"<HOST>\"'

Це дало мені позитивний результат.

Failregex: 1 усього

Тест fail2ban-regex також може бути реалізований для цілих файлів журналу.

fail2ban-regex /var/log/postgresql/postgresql-9.3-main.log /etc/fail2ban/filter.d/postgresql.local

Сказане дало мені наступний позитивний результат із оновленим провалом.

Failregex: 169 всього

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.