Logo
连接管理

连接管理 #

登录认证 #

Proxy 拥有严格的登录认证机制,只有经过身份认证的用户才可以成功建立连接。

概念 #

为保障用户数据和分布式配置信息的安全,DBPlusEngine-Proxy 提供了用户认证的功能,且该功能不可关闭,否则,未经认证的客户端连接将被拒绝。 当前,DBPlusEngine-Proxy 已经支持了多种用户认证协议,包括:

  • MySQL 客户端:old password、native、clear-text、sha256
  • PostgreSQL 客户端:scram-sha-256、MD5、password
  • openGauss 客户端:scram-sha-256、md5

DBPlusEngine-Proxy 为各种数据库协议设置了默认的认证方式,且用户不能修改。其中:MySQL 使用 native,PG 使用 md5,OG 使用 scram-sha-256。为方便企业用户进行统一身份管理,DBPlusEngine 也提供了 LDAP(Lightweight Directory Access Protocol)认证方式,LDAP 认证已支持 MySQL 和 PostgreSQL 客户端。下面是配置用户使用不同的认证方式示例。

- !AUTHORITY
  users:
    - user: root@%
      password: root
      authenticationMethodName: md5
    - user: sharding
      password: sharding
  authenticators:
    md5:
      type: MD5
    scram_sha256:
      type: SCRAM_SHA256
  defaultAuthenticator: scram_sha256

特点 #

实际上,用户在使用 DBPlusEngine-Proxy 时不需要考虑选择何种协议,协议的协商过程是在 DBPlusEngine 与客户端之间自动完成的。

  • 当使用 MySQL 客户端时,默认使用 mysql_native_password。仅当用户需要进行 LDAP 认证时,DBPlusEngine 会要求客户端切换为 mysql_clear_password 协议进行通信。
  • 当使用 PostgreSQL 客户端时,默认使用 MD5。仅当用户需要进行 LDAP 认证时,DBPlusEngine 会要求客户端切换为 password 协议进行通信。

密码认证 #

默认情况下,Proxy 使用密码认证方式,登录用户需提供正确的用户名和密码。

特别的,由于 Proxy 支持多种数据库协议(如 MySQL、PostgreSQL 等),当用户应用不同的数据库客户端时,Proxy 能够自动适配密码通信协议,在复杂场景下为用户提供一致的安全体验。

主机限制 #

管理员可以为 Proxy 的用户限制登录主机地址,以提高安全等级。如:

- !AUTHORITY
    users:
      - user: root@127.0.0.1
        password: root

以上配置指定了 root 用户只能从 127.0.0.1 这个地址访问 Proxy,从其他地址登录时,即使密码正确也将被拒绝。

LDAP 认证 #

为方便企业用户进行统一认证管理,Proxy 也提供了 LDAP(Lightweight Directory Access Protocol)认证方式,LDAP 认证现已支持 MySQL 和 PostgreSQL 客户端。 同时, Proxy 允许用户以非常灵活的方式来接入 LDAP,例如:

  1. 可以配置为默认使用 LDAP,这样所有用户都通过 LDAP 认证;
  2. 支持为用户配置 auth 属性,指定用户使用密码或 LDAP 认证,各个用户可以使用不同方式;
  3. 各个用户可以使用不同的 LDAP 认证器,即对接不同的 LDAP 服务;
  4. 支持为用户指定 DN 模板,满足复杂场景的需要;
  5. 支持 LDAPS 协议,可进一步提升安全等级。

连接配置 #

SphereEx-DBPlusEngine 支持 MySQL 或 PostgreSQL 方式连接,用户可通过标准数据库的方式进行连接,可使用包括 JDBC、ODBC 及本地 Socket 等多种方式进行连接。

Socket 连接 #

SphereEx-DBPlusEngine 支持通过 Socket 方式,可使用 MySQL 或 PostgreSQL 命令行进行连接。SphereEx-DBPlusEngine 的 Proxy 启动时,可指定生成 -s 选型指定 Socket 路径及文件。当 MySQL 命令行进行连接,可通过如下方式进行连接。

mysql -s /path/xxx.sock 
mysql --socket /path/xxx.sock

SSL 连接 #

SphereEx-DBPlusEngine 支持 MySQL 或 PostgreSQL SSL加密方式连接。下文以 MySQL 为例进行说明。

TLS 版本 #

如果计算节点本地 openSSL 版本过低,可通过参数 proxy-frontend-ssl-version 进行设置。

props:                                                                                                                                   
  proxy-frontend-ssl-version: TLSv1.2

在客户端连接的时候,也使用此版本的 TLS 进行连接。

mysql -h xxx -P3306 -A --ssl-mode=REQUIRED --ssl-ca=/tmp/0608Test/proxy/certificate/Digicert-OV-DV-root.c
er --tls-version=TLSv1.2

CA 认证 #

