PostgreSQL'e başka bir makineden bağlanabilmek için iki dosyayı birlikte ayarlamanız gerekir. postgresql.conf içindeki listen_addresses sunucunun hangi ağ arayüzlerinde bağlantı kabul edeceğini belirler; varsayılan değer localhost olduğu için kurulumdan sonra uzaktan bağlantı mümkün değildir ve bu parametre ancak sunucu yeniden başlatılınca değişir. pg_hba.conf ise gelen bağlantının hangi veritabanına, hangi kullanıcıyla, hangi adresten ve hangi doğrulama yöntemiyle kabul edileceğini satır satır tanımlar. Uzak bağlantı için tipik bir satır host stok siparis_api 203.0.113.25/32 scram-sha-256 biçimindedir; dosyayı değiştirdikten sonra SELECT pg_reload_conf() ya da pg_ctl reload ile yeniden yüklersiniz.

Bu yazıda pg_hba.conf satır biçimini, bağlantı türlerini (local, host, hostssl), veritabanı ve kullanıcı alanlarındaki özel sözcükleri, doğrulama yöntemlerini, ilk eşleşen satır kuralını, pg_hba_file_rules görünümüyle kontrol yapmayı ve sık görülen hata mesajlarını göreceksiniz. Örnekler PostgreSQL 18.1 üzerinde, parola doğrulamasıyla kurulmuş ayrı bir test kümesinde çalıştırıldı. Rollerin ve parolaların oluşturulması kullanıcı ve rol yönetimi yazısında, bağlantının şifrelenmesi SSL/TLS yazısında anlatılıyor; serinin tamamı için PostgreSQL öğrenme rehberi sayfasına bakabilirsiniz.

İki ayrı katman: listen_addresses ve pg_hba.conf

Bağlantı denemesi sunucuya iki kapıdan geçerek ulaşır. Birinci kapı listen_addresses parametresidir. Değer virgülle ayrılmış bir adres ya da ad listesidir; * bütün arayüzleri, 0.0.0.0 bütün IPv4 adreslerini, :: bütün IPv6 adreslerini ifade eder, boş liste ise TCP/IP'yi tamamen kapatıp yalnızca Unix soketine izin verir. port varsayılan olarak 5432'dir ve bütün adresler için aynıdır. İkisi de yalnızca sunucu başlarken okunur. Belgeler, istemci doğrulaması ince ayar sağlasa da listen_addresses değerini daraltmanın güvensiz arayüzlerden gelen tekrar eden kötü niyetli denemeleri baştan kesmeye yardım ettiğini belirtir.

Test kümemizde bu değerleri SHOW ile kontrol ettik, ardından ALTER SYSTEM ile listen_addresses değerini değiştirip yapılandırmayı yeniden yükledik:

sql
SHOW listen_addresses;     -- sonuç: 127.0.0.1
ALTER SYSTEM SET listen_addresses = '127.0.0.1,localhost';
SELECT pg_reload_conf();
SELECT name, setting, context, pending_restart FROM pg_settings
WHERE name IN ('listen_addresses', 'port');
text
       name       |  setting  |  context   | pending_restart 
------------------+-----------+------------+-----------------
 listen_addresses | 127.0.0.1 | postmaster | t
 port             | 46461     | postmaster | f
(2 rows)

context sütunundaki postmaster değeri, parametrenin yalnızca sunucu başlangıcında uygulanabileceğini; pending_restart = t ise yeni değerin dosyada beklediğini ama henüz etkin olmadığını gösterir. Sunucu günlüğü de aynı şeyi söyledi: parameter "listen_addresses" cannot be changed without restarting the server. Parametre bağlamları ve ALTER SYSTEM ayrıntısı postgresql.conf yazısında var. İkinci kapı olan pg_hba.conf ise kümenin veri dizininde bulunur; tam yolunu SHOW hba_file verir.

pg_hba.conf satır biçimi

pg_hba.conf satır biçimi: local, host, hostssl, hostnossl

Dosya, her satırı bir kayıt olan düz bir metindir. Boş satırlar ve # sonrasındaki yorumlar yok sayılır, alanlar boşluk ya da sekmeyle ayrılır, satır sonundaki ters bölü işareti kaydı bir alt satıra taşır. Bir kayıt şu alanlardan oluşur:

ini
# TÜR      VERİTABANI   KULLANICI   ADRES             YÖNTEM          [SEÇENEKLER]
local      database     user                          auth-method     [auth-options]
host       database     user        address           auth-method     [auth-options]
hostssl    database     user        address           auth-method     [auth-options]
hostnossl  database     user        address           auth-method     [auth-options]
TürEşleştiği bağlantı
localUnix soketi üzerinden gelen bağlantılar; bu türde satır yoksa soket bağlantısı reddedilir
hostTCP/IP bağlantıları, SSL olsun ya da olmasın
hostsslYalnızca SSL ile şifrelenmiş TCP/IP bağlantıları; sunucuda ssl açık değilse satır uyarı verip yok sayılır
hostnosslYalnızca SSL kullanmayan TCP/IP bağlantıları
hostgssenc, hostnogssencGSSAPI şifrelemesi olan ya da olmayan TCP/IP bağlantıları

Veritabanı alanı belirli bir ad, virgülle ayrılmış bir liste ya da özel bir sözcük alabilir: all bütün veritabanları, sameuser kullanıcı adıyla aynı adlı veritabanı, samerole kullanıcının veritabanıyla aynı adlı rolün üyesi olması, replication ise fiziksel replikasyon bağlantıları demektir. / ile başlayan değer düzenli ifade olarak yorumlanır, @dosya ise adları ayrı bir dosyadan okur.

Kullanıcı alanında all, belirli bir rol adı, / ile başlayan bir düzenli ifade ya da başında + olan bir grup adı kullanılır. +uygulama_grubu, bu role doğrudan ya da dolaylı olarak üye olan herkesle eşleşir. Belgelerin vurguladığı bir ayrıntı: süper kullanıcı, sırf süper kullanıcı olduğu için bir grubun üyesi sayılmaz; açıkça üye yapılmış olması gerekir. Anahtar sözcükleri çift tırnak içine alırsanız özel anlamlarını kaybederler; "all", adı all olan bir veritabanını ifade eder.

Adres alanı CIDR biçiminde bir IP aralığıdır: tek bir IPv4 makine için /32, IPv6 için /128 kullanılır; 172.20.143.0/24 küçük bir ağı, 0.0.0.0/0 bütün IPv4 adreslerini kapsar. IPv4 biçiminde yazılan bir kayıt yalnızca IPv4 bağlantılarıyla eşleşir. Ayrıca samehost (sunucunun kendi adresleri), samenet (sunucunun doğrudan bağlı olduğu alt ağlar) ve makine adları kullanılabilir. Makine adı verdiğinizde PostgreSQL istemci IP'sini önce tersine, sonra düz yönde çözümleyip ikisinin tutmasını bekler; .example.com gibi noktayla başlayan değer ise ad son ekiyle eşleşir.

Doğrulama yöntemleri

Doğrulama yöntemleri: trust, reject, scram-sha-256, MD5 meydan okuma ve yanıt; parola SCRAM ile saklanmışsa otomatik olarak SCRAM kullanılır
YöntemNe yaparNot
trustHiçbir doğrulama yapmadan bağlantıya izin verirBelgelere göre ancak işletim sistemi düzeyinde yeterli koruma varsa uygun; uzak bağlantıda kullanmayın
rejectBağlantıyı koşulsuz reddederBir ağ içinden belirli bir makineyi ya da kullanıcıyı dışlamak için
scram-sha-256SCRAM-SHA-256 meydan okuma ve yanıt doğrulamasıBelgelerde mevcut parola yöntemlerinin en güvenlisi olarak geçer
md5MD5 meydan okuma ve yanıt; parola SCRAM ile saklanmışsa otomatik olarak SCRAM kullanılırMD5 parola desteği kullanımdan kaldırılıyor
passwordParolayı açık metin gönderirYalnızca SSL ile korunan bağlantılarda güvenli
peerYerel bağlantıda istemcinin işletim sistemi kullanıcı adını çekirdekten alırYalnızca local; Linux, BSD, macOS ve Solaris
identİstemci makinedeki ident sunucusuna sorarYalnızca TCP/IP; local için peer kullanılır
certSSL istemci sertifikasıyla doğrularhostssl satırlarında
gss, sspi, ldap, radius, pam, bsdHarici doğrulama altyapılarısspi yalnızca Windows
oauthHarici bir OAuth 2.0 kimlik sağlayıcısının belirteciyle doğrularPostgreSQL 18 ile eklendi

