PG 数据库安全

Wesley13
• 阅读 687

身份鉴别

PostgreSQL默认使用5432端口作为连接端口,如果数据库是在互联网环境中,则建议改用其他端口,默认端口容易被利用发起攻击。

pg_hba.conf的配置原则

需要配置合理的pg_hba内容,将连接数据库的权限控制到最小。
目前支持的认证方式有ident、password、LDAP、证书认证等。
在生产环境中,以下几点必须保证:

  • 不使用trust认证方式
  • 密码认证方式必须采用MD5加密方式,网络传输过程采用密文传输
  • superuser只能通过本地socket连接,不能通过网络连接
  • postgres.conf中的listen_address参数值禁止为 '*'

用户密码复杂度

在创建或修改数据库中用户的密码时,必须强制限制密码的复杂度,比如包含字母大小写、数字、特殊字符、密码长度等,防止弱密码被暴力破解。
在PostgreSQL中,可以使用passwordcheck模块来简单的对用户设置的密码进行检测,如果复杂度过低,则会返回error信息,相关语句回滚。
要启用这个模块,需要将passwordcheck添加到postgres.conf中的shared_preload_libraries参数中,并重启服务。

postgres@postgres:5432 # show shared_preload_libraries ;
     shared_preload_libraries     
----------------------------------
 pg_stat_statements,passwordcheck
