sql >> Base de Datos >  >> RDS >> PostgreSQL

Privilegios de PostgreSQL y administración de usuarios:lo que debe saber

La gestión de usuarios dentro de PostgreSQL puede ser complicada. Por lo general, los nuevos usuarios se administran, en conjunto, dentro de un par de áreas clave en el entorno. A menudo, los privilegios son perfectos en un frente, pero están configurados incorrectamente en el otro. Esta publicación de blog proporcionará 'Consejos y trucos' prácticos para un usuario o rol, tal como lo conoceremos, configurado dentro de PostgreSQL.

Las áreas temáticas en las que nos centraremos son:

  • Asumir roles de PostgreSQL

Aprenderá sobre roles, atributos de roles, mejores prácticas para nombrar sus roles y configuraciones de roles comunes.

  • El archivo pg_hba.conf

En esta sección, veremos uno de los archivos clave y su configuración, para las conexiones del lado del cliente y la comunicación con el servidor.

  • Privilegios y restricciones a nivel de base de datos, tabla y columna.

¿Desea configurar funciones para un rendimiento y un uso óptimos? ¿Sus tablas contienen datos confidenciales, solo accesibles para roles privilegiados? ¿Sin embargo, con la necesidad de permitir que diferentes roles realicen un trabajo limitado? Estas preguntas y más serán expuestas en esta sección.

Asumir roles de PostgreSQL:¿Qué es un 'Rol' y cómo crear uno?

Los permisos para el acceso a la base de datos dentro de PostgreSQL se manejan con el concepto de rol, que es similar a un usuario. Los roles también pueden representar grupos de usuarios en el ecosistema de PostgreSQL.

PostgreSQL establece la capacidad de los roles para asignar privilegios a los objetos de la base de datos que poseen, lo que permite el acceso y las acciones a esos objetos. Los roles tienen la capacidad de otorgar membresía a otro rol. Los atributos proporcionan opciones de personalización para la autenticación de clientes permitida.

Los atributos para roles a través del comando CREATE ROLE están disponibles en la documentación oficial de PostgreSQL.

A continuación, se encuentran los atributos que comúnmente asignará al configurar un nuevo rol. La mayoría de estos se explican por sí mismos. Sin embargo, se proporciona una breve descripción para aclarar cualquier confusión junto con usos de ejemplo.

SUPERUSUARIO:un SUPERUSUARIO de una base de datos merece una advertencia. En pocas palabras, los roles con este atributo pueden crear otro SUPERUSUARIO. De hecho, este atributo es necesario para crear otro rol SUPERUSUARIO. Dado que los roles con este atributo pasan por alto todas las comprobaciones de permisos, otorgue este privilegio juiciosamente.

CREATEDB:permite que el rol cree bases de datos.

CREATEROLE:con este atributo, un rol puede emitir el comando CREATE ROLE. Por lo tanto, cree otros roles.

INICIAR SESIÓN:activa la capacidad de iniciar sesión. Se puede utilizar un nombre de rol con este atributo en el comando de conexión del cliente. Más detalles sobre este atributo con próximos ejemplos.

Ciertos atributos tienen un comando con nombre opuesto polar explícito y, por lo general, es el valor predeterminado cuando no se especifica.

p. ej.
SUPERUSUARIO | NOSUPERUSUARIO
CREATEROLE |NOCREATEROLE
INICIAR SESIÓN |NOLOGIN

Veamos algunos de estos atributos en acción para varias configuraciones que puede configurar para comenzar.

Creación y eliminación de roles

Crear un rol es relativamente sencillo. He aquí un ejemplo rápido:

postgres=# CREATE ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: CREATE ROLE $money_man;

¿Qué salió mal allí? Resulta que los nombres de los roles no pueden comenzar con otra cosa que no sea una letra.

"¿Qué hay de envolver el nombre entre comillas dobles?" Veamos:

postgres=# CREATE ROLE "$money_man";
CREATE ROLE

Eso funcionó, aunque probablemente no sea una buena idea. ¿Qué tal un carácter especial en medio del nombre?

postgres=# CREATE ROLE money$_man;
CREATE ROLE

No hay problema allí. Incluso sin comillas dobles, no se devolvió ningún error.

