PostgreSQL không bao giờ biết rằng một máy khách đang ở trên VPN. Nó nhận một kết nối TCP từ một địa chỉ và một tập thông tin xác thực, rồi quyết định làm gì với chúng. Vì vậy, làm cho quyền truy cập phụ thuộc vào đường hầm nghĩa là sắp xếp ba quyết định riêng biệt sao cho chúng khớp nhau, sau đó kiểm tra một địa chỉ duy nhất mà máy chủ thực sự nhìn thấy thay vì địa chỉ bạn đã vẽ trên sơ đồ.

Ba quyết định không được hợp nhất

Máy chủ lắng nghe ở đâu là một quyết định. Lưu lượng nào có thể đến địa chỉ đó là quyết định thứ hai, do tường lửa của máy chủ và mọi ranh giới mạng phía trước nó đưa ra. Danh tính cơ sở dữ liệu nào được xác thực từ nguồn nào là quyết định thứ ba, được đưa ra trong pg_hba.conf.

Mỗi quyết định do một thành phần khác nhau thực thi, và mỗi quyết định thất bại với một thông báo khác nhau. Hợp nhất chúng trong một cuộc thảo luận là cách mọi người cuối cùng phải sửa tệp HBA để khắc phục sự cố tường lửa. Hãy giữ chúng theo thứ tự: một listener không được liên kết thì không thể tiếp cận, một cổng bị lọc thì không thể kết nối, và quy tắc HBA chỉ quyết định điều gì xảy ra sau khi kết nối tồn tại. Khi một thay đổi không có tác dụng, hãy xác định bạn thực sự đã thay đổi lớp nào trong ba lớp.

Máy chủ lắng nghe ở đâu

Liên kết với một địa chỉ thực sự được gán cho máy, không phải tên giao diện:

listen_addresses = '10.20.0.30'

Cơ sở dữ liệu có thể nằm sau cổng VPN mà không có giao diện đường hầm riêng, và đó chính là lý do địa chỉ là thứ đúng đắn để đặt tên. Thay đổi cài đặt này cần khởi động lại hoàn toàn; tải lại không đủ.

Sau đó lọc cổng, thường là 5432, trên máy chủ và tại mọi ranh giới phía trước nó. Liên kết với một địa chỉ riêng không phải là bằng chứng của việc từ chối công khai, vì chuyển tiếp cổng hoặc ánh xạ địa chỉ đám mây vẫn có thể gửi gói tin đến listener riêng đó.

Địa chỉ mà HBA thực sự nhìn thấy

Với quyền truy cập được định tuyến, máy chủ nhìn thấy địa chỉ đường hầm bên trong của từng máy khách. Với dịch địa chỉ nguồn, nó nhìn thấy địa chỉ đã dịch của cổng thay vào đó, và mọi máy khách đều thu gọn thành một giá trị duy nhất đó. Hãy kiểm tra nguồn thông qua bằng chứng kết nối của chính máy chủ trước khi chọn tiền tố để cho phép.

Đối với một triển khai đã dùng TLS và SCRAM, một ví dụ truy cập từ xa cố ý hẹp trông như sau:

hostssl appdb app_login 10.8.0.0/24 scram-sha-256
host all all 0.0.0.0/0 reject
host all all ::/0 reject

Điều đó cho phép một vai trò và một cơ sở dữ liệu qua TLS từ nhóm được nêu, sau đó từ chối quyền truy cập TCP từ xa khác. Đây không phải là sự thay thế cho một tệp HBA đầy đủ: hãy giữ quản trị cục bộ, sao chép và bất kỳ dịch vụ được ủy quyền nào khác, và đặt các quy tắc hẹp trước các cho phép rộng hơn.

Khi dịch địa chỉ diễn ra, HBA không thể phân biệt các máy khách bằng địa chỉ gốc của chúng. Hãy giữ chặt việc tiếp nhận mạng và yêu cầu thông tin xác thực cơ sở dữ liệu thật, và không bao giờ thay thế xác thực trust bằng một tài khoản thực.

Kết quả khớp đầu tiên thắng, không có dự phòng

PostgreSQL đọc tệp từ trên xuống dưới và dùng bản ghi đầu tiên khớp với kết nối. Không có lần thử thứ hai nếu xác thực của bản ghi đó thất bại, vì vậy một cho phép rộng trước đó sẽ âm thầm đánh bại một từ chối sau đó.

Quy tắc thứ tự đó là lý do phổ biến nhất khiến một từ chối được viết cẩn thận không bao giờ có hiệu lực. Đặt các quy tắc cụ thể trước và các quy tắc rộng cuối cùng, sau đó đọc tệp như một trình tự chứ không phải một tập hợp. Một quy tắc bạn thêm ở cuối không phải là chính sách, đó là chú thích. Hãy di chuyển nó lên và tải lại trước khi kết luận rằng tệp đang bị bỏ qua.

Tham chiếu HBA định nghĩa cả thứ tự và sự khác biệt giữa các bản ghi host và hostssl, điều này quan trọng khi mục đích của quy tắc là kết nối phải được mã hóa.

Tải lại, khởi động lại và trường hợp bị từ chối

Các thay đổi HBA được áp dụng bằng cách tải lại, và chế độ xem pg_hba_file_rules giúp bạn tìm lỗi phân tích cú pháp. Chế độ xem đó mô tả nội dung hiện tại của tệp, không phải việc máy chủ đang chạy đã tải chúng thành công hay chưa, vì vậy một danh sách sạch không phải là bằng chứng rằng các quy tắc mới đang hoạt động.

Các thay đổi đối với listener cần khởi động lại riêng, và hai thao tác này dễ bị nhầm lẫn khi một thay đổi có vẻ không có tác dụng.

Hãy kiểm tra với các phiên mới: một máy khách được chấp thuận với tài khoản dự định sẽ kết nối, cùng tài khoản đó từ một đường dẫn không được chấp thuận thì không, và một danh tính cơ sở dữ liệu không được ủy quyền vẫn thất bại từ bên trong VPN. Ba kết quả đó tách ranh giới mạng khỏi ủy quyền cơ sở dữ liệu, đó chính là toàn bộ mục đích của việc giữ các quyết định riêng biệt.

Bài viết liên quan