Belgelerin genel önerisi şudur: yerel bağlantılar için genellikle peer, uzak bağlantılar için en kolay seçenek parola doğrulamasıdır; diğer yöntemler bir doğrulama sunucusu ya da sertifika otoritesi gibi ek altyapı ister. Parola tabanlı yöntemler arasında tercih scram-sha-256 olmalıdır. Dikkat edilmesi gereken nokta, bir yöntemin işe yarayıp yaramadığının kullanıcının parolasının nasıl saklandığına bağlı olmasıdır: MD5 ile saklanmış bir parola scram-sha-256 satırıyla doğrulanamaz. Ters yön ise çalışır: testimizde md5 yazan bir satırla, parolası SCRAM olarak saklanan siparis_api kullanıcısı sorunsuz bağlandı; belgelere göre bu durumda sunucu kendiliğinden SCRAM'a geçer. MD5'ten SCRAM'a geçiş adımları rol yönetimi yazısında var.

Linux paket kurulumlarında sık görülen düzen, Unix soketi için peer satırıdır. Aşağıdaki satır belgelerdeki biçimdedir; Windows'ta çalışmadığı için bizim ortamımızda denenmedi. Bu satır varsa, Linux'ta işletim sisteminin postgres kullanıcısıyla çalıştırılan psql aynı adlı veritabanı rolüne parola sormadan bağlanır:

ini
# Linux: işletim sistemi kullanıcısıyla aynı adlı veritabanı rolüne parolasız yerel giriş
local   all             all                                     peer

İlk eşleşen satır kazanır

PostgreSQL her bağlantı için satırları yukarıdan aşağı okur ve bağlantı türü, istemci adresi, istenen veritabanı ve kullanıcı adının dördü birden tutan ilk satırı seçer. Seçilen satırda doğrulama başarısız olursa sonraki satırlara bakılmaz; geri düşme ya da yedek yoktur. Hiçbir satır eşleşmezse bağlantı reddedilir. Bu yüzden belgeler, sıkı eşleşme koşulları ve zayıf yöntemleri olan satırların önce, geniş eşleşmeli ve güçlü yöntemli satırların sonra gelmesini önerir. Test kümemizde dosyayı şöyle yazdık:

ini
# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    all             postgres        127.0.0.1/32            scram-sha-256
host    all             stajyer         127.0.0.1/32            reject
host    stok            +uygulama_grubu 127.0.0.1/32            scram-sha-256
host    stok            all             127.0.0.1/32            scram-sha-256

Sonra farklı bağlantılar denedik. stajyer doğru parolasıyla bile reddedildi, çünkü onunla ilk eşleşen satır reject idi. siparis_api, stok veritabanına bağlanabildi ama postgres veritabanı için dosyada ona uyan bir satır olmadığından içeri alınmadı:

bash
PGPASSWORD=Stajyer-Parola-1 psql -h 127.0.0.1 -p 46461 -U stajyer -d stok -c "select 1"
# psql: error: connection to server at "127.0.0.1", port 46461 failed: FATAL:  pg_hba.conf rejects connection for host "127.0.0.1", user "stajyer", database "stok", no encryption