Simplemente no me gusta la estructura de nombre de $money_man para un usuario. Te dejaré $money_man y empezaré de nuevo. El comando DROP ROLE se encarga de eliminar un rol. Aquí está en uso.

postgres=# DROP ROLE $money_man;
ERROR: syntax error at or near "$"
LINE 1: DROP ROLE $money_man;

Y otro error con el rol $money_man. Nuevamente, recurriendo a las comillas dobles es.

postgres=# DROP ROLE "$money_man";
DROP ROLE

El privilegio de INICIO DE SESIÓN

Veamos dos usuarios diferentes, uno con el privilegio LOGIN y otro sin él. También les asignaré contraseñas.

postgres=# CREATE ROLE nolog_user WITH PASSWORD 'pass1';
CREATE ROLE
postgres=# CREATE ROLE log_user WITH LOGIN PASSWORD 'pass2';
CREATE ROLE

Nota:Las contraseñas proporcionadas para los roles ficticios anteriores son solo para fines de demostración. Siempre debe esforzarse por proporcionar contraseñas únicas y protegidas al implementar roles. Si bien una contraseña es mejor que ninguna contraseña, una contraseña reforzada es incluso mejor que una trivial.

Asignemos log_user los atributos CREATEDB y CREATEROLE con el comando ALTER ROLE.

postgres=# ALTER ROLE log_user CREATEROLE CREATEDB;
ALTER ROLE

Puede verificar estos atributos establecidos consultando el catálogo pg_role. Dos columnas de interés son rolcreaterol y rolcreatedb. Ambos son del tipo de datos booleano, por lo que deben establecerse en t para que sean verdaderos para estos atributos.

Confirme con una consulta SELECT similar.

postgres=# SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = 'log_user';
rolcreaterole | rolcreatedb 
---------------+-------------
t | t
(1 row)
Descargue el documento técnico hoy Administración y automatización de PostgreSQL con ClusterControlObtenga información sobre lo que necesita saber para implementar, monitorear, administrar y escalar PostgreSQLDescargar el documento técnico

¿Cómo puede determinar los roles existentes presentes en la base de datos?

Dos métodos disponibles son el comando psql \du o seleccionar del catálogo pg_roles.

Aquí ambos están en 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)

Iniciar sesión

Démosle a ambos roles la oportunidad de iniciar sesión en el 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, tenemos que profundizar en ese archivo pg_hba.conf. La solución se analiza a medida que continuamos en esta publicación, en esa sección específica.

Conclusiones procesables

  • CREATE ROLE y su contraparte, DROP ROLE, son sus comandos para implementar y eliminar roles.
  • ALTER ROLE maneja el cambio de atributos de un rol.
  • Los roles son válidos en todas las bases de datos debido a la definición en el nivel de clúster de la base de datos.
  • Tenga en cuenta que crear un nombre de función que comience con un carácter especial requiere que lo "dirija" con comillas dobles.
  • Los roles y sus privilegios se establecen mediante atributos.
  • Para establecer roles que necesitan el atributo INICIO DE SESIÓN de forma predeterminada, CREAR USUARIO es un comando opcional a su disposición. Usados ​​en lugar de CREATE ROLE role_name LOGIN, son esencialmente iguales.

El archivo pg_hba.conf - Establecer un terreno común entre el servidor y el cliente

Cubrir todos los aspectos y configuraciones para el archivo pg_hba.conf en una publicación de blog sería, en el mejor de los casos, desalentador. En su lugar, esta sección presentará las trampas comunes que puede encontrar y las soluciones para remediarlas.

Las conexiones exitosas requieren un esfuerzo conjunto de ambas partes como un todo. Los roles que se conectan al servidor aún deben cumplir con las restricciones de acceso establecidas en el nivel de la base de datos, después de pasar la configuración en el archivo pg_hba.conf.

Se incluyen ejemplos relevantes de esta relación a medida que avanza esta sección.

Para ubicar su archivo pg_hba.conf, emita una consulta SELECCIONAR similar, en pg_settings VIEW. Debe iniciar sesión como SUPERUSUARIO para consultar esta VISTA.

postgres=# SELECT name, setting
FROM pg_settings WHERE name LIKE '%hba%';
name | setting 
----------+-------------------------------------
hba_file | /etc/postgresql/10/main/pg_hba.conf
(1 row)