用户可以选择使用 CA 认证登录。使用 openssl 生成服务器端数字证书和私钥,放于服务器指定路径。

props:                                                                                                                                   
  props:
  proxy-frontend-ssl-enabled: true
  proxy-frontend-ssl-cert-file: /path/xxx.pem
  proxy-frontend-ssl-key-file: /path/xxx.key

启动服务器,可看到有如下日志输出。

[INFO ] 2023-05-06 11:54:32.190 [main] o.a.s.p.frontend.ssl.ProxySSLContext - Using X.509 certificate chain file [/home/wuweijie/projects/shardingsphere/.settings/ssl/9917537_proxy.wwj.icu.pem] and private key file [/home/wuweijie/projects/shardingsphere/.settings/ssl/9917537_proxy.wwj.icu.key]

可使用客户端验证服务端证书及域名,连接使用 CA 签发证书的计算节点。

mysql -h xxx -proot -P13306 -A --ssl-mode=VERIFY_IDENTITY --ssl-ca=/tmp/xxx.cer

也可以使用客户端仅验证服务端 CA,使用非 SSL 证书域名连接使用 CA 签发证书的计算节点

mysql -h xxx -proot -P13306 -A --ssl-mode=VERIFY_CA --ssl-ca=/tmp/xxx.cer

如客户端仅要求 SSL,可使用非 SSL 证书域名连接使用 CA 签发证书的计算节点

mysql -h xxx -proot -P13306 -A --ssl-mode=REQUIRED --ssl-ca=/tmp/xxx.cer

自签发认证 #

如客户端仅要求 SSL,可连接使用自签发证书的计算节点。

props:                                                                                                                                   
  props:
  proxy-frontend-ssl-enabled: true

启动服务器,可看到有如下日志输出。

[WARN ] 2023-05-06 11:52:58.181 [main] o.a.s.p.frontend.ssl.ProxySSLContext - RSA key pair and CA certificate are generated by ShardingSphere-Proxy and self-signed.

使用客户端连接

mysql -h xxx -proot -P13306 -A --ssl-mode=REQUIRED 

Proxy + LDAP & LDAPS 应用案例 #

背景 #

SphereEx-DBPlusEngine 增加了对 LDAP 登录认证的支持,以下应用案例展示了 LDAP 登录认证的使用流程。

在案例展示过程中,使用 Wireshark 工具进行抓包,以更形象的展示 LDAP 与 LDAPS 协议的区别。

LDAPS 是基于 SSL/TLS 的 LDAP 通信方式。

基础环境 #

名称版本
MySQL5.7+
SphereEx-DBPlusEngine1.0+
Wireshark3.6
ApacheDS2.0.0
  • database-sharding-databases.yaml
schemaName: sharding_db

dataSources:
  ds_0:
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_0?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 10
    minPoolSize: 1
  ds_1:
    url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
    username: root
    password:
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 10
    minPoolSize: 1

rules:
- !SHARDING
  tables:
    t_order:
      actualDataNodes: ds_${0..1}.t_order
      keyGenerateStrategy:
        column: order_id
        keyGeneratorName: snowflake
  defaultDatabaseStrategy:
    standard:
      shardingColumn: user_id
      shardingAlgorithmName: database_inline
  defaultTableStrategy:
    none:
  shardingAlgorithms:
    database_inline:
      type: INLINE
      props:
        algorithm-expression: ds_${user_id % 2}
  keyGenerators:
    snowflake:
      type: SNOWFLAKE

LDAP 服务器配置 #

采用 ApacheDS™ 的 Docker 镜像:tremolosecurity/apacheds

a. 拉取镜像

docker pull tremolosecurity/apacheds:latest

b. 生成 SSL 证书

说明页:https://directory.apache.org/apacheds/basic-ug/3.3-enabling-ssl.html

按照页面中的方法,使用 keytool 生成证书。

这里以 Common name 为 localhost 为例,生成两个文件:

.
├── localhost.ks
└── localhost.cer

由于使用的容器对文件名有特殊要求,这里将 localhost.ks 重命名为 apacheds.jks。

.
├── apacheds.jks
└── localhost.cer

说明: 证书文件可以保存在任意路径,如:

  • /Users/${yourname}/apacheds/apacheds.jks
  • /Users/${yourname}/apacheds/localhost.cer

c. 启动容器

docker run --detach --rm --name apacheds \
  -p 10389:10389 \
  -p 10636:10636 \
  -v /Users/${yourname}/apacheds:/etc/apacheds \
  -e APACHEDS_ROOT_PASSWORD=secret \
  -e APACHEDS_TLS_KS_PWD=secret \
  tremolosecurity/apacheds:latest

说明:

  • 该容器映射出两个端口,其中 10389 用作 ldap 非加密连接,10636 用作 ldaps 加密连接。
  • ApacheDS 服务中包含一个默认用户 uid=admin,ou=system,通过 APACHEDS_ROOT_PASSWORD 参数指定了其密码为 secret。

