Cada nova conexão recebida precisa passar por uma etapa de autenticação antes de ser permitido o acesso aos dados do banco de dados de destino. Essa autenticação é baseada em diversas configurações, permissões de usuário e em uma tabela de regras contida no arquivo pg_hba.conf.
Sobre cada nova conexão, o PostgreSQL tem conhecimento do tipo socket (UNIX ou TCP), do IP do host (apenas para sockets TCP), do usuário e do banco de dados. Com esses dados, ele percorre o arquivo pg_hba.conf
, de cima a baixo, buscando uma regra de autenticação que seja válida para aquela conexão. A primeira linha encontrada é usada para decidir qual método de autenticação será aplicado à nova conexão. Isso é análogo a como tabelas de firewall e roteamento funcionam, e permite a escrita de regras poderosas pelo uso de máscaras de rede e regras de aceitação e rejeição.
Linhas iniciadas com uma cerquilha (#
) são comentários e são ignoradas. Outras linhas seguem uma estrutura de colunas bem definidas e separadas por um ou mais espaços.
A primeira coluna representa o tipo da conexão e tem os seguintes valores possíveis:
local
: conexões através de socket UNIXhost
: conexões por socket TCPhostssl
: conexões TCP com encriptação SSLhostnossl
: conexões TCP sem encriptação SSLhostgssenv
: conexões TCP com encriptação GSSAPIhostnogssencl
: conexões TCP sem encriptação GSSAPI
A segunda coluna representa o banco de dados de destino da conexão. Nomes de bancos de dados podem ser colocados nessa coluna, mas mais de um nome pode ser informado separando os nomes por vírgulas (sem espaços). O valor especial all
pode ser usado para representar todos os bancos de dados. O valor especial replication
pode ser usado para representar conexões de replicação (que afetam a instância). O valor especial sameuser
pode ser usado para conexões cujo nome de banco de dados é igual ao nome do usuário. O valor especial samerole
pode ser usado para conexões cujo usuário pertença a um papel com o mesmo nome do banco de dados. Também pode ser informado um nome de arquivo prefixado com @
para que a lista de nomes de bancos de dados seja fornecida por um arquivo externo.
A terceira coluna representa o usuário da conexão. Nomes de usuários, papéis e grupos podem ser colocados nessa coluna, mas mais de um nome pode ser informado separando os nomes por vírgulas (sem espaços). O valor especial all
pode ser usado para representar todos os usuários. Caso um nome seja prefixado por um +
, ele é tomado como um nome de papel e a regra aceita todos os usuários que façam parte direta ou indiretamente daquele papel. Também pode ser informado um nome de arquivo prefixado com @
para que a lista de nomes de usuários seja fornecida por um arquivo externo.
A quarta e, possivelmente, quinta colunas indicam o endereço TCP/IP da origem da conexão (e, portanto, não são usadas para conexões do tipo local
). O endereço pode ser fornecido como uma coluna em formato CIDR ou como duas colunas com IP e máscara separados, mas a primeira forma é recomendada por ser mais flexível. Nela, é possível representar origens de conexões, não só pelo formato CIDR, mas também por FQDN, contanto que o servidor possa resolvê-lo por DNS (tanto direto quanto reverso). Além disso, também é possivel usar o valor especial all
para representar todos os endereços IP, localhost
para representar todos os endereços de escopo local (::1/128 e 127.0.0.1/8), samehost
para representar os endereços associados a interfaces da máquina (por exemplo, se uma interface tiver o endereço 192.168.12.34 na rede /24, o endereço do host /32 será incluído) e samenet
para representar todos os endereços das mesmas redes nas quais a máquina está (por exemplo, se uma interface tiver o endereço 192.168.12.34 na rede /24, todos os endereços da rede /24 serão incluídos). Endereços explícitos de IPv4 ou IPv6 podem ser usados, mas afetarão apenas aquela versão do protocolo IP.
A coluna seguinte contém o método de autenticação que deve ser usado para conexões que alcançarem a regra. Alguns métodos, como autenticações externas por LDAP, precisam de informações adicionais, como opções ou parâmetros, que são informados após o nome do método. Diversas opções de métodos estão disponíveis, mas algumas das mais úteis são:
trust
: aceita a conexão; útil para testes e laboratórios, mas não recomendado para ambientes de produçãoreject
: rejeita a conexão; útil para implementar blacklists de configurações indesejáveis, criando regras no topo do arquivo, como por exemplo `hostnossl all all all reject`, para evitar receber conexões não encriptadasscram-sha-256
: autenticação por senha usando o método SCRAM-SHA-256md5
: autenticação menos segura por senha usando método SCRAM-SHA-256 ou MD5, dependendo do hash usado na senha do usuário no servidorpeer
: aceita a conexão caso o usuário do sistema operacional do cliente tenha o mesmo nome do usuário do banco de dados; disponível apenas para conexões do tipolocal
ident
: semelhante apeer
, mas para conexões dos outros tipos; depende de um servidorident
confiável na rede localldap
: autentica usando um servidor LDAPcert
: autentica usando certificados SSL de cliente
Uma vez que o arquivo tenha sido editado com um novo conjunto de regras, elas podem ser aplicadas com um reload
do serviço do PostgreSQL. E as regras carregadas e efetivadas com sucesso podem ser consultadas pela visão do sistema pg_hba_file_rules
.
Por exemplo, um arquivo populado inicialmente pelo initdb com:
# TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all peer # IPv4 local connections: host all all 127.0.0.1/32 ident # IPv6 local connections: host all all ::1/128 ident # Allow replication connections from localhost, by a user with the replication privilege. local replication all peer host replication all 127.0.0.1/32 ident host replication all ::1/128 ident
Apresenta a seguinte tabela de autenticação:
[[local]:5432] postgres@postgres=# SELECT * FROM pg_hba_file_rules; ╔═════════════╤═══════╤═══════════════╤═══════════╤═══════════╤═════════════════════════════════════════╤═════════════╤═════════╤═══════╗ ║ line_number │ type │ database │ user_name │ address │ netmask │ auth_method │ options │ error ║ ╠═════════════╪═══════╪═══════════════╪═══════════╪═══════════╪═════════════════════════════════════════╪═════════════╪═════════╪═══════╣ ║ 84 │ local │ {all} │ {all} │ │ │ peer │ │ ║ ║ 86 │ host │ {all} │ {all} │ 127.0.0.1 │ 255.255.255.255 │ ident │ │ ║ ║ 88 │ host │ {all} │ {all} │ ::1 │ ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff │ ident │ │ ║ ║ 91 │ local │ {replication} │ {all} │ │ │ peer │ │ ║ ║ 92 │ host │ {replication} │ {all} │ 127.0.0.1 │ 255.255.255.255 │ ident │ │ ║ ║ 93 │ host │ {replication} │ {all} │ ::1 │ ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff │ ident │ │ ║ ╚═════════════╧═══════╧═══════════════╧═══════════╧═══════════╧═════════════════════════════════════════╧═════════════╧═════════╧═══════╝