vivion32 发表于 2016-11-21 06:34:25

PostgreSQL启动过程中的那些事十五.一:pg_hba.conf的用法

          前几天配pgcluster,改错了pg_hba.conf文件,查了好一阵子。这个文件网上也有写的,现在把下面两篇博文合起来放在这儿备查。

                  http://swingfly.iyunv.com/blog/508465

                  http://francs3.blog.163.com/blog/static/4057672720113243113534/

          还有篇文章写的不错,也加在最后,原文地址在下面

                  http://blog.sina.com.cn/s/blog_6c11273c0100lfap.html


  -------------------------
   pg_hba.conf是设置访问认证的主要文件,格式为每条记录一行,每行指定一条访问认证。设定一条访问认证
包含了7个部分:连接方式(type)、数据库(database)、用户名(user)、ip地址(ip-address)、子网掩码(ip-
mask)、认证方法(authentication
method)、认证配置(authentication-option),以下是这7个部分的详细说明: 


连接方式(type) 


连接方式共有三种:local、host、hostssl 


local 


这条记录匹配通过 Unix 域套接字进行的联接企图, 没有这种类型的记录,就不允许 Unix 域套接字的联接。 


host 


这条记录匹配通过 TCP/IP 网络进行的联接尝试,请注意,除非服务器是 带着 -i 选项或者打开了 postgresql.conf 里面的 tcpip_socket 配置参数集启动的,否则 TCP/IP 联接是被禁止掉的。 


hostssl 


这条记录匹配通过在 TCP/IP 上进行的 SSL 联接企图, host 记录可以匹配 SSL 和非 SSL 的联接企图, 但 hostssl 记录需要 SSL 联接。 


数据库(database) 


  声明记录所匹配的数据库。值 all 表明该记录匹配所有数据库, 值 sameuser表示如果被请求的数据库和请求的用户同名,则匹配。
samegroup 表示请求的用户必须是一个与数据库同名的组中的成员。 在其他情况里,这就是一个特定的 PostgreSQL 的名字。
我们可以通过用逗号分隔的方法声明多个数据库。 一个包含数据库名的文件可以 通过对该文件前缀 @ 来声明.该文件必需和 pg_hba.conf
在同一个目录。 


用户名(user) 


  为这条记录声明所匹配的 PostgreSQL 用户,值 all 表明它匹配 于所有用户。否则,它就是特定 PostgreSQL
用户的名字,多个用户名可以通过用逗号分隔的方法声明,组名字 可以通过用 + 做组名字前缀来声明。一个包含用户名的文件可以 通过在文件名前面前缀 @
来声明,该文件必需和 pg_hba.conf 在同一个目录。 


ip地址(ip-address)、子网掩码(ip-mask) 


这两个字段包含标准的点分十进制表示的 IP地址/掩码值。
(IP地址只能用数字的方式声明,而不能用域名或者主机名)它们俩放在一起,声明了这条记录匹配的客户机的 IP 地址。
准确的逻辑是:(actual-IP-address xor IP-address-field) and IP-mask-field
对于要匹配的记录必需为零。如果连接方式是host或者hostssl的话,这两项必须指定,否则可以不填。 


认证方法(authentication method) 


trust 


无条件地允许联接,这个方法允许任何可以与PostgreSQL 数据库联接的用户以他们期望的任意 PostgreSQL 数据库用户身份进行联接,而不需要口令。 


reject 


联接无条件拒绝,常用于从一个组中"过滤"某些主机。 


md5 


要求客户端提供一个 MD5 加密的口令进行认证,这个方法是允许加密口令存储在pg_shadow里的唯一的一个方法。 


crypt 


类似 md5 方法,只是用的是老式的 crypt 加密认证, 用于 7.2 以前的客户端,对于 7.2 以及以后的客户端,我们建议使用 md5。 


password 


和"md5"一样,但是口令是以明文形式在网络上传递的,我们不应该在不安全的网络上使用这个方式。 


krb4 


用 Kerberos V4 认证用户,只有在进行 TCP/IP
联接的时候才能用。(译注:Kerberos,"克尔波洛斯",故希腊神话冥王哈得斯的多头看门狗。Kerberos 是 MIT
开发出来的基与对称加密算法的认证协议和/或密钥 交换方法,其特点是需要两个不同用途的服务器,一个用于认证身份,
一个用于通道两端用户的密钥交换。同时 Kerberos 对网络时间同步 要求比较高,以防止回放攻击,因此通常伴随 NTP 服务。) 


krb5 


用 Kerberos V5 认证用户.只有在进行 TCP/IP 联接的时候才能用。(译注:Kerberos V5 是上面 V4 的改良,主要是不再依赖 DES 算法, 同时增加了一些新特性。) 


ident 


获取客户的操作系统名(对于 TCP/IP 联接,用户的身份是通过与运行在客户端上的 ident
服务器联接进行判断的,对于本地联接,它是从操作系统获取的。) 然后检查一下,看看用户是否允许以要求的数据库用户进行联接, 方法是参照在
ident 关键字后面声明的映射。 


如果你使用了 sameuser 映射,那么假设用户名 是相等的。如果没有声明这个关键字,则在 $PGDATA/pg_ident.conf
文件中找出映射名。如果这个文件里包含一条记录标识着ident提供的用户名 和请求的 PostgreSQL 用户名的映射, 那么联接被接受。 


对于本地联接,只有在系统支持Unix域套接字信任证的情况下 才能使用(目前是 Linux, FreeBSD, NetBSD, 和 BSD/OS)。 


pam 


使用操作系统提供的可插入的认证模块服务 (Pluggable Authentication Modules)(PAM)来认证。 


认证配置(authentication-option) 


这个可选的字段的含义取决与选择的认证方法。


  


  ======================================

          大家知道PostgreSQL在连接认证体系方面功能非常全面,因为它用到了一个 pg_hba.conf

( HBA stands for host-based authentication )文件。

  


 

  --先来看 pg_hba.conf 文件的一个例子



# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD

  # "local" is for Unix domain socket connections only

local   all             all                                     trust

  # IPv4 local connections:

host    all             all             127.0.0.1/32            md5

  # IPv6 local connections:

host   mydb            query_man              192.168.1.55/32               md5

         备注:为了显示方便,上面仅列出 pg_hba.conf文件的最后一部分。从上面看出 pg_hba.conf

文件是由一行行记录组成,每行记录包括认证类型,数据库名,用户名,认证IP,认证方式字段。就

是这些记录控制着客户端的连接。

           本文不准备详细介绍 pg_hba.conf 文件的配置方法,关于 pg_hba.conf 的详细概述可以

参考手册
http://www.postgresql.org/docs/9.0/static/client-authentication.html
, 本

文仅讲述以下场景 pg_hba.conf 的配置方法。

          假设场景: 有一套生产库已经上线了,假设这个生产库的库名为 mydb, 生产用户为 skytf,

现在开发人员需要定期的去查看这个库里的某些表,这时考虑到生产库的安全,可以创建一个查询

用户 query_man, 并授予一定的查询权限。这时开发人员可以在自己的电脑上通过 pgadmin等客户端

工具连接数据库了,但此时有个问题,开发人员手里同时也有生产用户 skytf 的密码 ,因为项目上

线时,DBA会所生产用户密码给开发人员,对应用进行配置,一般情况下都没收回这个权限,那么,

理论上说,开发人员可以在本机使用生产帐号 skytf 连接生产库了( 不考虑网络情况下 ), 很明显,

这是一种安全隐患,但是,PG里的 pg_hba.conf非常强大,可以利用它来配置一种比较严谨的认证方法。

  

--修改后的 pg_hba.conf 文件



# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD

  # "local" is for Unix domain socket connections only

local   all             all                                     trust

  # IPv4 local connections:

host    all             all             127.0.0.1/32            md5

  # IPv6 local connections:
host   mydb            query_man              192.168.1.55/32               md5

host    all                  all                            192.168.1.55/32                reject

host    all                 all                             0.0.0.0/0               md5



          这里假设 "192.168.1.55" 是指开发人员的IP, 这只是举个例子,如果有多数开发人员,您也可以将它

设置成一个网段。这里主要看以下两段, 第一段的意思是,主机 192.168.1.55 仅允许用 query_man 用户连接

数据库 mydb, 第二段的意思是拒绝主机  192.168.1.55 以任何用户连接任何数据库。

  # IPv6 local connections:

host   mydb            query_man              192.168.1.55/32               md5

host   all                 all                            192.168.1.55/32               reject

        讲到这里,需要讲解下 pg_hba.conf 认证流程,客户端在连接 PostgreSQL时,PostgreSQL 会从上到下

读取 pg_hba.conf 文件,如果有匹配的记录且认证通过,则可以连接数据库,如果有匹配的记录且认证失败

则访问被拒绝,而不再考虑 pg_hba.conf 接下来的记录。上面的配置有效地控制了开发人员通过本机以生产

用户连接生产库的情况, 同时只允许他们以查询用户连接生产库。

  --附:pg_hba.conf 认证流程图


  






                                                     
图一  pg_hba.conf 认证流程图









=======================
  客户端认证是由一个配置文件(通常名为 pg_hba.conf
)控制的,它存放在数据库集群的数据目录里。HBA
的意思是"host-based authentication",也就是基于主机的认证。在 initdb
初始化数据目录的时候,它会安装一个缺省的 pg_hba.conf
文件。不过我们也可以把认证配置文件放在其它地方;参阅
hba_file
配置参数。
  pg_hba.conf
文件的常用格式是一组记录,每行一条。空白行将被忽略,井号 #
开头的注释也被忽略。一条记录是由若干用空格和/或制表符分隔的字段组成。如果字段用引号包围,那么它可以包含空白。记录不能跨行存在。
  每条记录声明一种连接类型、一个客户端 IP
地址范围(如果和连接类型相关的话)、一个数据库名、一个用户名字、对匹配这些参数的连接使用的认证方法。第一条匹配连接类型、客户端地址、连接请求的数
据库名和用户名的记录将用于执行认证。这个处理过程没有"跨越"或者"回头"的说法:如果选择了一条记录而且认证失败,那么将不再考虑后面的记录。如果没
有匹配的记录,那么访问将被拒绝。
  每条记录可以是下面七种格式之一:

local      database

user

auth-method

[auth-option


]
host       database

user

CIDR-address

auth-method

[auth-option



hostssl    database

user

CIDR-address

auth-method

[auth-option


]
hostnossldatabase

user

CIDR-address

auth-method

[auth-option


]
host       database

user

IP-address

IP-mask

auth-method

[auth-option


]
hostssl    database

user

IP-address

IP-mask

auth-method

[auth-option


]
hostnossldatabase

user

IP-address

IP-mask

auth-method

[auth-option


]

  各个字段的含义如下:


local

  这条记录匹配企图通过 Unix 域套接字进行的连接。没有这种类型的记录,就不允许 Unix 域套接字的连接。



host

  这条记录匹配企图通过 TCP/IP 进行的连接。host
记录匹配 SSL 和非 SSL 的连接请求。

  【注意】
除非服务器带着合适的
listen_addresses
配置参数值启动,否则将不可能进行远程的 TCP/IP
连接,因为缺省的行为是只监听本地自环地址 localhost
的连接。






hostssl

  这条记录匹配企图使用 TCP/IP 的 SSL 连接。但必须是使用 SSL 加密的连接。
  要使用这个选项,编译服务器的时候必须打开 SSL 支持。而且在服务器启动的时候必须打开
ssl
配置选项(参阅节16.7
)。



hostnossl

  这条记录与 hostssl
相反:它只匹配那些在 TCP/IP 上不使用 SSL 的连接请求。



database


  声明记录所匹配的数据库名称。值 all
表明该记录匹配所有数据库,值 sameuser
表示如果被请求的数据库和请求的用户同名,则匹配。值 samerole
表示请求的用户必须是一个与数据库同名的角色中的成员(samegroup
是一个已经废弃了,但目前仍然被接受的
samerole
同义词)。在其它情况里,这就是一个特定的 PostgreSQL
数据库名字。可以通过用逗号分隔的方法声明多个数据库,也可以通过前缀 @
来声明一个包含数据库名的文件。



user


  为这条记录声明所匹配的数据库用户。值 all
表明它匹配于所有用户。否则,它就是特定数据库用户的名字或者是一个前缀 的组名称。请注意,在 PostgreSQL
里,用户和组没有真正的区别, 实际上只是意味着"匹配任何直接或者间接属于这个角色的成员",而没有
记号的名字只匹配指定的角色。多个用户名可以通过用逗号分隔的方法声明。一个包含用户名的文件可以通过在文件名前面前缀 @
来声明。



CIDR-address


  声明这条记录匹配的客户端机器的 IP 地址范围。它包含一个标准的点分十进制的 IP 地址(只能用数值而不能用域或主机名)和一个
CIDR 掩码长度。掩码长度表示客户端 IP 地址必须匹配的高位二进制位数。在给出的 IP
地址里,这个长度的右边的二进制位必须为零。在 IP 地址、/
、CIDR 掩码长度之间不能有空白。
  典型的 CIDR-address

举例:172.20.143.89/32
表示一个主机,172.20.143.0/24
表示一个小子网,10.6.0.0/16
表示一个大子网。要声明单个主机,给 IPv4 地址声明 CIDR 掩码 32 ,给 IPv6 地址声明 128
。不要在地址中省略结尾的 0 。
  以 IPv4 格式给出的 IP 地址会匹配那些拥有对应地址的 IPv6 连接,比如 127.0.0.1
将匹配
IPv6 地址 ::ffff:127.0.0.1
。一个以 IPv6 格式给出的记录将只匹配 IPv6
连接,即使对应的地址在 IPv4-in-IPv6 范围内。请注意如果系统的 C 库不支持 IPv6 地址,那么 IPv6
的格式将被拒绝。
  这个字段只适用于 host
, hostssl
, hostnossl
记录。



IP-address


IP-mask


  这些方法可以用于作为 CIDR-address

表示法的替补。它不是声明掩码的长度,而是在另外一个字段里声明实际的掩码。比如,255.0.0.0
表示 IPv4
CIDR 掩码长度 8 ,而 255.255.255.255
表示 CIDR 掩码长度 32 。
  这些字段只适用于 host
, hostssl
, hostnossl
记录。



auth-method


  声明通过这条记录连接的时候使用的认证方法。可能的选择在下面简介,详细情况在节20.2
中介绍。


trust

  无条件地允许连接。这个方法允许任何可以与 PostgreSQL 数据库服务器连接的用户以他们期望的任意 PostgreSQL
数据库用户身份进行连接,而不需要口令。参阅节20.2.1
获取细节。



reject

  无条件地拒绝连接。常用于从一个组中"过滤"某些主机。



md5

  要求客户端提供一个 MD5 加密的口令进行认证。参阅节20.2.2
获取细节。



crypt


  【注意】
这个选项只有在与 7.2 以前的客户端进行通讯的时候才建议使用。



  crypt
要求客户端提供一个 crypt()
加密的口令用于认证。现在我们建议使用
md5
。参阅节20.2.2




password

  
要求客户端提供一个未加密的口令进行认证。因为口令是以明文形式在网络上传递的,所以我们不应该在不安全的网络上使用这个方式。并且它通常还不能和线程化的客户端应用一起使用。参阅节20.2.2
获取细节。



krb5

  用 Kerberos V5 认证用户。只有在进行 TCP/IP 连接的时候才能用。参阅节20.2.3
获取细节。



ident

  获取客户的操作系统名然后检查该用户是否允许以要求的数据库用户进行连接,方法是参照在 ident
关键字后面声明的映射。对于 TCP/IP 连接,用户的身份是通过与运行在客户端上的 ident
服务器连接进行判断的,对于本地连接,它是从操作系统获取的。参阅节20.2.4
获取细节。



ldap

  使用 LDAP 进行认证。参阅节20.2.5
获取细节。



pam

  使用操作系统提供的可插入认证模块服务(PAM)来认证。参阅节20.2.6
获取细节。






auth-option


  这个可选字段的含义取决于选择的认证方法。细节在下面。



  用 @
构造包含的文件是当作一列名字读取的,这些名字可以用空白或者逗号分隔。注释用 #
引入,就像在 pg_hba.conf
里那样,允许嵌套 @
构造。除非跟在 @
后面的文件名是一个绝对路径,否则被当作与该文件所在目录相对的路径。
  因为认证时系统是为每个连接请求顺序检查 pg_hba.conf
里的记录的,所以这些记录的顺序是非常关键的。通常,靠前的记录有比较严的连接匹配参数和比较弱的认证方法,而靠后的记录有比较松的匹配参数和比较严的认证方法。比如,我们一般都希望对本地
TCP/IP 连接使用 trust
认证,而对远端的 TCP/IP 连接要求口令。在这种情况下我们将
trust
认证方法用于来自 127.0.0.1 的连接,这条记录将出现在允许更广泛的客户端 IP
地址的使用口令认证的记录前面。
  在启动和主服务器进程收到 SIGHUP
信号的时候,系统都会重新装载
pg_hba.conf
文件。如果你在活跃的系统上编辑了该文件,就必须通知服务器(使用 pg_ctl
reload
或 kill -HUP
)重新加载该文件。

  【提示】
一个用户要想成功连接到特定的数据库,不仅需要通过 pg_hba.conf
的检查,还必须要有该数据库上的 CONNECT
权限。如果希望限制哪些用户能够连接到哪些数据库,赋予/撤销
CONNECT
权限通常比在 pg_hba.conf
中设置规则简单。



  
例20-1
里是 pg_hba.conf
记录的一些例子。阅读下文理解不同认证方法的细节。
  例20-1. pg_hba.conf
记录的例子


# Allow any user on the local system to connect to any database under
# 允许在本机上的任何用户使用 Unix 域套接字(本地连接的缺省)以任何数据库用户身份连接任何数据库
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
localall         all                               trust

# 和上面相同,但是使用的是回环的(loopback)TCP/IP 连接
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
host    all         all         127.0.0.1/32          trust

# 和上面一行相同,但是用的是独立的掩码字段
# TYPEDATABASE    USER      IP-ADDRESS    IP-MASK             METHOD
host    all         all         127.0.0.1   255.255.255.255   trust   

# 允许 IP 地址为 192.168.93.x 的任何主机与 "postgres" 数据库相连,
# 用与他们在自己的主机上相同 ident 的用户名标识他自己(通常是他的 Unix 用户名)
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
host    postgres    all         192.168.93.0/24       ident sameuser

# 允许来自主机 192.168.12.10 的用户提供了正确的口令之后与 "postgres" 数据库连接。
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
host    postgres    all         192.168.12.10/32      md5
# 如果前面没有其它 "host" 行,那么下面两行将拒绝所有来自 192.168.54.1 的连接请求(因为前面的记录先匹配)。
# 但是允许来自互联网上其它任何地方的有效的 Kerberos 5 认证的连接。
 # 零掩码表示不考虑主机 IP 的任何位。因此它匹配任何主机。
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
host    all         all         192.168.54.1/32       reject
host    all         all         0.0.0.0/0             krb5

# 允许来自 192.168.x.x 的任何用户与任意数据库连接,只要他们通过 ident 检查。
# 但如果 ident 说该用户是 "bryanh" 且他要求以 PostgreSQL 用户 "guest1" 连接,
# 那么只有在 pg_ident.conf 里有 "omicron" 的映射说 "bryanh" 允许以 "guest1" 进行连接时才真正可以进行连接。
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
host    all         all         192.168.0.0/16      ident omicron

# 如果下面是用于本地连接的仅有的三行,那么它们将允许本地用户只和同名数据库连接。
# 只有管理员和 "support" 角色里的成员例外,他们可以连接到任何数据库。
# $PGDATA/admins 文件列出了那些允许与所有数据库连接的用户名。
# 在所有情况下都需要口令。
# TYPEDATABASE    USER      CIDR-ADDRESS          METHOD
local   sameuser    all                               md5
local   all         @admins                           md5
local   all          support                        md5

# 上面最后两行可以合起来写成一行
local   all         @admins, support                  md5

# 数据库字段也可以使用列表和文件名:
local   db1,db2,@demodbsall                         md5
页: [1]
查看完整版本: PostgreSQL启动过程中的那些事十五.一:pg_hba.conf的用法