postgres postgresql hba auth
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 UNIX -
host
: conexões por socket TCP -
hostssl
: conexões TCP com encriptação SSL -
hostnossl
: conexões TCP sem encriptação SSL -
hostgssenv
: conexões TCP com encriptação GSSAPI -
hostnogssencl
: 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ção -
reject
: 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 encriptadas -
scram-sha-256
: autenticação por senha usando o método SCRAM-SHA-256 -
md5
: autenticação menos segura por senha usando método SCRAM-SHA-256 ou MD5, dependendo do hash usado na senha do usuário no servidor -
peer
: 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 local -
ldap
: autentica usando um servidor LDAP -
cert
: 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 │ │ ║ ╚═════════════╧═══════╧═══════════════╧═══════════╧═══════════╧═════════════════════════════════════════╧═════════════╧═════════╧═══════╝ (6 rows) [[local]:5432] postgres@postgres=#
O restante do laboratório dependerá das máquinas acessando umas as outras. Então o objetivo desta prática é fazer com que o psql de uma máquina (pg-2) acesse o servidor na outra (pg-1). A autenticação deve ser por senha não interativa. Para isso, siga os passos:
-
Mude as configurações do servidor para que ele aceite conexões externas (
listen_addresses
) e use SCRAM-SHA-256 (password_encryption
) - Adicione regras de autenticação por SCRAM-SHA-256 para a rede local
- Reinicie o serviço para aplicar as configurações
- Crie um usuário comum com senha
- Instale os pacotes de cliente nas outras máquinas
- Crie um arquivo .pgpass no usuário de outra máquina, contendo o usuário e a senha escolhidas
-
Teste a conexão com o
psql
╔═════════════╤═══════╤═══════════════╤═══════════╤═══════════╤═════════════════════════════════════════╤═══════════════╤═════════╤═══════╗ ║ 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 │ scram-sha-256 │ │ ║ ║ 88 │ host │ {all} │ {all} │ ::1 │ ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff │ scram-sha-256 │ │ ║ ║ 91 │ local │ {replication} │ {all} │ │ │ peer │ │ ║ ║ 92 │ host │ {replication} │ {all} │ 127.0.0.1 │ 255.255.255.255 │ scram-sha-256 │ │ ║ ║ 93 │ host │ {replication} │ {all} │ ::1 │ ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff │ scram-sha-256 │ │ ║ ║ 95 │ host │ {all} │ {all} │ samenet │ │ scram-sha-256 │ │ ║ ║ 96 │ host │ {replication} │ {all} │ samenet │ │ scram-sha-256 │ │ ║ ╚═════════════╧═══════╧═══════════════╧═══════════╧═══════════╧═════════════════════════════════════════╧═══════════════╧═════════╧═══════╝