PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Privilégios e gerenciamento de usuários do PostgreSQL - O que você deve saber


O gerenciamento de usuários no PostgreSQL pode ser complicado. Normalmente, os novos usuários são gerenciados, em conjunto, em algumas áreas-chave do ambiente. Muitas vezes, os privilégios são perfeitos por um lado, mas configurados incorretamente por outro. Esta postagem de blog fornecerá 'Dicas e Truques' práticos para um usuário ou função, como veremos, configurados no PostgreSQL.

As áreas temáticas que iremos focar são:
  • As funções do PostgreSQL

Você aprenderá sobre funções, atributos de função, práticas recomendadas para nomear suas funções e configurações de funções comuns.
  • O arquivo pg_hba.conf

Nesta seção, veremos um dos arquivos-chave e suas configurações, para conexões do lado do cliente e comunicação com o servidor.
  • Privilégios e restrições em nível de banco de dados, tabela e coluna.

Procurando configurar funções para desempenho e uso ideais? Suas tabelas contêm dados confidenciais, acessíveis apenas a funções privilegiadas? No entanto, com a necessidade de permitir que diferentes funções executem um trabalho limitado? Essas e outras perguntas serão expostas nesta seção.

A função do PostgreSQL sobre as funções - O que é uma 'Função' e como criar uma?


As permissões para acesso ao banco de dados no PostgreSQL são tratadas com o conceito de uma função, que é semelhante a um usuário. As funções também podem representar grupos de usuários no ecossistema PostgreSQL.

O PostgreSQL estabelece a capacidade das funções de atribuir privilégios aos objetos de banco de dados que possuem, permitindo acesso e ações a esses objetos. As funções têm a capacidade de conceder associação a outra função. Os atributos fornecem opções de personalização para autenticação de cliente permitida.

Atributos para funções através do comando CREATE ROLE, estão disponíveis na documentação oficial do PostgreSQL.

Abaixo, estão os atributos que você normalmente atribuirá ao configurar uma nova função. A maioria deles são autoexplicativos. No entanto, uma breve descrição é fornecida para esclarecer qualquer confusão junto com exemplos de uso.

SUPERUSER - Um banco de dados SUPERUSER merece uma palavra de cautela. Resumindo, papéis com este atributo podem criar outro SUPERUSER. Na verdade, esse atributo é necessário para criar outra função SUPERUSER. Como as funções com esse atributo ignoram todas as verificações de permissão, conceda esse privilégio criteriosamente.

CREATEDB - Permite que a função crie bancos de dados.

CREATEROLE - Com este atributo, uma função pode emitir o comando CREATE ROLE. Portanto, crie outros papéis.

LOGIN - Habilita a capacidade de login. Um nome de função com esse atributo pode ser usado no comando de conexão do cliente. Mais detalhes sobre este atributo com os próximos exemplos.

Certos atributos têm um comando nomeado oposto polar explícito e normalmente é o padrão quando não especificado.

ex.
SUPERUSUÁRIO | NOSUPERUSER
CREATEROLE |NOCREATEROLE
LOGIN |NOLOGIN

Vejamos alguns desses atributos em ação para várias configurações que você pode definir para começar.

Criando e descartando funções


Criar uma função é relativamente simples. Aqui está um exemplo rápido:
postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;

O que deu errado ali? Acontece que os nomes das funções não podem começar com nada além de uma letra.

"Que tal colocar o nome entre aspas duplas?" Vamos ver:
postgres=# CREATE ROLE "$money_man";
CREATE ROLE

Isso funcionou, embora provavelmente não seja uma boa ideia. Que tal um caractere especial no meio do nome?
postgres=# CREATE ROLE money$_man;
CREATE ROLE

Não há problema. Mesmo sem aspas, nenhum erro foi retornado.

Eu simplesmente não gosto da estrutura de nomes de $money_man para um usuário. Estou te deixando $money_man e começando de novo. O comando DROP ROLE cuida da remoção de uma função. Aqui está em uso.
postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;

E outro erro com a função $money_man. Novamente, recorrendo às aspas duplas.
postgres=# DROP ROLE "$money_man";
DROP ROLE

O privilégio LOGIN


Vejamos dois usuários diferentes, um com o privilégio LOGIN e outro sem. Vou atribuir-lhes senhas também.
postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE

Observação:as senhas fornecidas para as funções fictícias acima são apenas para fins de demonstração. Você deve sempre se esforçar para fornecer senhas exclusivas e protegidas ao implementar funções. Enquanto uma senha é melhor do que nenhuma senha, uma senha reforçada é ainda melhor do que uma trivial.

Vamos atribuir log_user os atributos CREATEDB e CREATEROLE com o comando ALTER ROLE.
postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Você pode verificar esses atributos definidos, verificando o catálogo pg_role. Duas colunas de interesse são rolcreaterole e rolcreatedb. Ambos são do tipo de dados Boolean, portanto, devem ser definidos como t para true para esses atributos.

Confirme com uma consulta SELECT semelhante.
postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper
Como você pode determinar as funções existentes presentes no banco de dados?

Dois métodos disponíveis são o comando psql \du ou a seleção no catálogo pg_roles.

Aqui ambos estão em uso.
postgres=> \du
List of roles
Role name | Attributes | Member of 
------------+------------------------------------------------------------+-----------
log_user | Create role, Create DB | {}
nolog_user | Cannot login | {}

postgres=> SELECT rolname FROM pg_roles;
rolname 
----------------------
nolog_user
log_user
(2 rows)

Login


Vamos dar a ambas as funções, uma oportunidade de fazer login no servidor.
psql -U nolog_user -W postgres
Password for user nolog_user: 
psql: FATAL: no pg_hba.conf entry for host "[local]", user "nolog_user", database "postgres", SSL off
psql -U log_user -W postgres
Password for user log_user: 
psql: FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off

Para resolver este problema, temos que cavar no arquivo pg_hba.conf. A solução é discutida à medida que continuamos neste post, para essa seção específica.

Resumos acionáveis

  • CREATE ROLE e sua contraparte, DROP ROLE, são seus comandos principais para implementar e remover funções.
  • ALTER ROLE lida com a alteração dos atributos de uma função.
  • As funções são válidas em todos os bancos de dados devido à definição no nível do cluster de banco de dados.
  • Lembre-se de que criar um nome de função começando com um caractere especial exige que você o 'endereça' com aspas duplas.
  • Os papéis e seus privilégios são estabelecidos usando atributos.
  • Para estabelecer papéis que precisam do atributo LOGIN por padrão, CREATE USER é um comando opcional à sua disposição. Usados ​​no lugar de CREATE ROLE role_name LOGIN, eles são essencialmente iguais.

O arquivo pg_hba.conf - Estabelecendo um terreno comum entre o servidor e o cliente


Cobrir todos os aspectos e configurações do arquivo pg_hba.conf em um post de blog seria, na melhor das hipóteses, assustador. Em vez disso, esta seção apresentará armadilhas comuns que você pode encontrar e soluções para remediá-las.

Conexões bem-sucedidas exigem um esforço conjunto de ambas as partes como um todo. As funções que se conectam ao servidor ainda devem atender às restrições de acesso definidas no nível do banco de dados, após passar as configurações no arquivo pg_hba.conf.

Exemplos relevantes dessa relação são incluídos à medida que esta seção avança.

Para localizar seu arquivo pg_hba.conf, emita uma consulta SELECT semelhante, na VIEW pg_settings. Você deve estar logado como SUPERUSER para consultar esta VIEW.
postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting 
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)

O arquivo pg_hba.conf contém registros que especificam um dos sete formatos disponíveis para uma determinada solicitação de conexão. Veja o espectro completo aqui.

Para os propósitos desta postagem no blog, veremos as configurações que você pode usar para um ambiente local.

Talvez este servidor seja para seu aprendizado e estudo contínuos (como o meu).

Devo fazer uma observação especial de que essas configurações não são as configurações ideais para um sistema protegido contendo vários usuários.

Os campos para este tipo de conexão são:
local database user auth-method [auth-options]

Onde eles significam:

local - as conexões são tentadas com soquetes de domínio Unix.

banco de dados - Especifica o(s) banco(s) de dados nomeado(s) para esta correspondência de registro.

user - O nome de usuário do banco de dados correspondente a este registro. Uma lista separada por vírgulas de vários usuários ou todos também é permitida para este campo.

auth-method - É usado quando uma conexão corresponde a esse registro exclusivo. As opções possíveis para este campo são:
  • confiança
  • rejeitar
  • scram-sha-256
  • md5
  • senha
  • gss
  • sspi
  • identidade
  • par
  • ldap
  • raio
  • certificado
  • pam
  • bd

As linhas definidas no arquivo pg_hba.conf para as funções nolog_user e log_user são assim:
local all nolog_user password
local all log_user password

Nota:Como a senha é enviada em texto não criptografado, ela não deve ser usada em ambientes não confiáveis ​​com redes não confiáveis.

Vejamos três colunas interessantes da VIEW pg_hba_file_rules com a consulta abaixo. Novamente, sua função precisa do atributo SUPERUSER para consultar essa VIEW.
postgres=# SELECT database, user_name, auth_method
postgres-# FROM pg_hba_file_rules
postgres-# WHERE CAST(user_name AS TEXT) LIKE '%log_user%';
database | user_name | auth_method 
----------+--------------+-------------
{all} | {nolog_user} | password
{all} | {log_user} | password
(2 rows)

Podemos ver informações idênticas nas linhas fornecidas acima encontradas no arquivo pg_hba.conf como podemos ver na consulta que acompanha. À primeira vista, parece que ambas as funções podem fazer login.

Vamos testar e confirmar.
psql -U nolog_user -W postgres
Password for user nolog_user: 
psql: FATAL: role "nolog_user" is not permitted to log in
psql -U log_user -W postgres
Password for user log_user: 
psql (10.1)
Type "help" for help.
postgres=>

O ponto chave aqui é que, embora nolog_user e log_user sejam capazes de efetuar login de acordo com o arquivo pg_hba.conf, apenas log_user tem permissão para efetuar login.

Onde log_user passou as restrições de acesso de nível de banco de dados (por ter o atributo LOGIN), nolog_user não.

Vamos editar a linha do log_user no arquivo pg_hba.conf e alterar o nome do banco de dados que esta função tem permissão para acessar. Aqui está a mudança, indicando que o log_user agora pode fazer login apenas no banco de dados de teste.
local trial log_user password

Primeiro vamos tentar fazer login no banco de dados postgres, ao qual log_user tinha acesso anteriormente devido ao sinalizador all.
$ psql -U log_user -W postgres
Password for user log_user: 
psql: FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off

Agora, com o banco de dados de teste, log_user tem privilégio para
$ psql -U log_user -W trial
Password for user log_user: 
psql (10.1)
Type "help" for help.
trial=>

Nenhum erro e o prompt trial=> mostra o banco de dados conectado no momento.

Essas configurações também se aplicam ao ambiente do servidor, uma vez que uma conexão é estabelecida.

Vamos tentar uma conexão com esse banco de dados postgres novamente:
trial=> \c postgres;
Password for user log_user: 
FATAL: no pg_hba.conf entry for host "[local]", user "log_user", database "postgres", SSL off
Previous connection kept

Por meio dos exemplos apresentados aqui, você deve estar ciente das opções de customização para as funções em seu cluster.

Nota:Muitas vezes, é necessário recarregar o arquivo pg_hba.conf para que as alterações tenham efeito.

Use o utilitário pg_ctl para recarregar seu servidor.

A sintaxe seria:
pg_ctl reload [-D datadir] [-s]

Para saber onde está seu datadir, você pode consultar a VIEW do sistema pg_settings, se estiver logado como SUPERUSER com uma consulta SELECT semelhante à abaixo.
postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
           setting           
-----------------------------
 /var/lib/postgresql/10/main
(1 row)

Então, dê seu shell para o usuário postgres (ou outro SUPERUSER) com:
$ sudo -u postgres bash

A menos que você tenha adicionado o utilitário pg_ctl ao seu $PATH, você deve qualificá-lo totalmente para uso e, em seguida, passar o comando para executar, juntamente com o local do datadir.

Aqui está um exemplo:
$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled

Vamos verificar o status do servidor com:
$ /usr/lib/postgresql/10/bin/pg_ctl status -D /var/lib/postgresql/10/main
pg_ctl: server is running (PID: 1415)
/usr/lib/postgresql/10/bin/postgres "-D" "/var/lib/postgresql/10/main" "-c" "config_file=/etc/postgresql/10/main/postgresql.conf"

Resumos acionáveis

  • As funções devem passar pelos requisitos do arquivo pg_hba.conf e dos privilégios de acesso no nível do banco de dados.
  • O arquivo
  • pg_hba.conf é verificado de cima para baixo, para cada solicitação de conexão. A ordem no arquivo é significativa.

Privilégios e Restrições de Banco de Dados, Tabela e Coluna - Adaptar Funções para Tarefas e Responsabilidades


Para que os papéis usem objetos de banco de dados (tabelas, visualizações, colunas, funções, etc...), eles devem receber privilégios de acesso a eles.

O comando GRANT define esses privilégios essenciais.

Veremos alguns exemplos para entender a essência de seu uso.

Criando bancos de dados


Como log_user recebeu os atributos CREATEDB e CREATEROLE, podemos usar essa função para criar um banco de dados de teste chamado trial.
postgres=> CREATE DATABASE trial:
CREATE DATABASE

Além de criar um novo ROLE:
postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE

Por fim, log_user se conectará ao novo banco de dados de avaliação:
postgres=> \c trial;
Password for user log_user: 
You are now connected to database "trial" as user "log_user".
trial=>

Observe que o prompt mudou para o nome 'trial', indicando que estamos conectados a esse banco de dados.

Vamos utilizar log_user para CRIAR uma tabela simulada.
trial=> CREATE TABLE another_workload(
trial(> id INTEGER,
trial(> first_name VARCHAR(20),
trial(> last_name VARCHAR(20),
trial(> sensitive_info TEXT);
CREATE TABLE

A função log_user criou recentemente uma função auxiliar, db_user. Exigimos que db_user tenha privilégios limitados para a tabela another_workload.

Sem dúvida, a coluna sensitive_info não deve ser acessada por esta função. Os comandos INSERT, UPDATE e DELETE também não devem ser concedidos neste momento, até que db_user atenda a certas expectativas.

No entanto, db_user é necessário para emitir consultas SELECT. Como podemos limitar as habilidades dessas funções na tabela another_workload?

Primeiro, vamos examinar a sintaxe exata encontrada nos documentos do comando GRANT do PostgreSQL, no nível da tabela.
GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]

Em seguida, implementamos os requisitos estabelecidos para a função db_user, aplicando uma sintaxe específica.
trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT

Observe que logo após a palavra-chave SELECT, listamos as colunas que db_user pode acessar. Até que seja alterado, se db_user tentar consultas SELECT na coluna sensitive_info, ou qualquer outro comando para esse assunto, essas consultas não serão executadas.

Com o db_user logado, colocaremos isso em prática, tentando uma consulta SELECT para retornar todas as colunas e registros da tabela.
trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload

A coluna sensitive_info está incluída nesta consulta. Portanto, nenhum registro é retornado para db_user.

Mas db_user pode SELECT as colunas permitidas
trial=> SELECT id, first_name, last_name
trial-> FROM another_workload;
id | first_name | last_name 
-----+------------+-----------
10 | John | Morris
191 | Jannis | Harper
2 | Remmy | Rosebuilt
(3 rows)

Isso funciona muito bem.

Testaremos os comandos INSERT, UPDATE e DELETE também.
trial=> INSERT INTO another_workload(id,first_name,last_name,sensitive_info)
VALUES(17,'Jeremy','Stillman','key code:400Z');
ERROR: permission denied for relation another_workload
trial=> UPDATE another_workload
trial-> SET id = 101
trial-> WHERE id = 10;
ERROR: permission denied for relation another_workload
trial=> DELETE FROM another_workload
trial-> WHERE id = 2;;
ERROR: permission denied for relation another_workload

Ao não atribuir os comandos INSERT, UPDATE ou DELETE a db_user, a função tem acesso negado para usá-los.

Com a infinidade de opções disponíveis, configurar sua função é praticamente ilimitado. Você pode torná-los totalmente funcionais, capazes de executar qualquer comando ou tão restritos quanto seus requisitos exigirem.

Resumos acionáveis

  • As funções recebem privilégios de acesso a objetos de banco de dados por meio do comando GRANT.
  • Objetos de banco de dados e comandos nesses objetos são altamente configuráveis ​​no ambiente PostgreSQL.

Fechando


Por meio dos exemplos fornecidos nesta postagem do blog, você deve ter uma melhor compreensão de:
  1. Criando uma função com atributos específicos.
  2. Configurando uma conexão viável entre o cliente e o servidor, permitindo o acesso de login de funções aos bancos de dados.
  3. Personalizar altamente suas funções para atender aos requisitos individuais de acesso em nível de banco de dados, tabela e coluna, implementando os atributos necessários.