quarta-feira, 25 de março de 2009

Meu PostgreSQL não conecta!


Começando do início...


Observação: Apesar de os testes terem sido feitos em ambiente Linux, os comandos (ping, telnet, psql) e arquivos de configuração (postgresql.conf, pg_hba.conf) existem e funcionam também no Windows, Macintosh ou FreeBSD, no respectivo terminal.

Antes de tudo, façamos alguns testes que respondem à algumas perguntas.

A máquina está no ar e é enxergada na rede pelo cliente?


Um simples "ping" pode nos ajudar:
$ ping 10.15.23.15
Se estiver tudo correto, aparecerá o texto abaixo:
rodrigo@asgard:~$ ping 10.15.23.15
PING 10.15.23.15 (10.15.23.15) 56(84) bytes of data.
64 bytes from 10.15.23.15: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 10.15.23.15: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 10.15.23.15: icmp_seq=3 ttl=64 time=0.034 ms

--- 10.15.23.15 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.034/0.037/0.044/0.006 ms
Caso contrário, será exibido algo como:
rodrigo@asgard:~$ ping 10.15.23.150
PING 10.15.23.150 (10.15.23.150) 56(84) bytes of data.
From 10.15.23.15 icmp_seq=1 Destination Host Unreachable
From 10.15.23.15 icmp_seq=2 Destination Host Unreachable
From 10.15.23.15 icmp_seq=3 Destination Host Unreachable

--- 10.15.23.150 ping statistics ---
6 packets transmitted, 0 received, +3 errors,
100% packet loss, time 5008ms, pipe 3
Se este for o caso, resolva este problema de conexão e configuração de rede antes de continuar.

O servidor está respondendo ao serviço na porta do PostgreSQL?


Se não estiver, qualquer acesso externo ao PostgreSQL é barrado, e a seguinte mensagem será exibida:
psql: could not connect to server: Conexão recusada
Is the server running on host "10.15.23.15" and accepting
TCP/IP connections on port 5432?
Para comprovar isso, podemos fazer um simples teste com o "telnet":
$ telnet 10.15.23.15 5432
rodrigo@asgard:~$ telnet 10.15.23.15 5432
Trying 10.15.23.15...
telnet: Unable to connect to remote host: Connection refused
Este é um problema que ocorre com 5 de cada 4 iniciantes neste banco de dados: a conexão não-local!
Bom, o fato é que a configuração padrão do PostgreSQL faz com que apenas conexões locais (via soquete UNIX) sejam permitidas. O primeiro passo é alterar uma opção no arquivo de configurações postgresql.conf:















VersãoOriginalMudar para
7.X e anteriorestcpip_socket = falsetcpip_socket = true
8.X em diantelisten_addresses = 'localhost'listen_addresses = '*'

Após salvar o arquivo, será preciso reiniciar o SGBD (não basta apenas fazer um "reload").

Agora refaça o teste do "telnet". Terá que aceitar a conexão e aparecer este texto:
rodrigo@asgard:~$ telnet 10.15.23.15 5432
Trying 10.15.23.15...
Connected to 10.15.23.15.
Escape character is '^]'.
Dê um CTRL+C para sair. Se ainda não funcionar, será preciso verificar se firewalls não estão impedindo a conexão entre o cliente e o servidor, na porta do PostgreSQL (padrão: 5432). Resolva essa questão antes de continuar a leitura...

Opa! Metade do serviço está concluída! Agora, outro problema que atormenta quem está começando, este erro ao tentar se conectar:
$ psql -h 10.15.23.15 correios rodrigo
psql: FATAL:  nenhuma entrada no pg_hba.conf para máquina "10.15.22.32",
usuário "rodrigo", banco de dados "correios", SSL desabilitado
Sigamos a dica que o PostgreSQL nos dá! Abra o seguinte arquivo de configuração: pg_hba.conf.

Este arquivo controla: quais hosts têm permissão de conexão, como os clientes se autenticam, quais usuários do PostgreSQL podem ser usados e que bancos de dados eles podem acessar. Os registros podem ter uma das seguintes formas:

local      DATABASE  USER  METHOD  [OPTION]
host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
hostssl DATABASE USER CIDR-ADDRESS METHOD [OPTION]
hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTION]
Sendo assim, nestas entradas de permissões de acesso ao PostgreSQL, podemos alterar:
  • tipo de conexão ("local", "host")
  • banco de dados ("all": todos)
  • usuário ("all": todos)
  • endereço IP e máscara (estilo CIDR)
  • método ("reject", "trust", "password", "md5", "ident same user")

Importante: o arquivo é lido de cima para baixo, e a primeira entrada que esteja de acordo com a requisição é considerada. Isso é um fato que às vezes confunde os administradores. Os campos podem ser separados por espaços ou tabulações - tanto faz, funcionará de ambas as formas.

Bom, para resolver o problema em questão, precisamos incluir a seguinte linha:

host    correios    rodrigo        10.15.22.32/32        md5
Desta vez, não será preciso reiniciar o PostgreSQL. No Linux, podemos enviar um sinal do tipo HUP das seguintes maneiras:
$ /etc/init.d/postgresql-8.1 reload
$ killall -HUP postmaster
No Windows eu vou ficar devendo, mas deve ser algo como "recarregar o serviço".

Pronto! Simples, não?

Se você quiser, pode fazer com que o PostgreSQL funcione de modo promíscuo, adicionando a seguinte linha:

host    all    all        0.0.0.0/0        trust
Isso faz com que qualquer usuário, de qualquer IP acesse qualquer banco de dados, e sem necessidade de senha!

Se, ao invés de "trust" for usado "reject", todo acesso será fechado.

Lembre-se que, pelo padrão CIDR de endereçamento, diversos IPs podem ser
configurados com uma só linha! Por exemplo, ambas as linhas abaixo fazem
com que toda a subrede do IP 10.15.22.32/22 tenha acesso, por senha, ao
banco "correios":

host    correios    all        10.15.20.0/22        password
host correios all 10.15.22.32 255.255.252.0 password

Uma coisa interessante é restringir o acesso ao usuário "postgres", Senhor de Todo o Cluster, com a inclusão da seguinte linha:

local   all         postgres                          ident sameuser
Com isso, somente acesso local (via "ssh" e instrução "su - postgres") poderá ser feita com este super usuário, que tem permissão para fazer o que quiser em qualquer banco de dados.

7 comentários:

  1. Caro Hjort, já estavamos com saudades deste artigo. Gostaria de lhe pedir um imenso favor. Pedir para você postar ou autorizar postarmos no wiki.postgresql.org este artigo. Ele pode ser considerado um "must have" na comunidade.

    Então, o que você acha?

    ResponderExcluir
  2. Fala Telles!

    Opa, não precisa nem pedir, pode postá-lo sim. :)

    ResponderExcluir
  3. Boa Noite Rodrigo,
    Estamos Desenvolvendo uma aplicação no Lazarus, tentando fazer a conexao com Postgres. Como iniciantes que somos, gostaria q vc nos ajudasse informando um breve passo a passo para efetuarmos essa conexão.
    Um Abraço,
    Darci, Jailson (academicos)
    Darci318@yahoo.com.br; Jailsonja@yahoo.com.br

    ResponderExcluir
  4. Estou com este problema:

    psql: could not connect to server: Conexão recusada Is the server running on host "10.15.23.15" and accepting TCP/IP connections on port 5432?

    só que estou usando o windows server, como faço para mudar as conigurações para acessar via rede banco de dados?

    ResponderExcluir
    Respostas
    1. É só seguir os passos do artigo. :)

      Mesmo no Windows existem os arquivos de configurações postgresql.conf e pg_hba.conf.

      Hjort

      Excluir
  5. Muito bom o tutorial!

    Tive uns probleminhas com postgres na rede e resolvi usando-o!
    Parabéns!

    ResponderExcluir
    Respostas
    1. São problemas clássicos e frequentes de conexão ao PostgreSQL e por isso escrevi o artigo lá em meados de 2005... :D

      Hjort

      Excluir