Snova运维篇(八):GP数据库访问管理及认证

2019-12-30 14:27:02 浏览数 (1)

本节主要从网络、用户及加密认证的角度学习gp维护的安全管理工作。

目录:

  1. 配合客户端认证
  2. 管理角色和权限


基本概念::

CIDR-address

包含一个标准点分十进制表示的IP地址和一个CIDR掩码长度

kerberos

Kerberos(/ˈkərbərəs/)是一种计算机网络授权协议,用来在非安全网络中,对个人通信以安全的手段进行身份认证。


1.配置客户端认证

(一)配置概览

Master实例的pg_hba.conf文件控制对Greenplum数据库系统的客户端访问及认证。

  • 文件配置格式如下:
代码语言:javascript复制
host   database   role   CIDR-address   authentication-method

local

匹配尝试使用UNIX-域套接字的连接。如果没有这种类型的记录,则UNIX-域套接字连接不被允许。

host

匹配尝试使用TCP/IP的连接。除非用合适的listen_addresses服务器配置参数值启动,就不能进行远程TCP/IP连接。

hostssl

匹配尝试使用TCP/IP建立的连接,但只有用SSL加密建立该连接时才允许。必须通过设置ssl配置参数在服务器启动时启用SSL

hostnossl

匹配在不使用SSL的TCP/IP上建立的连接尝试。

database

指定这一记录匹配的数据库名。值all指定它匹配所有数据库。可以提供多个数据库名,用逗号分隔它们。在文件名前面放一个@,可以指定一个含有数据库名的单独的文件。

role

指定这一记录匹配的数据库角色名。值all指定它匹配所有角色。如果指定的角色是一个组并且希望该组中的所有成员都被包括在内,在该角色名前面放一个 。可以提供多个角色名,用逗号分隔它们。在文件名前面放一个@,可以指定一个含有角色名的单独的文件。

CIDR-address

指定这一记录匹配的客户端机器的IP地址范围。它包含一个标准点分十进制表示的IP地址和一个CIDR掩码长度。IP地址只能用数字指定,不能写成域或者主机名。掩码长度指示客户端IP地址必须匹配的高位位数。给定IP地址中,在这些位的右边必须是零。IP地址、/和CIDR掩码长度之间不能有任何空格。典型的CIDR地址例子是:192.0.2.89/32是一个单一主机,192.0.2.0/24是一个小网络,10.6.0.0/16是一个大网络。要指定一个单一主机,对IPv4使用一个CIDR掩码32,对IPv6使用128。在一个网络地址中,不要省略拖尾的零。

IP-addressIP-mask

这些域可以被用作CIDR地址记号的一种替代。实际的掩码在一个单独的列中指定,而不是指定掩码长度。例如,255.255.255.255表示CIDR掩码长度32。这些域只适用于host、hostssl和hostnossl记录。

authentication-method

指定连接时使用的认证方法。

  • 编辑pg_hba.conf

$MASTER_DATA_DIRECTORY/pg_hba.conf

代码语言:javascript复制
[gpadmin@gp-master gpseg-1]$ pwd
/data/master/gpseg-1
[gpadmin@gp-master gpseg-1]$ more pg_hba.conf
# PostgreSQL Client Authentication Configuration File
# ===================================================
#
# Refer to the "Client Authentication" section in the PostgreSQL
# documentation for a complete description of this file.  A short
# synopsis follows.
#
# This file controls: which hosts are allowed to connect, how clients
# are authenticated, which PostgreSQL user names they can use, which
# databases they can access.  Records take one of these forms:
#
# local      DATABASE  USER  METHOD  [OPTIONS]
# host       DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
# hostssl    DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
# hostnossl  DATABASE  USER  ADDRESS  METHOD  [OPTIONS]
#

保存文件并重载配置来生效:

代码语言:javascript复制
[gpadmin@gp-master gpseg-1]$ gpstop  -u
20191230:10:26:37:031183 gpstop:gp-master:gpadmin-[INFO]:-Starting gpstop with args: -u
20191230:10:26:37:031183 gpstop:gp-master:gpadmin-[INFO]:-Gathering information and validating the environment...
20191230:10:26:37:031183 gpstop:gp-master:gpadmin-[INFO]:-Obtaining Greenplum Master catalog information
20191230:10:26:37:031183 gpstop:gp-master:gpadmin-[INFO]:-Obtaining Segment details from master...
20191230:10:26:37:031183 gpstop:gp-master:gpadmin-[INFO]:-Greenplum Version: 'postgres (Greenplum Database) 5.21.1 build commit:ca0b8106b893028d18f241dcb858d85f12af90b6'
20191230:10:26:37:031183 gpstop:gp-master:gpadmin-[INFO]:-Signalling all postmaster processes to reload
...
  • 限制并发连接

Greenplum数据库以每个连接为基础分配资源。

max_connections这是一个local参数,意味着必须在Master、后备Master和每个Segment实例(主要和镜像)的postgresql.conf文件中设置它。Segment上的max_connections值应该是Master上的5-10倍。

还必须设置依赖参数max_prepared_transactions。

修改配置文件:

代码语言:javascript复制
[gpadmin@gp-master gpseg-1]$ vi $MASTER_DATA_DIRECTORY/postgresql.conf  //master

# -----------------------------
# PostgreSQL configuration file
# -----------------------------
#
# This file consists of lines of the form:
#
#   name = value

max_connections=100
max_prepared_transactions=100
代码语言:javascript复制
[gpadmin@gp-node2 gpseg1]$ pwd   //segment
/data/primary/gpseg1
[gpadmin@gp-node2 gpseg1]$ vi postgresql.conf

# -----------------------------
# PostgreSQL configuration file
# -----------------------------
#
# This file consists of lines of the form:
#
#   name = value

max_connections=500
max_prepared_transactions=100
  • 通过命令修改连接数
代码语言:javascript复制
$ gpconfig -c max_connections -v 1000 -m 200
代码语言:javascript复制
$ gpconfig -c max_prepared_transactions -v 200 

重启集群:

代码语言:javascript复制
$ gpstop -r

[gpadmin@gp-master ~]$ gpconfig  -s max_connections;
Values on all segments are consistent
GUC          : max_connections
Master  value: 200
Segment value: 1000
  • 加密连接

SSL连接防止第三方对包进行嗅探,还能防止中间人攻击。

创建一个自签名无密码的证书:

代码语言:javascript复制
# openssl req -new -text -out server.req
代码语言:javascript复制
# openssl rsa -in privkey.pem -out server.key
# rm privkey.pem
代码语言:javascript复制
# openssl req -x509 -in server.req -text -key server.key -out server.crt
代码语言:javascript复制
# chmod og-rwx server.key

(二)TLS/SSL的LDAP认证

Greenplum数据库支持在LDAP认证中用TLS/SSL协议加密与LDAP服务器的通信

  • 配置STARTTLS和TLS的LDAP认证 配置pg_hba.conf

默认端口

代码语言:javascript复制
ldap ldapserver=myldap.com ldaptls=1 ldapprefix="uid=" ldapsuffix=",ou=People,dc=example,dc=com"

自定义端口

代码语言:javascript复制
ldap ldapserver=myldap.com ldaptls=1 ldapport=550 ldapprefix="uid=" ldapsuffix=",ou=People,dc=example,dc=com"
  • 配置系统级ldap认证
代码语言:javascript复制
# cd /etc/pki/tls/certs  
# openssl x509 -noout -hash -in <ca-certificate-file>  
# ln -s <ca-certificate-file> <ca-certificate-file>.0
代码语言:javascript复制
SASL_NOCANON on
 URI ldaps://ldapA.example.priv ldaps://ldapB.example.priv ldaps://ldapC.example.priv
 BASE dc=example,dc=priv
 TLS_CACERTDIR /etc/pki/tls/certs
 TLS_CACERT /etc/pki/tls/certs/<ca-certificate-file>
代码语言:javascript复制
export LDAPCONF=/etc/openldap/ldap.conf

范例:

代码语言:javascript复制
host all plainuser 0.0.0.0/0 ldap ldapserver=myldap.com ldapprefix="uid=" ldapsuffix=",ou=People,dc=example,dc=com"

(三)kerberos认证

使用kerbos认证的前提条件

使用krb5-server库的Kerberos密钥分发中心(KDC)

Kerberos的版本5的krb5-libs以及安装在Greenplum数据库的Master主机上的krb5-workstation包

带有Kerberos支持的Greenplum数据库版本

Kerberos服务器和Greenplum数据库的Master主机上的系统时间必须同步(在两种服务器上安装Linux的ntp包)

Kerberos服务器和Greenplum数据库的Master之间的网络连接

在Red Hat Enterprise Linux 6.x上使用Kerberos认证的JDBC要求Java 1.7.0_17或者其后的版本

  • 安装一台kerbos服务器

独立的认证服务器:

代码语言:javascript复制
sudo yum install krb5-libs krb5-server krb5-workstation

编辑配置文件:

代码语言:javascript复制
[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = KRB.GREENPLUM.COM
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 default_tgs_enctypes = aes128-cts des3-hmac-sha1 des-cbc-crc des-cbc-md5
 default_tkt_enctypes = aes128-cts des3-hmac-sha1 des-cbc-crc des-cbc-md5
 permitted_enctypes = aes128-cts des3-hmac-sha1 des-cbc-crc des-cbc-md5

[realms]
 KRB.GREENPLUM.COM = {
  kdc = kerberos-gpdb:88
  admin_server = kerberos-gpdb:749
  default_domain = kerberos-gpdb
 }

[domain_realm]
 .kerberos-gpdb = KRB.GREENPLUM.COM
 kerberos-gpdb = KRB.GREENPLUM.COM

[appdefaults]
 pam = {
    debug = false
    ticket_lifetime = 36000
    renew_lifetime = 36000
    forwardable = true
    krb4_convert = false
 }

创建kdc数据库:

代码语言:javascript复制
kdb5_util create -s

增加本地管理用户:

代码语言:javascript复制
kadmin.local -q "addprinc gpadmin/admin"

启动kerbos进程,设置开机自启动:

代码语言:javascript复制
/sbin/service krb5kdc start
/sbin/service kadmin start
/sbin/chkconfig krb5kdc on
/sbin/chkconfig kadmin on
  • kdc数据库中创建greenplum数据库角色

启动kadmin.local

代码语言:javascript复制
kadmin.local
代码语言:javascript复制
kadmin.local: addprinc gpadmin/kerberos-gpdb@KRB.EXAMPLE.COM
kadmin.local: addprinc postgres/master.test.com@KRB.EXAMPLE.COM

创建keytab文件:把这个文件复制到Greenplum数据库的Master主机。

代码语言:javascript复制
kadmin.local: xst -k gpdb-kerberos.keytab
    gpadmin/kerberos-gpdb@KRB.EXAMPLE.COM
    postgres/master.test.com@KRB.EXAMPLE.COM

退出交互模式:

代码语言:javascript复制
kadmin.local: quit
  • kerberos客户端配置

gp-master主机配置:

代码语言:javascript复制
sudo yum install krb5-libs krb5-workstation

gpdb-kerberos.keytab文件复制到Greenplum数据库的Master主机上

移除已有的ticket

代码语言:javascript复制
sudo kdestroy

分配ticket

代码语言:javascript复制
# kinit -k -t gpdb-kerberos.keytab gpadmin/kerberos-gpdb@KRB.EXAMPLE.COM

显示ticket缓存:

代码语言:javascript复制
# klist
Ticket cache: FILE:/tmp/krb5cc_108061
Default principal: gpadmin/kerberos-gpdb@KRB.EXAMPLE.COM
Valid starting     Expires            Service principal
  • psql客户端认证设置
代码语言:javascript复制
psql postgres -c 'create role "gpadmin/kerberos-gpdb" login superuser;'

指定keytab文件位置:

代码语言:javascript复制
krb_server_keyfile = '/home/gpadmin/gpdb-kerberos.keytab'

修改pg_hba.conf

代码语言:javascript复制
host all all 0.0.0.0/0 gss include_realm=0 krb_realm=KRB.GREENPLUM.COM

测试验证:

代码语言:javascript复制
psql -U "gpadmin/kerberos-gpdb" -h master.test postgres

创建简化映射:

代码语言:javascript复制
$ psql -U "adminuser/mdw.proddb" -h mdw.proddb
$ psql -h mdw.proddb
  • jdbc客户端认证配置

/home/gpadmin 中创建文件:java.login.config

代码语言:javascript复制
pgjdbc {
  com.sun.security.auth.module.Krb5LoginModule required
  doNotPrompt=true
  useTicketCache=true
  debug=true
  client=true;
};

创建java应用:

代码语言:javascript复制
jdbc:postgresql://mdw:5432/mytest?kerberosServerName=postgres
&jaasApplicationName=pgjdbc&user=gpadmin/kerberos-gpdb

2.管理角色和特权

(一)基本原则

  • 严格控制gpamin用户的使用

用户只应使用gpadmin账户进行扩展和升级等系统维护任务。

  • 对不同类别的用户分配唯一的角色
  • 使用用户组集中管理和区别用户
  • 限制超级用户角色的使用

0 人点赞