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/

创建证书:

虽然可以使用自签名证书进行测试,但在实际生产中应该使用由证书颁发机构(CA)(通常是企业范围的根CA)签署的证书。

要创建可以由客户端验证身份的服务器证书,首先创建证书签名请求(certificate signing request (CSR))和公钥/私钥文件:

[root@xxx data]# openssl req -new -nodes -text -out root.csr -keyout root.key -subj "/CN=root.yourdomain.com" aisainfo

Generating a 2048 bit RSA private key

............................................................................................................................+++

....+++

writing new private key to 'root.key'

-----

[root@xxx data]# ll

-rw-r--r--. 1 root root 3315 May 6 07:30 root.csr

-rw-r--r--. 1 root root 1704 May 6 07:30 root.key

然后,使用密钥对请求进行签名,以创建根证书颁发机构(在Linux上使用默认的OpenSSL配置文件位置):

[root@xxx data]# openssl x509 -req -in root.csr -text -days 3650 -extfile /etc/pki/tls/openssl.cnf -extensions v3_ca -signkey root.key -out root.crt

Signature ok

subject=/CN=postgres

Certificate:

Data:

Version: 1 (0x0)

Serial Number:

9c:dc:90:eb:19:e4:e4:6d

Signature Algorithm: NULL

Issuer: CN=postgres

Validity

Not Before: May 6 03:28:00 2023 GMT

Not After : May 3 03:28:00 2033 GMT

Subject: CN=postgres

Subject Public Key Info:

Public Key Algorithm: rsaEncryption

Public-Key: (2048 bit)

Modulus:

00:c4:35:2b:73:a1:d2:b5:17:3b:10:9c:2e:b6:53:

a6:90:fb:22:a4:97:5b:73:58:19:cc:9a:1f:08:0d:

2f:07:2d:df:ee:4e:18:f4:c5:12:5c:95:3b:90:d2:

ca:28:31:4d:b2:fa:e9:5f:6d:57:c0:30:ec:bf:55:

ff:9b:18:c6:68:f3:7c:2a:bc:94:1d:52:0a:d2:00:

ae:f4:79:9c:53:b1:43:b0:12:65:1f:ef:d0:14:b2:

64:7c:32:ec:97:93:a0:e1:41:b1:54:53:85:99:d8:

ac:3f:a3:f0:d0:d4:95:0d:b2:15:86:aa:6b:df:5d:

c6:70:bf:ea:d4:c0:01:51:24:ef:7b:f0:6e:8a:42:

7a:e2:ed:7d:29:a4:c5:7f:5e:2d:dc:fd:bb:3c:35:

4b:af:13:3b:22:c7:47:a5:49:92:36:f7:f2:57:78:

ef:c8:e1:cb:47:ff:6d:31:cd:97:f5:2f:02:76:07:

05:27:9a:39:da:e0:92:a7:fc:51:cb:b9:59:ea:c9:

b2:65:23:29:7e:88:62:59:c6:5a:a3:3c:91:ab:ea:

4d:1b:32:04:e1:45:6e:98:5b:a5:42:51:47:51:1c:

b3:74:58:08:5d:51:d9:1d:62:3f:37:4e:4a:ed:1e:

72:ae:d0:58:17:bb:26:57:20:95:72:ef:04:02:00:

bd:27

Exponent: 65537 (0x10001)

Signature Algorithm: NULL

Getting Private key

[root@xxx data]# ll

-rw-r--r--. 1 root root 1090 May 6 07:31 root.crt

-rw-r--r--. 1 root root 3315 May 6 07:30 root.csr

-rw-r--r--. 1 root root 1704 May 6 07:30 root.key

最后,创建一个由新的根证书颁发机构签名的服务器证书:

[root@xxx data]# openssl req -new -nodes -text -out server.csr -keyout server.key -subj "/CN=dbhost.yourdomain.com" udmuser

Generating a 2048 bit RSA private key

...............................................+++

.....+++

writing new private key to 'server.key'

-----

[root@xxx data]# ll

-rw-r--r--. 1 root root 3315 May 6 07:37 server.csr

-rw-r--r--. 1 root root 1704 May 6 07:37 server.key

[root@xxx data]# chmod og-rwx server.key

[root@xxx data]# openssl x509 -req -in server.csr -text -days 365 -CA root.crt -CAkey root.key -CAcreateserial -out server.crt

Signature ok

subject=/CN=postgres

Certificate:

Data:

Version: 1 (0x0)

Serial Number:

bb:ca:fa:52:ef:54:e9:c7

Signature Algorithm: NULL

Issuer: CN=postgres

Validity

Not Before: May 6 07:39:04 2023 GMT

Not After : May 5 07:39:04 2024 GMT

Subject: CN=postgres

Subject Public Key Info:

Public Key Algorithm: rsaEncryption

Public-Key: (2048 bit)

Modulus:

00:e5:41:69:05:65:23:dc:5e:ef:b0:af:29:01:b6:

00:91:4b:a6:20:09:72:9b:d4:eb:75:3a:1d:75:ae:

76:9d:7c:6f:f8:cc:2b:03:39:d1:37:23:4e:cf:99:

69:8e:93:45:61:b7:af:e5:a2:63:61:31:05:07:ca:

d6:5a:cf:f5:53:02:60:1c:15:ed:32:7f:18:27:c8:

d0:c1:b4:f7:2d:87:19:51:34:ed:ef:04:2f:65:18:

74:0d:b9:5c:c0:e2:ff:21:16:4a:cd:b3:13:a8:2c:

bb:4f:e5:20:83:26:16:0c:48:ce:c1:d9:36:c1:fb:

db:8e:dd:9e:1b:fc:11:d6:73:a6:74:b0:27:bb:0d:

d9:80:2f:b9:ee:b3:bf:a2:3e:8c:15:12:be:35:85:

2c:5c:5a:2c:c1:c6:a4:63:ae:cd:37:49:38:aa:55:

67:32:b3:11:7e:ce:e8:e2:46:1e:57:52:a6:2a:6b:

2e:90:f8:e0:25:aa:0c:fa:8a:74:d1:4f:39:c9:0e:

68:09:89:8c:54:e6:0a:68:27:76:82:e4:eb:f0:64:

9d:e1:34:f5:19:e5:cf:dc:81:03:cb:40:d9:a2:64:

64:a1:92:b3:c4:14:3a:c3:0d:7b:b8:86:6a:c3:a2:

f5:1a:af:20:9e:e3:da:fc:58:38:6f:4d:8c:b6:1f:

ad:cb

Exponent: 65537 (0x10001)

Signature Algorithm: NULL

Getting CA Private Key

[root@xxx data]# ll

-rw-r--r--. 1 root root 973 May 6 07:39 server.crt

-rw-r--r--. 1 root root 3315 May 6 07:37 server.csr

-rw-------. 1 root root 1679 May 6 07:38 server.key

执行初始化数据库命令:

/usr/local/postgresql/bin/initdb -D /usr/local/postgresql/data/

注意: 1)不能在 root 用户下初始数据库,否则会报错; 2)初始化之后配置pg_hba.conf和postgres.conf,接着启动数据库可直接按配置启动数据库;下面描述的方法是启动数据库后,再修改配置并使配置生效的方法,配置参数都是一样的。

切到root下,为 pg_ctl 创建软链接:

su

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启动服务:

su 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_cert_file = 'server.crt' #指定包含SSL服务器证书的文件的名称。

ssl_key_file = 'server.key' #指定包含SSL服务器私钥的文件的名称。

注意: 单项认证采用以上配置即可,双向认证使用以下配置【双向认证必须配置ssl_ca_file项】:

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服务器私钥的文件的名称。

修改pg_hba.conf

如果强制SSL连接(仅允许SSL连接)、不允许普通连接,则修改pg_hba.conf,配置SSL连接认证规则: vim pg_hba.conf

单向认证:

hostssl all all 0.0.0.0/0 md5

双向认证(以下两种配置方式都可以):

hostssl all all 0.0.0.0/0 md5 clientcert=1

hostssl all all 0.0.0.0/0 cert

注意: 不同版本的postgresql配置双向认证的参数略有不同,我当前安装的v11.4版本就可以用clientcert=1或者cert,具体可以根据自己安装的版本查看官方说明,v11.4版本的配置说明如下: 【参考资料】:PostgreSQL: Documentation: 11: 18.9. Secure TCP/IP Connections with SSL

18.9.3. Using Client Certificates To require the client to supply a trusted certificate, place certificates of the root certificate authorities (CAs) you trust in a file in the data directory, set the parameter ssl_ca_file in postgresql.conf to the new file name, and add the authentication option clientcert=1 to the appropriate hostssl line(s) in pg_hba.conf. A certificate will then be requested from the client during SSL connection startup. (See Section 34.18 for a description of how to set up certificates on the client.) The server will verify that the client’s certificate is signed by one of the trusted certificate authorities. The clientcert authentication option is available for all authentication methods, but only in pg_hba.conf lines specified as hostssl. When clientcert is not specified or is set to 0, the server will still verify any presented client certificates against its CA file, if one is configured — but it will not insist that a client certificate be presented. If you are setting up client certificates, you may wish to use the cert authentication method, so that the certificates control user authentication as well as providing connection security. See Section 20.12 for details. (It is not necessary to specify clientcert=1 explicitly when using the cert authentication method.)

说明: 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。

登陆PostgreSQL数据库,打开ssl开关:

psql -U postgres -d postgres

postgres=# alter system set ssl=on;

ALTER SYSTEM

调用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)

总结: 服务端按需求配置postgres.conf、pg_hba.conf两个配置文件,并放入相关证书文件(root.crt, server.crt, server.key)即可打开SSL单/双向认证连接;仅做单向认证的话到这里就完成了,无需对客户端进行配置;下面描述的是客户端双向认证配置流程。

二、客户端:

1)生成客户端SSL配置(在服务端进行):

服务端为客户端生成客户后端证书,提供给客户端连接时使用。 客户端开启SSL配置双向认证连接服务器,需要三个文件: root.key(根证书) postgresql.crt(客户端证书) postgresql.key(客户端私钥)

在服务器端操作、生成客户端需要的文件,即客户后端私钥(postgresql.key)和客户端证书(postgresql.crt):

创建一个由根证书颁发机构签名的客户端证书:

[root@xxx data]# openssl req -new -nodes -text -out postgresql.csr -keyout postgresql.key -subj "/CN=dbhost.yourdomain.com" udmuser

Generating a 2048 bit RSA private key

...........+++

............................................................+++

writing new private key to 'postgresql.key'

-----

[root@xxx data]# ll

-rw-r--r--. 1 root root 3315 May 6 08:26 postgresql.csr

-rw-r--r--. 1 root root 1704 May 6 08:26 postgresql.key

[root@xxx data]# chmod og-rwx postgresql.key

[root@xxx data]# openssl x509 -req -in postgresql.csr -text -days 365 -CA root.crt -CAkey root.key -CAcreateserial -out postgresql.crt

Signature ok

subject=/CN=postgres

Certificate:

Data:

Version: 1 (0x0)

Serial Number:

c1:32:b7:ec:c8:a1:31:4f

Signature Algorithm: NULL

Issuer: CN=postgres

Validity

Not Before: May 6 08:28:15 2023 GMT

Not After : May 5 08:28:15 2024 GMT

Subject: CN=postgres

Subject Public Key Info:

Public Key Algorithm: rsaEncryption

Public-Key: (2048 bit)

Modulus:

00:e0:8c:eb:29:3c:df:17:ca:8c:e4:ab:37:8f:f9:

02:ec:3e:c3:0f:0d:86:2c:fb:21:aa:81:39:31:fd:

45:4e:3e:a4:99:f8:f4:49:cc:69:d2:1a:31:87:f1:

e8:17:46:86:0b:d5:06:46:9a:85:1a:d5:7a:1a:d4:

27:b7:09:6d:28:0e:9b:ff:c4:96:90:5e:02:b2:b3:

be:49:d0:6b:f3:aa:25:5d:1f:22:b3:a1:e2:0d:29:

6b:e6:41:09:85:a6:66:ee:2f:6b:a7:25:8a:25:f3:

92:71:6b:fc:d9:34:68:eb:70:0c:f0:d8:b2:4f:82:

f3:02:fa:0f:02:c8:95:5e:32:09:d0:01:ae:39:8d:

13:c4:9a:e1:6b:ab:3b:01:96:c1:d8:95:0c:70:22:

2b:7d:a8:e9:0d:5f:18:5f:5c:6e:84:80:0a:51:77:

2e:87:3d:62:6e:0b:30:39:a2:76:19:ff:95:da:ad:

fb:61:44:e7:15:f3:c9:c6:fa:b2:26:db:b9:79:08:

ad:75:bf:26:15:54:62:63:ee:ed:0e:67:6d:05:df:

3c:03:4a:fc:d8:6c:f8:b3:b4:fb:ab:66:c0:f8:e6:

4d:3f:0b:77:9d:be:4f:a8:5c:c0:4f:1f:76:d4:cf:

4b:33:e8:40:09:96:8c:02:dc:9c:9e:d3:37:59:d4:

65:d3

Exponent: 65537 (0x10001)

Signature Algorithm: NULL

Getting CA Private Key

[root@xxx data]# ll

-rw-r--r--. 1 root root 973 May 6 08:28 postgresql.crt

-rw-r--r--. 1 root root 3315 May 6 08:26 postgresql.csr

-rw-------. 1 root root 1679 May 6 08:27 postgresql.key

2) 拷贝客户端SSL配置文件到客户端机器

root.key #根证书

postgresql.crt #客户端证书

postgresql.key #客户端私钥

将 1)中生成的客户端证书从服务端复制到客户端以下路径: (a)~/.postgresql/目录下(没有找到的话在root下mkdir一个.postgresql文件夹再放进去证书),这是默认路径 (b) 将证书放到自定义路径下,并通过设置环境变量指定证书路径:

export PGSSLROOTCERT=/home/pgcert/root.crt

export PGSSLCERT=/home/pgcert/postgresql.crt

export PGSSLKEY=/home/pgcert/postgresql.key

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地址

进行SSL连接的话仅考虑配置后三种连接模式,其区别在于: Require:只对数据链路加密,并不验证数据库的真实性。 Verify-CA:加密数据链路,同时验证数据库的真实性。 Verify-Full:加密数据链路,验证数据库的真实性,同时比对证书内的CN或DNS与连接时配置的数据库连接地址是否一致。

并且: verify-ca和verify-full之间的区别取决于根CA的策略。如果使用了一个公共CA,verify-ca允许连接到那些可能已经被其他人注册到该CA的服务器。在这种情况下,总是应该使用verify-full。如果使用了一个本地CA或者甚至是一个自签名的证书,使用verify-ca常常就可以提供足够的保护。

由于我的项目使用的是自签名的证书,因此我配置Sslmode = require,无证书时可进行单向认证连接;放入相关证书(等同于verify-ca)即可满足双向认证连接的需求。

增加下面的配置: vim /etc/odbc.ini

Sslmode = require

三、测试:

远程连接数据源并进行数据库操作:

[root@xxx /root]#isql xxxxx -v

+---------------------------------------+

| Connected! |

| |

| sql-statement |

| help [tablename] |

| quit |

| |

+---------------------------------------+

SQL> select * from xxxTable;

操作数据库和抓包:

1、远程连接 2、操作数据库 3、断开远程连接 单向认证抓包: 双向认证抓包:

相关阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: