Incidentu reaģēšana

PostgreSQL "no pg_hba.conf entry for host": kā to labot

Serveris darbojas, ports ir atvērts, bet katrs savienojums tiek noraidīts ar "no pg_hba.conf entry for host". Paskaidrojam, kā PostgreSQL izvēlas pg_hba.conf rindu, kāpēc jūsu jaunais noteikums nesakrīt un kā to labot, neatverot datubāzi visai pasaulei.

· 18 min lasīšanai · AG Data komanda

PostgreSQL kļūdai "no pg_hba.conf entry for host" ir arī mierinoša puse: tīkls ir kārtībā. Klients sasniedza serveri, serveris nolasīja pieprasījumu, izgāja cauri saviem host-based autentifikācijas noteikumiem un neatrada nevienu atbilstošu. Nekas nav salūzis. Vienkārši nav noteikuma tieši šai adreses, lietotāja, datubāzes un savienojuma veida kombinācijai. Jāatrod, kura no četrām vērtībām nesakrīt, un lielāko daļu atbildes jau satur pats kļūdas ziņojums.

Aktuālajās PostgreSQL versijās ziņojums izskatās šādi:

FATAL:  no pg_hba.conf entry for host "10.20.0.15", user "app", database "appdb", no encryption

PostgreSQL dokumentācija par autentifikācijas problēmām raksturo to kā visticamāko kļūdu gadījumā, ja serveri sasniedzat, bet tas nevēlas ar jums runāt. Salīdziniet to ar "Connection refused" vai taimautu. Tie nozīmē, ka līdz šim brīdim nemaz netikāt: serveris neklausās uz šīs adreses vai ceļā ir ugunsmūris.

Nolasiet ziņojumu pa laukiem

Teksts tiek veidots failā auth.c, un katra tā daļa ir noderīga:

Fiziskās replikācijas savienojumam teksts mainās uz "no pg_hba.conf entry for replication connection from host ...", un datubāzes lauka tajā nav. Tas jau pats par sevi ir mājiens: replikācijai vajag atsevišķu noteikumu, kā redzēsim tālāk.

Skatiet arī servera žurnālu, ne tikai klienta izvadi. Dokumentācija norāda, ka žurnālā bieži ir vairāk informācijas nekā klientam nosūtītajā ziņojumā. Ja pg_hba.conf izmantojat hostu vārdus, žurnālā būs arī redzams, vai klienta IP tika atrisināts uz vārdu un vai sakrita tiešā (forward) pārbaude.

Kā PostgreSQL izvēlas noteikumu

pg_hba.conf dokumentācijā noteikumi ir īsi. Ieraksti tiek pārbaudīti no augšas uz leju, un tiek izmantots pirmais ieraksts, kuram sakrīt savienojuma veids, klienta adrese, datubāze un lietotājs. Pāriešanas uz nākamo nav: ja šī ieraksta autentifikācija neizdodas, nākamie ieraksti netiek pārbaudīti. Ja nesakrīt neviens, piekļuve tiek liegta ar iepriekš minēto kļūdu.

Tātad "no entry" nozīmē, ka neviena rinda nesakrita pēc visiem četriem laukiem vienlaikus. Biežākie iemesli, aptuveni tādā secībā, kādā ar tiem saskaramies:

  1. Adrese nav tā, ko domājat. Noteikums atļauj 10.20.0.0/24, bet lietotne pēc migrācijas darbojas citā apakštīklā. Vai arī tā pieslēdzas caur PgBouncer vai starpniekserveri, un serveris redz starpnieka adresi. Uzticieties IP adresei kļūdas ziņojumā, nevis tīkla shēmai.
  2. IPv4 pret IPv6. Dokumentācija to saka skaidri: IPv4 formātā rakstīts ieraksts atbilst tikai IPv4 savienojumiem, bet IPv6 ieraksts tikai IPv6. Ja localhost tiek atrisināts uz ::1, noteikums 127.0.0.1/32 šim klientam neko nedod.
  3. Nepareizs savienojuma veids. local rindas attiecas tikai uz Unix domēna soketiem, host uz TCP/IP ar šifrēšanu vai bez tās, hostssl tikai uz TCP/IP ar SSL, bet hostnossl tikai uz TCP/IP bez tā. Noteikumu kopa, kas sastāv tikai no hostssl rindām, noraidīs klientu bez TLS, un ziņojums beigsies ar "no encryption". Ja serverī ssl nav ieslēgts, dokumentācija norāda, ka hostssl ieraksti tiek ignorēti, tikai žurnālā parādās brīdinājums.
  4. Replikācija neietilpst "all". Atslēgvārds all datubāzes kolonnā neattiecas uz fizisko replikāciju. Vajag rindu ar replication datubāzes kolonnā. Dokumentācijā ir vēl viena nianse: replication atbilst fiziskās replikācijas savienojumiem, bet ne loģiskās. Loģiskās replikācijas savienojumi norāda datubāzi un tiek salīdzināti kā parasti savienojumi.
  5. Dalība grupās. Vienkāršs lomas vārds atbilst tikai šai lomai. Lai atbilstu grupas lomas dalībniekiem, pievienojiet priekšā +. Superlietotāji netiek uzskatīti par lomas dalībniekiem tikai tāpēc, ka ir superlietotāji.
  6. Rediģētais fails nav tas, kas tiek lietots. Ceļu nosaka hba_file. Dažās no pakotnēm instalētās sistēmās tas atrodas ārpus datu direktorijas. Pirms ko labojat, pārbaudiet ar SHOW hba_file;.
  7. Labojāt, bet nepārlādējāt. Fails tiek nolasīts startējot un saņemot SIGHUP. Saglabāšana neko nemaina, kamēr konfigurācija netiek pārlādēta. Izņēmums ir Windows: tur izmaiņas uzreiz attiecas uz jauniem savienojumiem.

Apskatiet noteikumus tā, kā tos redz serveris

Sāciet ar rindu servera žurnālā un salīdziniet to ar nolasītajiem noteikumiem. Skats pg_hba_file_rules rāda vienu rindu katrai rindai, kas nav komentārs, tādā secībā, kādā tās tiek vērtētas:

SELECT rule_number, file_name, line_number, type,
       database, user_name, address, netmask, auth_method, error
FROM pg_hba_file_rules
ORDER BY rule_number NULLS LAST, line_number;

Kolonnas rule_number un file_name ir pieejamas no PostgreSQL 16, kurā pg_hba.conf parādījās arī include direktīvas. Versijās 15 un vecākās izņemiet šīs divas kolonnas no vaicājuma. Pēc noklusējuma skatu var lasīt tikai superlietotāji.

Viena detaļa padara skatu ļoti ērtu, bet to ir arī viegli pārprast: tas rāda faila pašreizējo saturu, nevis to, ko serveris ielādēja pēdējo reizi. Tas ir lieliski, lai pārbaudītu izmaiņas pirms pārlādēšanas. Rinda, kurā error nav NULL, nozīmē, ka to nevar parsēt:

SELECT file_name, line_number, error
FROM pg_hba_file_rules
WHERE error IS NOT NULL;

Pēc tam ejiet cauri sarakstam no augšas ar četrām vērtībām no kļūdas ziņojuma un apstājieties pie pirmās rindas, kas atbilst tām visām. Ja nonākat līdz beigām, tā arī ir atbilde. Ja agrāk sakrīt rinda ar reject, klients saņem citu ziņojumu, "pg_hba.conf rejects connection for host ...", kas nozīmē, ka to bloķēja tiešs noteikums.

Labojiet ar šauru noteikumu

Pievienojiet pēc iespējas konkrētāku rindu, kas aptver reālo klientu, un novietojiet to virs plašākiem noteikumiem, kas varētu sakrist agrāk:

# TYPE   DATABASE   USER   ADDRESS          METHOD
# lietotņu serveri, obligāts TLS
hostssl  appdb      app    10.20.0.0/24     scram-sha-256
# replikas straumēšana (fiziskā replikācija)
hostssl  replication replicator 10.20.1.12/32 scram-sha-256

Pēc tam pārlādējiet konfigurāciju. Restartēt nevajag. Noteikumi tiek pārbaudīti, kad savienojums tiek atvērts, tāpēc esošās sesijas turpina darboties:

SELECT pg_reload_conf();
-- pēc tam pārliecinieties, ka fails ir nolasīts bez kļūdām
SELECT count(*) FROM pg_hba_file_rules WHERE error IS NOT NULL;

pg_ctl reload vai kill -HUP postmaster procesam dara to pašu. Ja failā ir sintakses kļūda, pārlādēšana nevienu neizslēgs. Kods failā hba.c parsē jauno failu pagaidu sarakstā un saglabā vecos noteikumus, ja kaut kas neizdodas. Žurnālā parādās "... pg_hba.conf was not reloaded". Tas ir droši, bet nozīmē arī to, ka jūsu labojums klusi nav stājies spēkā, tāpēc pēc katras pārlādēšanas pārbaudiet žurnālu vai skatu.

Nelabojiet to ar trust vai 0.0.0.0/0. Kad produkcija nedarbojas, kārdina ierakstīt host all all 0.0.0.0/0 trust. Dokumentācija tieši saka, ko nozīmē trust: ikviens, kas var pieslēgties, var ielogoties kā jebkurš lietotājs, arī superlietotājs, bez paroles. Izmantojiet precīzu adrešu diapazonu un scram-sha-256, arī kā pagaidu risinājumu. Kā šo failu pēc tam uzturēt stingru, aprakstījām mūsu PostgreSQL drošības nostiprināšanas kontrolsarakstā.

Vēl viena pārbaude pirms aiziešanas: attālie klienti var pieslēgties tikai tad, ja listen_addresses ietver interfeisu, līdz kuram tie var tikt. Savienojumu iestatījumu dokumentācijā noklusējuma vērtība ir localhost, un tās maiņai vajag restartu, nevis pārlādēšanu. Ja serveris tur neklausās, klients šīs kļūdas vietā saņem "Connection refused".

Kad kļūda mainās uz "password authentication failed"

Bieži nākamais mēģinājums pēc labojuma beidzas ar FATAL: password authentication failed for user "app". Tas ir progress: noteikums sakrita, un tagad neizdodas šī noteikuma metode. Klients apzināti redz tikai šo vispārīgo tekstu. Īstais iemesls ir servera žurnālā, kas norāda arī, kura pg_hba.conf rinda sakrita (PostgreSQL 16 un jaunākās versijas pievieno arī faila nosaukumu). crypt.c un SCRAM kods žurnālā raksta, piemēram:

Pēdējais gadījums bieži parādās pēc drošības nostiprināšanas. Saskaņā ar paroles autentifikācijas dokumentāciju SCRAM formātā glabāta parole darbojas ar scram-sha-256, md5 (PostgreSQL klusi pārslēdzas uz SCRAM) un password. MD5 formātā glabāta parole darbojas tikai ar md5 un password. Tātad, ja rindu nomaināt no md5 uz scram-sha-256, pirms vecās paroles ir iestatītas no jauna, šie lietotāji paliek ārpusē. Dokumentētā secība ir šāda: pārliecinieties, ka visas klientu bibliotēkas atbalsta SCRAM, iestatiet password_encryption = 'scram-sha-256' (aktuālajās versijās tas jau ir noklusējums), lieciet lietotājiem iestatīt jaunas paroles un tikai tad mainiet metodi pg_hba.conf.

-- kāds hash tips ir lomai? (tikai superlietotājam)
SELECT rolname, left(rolpassword, 14) AS hash_prefix, rolvaliduntil
FROM pg_authid
WHERE rolname = 'app';

-- iestatiet paroli no jauna, lai tā tiktu glabāta kā SCRAM
SET password_encryption = 'scram-sha-256';
\password app

Hash, kas sākas ar SCRAM-SHA-256$, ir SCRAM, bet tas, kas sākas ar md5, ir vecais formāts.

Divas īpatnības, kas rada mulsinošas kļūdas

Tā pati kļūda divreiz. libpq noklusējuma sslmode ir prefer. libpq dokumentācija to apraksta kā "vispirms mēģināt SSL savienojumu; ja tas neizdodas, mēģināt bez SSL". Tāpēc klients var parādīt divas FATAL rindas, vienu ar "SSL encryption" beigās un otru ar "no encryption". Tas nozīmē, ka neviens no mēģinājumiem neatbilda noteikumam. Produkcijas klientiem iestatiet sslmode=require vai stingrāku režīmu, lai vienmēr zinātu, kāda veida savienojumu atkļūdojat.

Peer autentifikācijas kļūdas. local rinda ar peer salīdzina operētājsistēmas lietotāja vārdu ar pieprasīto lomu. Palaižot psql -U postgres kā root caur soketu, tiek sakrists ar šo rindu un saņemta kļūda "Peer authentication failed for user "postgres"". Tā ir cita kļūda nekā "no entry", un risinājums ir palaist komandu kā pareizajam OS lietotājam (vai izmantot lietotāju vārdu karti), nevis pārrakstīt noteikumu.

Lai nākamreiz būtu ātrāk

Galvenās atziņas

PostgreSQL Drošība Autentifikācija Problēmu novēršana
Sadarbība ar mums

Nevarat pieslēgties PostgreSQL?

Savienojuma kļūdas pēc migrācijas, tīkla maiņas vai failover ir tieši tie incidenti, ar kuriem strādājam. Atsūtiet kļūdas tekstu un attiecīgās pg_hba.conf rindas, un mēs palīdzēsim droši atjaunot piekļuvi.

Sazināties Vairāk no emuāra