openGauss

开源数据库

openGauss社区官网

开源社区

openGauss与PostgreSQL对比测试SSL之自签名CA证书双向认证测试

多米爸比2021-03-31openGauss与PostgreSQL对比

openGauss 与 PostgreSQL 对比测试 SSL 之自签名 CA 证书双向认证测试

本文测试自签名 CA 证书的双向认证: 客户端验证服务器证书的有效性,同时服务器端也要验证客户端证书的有效性,只有认证成功,连接才能建立。

服务端证书的客户端认证模式

1.客户端 SSLMODE 设置为 verify-ca 仅校验数据库证书真伪。

2.客户端 SSLMODE 设置为 verify-full 校验数据库证书真伪及通用名 CN 匹配数据库连接的 hostname。

客户端证书的服务器认证模式

1.数据库认证文件 pg_hba.conf 配置认证选项 clientcert=verify-ca 仅验证客户端证书真伪,认证方法可选。

2.数据库认证文件 pg_hba.conf 配置认证选项 clientcert=verify-full 验证客户端证书真伪及 CN 匹配数据库连接用户名或映射匹配,认证方法可选。

3.数据库认证文件 pg_hba.conf 配置认证方法 cert,免密验证客户端证书真伪及 CN 匹配数据库连接用户名或映射匹配

自签名 CA 证书双向认证测试

1.创建 CA 证书

用于给数据库服务器证书签名的 CA 证书:ca_server.crt

$ openssl req -new -x509 -days 365 -nodes \
-config openssl.cnf \
-out ca_server.crt -keyout ca_server.key -subj "/CN=FooServerCA"

用于给客户端证书签名的 CA 证书:ca_client.crt

$ openssl req -new -x509 -days 365 -nodes \
-config openssl.cnf \
-out ca_client.crt -keyout ca_client.key -subj "/CN=FooClientCA"

2.生成数据库服务器证书请求文件并签名

$ openssl req -new -nodes -text \
-config openssl.cnf \
-out server.csr \
-keyout server.key \
-subj "/CN=***.***.***.***"

将证书请求文件(包含用户信息)和证书签名分开操作,证书请求文件可重用,因为后面可能需要重新生成证书。

使用 ca_server.crt 对证书请求文件签名

$ openssl x509 -req -in server.csr -text -days 5 \
-CA ca_server.crt \
-CAkey ca_server.key \
-CAcreateserial \
-out server.crt

这里设置有效期为 5 天,可以观察在服务器证书有效期小于 7 天的时候,连接登录后会在日志中产生告警提醒。

3.生成客户端证书请求文件并签名

$ openssl req -new -nodes -text \
-config openssl.cnf \
-out client.csr \
-keyout client.key \
-subj "/CN=dbuser1"

将证书请求文件(包含用户信息)和证书签名分开操作,证书请求文件可重用,因为后面可能需要重新生成证书。

使用 ca_client.crt 对证书请求文件签名

$ openssl x509 -req -in client.csr -text -days 30 \
-CA ca_client.crt \
-CAkey ca_client.key \
-CAcreateserial \
-out client.crt

4.传输数据库服务器证书及未加密的私钥文件至数据库服务器

修改文件权限以符合安全设置

$ chmod 0600 ca_client.crt server.crt server.key

传输文件到数据库服务器 PGDATA 目录

$ cp ca_client.crt server.crt server.key $PGDATA

注意:如果 PostgreSQL 使用-g, --allow-group-access

开启了组访问权限,则需要拷贝文件到 PGDATA 目录之外以符合安全设置。

5.数据库 SSL 参数配置

postgreql.conf 文件配置参数

ssl=on
ssl_cert_file= 'server.crt'
ssl_key_file= 'server.key'
ssl_ca_file='ca_client.crt'

然后重启数据库服务。

6.配置数据库客户端

客户端使用 linux 下 psql,证书文件的默认路径为$HOME/.postgresql/

chmod 0600 client.key client.crt
cp client.crt client.key  ~/.postgresql/
cat ca_server.crt > ~/.postgresql/root.crt
chmod 0600 ~/.postgresql/root.crt

测试一

pg_hba.conf 文件配置 hostssl 条目。

hostssl  all  all  ***.***.***.***/0  md5

测试验证数据库服务器证书

openGauss 数据库

gsql "sslmode=verify-ca" -p6432 -h ***.***.***.*** -Upostgres
Password for user postgres:
gsql ((GaussDB Kernel V500R001C20 build ) compiled at 2021-03-09 18:30:51 commit 0 last mr  )
SSL connection (cipher: DHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.

postgres=>

PostgreSQL 数据库

psql "sslmode=verify-ca"  -h***.***.***.***
Password for user postgres:
psql (12.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \q

使用 sslmode=verify-ca 仅验证服务器证书真伪,符合预期。

测试二

测试数据库服务器证书设置的通用名 CN 是否匹配客户端连接的 hostname

openGauss 数据库

gsql "sslmode=verify-full" -p6432 -h opengauss1 -Upostgres
gsql: server common name "***.***.***.***" does not match host name "opengauss1"

PostgreSQL 数据库

psql "sslmode=verify-full" -hnode11
psql: error: server certificate for "***.***.***.***" does not match host name "node11"

分别使用 ip 地址及主机名测试,与通用名 CN 匹配的 ip 地址可成功登录,使用主机名连接报错,报错提示如上,符合预期。

测试三

测试验证客户端证书

pg_hba.conf 文件配置 hostssl 条目。

hostssl  all  all  ***.***.***.***/0  md5 clientcert=verify-ca

此时数据库连接使用 ip 地址或者 hostname 均可连接。

openGauss 数据库

gsql "sslcert=/home/omm/.postgresql/client.crt sslkey=/home/omm/.postgresql/client.key"
-h***.***.***.*** -p6432 -Upostgres
Password for user postgres:
Warning: The client certificate will expire in 29 days.
gsql ((GaussDB Kernel V500R001C20 build ) compiled at 2021-03-09 18:30:51 commit 0 last mr  )
SSL connection (cipher: DHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.

postgres=>

使用 hostname 也可连接

gsql "sslcert=/home/omm/.postgresql/client.crt sslkey=/home/omm/.postgresql/client.key"
-hopengauss1 -p6432 -Upostgres

如果使用不正确的客户端证书,比如手工修改 client.crt 内容,测试会失败。

PostgreSQL 数据库

psql "sslcert=/home/postgres/.postgresql/client.crt sslkey=/home/postgres/.postgresql/client.key" -h***.***.***.***
Password for user postgres:
psql (12.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \q

使用 hostname 也可连接。

psql "sslcert=/home/postgres/.postgresql/client.crt sslkey=/home/postgres/.postgresql/client.key" -hnode11
Password for user postgres:
psql (12.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \q

如果使用不正确的客户端证书,比如手工修改 client.crt 内容,测试会失败。

psql "sslcert=/home/postgres/.postgresql/client.crt sslkey=/home/postgres/.postgresql/client.key" -h***.***.***.***
psql: error: SSL error: tlsv1 alert unknown ca
FATAL:  no pg_hba.conf entry for host "***.***.***.***", user "postgres", database "postgres", SSL off

分别使用 ip 地址及主机名测试 clientcert=verify-ca 选项,测试结果符合预期。

测试四

测试验证客户端证书及 CN 匹配用户或用户映射。

pg_hba.conf 文件配置 hostssl 条目。

hostssl  all  all  ***.***.***.***/0  md5 clientcert=verify-full

此时数据库连接用户必须配置 CN 中配置的名称 dbuser1

openGauss 数据库

gsql "dbname=postgres sslcert=/home/omm/.postgresql/client.crt sslkey=/home/omm/.postgresql/client.key" -h***.***.***.*** -p6432 -Udbuser1

上面使用 dbuser1 可以登录成功,如果使用其他用户也能登录成功。

PostgreSQL 数据库

psql "dbname=postgres sslcert=/home/postgres/.postgresql/client.crt sslkey=/home/postgres/.postgresql/client.key" -h***.***.***.*** -p6000 -Udbuser1

上面使用 dbuser1 可以登录成功,如果使用其他用户比如 postgres 则会出现下面的错误提示。

psql: error: FATAL:  password authentication failed for user "postgres"
FATAL:  no pg_hba.conf entry for host "***.***.***.***", user "postgres", database "postgres", SSL off

测试五

测试 cert 免密认证:验证客户端证书及 CN 匹配用户或用户映射

pg_hba.conf 文件配置 hostssl 条目。

hostssl  all  all  ***.***.***.***/0  cert

此时数据库连接用户必须配置 CN 中配置的名称 dbuser1,同时不需要输入密码。

openGauss 数据库

gsql "dbname=postgres sslcert=/home/omm/.postgresql/client.crt sslkey=/home/omm/.postgresql/client.key" -h***.***.***.*** -p6432 -Udbuser1
Warning: The client certificate will expire in 29 days.
gsql ((GaussDB Kernel V500R001C20 build ) compiled at 2021-03-09 18:30:51 commit 0 last mr  )
SSL connection (cipher: DHE-RSA-AES128-GCM-SHA256, bits: 128)
Type "help" for help.

postgres=>

上面使用 dbuser1 用户可直接登录,不需要输入密码,如果使用其他用户比如 postgres 则会出现下面的错误提示。

Warning: The client certificate will expire in 29 days.
gsql: FATAL:  certificate authentication failed for user "postgres"
FATAL:  no pg_hba.conf entry for host "***.***.***.***", user "postgres", database "postgres", SSL off

PostgreSQL 数据库

psql "dbname=postgres sslcert=/home/postgres/.postgresql/client.crt sslkey=/home/postgres/.postgresql/client.key"
-h***.***.***.*** -Udbuser1
psql (12.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=> \q

上面使用 dbuser1 用户可直接登录,不需要输入密码,如果使用其他用户比如 postgres 则会出现下面的错误提示。

psql: error: FATAL:  certificate authentication failed for user "postgres"
FATAL:  no pg_hba.conf entry for host "***.***.***.***", user "postgres", database "postgres", SSL off

总结

1.sslmode 连接参数设置为 verify-ca 仅校验数据库证书真伪,设置为 verify-full 校验数据库证书真伪及通用名 CN 匹配数据库连接的 hostname。

2.clientcert 认证选项设置为 verify-ca 仅校验客户端证书真伪,设置为 verify-full 校验客户端证书真伪及通用名 CN 匹配数据库用户或用户映射。

3.使用 clientcert 认证选项时,连接类型可以设置为 hostssl,但 host 类型也同时支持 hostssl 及 hostnossl。

4.使用 cert 认证方法只能设置连接类型为 hostssl。

5.客户端证书 clientcert=verify-full 认证方式,openGauss 与 PostgreSQL 有差异,参见测试四。