设置帐户安全策略
背景信息
GaussDB(for openGauss)为帐户提供了自动锁定和解锁帐户、手动锁定和解锁异常帐户和删除不再使用的帐户等一系列的安全措施,保证数据安全。
自动锁定和解锁帐户
- 为了保证帐户安全,如果用户输入密码次数超过一定次数(failed_login_attempts),系统将自动锁定该帐户,默认值为10。次数设置越小越安全,但是在使用过程中会带来不便。
- 当帐户被锁定时间超过设定值(password_lock_time),则当前帐户自动解锁,默认值为1天。时间设置越长越安全,但是在使用过程中会带来不便。
- 参数password_lock_time的整数部分表示天数,小数部分可以换算成时、分、秒,如:password_lock_time=1.5,表示1天零12小时。
- 当failed_login_attempts设置为0时,表示不限制密码错误次数。当password_lock_time设置为0时,表示即使超过密码错误次数限制导致帐户锁定,也会在短时间内自动解锁。因此,只有两个配置参数都为正数时,才可以进行常规的密码失败检查、帐户锁定和解锁操作。
- 这两个参数的默认值都符合安全标准,用户可以根据需要重新设置参数,提高安全等级。建议用户使用默认值。
- 配置failed_login_attempts和password_lock_time参数的方法请参考用户指南。
- 由于配置对外提供接口服务的CN数量不同,数据库在帐户锁定上提供两种模式供用户选择:
- 单CN模式:集群部署时配置一个CN对外提供接口服务。
- 多CN模式:集群部署时配置多个CN对外提供接口服务。
安全模式下单CN具备帐户锁定机制。高并发模式下提供多个CN,每个节点都具备帐户锁定机制,但各个节点的帐户锁定信息并不共享,每个节点帐户锁定是独立裁定的,在高并发的需求下,用户可以选择此模式,但要控制CN个数,以控制密码暴力破解风险。另外各节点的自动解锁时间依据的是各节点操作系统的时钟,用户集群部署时要确保各集群节点时间同步保持一致性,可以使用NTP来配置,否则会有各节点帐户解锁时间不一致的风险。
手动锁定和解锁帐户
若管理员发现某帐户被盗、非法访问等异常情况,可手动锁定该帐户。当管理员认为帐户恢复正常后,可手动解锁该帐户。
以手动锁定和解锁用户joe为例,用户的创建请参见用户,命令格式如下:
- 手动锁定
1 2
postgres=# ALTER USER joe ACCOUNT LOCK; ALTER ROLE
- 手动解锁
1 2
postgres=# ALTER USER joe ACCOUNT UNLOCK; ALTER ROLE
删除不再使用的帐户
当确认帐户不再使用,管理员可以删除帐户。该操作不可恢复。
当删除的用户正处于活动状态时,此会话状态不会立马断开,用户在会话状态断开后才会被完全删除。
以删除帐户joe为例,命令格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | postgres=# DROP USER joe CASCADE;
DROP ROLE
当在多个用户多个数据库多个schema赋予权限的场景下,drop某个用户,由于该用户拥有其他用户赋予的权限,因此直接删除会产生如下报错。
postgres=# drop user test1 cascade;
ERROR: role "test1" cannot be dropped because some objects depend on it
在这种场景只能通过查看系统表找到该用户被其他用户赋予的权限,并且登录该用户手动删除其赋予的权限,才能执行drop user,下面通过一个例子来详细讲解如何处理这种场景。
登录系统库,查看该用户的OID
postgres=# select oid from pg_roles where rolname='test1';
oid
-------
16386
(1 row)
通过查看pg_shdepend 该视图来获取该用户被赋予的权限,可以看到该用户存在被其他用户赋予的两个权限,先处理第一个。
postgres=# select * from pg_shdepend where refobjid='16386';
dbid | classid | objid | objsubid | refclassid | refobjid | deptype | objfile
-------+---------+-------+----------+------------+----------+---------+---------
16394 | 826 | 16400 | 0 | 1260 | 16386 | a |
16394 | 2615 | 16399 | 0 | 1260 | 16386 | a |
查看pg_database 视图获取所在数据库,根据结果可知在test数据库。
postgres=# select * from pg_database where oid='16394'
datname | datdba | encoding | datcollate | datctype | datistemplate | datallowconn | datconnlimit | datlastsysoid | datfrozenxid | dattablespace | datcompatibility | datacl
| datfrozenxid64
---------+--------+----------+-------------+-------------+---------------+--------------+--------------+---------------+--------------+---------------+------------------+--------------------------------------
-------------+----------------
test | 10 | 7 | en_US.UTF-8 | en_US.UTF-8 | f | t | -1 | 16268 | 1985 | 1663 | MYSQL | {=Tc/wangwei,wangwei=CTc/wangwei,admi
n=c/wangwei} | 1985
(1 row)
登录到test数据库
[wangwei@euler_phy_194 opengauss]$ gsql -p 3730 -d test
gsql ((GaussDB Kernel V500R002C00 build 43ff9cd7) compiled at 2021-04-17 14:30:45 commit 0 last mr 330 debug)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
通过pg_class 查看权限的类型,where条件的oid即是之前pg_shdepend 视图中查到的classid。
test=# select * from pg_class where oid = 826;
relname | relnamespace | reltype | reloftype | relowner | relam | relfilenode | reltablespace | relpages | reltuples | relallvisible | reltoastrelid | reltoastidxid | reldeltarelid | reldeltaidx | rel
cudescrelid | relcudescidx | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relhaspkey | relhasrules | relhastriggers | relhassubclass | relcmprs | relhasclusterkey
| relrowmovement | parttype | relfrozenxid | relacl | reloptions | relreplident | relfrozenxid64 | relbucket | relbucketkey
----------------+--------------+---------+-----------+----------+-------+-------------+---------------+----------+-----------+---------------+---------------+---------------+---------------+-------------+----
------------+--------------+-------------+-------------+----------------+---------+----------+-----------+------------+------------+-------------+----------------+----------------+----------+-----------------
-+----------------+----------+--------------+--------------+------------+--------------+----------------+-----------+--------------
pg_default_acl | 11 | 11810 | 0 | 10 | 0 | 16063 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | t | f | p | r | 4 | 0 | t | f | f | f | f | 0 | f
| f | n | 0 | {=r/wangwei} | | n | 1985 | |
(1 row)
可以看到该用户被其他用户授予了表或者视图的ACL默认权限,查看pg_default_acl视图,oid即是之前pg_shdepend 中的查到的objid。
test=# select * from pg_default_acl oid = 16400;;
defaclrole | defaclnamespace | defaclobjtype | defaclacl | oid
------------+-----------------+---------------+---------------------------------------+-------
16395 | 16399 | r | {wangwei=arwd/admin,test1=arwd/admin} | 16400
(1 row)
根据该视图的defaclacl字段可以看到,test1用户被admin用户赋予了默认权限,下一步我们需要找到具体授予权限的对象(哪个表或者视图)。
通过pg_namespace 查看对象的名字,其中oid即是pg_default_acl 中查到的defaclnamespace,通过视图可以看出test1用户被admin用户授予了schema test_schema_1的权限。
test=# select * from pg_namespace where oid = 16399;
nspname | nspowner | nsptimeline | nspacl | in_redistribution | nspblockchain
---------------+----------+-------------+---------------------------------------+-------------------+---------------
test_schema_1 | 10 | 0 | {wangwei=UC/wangwei,admin=UC/wangwei} | n | f
(1 row)
用admin登录test数据库,执行ALTER DEFAULT PRIVILEGES IN SCHEMA test_schema_1 revoke all privileges ON TABLES from test1;收回admin用户向test1赋予的scheme 默认权限。
test=# ALTER DEFAULT PRIVILEGES IN SCHEMA test_schema_1 revoke all privileges ON TABLES from test1;
ALTER DEFAULT PRIVILEGES
下面处理第二个权限,登录系统库,查看pg_database 视图获取所在数据库,根据结果可知在test数据库。
postgres=# select * from pg_database where oid='16394'
datname | datdba | encoding | datcollate | datctype | datistemplate | datallowconn | datconnlimit | datlastsysoid | datfrozenxid | dattablespace | datcompatibility | datacl
| datfrozenxid64
---------+--------+----------+-------------+-------------+---------------+--------------+--------------+---------------+--------------+---------------+------------------+--------------------------------------
-------------+----------------
test | 10 | 7 | en_US.UTF-8 | en_US.UTF-8 | f | t | -1 | 16268 | 1985 | 1663 | MYSQL | {=Tc/wangwei,wangwei=CTc/wangwei,admi
n=c/wangwei} | 1985
(1 row)
登录到test数据库。
[wangwei@euler_phy_194 opengauss]$ gsql -p 3730 -d test
查看视图pg_class ,其中oid即是pg_shdepend 表中的第二行的classid。
postgres=# select * from pg_class where oid='2615';
relname | relnamespace | reltype | reloftype | relowner | relam | relfilenode | reltablespace | relpages | reltuples | relallvisible | reltoastrelid | reltoastidxid | reldeltarelid | reldeltaidx | relcu
descrelid | relcudescidx | relhasindex | relisshared | relpersistence | relkind | relnatts | relchecks | relhasoids | relhaspkey | relhasrules | relhastriggers | relhassubclass | relcmprs | relhasclusterkey |
relrowmovement | parttype | relfrozenxid | relacl | reloptions | relreplident | relfrozenxid64 | relbucket | relbucketkey
--------------+--------------+---------+-----------+----------+-------+-------------+---------------+----------+-----------+---------------+---------------+---------------+---------------+-------------+------
----------+--------------+-------------+-------------+----------------+---------+----------+-----------+------------+------------+-------------+----------------+----------------+----------+------------------+
----------------+----------+--------------+--------------+------------+--------------+----------------+-----------+--------------
pg_namespace | 11 | 11787 | 0 | 10 | 0 | 15947 | 0 | 1 | 20 | 1 | 0 | 0 | 0 | 0 |
0 | 0 | t | f | p | r | 6 | 0 | t | f | f | f | f | 0 | f |
f | n | 0 | {=r/wangwei} | | n | 1985 | |
(1 row)
根据结果可以看出是pg_namespace类型,查看pg_namespace系统视图,oid即是pg_shdepend 第二行objid。
test=# select * from pg_namespace where oid='16399';
nspname | nspowner | nsptimeline | nspacl | in_redistribution | nspblockchain
---------------+----------+-------------+-------------------------------------------------------+-------------------+---------------
test_schema_1 | 10 | 0 | {wangwei=UC/wangwei,admin=UC/wangwei,test1=U/wangwei} | n | f
(1 row)
通过该视图的nspacl可以看出test1用户的test_schema_1 视图被权限被wangwei用户赋权,因此通过wangwei用户登录test库,执行revoke all on schema test_schema_1 from test1,回收赋予test1用户的权限。
test=# revoke all on schema test_schema_1 from test1;
REVOKE
至此test1用户的被其他用户赋予的权限已经全部清除了,接下来只要执行drop user命令就可以了。
postgres=# drop user test1 cascade;
DROP ROLE
|