El archivo pg_hba.conf contiene registros que especifican uno de los siete formatos disponibles para una solicitud de conexión determinada. Vea el espectro completo aquí .

A los efectos de esta publicación de blog, veremos la configuración que puede usar para un entorno local.

Tal vez este servidor sea para su aprendizaje y estudio continuos (como lo es el mío).

Debo hacer una nota especial de que estas configuraciones no son las configuraciones óptimas para un sistema reforzado que contiene múltiples usuarios.

Los campos para este tipo de conexión son:

local database user auth-method [auth-options]

Donde significan:

local:las conexiones se intentan con sockets de dominio Unix.

base de datos:especifica las bases de datos nombradas para esta coincidencia de registros.

usuario:el nombre de usuario de la base de datos que coincide con este registro. También se permite una lista separada por comas de múltiples usuarios o todos para este campo.

método de autenticación:se usa cuando una conexión coincide con este registro único. Las opciones posibles para este campo son:

  • confianza
  • rechazar
  • lárgate-sha-256
  • md5
  • contraseña
  • gss
  • sspi
  • identificador
  • compañero
  • ldap
  • radio
  • certificado
  • pam
  • bsd

Las líneas establecidas en el archivo pg_hba.conf para los roles nolog_user y log_user se ven así:

local all nolog_user password
local all log_user password

Nota:dado que la contraseña se envía en texto no cifrado, no se debe usar en entornos que no sean de confianza con redes que no sean de confianza.

Veamos tres columnas interesantes de pg_hba_file_rules VIEW con la siguiente consulta. Una vez más, su función necesita el atributo SUPERUSUARIO para consultar esta VISTA.

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 información idéntica de las líneas proporcionadas anteriormente que se encuentran en el archivo pg_hba.conf como podemos ver en la consulta adjunta. A primera vista, parece que ambos roles pueden iniciar sesión.

Probaremos y confirmaremos.

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

El punto clave aquí es que, aunque nolog_user y log_user pueden iniciar sesión de acuerdo con el archivo pg_hba.conf, solo log_user puede iniciar sesión.

Donde log_user pasó las restricciones de acceso a nivel de base de datos (Al tener el atributo LOGIN), nolog_user no lo hizo.

Editemos la línea de log_user en el archivo pg_hba.conf y cambiemos el nombre de la base de datos a la que este rol puede acceder. Este es el cambio, que indica que log_user ahora solo puede iniciar sesión en la base de datos de prueba.

local trial log_user password

Primero, intentemos iniciar sesión en la base de datos de postgres, a la que log_user tenía acceso anteriormente debido a la marca 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

Ahora, con la base de datos de prueba, log_user tiene privilegios para

$ psql -U log_user -W trial
Password for user log_user: 
psql (10.1)
Type "help" for help.
trial=>

No hay ningún error allí y el indicador trial=> muestra la base de datos conectada actualmente.

Esta configuración también se aplica dentro del entorno del servidor, una vez que se establece una conexión.

Intentemos una conexión a esa base de datos de postgres nuevamente:

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

A través de los ejemplos presentados aquí, debe conocer las opciones de personalización de los roles en su clúster.

Nota:A menudo, es necesario volver a cargar el archivo pg_hba.conf para que los cambios surtan efecto.

Utilice la utilidad pg_ctl para recargar su servidor.

La sintaxis sería:

pg_ctl reload [-D datadir] [-s]

Para saber dónde está su directorio de datos, puede consultar la VISTA del sistema pg_settings, si inició sesión como SUPERUSUARIO con una consulta SELECCIONAR similar a la siguiente.

postgres=# SELECT setting FROM pg_settings WHERE name = 'data_directory';
           setting           
-----------------------------
 /var/lib/postgresql/10/main
(1 row)

Luego, entregue su shell al usuario de postgres (u otro SUPERUSUARIO) con:

$ sudo -u postgres bash

A menos que haya agregado la utilidad pg_ctl a su $PATH, debe calificarla por completo para su uso, luego pasar el comando para ejecutar, junto con la ubicación de datadir.

Aquí hay un ejemplo:

$ /usr/lib/postgresql/10/bin/pg_ctl reload -D /var/lib/postgresql/10/main
server signaled

Verifiquemos el estado del servidor con:

$ /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"

