terça-feira, 13 de abril de 2010

Meu PostgreSQL não conecta!

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.

https://www.youtube.com/watch?v=bZ6qMEf9e9A

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ão Original Mudar para
7.X e anteriores tcpip_socket = false tcpip_socket = true
8.X em diante listen_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.

https://www.youtube.com/watch?v=bZ6qMEf9e9A

Nenhum comentário: