Sửa lỗi PostgreSQL 'no pg_hba.conf entry for host'

beginner🌐 Networking2026-07-19| PostgreSQL 12, 13, 14, 15, hoặc 16 chạy trên Linux (Ubuntu/Debian/CentOS) hoặc Docker.

Error Message

FATAL: no pg_hba.conf entry for host "1.2.3.4", user "admin", database "prod_db", SSL off
#postgresql#quản-trị-cơ-sở-dữ-liệu#mạng#devops

Vấn đề

Gần đây tôi đã gặp bế tắc khi kết nối backend Node.js với một instance Postgres 15 mới. Các kết nối cục bộ (local) hoạt động hoàn hảo. Tuy nhiên, ngay khi tôi trỏ app server (IP 1.2.3.4) tới cơ sở dữ liệu, nó đã từ chối kết nối ngay lập tức.

PostgreSQL được thiết kế để bảo mật nghiêm ngặt. Nó từ chối mọi kết nối từ mạng bên ngoài trừ khi bạn liệt kê rõ ràng địa chỉ IP, người dùng và cơ sở dữ liệu đích vào danh sách trắng (whitelist). Nếu các quy tắc này không được thiết lập, máy chủ sẽ từ chối bắt tay và đưa ra lỗi FATAL.

Thông báo lỗi

FATAL: no pg_hba.conf entry for host "1.2.3.4", user "admin", database "prod_db", SSL off

Tại sao lỗi này xảy ra

Lỗi này thường do thiếu hai bước cấu hình sau:

  • Cửa đang khóa: Theo mặc định, Postgres chỉ lắng nghe trên localhost (127.0.0.1). Nó thậm chí sẽ không nhận thấy lưu lượng truy cập đến IP công cộng hoặc giao diện mạng riêng của máy chủ.
  • Bảo vệ nghiêm ngặt: Tệp pg_hba.conf đóng vai trò như một tường lửa ở cấp độ cơ sở dữ liệu. Nếu IP của client không khớp với một mục trong tệp này, Postgres sẽ ngắt kết nối ngay lập tức.

Bước 1: Mở trình lắng nghe (Listener)

Trước tiên, hãy đảm bảo cơ sở dữ liệu thực sự đang tìm kiếm lưu lượng mạng. Bạn cần tinh chỉnh tệp cấu hình chính.

Tìm tệp postgresql.conf của bạn. Trên Ubuntu, hãy kiểm tra /etc/postgresql/15/main/postgresql.conf. Nếu bạn đang sử dụng Docker, tệp này thường nằm bên trong volume dữ liệu đã được map.

sudo nano /etc/postgresql/15/main/postgresql.conf

Tìm cài đặt listen_addresses. Nó có thể đang bị chú thích (comment) hoặc được đặt thành 'localhost'. Hãy thay đổi nó để lắng nghe trên tất cả các giao diện:

# Cho phép máy chủ lắng nghe trên tất cả các giao diện mạng
listen_addresses = '*'

Lưu ý: Nếu bạn muốn bảo mật hơn, bạn có thể thay thế '' bằng địa chỉ IP riêng cụ thể của máy chủ.*

Bước 2: Ủy quyền cho IP của Client

Tiếp theo, bạn phải thông báo cho Postgres rằng IP 1.2.3.4 có quyền đăng nhập với tư cách người dùng admin vào cơ sở dữ liệu prod_db.

Mở tệp HBA (Host-Based Authentication) trong cùng thư mục:

sudo nano /etc/postgresql/15/main/pg_hba.conf

Thêm một dòng mới ở cuối cùng. Cú pháp tuân theo mẫu này: TYPE DATABASE USER ADDRESS METHOD.

# Cho phép một IP máy chủ ứng dụng cụ thể
host    prod_db    admin    1.2.3.4/32    scram-sha-256

# HOẶC cho phép toàn bộ subnet riêng (ví dụ: 10.0.0.0 đến 10.0.0.255)
host    prod_db    admin    10.0.0.0/24   scram-sha-256

Bạn nên sử dụng phương thức xác thực nào?

  • scram-sha-256: Tiêu chuẩn hiện đại cho Postgres 13 trở lên. Hãy sử dụng phương thức này.
  • md5: Phổ biến trong các thiết lập cũ (Postgres 12 trở xuống).
  • trust: Tránh sử dụng trong môi trường production. Nó cho phép bất kỳ ai truy cập mà không cần mật khẩu.

Bước 3: Tải lại cấu hình

Các thay đổi cấu hình sẽ không có hiệu lực cho đến khi bạn thông báo cho dịch vụ. Bạn không phải lúc nào cũng cần khởi động lại toàn bộ, điều này rất tốt để tránh thời gian ngừng hoạt động (downtime).

Chạy lệnh này từ terminal để khởi động lại dịch vụ:

sudo systemctl restart postgresql

Ngoài ra, nếu bạn đã ở trong một phiên psql, bạn có thể tải lại cấu hình mà không làm ngắt kết nối của người dùng hiện tại:

SELECT pg_reload_conf();

Kiểm tra kết nối

Quay lại máy từ xa (1.2.3.4) và thử kết nối. Sử dụng cờ -h để chỉ định IP của máy chủ cơ sở dữ liệu:

psql -h 10.0.0.50 -U admin -d prod_db

Nếu bạn thấy yêu cầu nhập mật khẩu, bạn đã thành công. Nếu kết nối bị treo, hãy kiểm tra lại các nhóm bảo mật đám mây (như AWS SG) hoặc tường lửa cục bộ (UFW). Cổng 5432 phải được mở cho lưu lượng truy cập đến.

Mẹo chuyên nghiệp cho môi trường Production

Đừng lạm dụng 0.0.0.0/0 trong tệp pg_hba.conf của bạn. Mặc dù nó giúp mọi thứ hoạt động ngay lập tức, nhưng nó sẽ để lộ cơ sở dữ liệu của bạn với toàn bộ internet. Luôn thu hẹp quyền truy cập vào các dải CIDR cụ thể.

Khi quản lý các VPC phức tạp với nhiều subnet, tôi thường sử dụng Trình tính toán Subnet trên ToolCraft. Đây là một cách nhanh chóng để có được ký hiệu CIDR chính xác cho một dải IP, giúp tôi không vô tình cấp quyền cho nhiều hơn mức cần thiết. Nó dựa trên trình duyệt và giữ dữ liệu cục bộ, hoàn hảo cho các bản sửa lỗi mạng nhanh chóng.

Finally, nếu nhật ký của bạn vẫn đề cập đến SSL off nhưng chính sách bảo mật của bạn yêu cầu mã hóa, hãy thay đổi TYPE từ host thành hostssl. Điều này buộc client phải thiết lập một đường truyền mã hóa trước khi gửi thông tin đăng nhập.

Related Error Notes