Conclusiones procesables

  • Los roles deben pasar los requisitos del archivo pg_hba.conf y los privilegios de acceso a nivel de base de datos.
  • El archivo pg_hba.conf se revisa de arriba hacia abajo, para cada solicitud de conexión. El orden en el archivo es significativo.

Privilegios y restricciones de bases de datos, tablas y columnas:roles personalizados para tareas y responsabilidades

Para que los roles utilicen los objetos de la base de datos (tablas, vistas, columnas, funciones, etc...), se les deben otorgar privilegios de acceso a ellos.

El comando GRANT define estos privilegios esenciales.

Repasaremos algunos ejemplos para obtener la esencia de su uso.

Crear bases de datos

Dado que a log_user se le otorgaron los atributos CREATEDB y CREATEROLE, podemos usar este rol para crear una base de datos de prueba llamada trial.

postgres=> CREATE DATABASE trial:
CREATE DATABASE

Además de crear un nuevo ROL:

postgres=> CREATE ROLE db_user WITH LOGIN PASSWORD 'scooby';
CREATE ROLE

Finalmente, log_user se conectará a la nueva base de datos de prueba:

postgres=> \c trial;
Password for user log_user: 
You are now connected to database "trial" as user "log_user".
trial=>

Observe que el indicador cambió al nombre 'prueba', lo que indica que estamos conectados a esa base de datos.

Utilicemos log_user para CREAR una tabla 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

El rol log_user creó recientemente un rol auxiliar, db_user. Requerimos que db_user tenga privilegios limitados para la tabla another_workload.

Indudablemente, este rol no debería acceder a la columna de información sensible. Los comandos INSERT, UPDATE y DELETE tampoco deben otorgarse en este momento, hasta que db_user cumpla con ciertas expectativas.

Sin embargo, se requiere db_user para emitir consultas SELECT. ¿Cómo podemos limitar las capacidades de estos roles dentro de la tabla another_workload?

Primero, examinemos la sintaxis exacta que se encuentra en los documentos del comando GRANT de PostgreSQL, a nivel de tabla.

GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column_name [, ...] )
[, ...] | ALL [ PRIVILEGES ] ( column_name [, ...] ) }
ON [ TABLE ] table_name [, ...]
TO role_specification [, ...] [ WITH GRANT OPTION ]

A continuación, implementamos los requisitos establecidos para el rol db_user, aplicando una sintaxis específica.

trial=> GRANT SELECT (id, first_name, last_name) ON TABLE another_workload TO db_user;
GRANT

Observe que justo después de la palabra clave SELECT, enumeramos las columnas a las que puede acceder db_user. Hasta que se cambie, si db_user intenta realizar consultas SELECT en la columna de información sensible, o cualquier otro comando, esas consultas no se ejecutarán.

Con db_user conectado, pondremos esto en práctica, intentando una consulta SELECT para devolver todas las columnas y registros de la tabla.

trial=> SELECT * FROM another_workload;
ERROR: permission denied for relation another_workload

La columna sensitivo_info se incluye en esta consulta. Por lo tanto, no se devuelve ningún registro a db_user.

Pero db_user puede SELECCIONAR las columnas 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)

Eso funciona bien.

También probaremos los comandos INSERTAR, ACTUALIZAR y ELIMINAR.

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

Al no asignar los comandos INSERTAR, ACTUALIZAR o ELIMINAR a db_user, se niega el acceso al rol para usarlos.

Con la plétora de opciones disponibles, la configuración de su función es prácticamente ilimitada. Puede hacerlos completamente funcionales, capaces de ejecutar cualquier comando, o tan restringidos como lo dicten sus requisitos.

Conclusiones procesables

  • Los roles reciben privilegios de acceso a los objetos de la base de datos a través del comando GRANT.
  • Los objetos de la base de datos y los comandos contra esos objetos son altamente configurables dentro del entorno de PostgreSQL.

Cierre

A través de los ejemplos proporcionados en esta publicación de blog, debería tener una mejor comprensión de:

  1. Crear un rol con atributos específicos.
  2. Establecer una conexión viable entre el cliente y el servidor, permitiendo que los roles inicien sesión en las bases de datos.
  3. Alta personalización de sus roles para cumplir con los requisitos individuales de acceso a nivel de base de datos, tabla y columna mediante la implementación de los atributos necesarios.