postgres postgresql hba auth

Autenticação

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:

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:

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=#

Prática

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:

  1. Mude as configurações do servidor para que ele aceite conexões externas (listen_addresses) e use SCRAM-SHA-256 (password_encryption)
  2. Adicione regras de autenticação por SCRAM-SHA-256 para a rede local
  3. Reinicie o serviço para aplicar as configurações
  4. Crie um usuário comum com senha
  5. Instale os pacotes de cliente nas outras máquinas
  6. Crie um arquivo .pgpass no usuário de outra máquina, contendo o usuário e a senha escolhidas
  7. 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 │         │       ║
╚═════════════╧═══════╧═══════════════╧═══════════╧═══════════╧═════════════════════════════════════════╧═══════════════╧═════════╧═══════╝