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:
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'); 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

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:
# 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ür | Eşleştiği bağlantı |
|---|---|
| local | Unix soketi üzerinden gelen bağlantılar; bu türde satır yoksa soket bağlantısı reddedilir |
| host | TCP/IP bağlantıları, SSL olsun ya da olmasın |
| hostssl | Yalnızca SSL ile şifrelenmiş TCP/IP bağlantıları; sunucuda ssl açık değilse satır uyarı verip yok sayılır |
| hostnossl | Yalnızca SSL kullanmayan TCP/IP bağlantıları |
| hostgssenc, hostnogssenc | GSSAPI ş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

| Yöntem | Ne yapar | Not |
|---|---|---|
| trust | Hiçbir doğrulama yapmadan bağlantıya izin verir | Belgelere göre ancak işletim sistemi düzeyinde yeterli koruma varsa uygun; uzak bağlantıda kullanmayın |
| reject | Bağlantıyı koşulsuz reddeder | Bir ağ içinden belirli bir makineyi ya da kullanıcıyı dışlamak için |
| scram-sha-256 | SCRAM-SHA-256 meydan okuma ve yanıt doğrulaması | Belgelerde mevcut parola yöntemlerinin en güvenlisi olarak geçer |
| md5 | MD5 meydan okuma ve yanıt; parola SCRAM ile saklanmışsa otomatik olarak SCRAM kullanılır | MD5 parola desteği kullanımdan kaldırılıyor |
| password | Parolayı açık metin gönderir | Yalnızca SSL ile korunan bağlantılarda güvenli |
| peer | Yerel bağlantıda istemcinin işletim sistemi kullanıcı adını çekirdekten alır | Yalnızca local; Linux, BSD, macOS ve Solaris |
| ident | İstemci makinedeki ident sunucusuna sorar | Yalnızca TCP/IP; local için peer kullanılır |
| cert | SSL istemci sertifikasıyla doğrular | hostssl satırlarında |
| gss, sspi, ldap, radius, pam, bsd | Harici doğrulama altyapıları | sspi yalnızca Windows |
| oauth | Harici bir OAuth 2.0 kimlik sağlayıcısının belirteciyle doğrular | PostgreSQL 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:
# 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:
# 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-256Sonra 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ı:
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:
SELECT rule_number, line_number, type, database, user_name, address, auth_method, error
FROM pg_hba_file_rules ORDER BY line_number; 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.
# 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# 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 rejectSon 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

- listen_addresses değiştirip yeniden başlatmamak: parametre
postmasterbağlamındadır,pg_reload_conf()yetmez.pending_restartsütununa bakın. - Satır sırasını yanlış kurmak: geniş bir
all all 0.0.0.0/0satı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_grubuyalnızca o adlı rolle,+uygulama_grubuise ü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