SSL单向认证和双向认证:
SSL单向认证:只有一端校验对端的证书合法性,通常都是客户端来校验服务器的合法性。即在一般的单向认证中,只要求服务器端部署了ssl证书就行,客户端可以无证书,任何用户都可以去访问服务端,服务端只是提供了身份认证。
client: 无证书
server: server.crt, server.key
SSL双向认证:客户端和服务端相互校验,服务器需要校验每个客户端,每个客户端也需要校验服务器,只有服务器和用户双方都有证书才能正常通信,因此只能是服务端允许的客户才能访问服务器。
client: root.crt, postgresql.crt, postgresql.key
server: root.crt, server.crt, server.key
下面分别从服务端和客户端说明如何配置SSL双向认证**********************************************
一、服务器端
下载pg安装包:
wget https://ftp.postgresql.org/pub/source/v11.4/postgresql-11.4.tar.gz
安装前准备:
yum install net-tools -y
yum install sysstat -y
yum install iotop libXp redhat-lsb gcc gdb –y
yum install xorg-x11-xauth -y
yum install -y vim lrzsz tree wget gcc gcc-c++ readline-devel hwloc smartmontools
yum install -y readline readline-devel openssl openssl-devel zlib zlib-devel numactl
解压 :
tar zxvf postgresql-11.4.tar.gz
编译:
./configure --prefix=/usr/local/postgresql --with-openssl #加 --with-openssl编译选项
安装:
make && make install
创建目录:
mkdir /usr/local/postgresql/data
mkdir /usr/local/postgresql/log
加入系统环境变量:
vim /etc/profile
export PGHOME=/usr/local/postgresql
export PGDATA=/usr/local/postgresql/data
export PATH=$PATH:$HOME/.local/bin:$HOME/bin:$PGHOME/bin
使配置文件生效:
source /etc/profile
增加用户 postgres 并赋权:
adduser postgres
passwd postgres
chown -R postgres:root /usr/local/postgresql/
切换到用户 postgres:
su postgres
创建证书:
cd /usr/local/postgresql/data
openssl req -nodes -new -x509 -keyout server.key -out server.crt -subj '/C=US/L=NYC/O=Percona/CN=postgres' Generating a 2048 bit RSA private key
....+++
.........................+++
writing new private key to 'server.key'
-----
修改一下文件的权限和属主
# chmod 400 server.{crt,key}
# chown postgres:postgres server.{crt,key}
# ll server.{crt,key}
-r--------. 1 postgres postgres 1212 Jul 6 20:12 20:49 server.crt
-r--------. 1 postgres postgres 1704 Jul 6 20:12 20:49 server.key
执行初始化数据库命令:
/usr/local/postgresql/bin/initdb -D /usr/local/postgresql/data/
注意:不能在 root 用户下初始数据库,否则会报错
切到root下,为 pg_ctl 创建软链接:
ln -s /usr/local/postgresql/bin/pg_ctl /usr/bin/pg_ctl
ln -s /usr/local/postgresql/bin/psql /usr/bin/psql
为用户 postgres 赋权:
chown -R postgres:postgres /usr/local/postgresql/data
chmod -R 0700 /usr/local/postgresql/data
切换到用户 postgres启动服务:
pg_ctl start -l /usr/local/postgresql/log/pg_server.log
查看日志
路径: /usr/local/postgresql/log/pg_server.log ----> /usr/local/postgresql/data/pg_log
修改postgres.conf,配置SSL参数:
vim postgres.conf
ssl = on #支持SSL,默认off(关闭)。该参数只能在Server启动时设置。SSL通信只能通过TCP/IP连接进行。
ssl_ca_file = 'root.crt' #指定根证书,SSL单项认证时也可以不配置、SSL双向认证必须配置
ssl_cert_file = 'server.crt' #指定包含SSL服务器证书的文件的名称。
ssl_key_file = 'server.key' #指定包含SSL服务器私钥的文件的名称。
登陆PostgreSQL数据库,打开ssl开关:
psql -U postgres -d postgres
postgres=# alter system set ssl=on;
ALTER SYSTEM
修改pg_hba.conf
如果强制SSL连接(仅允许SSL连接)、不允许普通连接,则修改pg_hba.conf,配置SSL连接认证规则:
vim pg_hba.conf
hostssl all all 0.0.0.0/0 md5
说明:
pg_hba.conf中的Client连接认证规则配置的几种类型:local、host、hostssl、hostnossl
local: 此记录匹配通过 Unix 域套接字进行的联接企图,没有这种类型的记录,就不允许 Unix 域套接字的联接。
host: 此记录匹配使用TCP/IP进行的连接尝试,他既匹配通过ssl方式的连接,也匹配通过非ssl方式的连接,会优先使用ssl认证。
hostssl: 此记录匹配使用TCP/IP进行的连接尝试,但仅在使用SSL加密进行连接时才匹配。hostssl表示强制使用ssl。
hostnossl:此记录类型具有与hostssl相反的行为:它仅匹配不使用SSL的TCP/IP上的连接尝试。hostnossl表示前置不使用ssl。
调用pg_reload_conf()以确保配置文件被加载:
postgres=# select pg_reload_conf();
重新加载配置遇到的几个问题:
1、未删除server.key的密码,报错:“private key file ““server.key”” cannot be reloaded because it requires a passphrase”,"
解决方法:删除私钥中的密码
openssl rsa -in server.key -out server.key
2、server.key未修改访问权限,报错:“private key file “server.key” has group or world access”
解决方法:修改文件权限
chmod 600 xxxfile
3、未正确配置pg_hba.conf,远程连接时报错:
“xxxuser”,“xxxdb”,25257,“10.11.58.83:44764”,644a0fb6.62a9,1,“authentication”,2023-04-27 06:01:26 UTC,3/2216,0,FATAL,28000,“no pg_hba.conf entry for host ““10.11.58.83"”, user ““xxxuser””, database ““xxxdb””, SSL off”,”"
解决方法:检查pg_hba.conf文件配置
重启数据库,ssl生效
[postgres@localhost~]$ psql -Upostgres postgres -h localhost
Password forusersa:
psql (11.1)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" forhelp.
查看ssl开关:
postgres=# show ssl;
ssl
-----
on
(1 row)
检查使用SSL/TLS的会话连接
postgres=# select pg_ssl.pid, pg_ssl.ssl, pg_ssl.version,pg_sa.backend_type, pg_sa.usename, pg_sa.client_addr from pg_stat_ssl pg_ssl join pg_stat_activity pg_sa on pg_ssl.pid = pg_sa.pid;
pid | ssl | version | backend_type | usename | client_addr
-------+-----+---------+------------------------------+----------+-------------
16629 | f | | autovacuum launcher | |
16748 | f | | logical replication launcher | postgres |
25923 | t | TLSv1.2 | client backend | postgres | ::1
16627 | f | | background writer | |
16626 | f | | checkpointer | |
16628 | f | | walwriter | |
(6 rows)
二、客户端:
1)生成客户端SSL配置:
服务端启用SSL后,客户端即使不开启SSL配置进行连接时,默认也是SSL连接。客户端无需任何配置,也能SSL连接。
服务端为客户端生成客户后端证书,提供给客户端连接时使用。客户端开启SSL配置连接服务器,需要三个文件:root.key(根证书)、postgresql.crt(客户端证书)、postgresql.key(客户端私钥)。
在服务器端操作生成客户端私钥(postgresql.key)
[root@zhouy data]# openssl genrsa -des3 -out postgresql.key 2048
删除私钥中的密码:
[root@zhouy data]# openssl rsa -in postgresql.key -out postgresql.key
创建客户端证书请求(postgresql.csr) & 签名生成客户后端证书(postgresql.crt):
它必须由我们受信任的根(正在使用服务器端的机器上的服务私钥文件)进行签名。 此外, 证书通用名(CN)必须设置为要连接的数据库用户名
$ openssl req -new -key postgresql.key -out postgresql.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
$ openssl x509 -req -in postgresql.csr -CA root.crt -CAkey server.key -out postgresql.crt -CAcreateserial
Signature ok
subject=/C=CN/L=Default City/O=Default Company Ltd
Getting CA Private Key
修改文件权限(postgresql.key)
chmod 600 postgresql.key
2) 拷贝客户端SSL配置文件到客户端机器
将客户端证书
root.key #根证书
postgresql.crt #客户端证书
postgresql.key #客户端私钥
从服务端复制到客户端的~/.postgresql/目录下(没有找到的话在root下mkdir一个.postgresql文件夹再放进去证书)
3)配置/etc/odbc.ini文件:
PostgreSQL 的几种SSL连接模式:
disable: 只尝试非SSL连接。
allow: 首先尝试非SSL连接,若失败再尝试SSL连接。
prefer: 默认模式,首先尝试SSL连接,若失败再尝试非SSL连接。
require: 只尝试SSL连接,若有根证书存在,等同于verify-ca。
verify-ca: 只尝试SSL连接,并用根证书验证服务器证书是不是根CA签发的。
verify-full:只尝试SSL连接,并用根证书验证服务器证书是不是根CA签发的,且主题必须匹配连接域名或IP地址
增加下面的配置:
vim /etc/odbc.ini
Sslmode = verify-ca
三、测试:
远程连接数据源并进行数据库操作:
[root@bj /root]#isql xxxxx -v
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL> select * from xxxTable;
抓包:
1、远程连接
2、操作数据库
3、断开远程连接