PGPASSWORD=Api-Parola-2026 psql -h 127.0.0.1 -p 46461 -U siparis_api -d postgres -c "select 1"
# psql: error: connection to server at "127.0.0.1", port 46461 failed: FATAL:  no pg_hba.conf entry for host "127.0.0.1", user "siparis_api", database "postgres", no encryption

İki mesajın farkı sorun gidermede yol gösterir. rejects connection bir reject satırının eşleştiğini, no pg_hba.conf entry hiçbir satırın eşleşmediğini söyler. Mesajın sonundaki no encryption, bağlantının şifresiz olduğunu belirtir; yalnızca hostssl satırı yazıp SSL'siz bağlanmaya çalışırsanız aynı ifadeyi görürsünüz. Satır bulunup parola yanlışsa mesaj password authentication failed for user "siparis_api" olur; istemci hiç parola vermediyse psql fe_sendauth: no password supplied yazar. Bu iki mesajı da test kümemizde aldık.

Değişikliği yüklemek ve pg_hba_file_rules ile kontrol

pg_hba.conf sunucu başlarken ve ana süreç SIGHUP sinyali aldığında okunur. Sinyali göndermenin üç yolu vardır: pg_ctl reload, SQL'den SELECT pg_reload_conf() ya da Unix'te kill -HUP. Windows'ta durum farklıdır: belgelere göre orada dosyadaki değişiklikler sonraki yeni bağlantılara hemen uygulanır.

Yeni dosyayı etkinleştirmeden önce pg_hba_file_rules görünümüyle kontrol edebilirsiniz. Görünüm sunucunun en son yüklediği kuralları değil, dosyanın şu anki içeriğini gösterir; hatalı satırlarda error sütunu dolu gelir. Varsayılan olarak yalnızca süper kullanıcılar okuyabilir:

sql
SELECT rule_number, line_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules ORDER BY line_number;
text
 rule_number | line_number | type | database |     user_name     |  address  |  auth_method  | error 
-------------+-------------+------+----------+-------------------+-----------+---------------+-------
           1 |           2 | host | {all}    | {postgres}        | 127.0.0.1 | scram-sha-256 | 
           2 |           3 | host | {all}    | {stajyer}         | 127.0.0.1 | reject        | 
           3 |           4 | host | {stok}   | {+uygulama_grubu} | 127.0.0.1 | scram-sha-256 | 
           4 |           5 | host | {stok}   | {all}             | 127.0.0.1 | scram-sha-256 | 
(4 rows)

rule_number, kuralların bağlantı sırasında hangi sırayla deneneceğini gösterir; line_number ise dosyadaki satır numarasıdır. İlk satır başlık yorumu olduğu için kurallar ikinci satırdan başlıyor. include, include_if_exists ve include_dir yönergeleriyle başka dosyalardaki kuralları da araya ekleyebilirsiniz; bu durumda görünümün file_name sütunu kuralın hangi dosyadan geldiğini söyler.

Uzak bağlantı için örnek yapılandırma

Aşağıdaki iki parça, belirli bir uygulama sunucusundan (203.0.113.25) tek bir veritabanına parola ile bağlantıya izin veren tipik bir kurulumu gösterir. Adresler temsilîdir; uzaktan bağlantı kısmı test ortamımızda denenemedi, satır sözdizimi ise yukarıdaki yerel testlerle aynıdır.

ini
# postgresql.conf (değişiklik yeniden başlatma gerektirir)
listen_addresses = 'localhost,10.0.0.5'    # sunucunun özel ağ adresi
port = 5432
password_encryption = scram-sha-256
ini
# pg_hba.conf (pg_reload_conf() yeterli)
# TYPE   DATABASE   USER          ADDRESS            METHOD
host     stok       siparis_api   203.0.113.25/32    scram-sha-256
hostssl  stok       +raporcular   10.0.0.0/24        scram-sha-256
host     all        all           0.0.0.0/0          reject

Son satır zorunlu değildir, çünkü hiçbir satırla eşleşmeyen bağlantı zaten reddedilir; ama dosyayı okuyan kişiye niyeti açıkça gösterir. listen_addresses = '*' yazmak yerine yalnızca gereken arayüzü dinlemek, PostgreSQL portunu internete hiç açmamak için iyi bir başlangıçtır. Ağ güvenlik duvarı ayarları PostgreSQL belgelerinin konusu değildir; bağlantıyı internete açmak istemiyorsanız bir SSH tüneli de kullanabilirsiniz. hostssl satırlarının çalışması için gereken sunucu ayarları SSL/TLS yazısında anlatılıyor.

Belgelerdeki bir ipucunu da akılda tutun: bir kullanıcının veritabanına bağlanabilmesi için pg_hba.conf kontrolünü geçmesi yetmez, o veritabanında CONNECT yetkisine de sahip olması gerekir. Hangi kullanıcının hangi veritabanına girebileceğini sınırlamak çoğu zaman pg_hba.conf satırlarıyla değil GRANT ve REVOKE CONNECT ile daha kolaydır; yetkilendirme yazısında bunun örneğini görebilirsiniz.

Sık yapılan hatalar

Sık yapılan hatalar: listen_addresses değiştirip yeniden başlatmamak, Satır sırasını yanlış kurmak, Uzak bağlantı için trust kullanmak, CIDR maskesini yanlış yazmak
  • listen_addresses değiştirip yeniden başlatmamak: parametre postmaster bağlamındadır, pg_reload_conf() yetmez. pending_restart sütununa bakın.
  • Satır sırasını yanlış kurmak: geniş bir all all 0.0.0.0/0 satırı yukarıda durursa altındaki özel satırlar hiç devreye girmez.
  • Uzak bağlantı için trust kullanmak: bu, o adresten gelen herkesin süper kullanıcı dahil istediği adla girebilmesi demektir.
  • CIDR maskesini yanlış yazmak: IP ile / ve maske arasında boşluk olmamalı, ağ adresinde sondaki sıfırlar atlanmamalıdır.
  • Grup adında + işaretini unutmak: uygulama_grubu yalnızca o adlı rolle, +uygulama_grubu ise üyeleriyle eşleşir.
  • MD5 parolası olan kullanıcı için scram-sha-256 satırı yazmak: parola SCRAM ile yeniden ayarlanmadan doğrulama başarısız olur.

Sık Sorulan Sorular

pg_hba.conf dosyası nerede?

Varsayılan olarak kümenin veri dizinindedir, ancak konumu hba_file parametresiyle başka bir yere taşınabilir. Bu yüzden tahmin etmek yerine süper kullanıcı olarak SHOW hba_file çalıştırın; tam yolu verir.

Değişiklikten sonra sunucuyu yeniden başlatmam gerekir mi?

pg_hba.conf için hayır; pg_reload_conf() ya da pg_ctl reload yeterlidir. listen_addresses ve port için ise evet. Sunucuyu durdurup başlatma adımları pg_ctl yazısında anlatılıyor.

Connection refused ile no pg_hba.conf entry arasındaki fark nedir?

Connection refused, istemcinin sunucuya hiç ulaşamadığını gösterir: sunucu çalışmıyordur, o adreste dinlemiyordur ya da port yanlıştır. Testimizde sunucu yalnızca 127.0.0.1 dinlerken -h ::1 ile denediğimizde bu hatayı aldık. no pg_hba.conf entry ise sunucuya ulaşıldığını ama kuralların bağlantıya izin vermediğini söyler. Bağlantı hatalarının ayrıntılı listesi bağlantı hataları yazısında.

Belirli bir IP adresini nasıl engellerim?

O adres için reject yöntemli bir satırı, aynı ağa izin veren satırın üstüne yazın. Belgelerdeki örnekte 192.168.54.1/32 için önce reject satırı, ardından daha geniş kurallar gelir.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: PostgreSQL öğrenme rehberi · SSL/TLS şifreli bağlantı · Kullanıcı ve rol yönetimi · Bağlantı hataları · postgresql.conf ve ALTER SYSTEM · SSH ile sunucuya bağlanma