启动操作后,查看日志是否正常:

docker logs -f apacheds

d. ldapsearch 测试

ldapsearch 命令可以便捷的对 LDAP 服务发起访问,验证 LDAP 服务是否正常:

docker exec -it apacheds ldapsearch -x -H ldap://localhost:10389 -b ou=system -D "uid=admin,ou=system" -w secret

至此,LDAP 服务器配置完成。

JDK 导入证书 #

由于 LDAP 服务端使用的是自签名证书,在客户端访问前需要先导入 JRE 的 keystore 中。 注意,导入过程需要输入该证书的密钥:secret。

keytool -import -alias localhost -keystore $JAVA_HOME/jre/lib/security/cacerts -file /Users/${yourname}/apacheds/localhost.cer

Proxy-LDAP 测试 #

a. global.yaml

authority:
 users:
   - user: root@%
   - user: admin
   - user: sharding
 authenticators:
   auth_ldap:
     type: LDAP
     props:
       ldap_server_url: ldap://localhost:10389
       ldap_dn_template: uid={0},ou=system
 defaultAuthenticator: auth_ldap

b. 启动 Proxy。

c. 启动 Wireshark,开始抓取 10389 端口的数据包。

d. MySQL 客户端登录测试

注意指定 –enable-cleartext-plugin 参数

# 由于 LDAP 服务器中只有一个 admin 用户,这里使用 admin 进行登录。
# 如果尝试其他用户,得到结果是登录失败。
mysql -h 127.0.0.1 -P 3307 -A -u admin -p --enable-cleartext-plugin

输入密码 secret 后登录成功:

e. 查看抓包数据

从抓取的 TCP 数据包中,我们可以轻松的找到一条包含用户 DN 和密码的报文:

f. 小结

从 global.yaml 配置可以看出,在已有 LDAP 服务器的前提下,使用 LDAP 进行登录认证并不复杂,只需要简单配置即可。

另一方面,由于 LDAP 协议是未经加密的,在公开网络中使用 LDAP 认证有密码泄露的风险。

Proxy-LDAPS 测试 #

a. global.yaml

与 LDAP 案例的区别仅仅是更换了 LDAP 服务器的 URL。

authority:
  users:
    - user: root@%
    - user: admin
    - user: sharding
  authenticators:
    auth_ldap:
      type: LDAP
      props:
        ldap_server_url: ldaps://localhost:10636
        ldap_dn_template: uid={0},ou=system
  defaultAuthenticator: auth_ldap

b. 启动 Proxy

c. 启动 Wireshark,开始抓取 10636 端口的数据包

d. MySQL 客户端登录测试

注意指定 –enable-cleartext-plugin 参数

# 由于 LDAP 服务器中只有一个 admin 用户,这里使用 admin 进行登录。
# 如果尝试其他用户,得到结果是登录失败。
mysql -h 127.0.0.1 -P 3307 -A -u admin -p --enable-cleartext-plugin

输入密码 secret 后登录成功:

e. 查看抓包数据 从数据包可以看到,Proxy 与 LDAP 服务器之间建立了 TLS 通信,已无法通过抓包获取通信的内容:

f. 小结

通过 SSL/TLS 加密,可以有效的保护用户登录信息。而 SphereEx-DBPlusEngine 对 LDAPS 的支持非常友好,仅需导入证书和替换 URL 就可以完成 LDAP 到 LDAPS 的切换。

其他问题 #

  • 是否可使用 SSL 连接?

    这分为两种情况,一是针对 SphereEx-DBPlusEngine 与底层数据库的连接;而是前端应用于 SphereEx-DBPlusEngine 的连接。针对前者,主要依赖于对应 SphereEx-DBPlusEngine 内置的 JDBC 驱动情况而定,针对 MySQL、PostgreSQL 都支持使用 SSL 方式进行连接。针对后者,SphereEx-DBPlusEngine 暂不支持 SSL 方式连接。

  • 是否支持连接池配置?

    SphereEx-DBPlusEngine 支持主流的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等。在具体配置时,需要关注连接池上限,以满足可能的高并发场景需求。

  • 是否支持负载均衡配置?

    SphereEx-DBPlusEngine 针对底层数据库提供读能力的负载均衡,具体参见读写分离部分。针对前端应用与 SphereEx-DBPlus Engine 连接,理论上支持任何四层负载均衡作为 SphereEx-DBPlusEngine 的负载均衡。

  • 是否支持通过VIP方式接入 SphereEx-DBPlusEngine ?

    SphereEx-DBPlusEngine 自身不提供 VIP 能力,可通过第三方服务完成。通过将 SphereEx-DBPlusEngine 作为标准服务来看待,通过 VIP 绑定来提升整体可用性。