(1 row

postgres@postgres:5432 # alter role  user01 with password '12345';
ERROR:  password is too short
postgres@postgres:5432 #  alter role user01 with password '12345678';
ERROR:  password must contain both letters and nonletters
postgres@postgres:5432 # alter role user01 with password 'a12345678';
ALTER ROLE

用户密码有效期

用户密码必须在一个有效期之后失效,比如三个月。在PostgreSQL中可以通过制定role的有效期来强制用户更换密码。

postgres@postgres:5432 # \d pg_roles
              View "pg_catalog.pg_roles"
     Column     |           Type           | Modifiers 
----------------+--------------------------+-----------
 rolname        | name                     | 
 rolsuper       | boolean                  | 
 rolinherit     | boolean                  | 
 rolcreaterole  | boolean                  | 
 rolcreatedb    | boolean                  | 
 rolcatupdate   | boolean                  | 
 rolcanlogin    | boolean                  | 
 rolreplication | boolean                  | 
 rolconnlimit   | integer                  | 
 rolpassword    | text                     | 
 rolvaliduntil  | timestamp with time zone | 
 rolconfig      | text[]                   | 
 oid            | oid                      | 

postgres@postgres:5432 # alter role user01 valid until '2016-09-01 18:00:00';
ALTER ROLE
postgres@postgres:5432 # \du
                             List of roles
 Role name |                   Attributes                   | Member of 
-----------+------------------------------------------------+-----------
 postgres  | Superuser, Create role, Create DB, Replication | {}
 user01    | Password valid until 2016-09-01 18:00:00+08    | {}
 user02    |  

user01在2016-09-01 18:00:00之后,密码到期,将不能使用密码登录。如果配置了trust认证,依然可以登录。由于目前postgres不能在密码到期前几天提醒用户,所以建议在数据库监控中加入此项,提前三天或者一周通过短信或者邮件的方式提醒数据库管理员延长role有效期,防止密码到期后无法登陆而对应用程序造成影响。

用户密码存储策略

用户密码在数据库中应该是以密文方式存储,否则设置用户密码的意义将不复存在。所以在创建role的时候,禁止使用unencrypted password 选项。

postgres@postgres:5432 # create role test_passwd with password 'a12345678' login;
CREATE ROLE
postgres@postgres:5432 # 
postgres@postgres:5432 # 
postgres@postgres:5432 # select * from pg_shadow;
   usename   | usesysid | usecreatedb | usesuper | usecatupd | userepl |               passwd                |        valuntil        | useconfig 
-------------+----------+-------------+----------+-----------+---------+-------------------------------------+------------------------+-----------
 postgres    |       10 | t           | t        | t         | t       |                                     |                        | 
 user02      |    90291 | f           | f        | f         | f       |                                     |                        | 
 user01      |    16395 | f           | f        | f         | f       | md58edaed86912c2230d53d43b897539ee3 | 2016-09-01 18:00:00+08 | 
 test_passwd |   229387 | f           | f        | f         | f       | md5967621c92d53e44761751667a6e9cdd5 |                        | 
(4 rows)

postgres@postgres:5432 # create role test_passwd1 unencrypted password 'a12345678' login;
CREATE ROLE
postgres@postgres:5432 #  select * from pg_shadow;
   usename    | usesysid | usecreatedb | usesuper | usecatupd | userepl |               passwd                |        valuntil        | useconfig 
--------------+----------+-------------+----------+-----------+---------+-------------------------------------+------------------------+-----------
 postgres     |       10 | t           | t        | t         | t       |                                     |                        | 
 user02       |    90291 | f           | f        | f         | f       |                                     |                        | 
 user01       |    16395 | f           | f        | f         | f       | md58edaed86912c2230d53d43b897539ee3 | 2016-09-01 18:00:00+08 | 
 test_passwd  |   229387 | f           | f        | f         | f       | md5967621c92d53e44761751667a6e9cdd5 |                        | 
 test_passwd1 |   229389 | f           | f        | f         | f       | a12345678                           |                        | 
(5 rows)

postgres@postgres:5432 # select md5('a12345678test_passwd'),usename,passwd from pg_shadow where usename='test_passwd';  
               md5                |   usename   |               passwd                
----------------------------------+-------------+-------------------------------------
 967621c92d53e44761751667a6e9cdd5 | test_passwd | md5967621c92d53e44761751667a6e9cdd5
(1 row)

应用服务器配置文件安全

有些场景下,应用服务器上需要部署脚本来连接数据库处理数据,而这些脚本中的数据库连接信息大多数情况下是明文存放,在技术可行的情况下,建议通过程序接口去加密环境中得到解密的密码,然后传值给应用程序使用,并且尽量使用加密传输。如果只能保存明文文件,则需要保证应用服务器的安全。

权限安全配置

  • 在权限配置部分,需要将应用程序账号的权限做到最小,使其尽量不能做删数据库、删schema、删表、删函数等危险操作。一是可以防止应用维护人员的误操作,二是可以限制应用账号被攻击后对数据库的破坏性。

  • 管理账号和应用账号分开。

  • 回收数据库、schema、langugage等对象的public权限。

    revoke all on database testdb from public; revoke all on schema user01 from public; revoke all on language plpgsql from public; revoke all on table test from public; revoke all on function test_func from public;

资源控制

资源控制包括但不限于:

  • 每个用户可使用的最大连接数
    通过 alter user/role username connection limit 3 来控制。 如果当前数据库中username的连接达到了limit值,再次用username发起连接的时候会报错:

    [postgres@dang-db ~]$psql -d testdb -U user01 psql: FATAL: too many connections for role "user01"

  • 每个session的资源使用最大值
    对资源使用的限制包括每个session使用的cpu资源,内存资源,申请锁的数量等系统资源的使用限制。 目前pg暂时无法实现。

  • 数据库中连接数的最大值
    通过 postgres.conf 中的 max_connections 参数来控制。

  • 锁等待的最长时间
    通过 postgres.conf 中的 lock_timeout 参数来控制。

  • 事务空闲的最长时间
    可以通过连接池中的参数来控制

  • 应用SQL的最长执行时间
    可以通过中间件的设置来控制,防止单个SQL执行时间过长,消耗过多资源,从而影响数据库中的其他应用SQL。

数据传输安全

数据在通过不可靠的网络传输的过程中,有可能会被恶意攻击者截获,如果数据传输不加密,则会存在数据泄露的风险。
可以在客户端和服务器端部署openssl来将数据加密传输。
参考链接:PostgreSQL hostssl auth use openssl - Encrypting Data Across A Network

数据自身安全

对于一些敏感数据,建议在数据库中加密存储,且加解密算法不能放在数据库侧,一般建议加解密在应用侧实现,这样即使密文泄露后,也降低了进一步数据泄露的风险。

外界安全因素

  • 数据库所在IT环境的安全影响
  • 数据库管理员的安全防范意识

总结

数据库作为IT系统的核心组件,安全问题不容忽视,需要结合应用部署的安全要求以及所在环境的安全条件,选择适合的方式对数据库进行安全加固。

学习链接

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
mysql用户
1\.学会能按着需求创建一个帐号2\.知道连接字符串是什么样3\.密码密码怎么恢复mysql用户权限介绍mysql用户管理 !(https://oscimg.oschina.net/oscnet/368d3c1e00a0a9515545c2962660a27a080.png)!(https://oscimg.oschin
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Greenplum安全
目录Greenplum安全身份认证pg\_hba.conf配置连接类型pg\_hba.conf配置连接数据库pg\_hba.conf配置连接用户pg\_hba.conf配置连接网络地址pg\_hba.conf配置用户的认证方法Greenplum安全 身份认证
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这