تونل بالا می‌آید، 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 همان چیزی است که اتصال بعدی را بد تشخیص می‌دهد.

مقالات مرتبط