相比mysql单一的f,postgresql的访问认证配置主要涉及到两个主要的配置文件:postgresql.conf和pg_hba.conf,本文从安全设置角度讲述这两个配置文件的配置选项。
部分文字、样例摘抄自postgresql的中文手册。
postgresql.confpostgresql.conf包含了许多的选项,这些选项控制了postgresql.conf的方方面面,中间影响访问认证的选项是:unix_socket_group设置Unix 域套接字的组所有人,(套接字的所有权用户总是启动postmaster 的用户)与UNIX_SOCKET_PERMISSIONS 选项一起使用可以给这种套接字类型增加额外的访问控制机制,缺省时是一个空字串,也就是使用当前用户的缺省的组,这个选项只能在服务器启动时设置。
unix_socket_permissions给Unix 域套接字设置访问权限,Unix 域套接字使用通常的Unix 文件系统权限集。
可选的值可以是一个chmod 和umask 系统调用可以接受的数字模式。
(要使用客户化的八进制格式,该数字必须以0 (零)开头)缺省权限是0777,意即任何人都可以联接,合理的选则可能是0770 (只有用户和组,参阅UNIX_SOCKET_GROUP)和0700 (只有用户)。
(请注意对于Unix 套接字而言,实际上只有写权限有意义,而且也没有办法设置或者取消读或执行权限)这个选项只能在服务器启动时设置。
pg_hba.conf是设置访问认证的主要文件,格式为每条记录一行,每行指定一条访问认证。
设定一条访问认证包含了7个部分:连接方式(type)、数据库(database)、用户名(user)、ip地址(ip-address)、子网掩码(ip-mask)、认证方法(authentication method)、认证配置(authentication-option),以下是这7个部分的详细说明:连接方式(type)连接方式共有三种:local、host、hostssllocal这条记录匹配通过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,"克尔波洛斯",故希腊神话冥王哈得斯的多头看门狗,FF8中“反击的狼烟”。
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)这个可选的字段的含义取决与选择的认证方法。
了解了以上的内容以后,我们可以开始设置自己的访问认证。
和mysql一样,postgresql 默认安装的访问认证是不安全的,当我第一次安装好我的postgresql以后,我发现只要输入`psql -U pgsql -d template1`就可以不需要任何密码的进入我的数据库,并且使用的是pgsql 用户(数据库的最高权限),即使在我使用ALTER USER为我的数据库用户添加了密码以后情况也没有得到改善,经过一番查找,我发现我的pg_hba.conf内容如下:local all all trusthost all all 0.0.0.0 0.0.0.0 trust这说明无论在本地还是通过tcp/ip,任何人都可以不加任何限制的使用任何他想用的身份访问我的数据库,于是我为所有的访问都使用了md5认证方法,我的pg_hba.conf变为:local all all md5host all all 0.0.0.0 0.0.0.0 md5事情似乎得到了解决,任何人想访问我的数据库都需要通过密码这一关,我的数据库安全了。
但是当我有一天重新启动计算机的以后发现我的postgresql并没有被正常的启动,在终端前我发现启动到postgresql服务启动脚本时,提示需要输入密码,原来在设置了md5认证方式以后我的pgsql需要密码才能够启动服务,为了不每次启动都跑到终端前去输入一次密码,我的pgsql用户的认证方法必须为trust:local pgsql all trustlocal all all md5host all all 0.0.0.0 0.0.0.0 md5在随后的检测中我发现,虽然通过网络得到了保护,但是如果在本地通过Unix域套接字进行连接的话,任何人都还是可以使用`psql -U pgsql -d template1`的方式轻松的进入我的数据库,这样做显而易见不是我想要的结果,现在我需要unix_socket_permissions的协助,当我把这个项设置为0700以后,就只有套接字的所有人,即系统用户pgsql可以使用套接字进行连接,另外如果我的数据库有几个管理员需要最高权限的话,0770也是一个选择,不过暂时只有我一个管理员,所以我选择了0700,现在我的pg_hba.conf改变为:local pgsql all trusthost all all 0.0.0.0 0.0.0.0 md5结合了unix_socket_permissions以后,现在只有系统用户pgsql可以无任何限制的连接(当然,伟大的root例外),并且我也不用每次启动的时候都跑到终端前去输入一次密码了,而其他人只能通过网络连接,即使登录到了本地计算机上,其他用户也只能使用`psql -U xx -d template1 -h 127.0.0.1`的方式连接,这种连接是受到密码认证的保护的,这一切正是我想要的。
pg_hda.conf看看pg_hda.conf的:# TYPE DATABASE USER CIDR-ADDRESS METHOD顺序一定不要搞错了,我的前面关于认证设置的文章是网上照搬的,将database和user顺序设反了,导致我一直出现错误。
汗颜!注意到type:包含local和host两种。
意思是本机(local)和远程调用(host)对于一个user,最好给本机和远程都给权限。
然后看method:有trust(不需要安全认证);md5(md5加密认证);password(明码认证)。
依然存在问题:我对用户使用md5和password方式,使用psql命令输入密码都提示密码错误。
不知道是什么原因。
问题分析中。
待续~~~~~~~~~~~eg:对globus用户,rftDatabase数据库的授权:local all globus trusthost rftDatabase globus 202.198.30.65 255.255.255.128 trust这个是保证GT4的container和使用psql命令都能简单进入的方式,不过使用password和md5方式就出现错误了。