Тунель піднімається, QGIS підключається, і вхід обривається помилкою сертифіката, у якій названо 127.0.0.1 замість хоста бази даних. Наступний спокусливий крок — послабити sslmode, що заглушує перевірку і відкидає ту гарантію ідентичності, якої ви насправді хотіли. Справжня проблема в тому, що локальний порт і ім’я сервера зберігаються в одному полі. Запис служби libpq розділяє їх, тому сокет іде на проброшений порт, а TLS і далі перевіряє ім’я, надруковане в сертифікаті.

До чого клієнт думає, що підключається

За sslmode=verify-full libpq порівнює сертифікат, який представляє сервер, із запитаним ім’ям хоста. Якщо це ім’я — адреса loopback, порівняння не проходить, хоча сертифікат дійсний для справжнього хоста бази даних. SSH-проброс змінює те, який сокет переносить байти, а не ідентичність, яку клієнт має очікувати. Щойно ці дві ідеї розділено, помилка перестає виглядати як збій TLS.

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

Прив’яжіть проброс лише до loopback

Слухач має існувати на машині QGIS і ніде більше. Явна вказівка 127.0.0.1 тримає його осторонь інших інтерфейсів, а пропущена адреса прив’язки може відкрити порт назовні залежно від налаштувань шлюзу SSH-клієнта.

ssh -N -L 127.0.0.1:15432:127.0.0.1:5432 [email protected]

Призначення після другої двокрапки визначається на боці SSH-сервера, тому цей приклад припускає, що PostgreSQL розташований на тому самому хості, що й sshd; базі даних на іншій машині потрібні ця адреса та її дозволи. Запустіть сеанс із -N, щоб не відкривалася жодна оболонка, не чіпайте перевірку ключа хоста і переконайтеся, що слухач з’явився, перш ніж звинувачувати QGIS. Якщо порт уже зайнятий, проброс завершується помилкою під час запуску, а не під час запиту.

Розмістіть ім’я та сокет в одному записі служби

Файл служби дозволяє тому самому з’єднанню нести ім’я для перевірки та інше призначення сокета. Збережіть запис там, де libpq шукає служби, або спрямуйте PGSERVICEFILE на нього.

[gis-via-ssh]
host=db.geo.example
hostaddr=127.0.0.1
port=15432
dbname=gisdb
user=gis_reader
sslmode=verify-full
gssencmode=disable
sslrootcert=/path/to/approved-root.crt

Тут host зберігає ідентичність, яку використовують для перевірок сертифіката, а hostaddr надсилає пакети на проброшений порт loopback, і для роботи такої схеми потрібні обидва. gssencmode=disable важливе в збірках, які інакше спершу узгоджували б шифрування GSSAPI, бо цей шлях ігнорує щойно задані налаштування TLS. Посилайтеся на службу за іменем із діалогу підключення PostgreSQL у QGIS і передавайте пароль через звичайний запит, а не всередині спільного файлу. Назви та шляхи вище — це заповнювачі; замініть їх своїми затвердженими значеннями.

Що PostgreSQL ще перевіряє після тунелю

Сервер бачить з’єднання з хоста SSH, у цій схемі — з loopback, і по черзі зіставляє його з правилами автентифікації за хостом. Вашій ролі в базі даних усе ще потрібно автентифікуватися, а вхід через SSH сам по собі не дає ідентичності в базі даних. Перевіряйте, що вважає сервер, а не що припустив клієнт.

psql "service=gis-via-ssh" -c "select inet_server_addr(), current_user"

Закрийте сеанс пробросу, коли роботу завершено; локальний запис тоді перестає працювати, і більше нічого не змінюється. Один шлях до бази даних — не VPN для всього клієнта GIS, і саме ставлення до нього як до VPN призводить до неправильної діагностики наступного з’єднання.

Схожі статті