GM

描述

gm 插件能启用国密相关的功能。目前支持通过该插件动态配置国密双证书。

GM - 图1相关介绍

国密就是国产化的密码算法。在我们日常开发过程中会接触到各种各样的密码算法,如 RSA、SHA256 等等。为了达到更高的安全等级,许多大公司和国家会制定自己的密码算法。国密就是这样一组由中国国家密码管理局制定的密码算法。在国际形势越发复杂多变的今天,密码算法的国产化替代,在一些领域已经成为了一股势不可挡的潮流。

启用插件

该插件要求 Apache APISIX 运行在编译了 Tongsuo 的 APISIX-Base 上。

首先,我们需要安装 Tongsuo(此处我们选择编译出 Tongsuo 的动态链接库):

  1. # TODO: use a fixed release once they have created one.
  2. # See https://github.com/Tongsuo-Project/Tongsuo/issues/318
  3. git clone https://github.com/api7/tongsuo --depth 1
  4. pushd tongsuo
  5. ./config shared enable-ntls -g --prefix=/usr/local/tongsuo
  6. make -j2
  7. sudo make install_sw

其次,我们需要构建 APISIX-Base,让它使用 Tongsuo 作为 SSL 库:

  1. export OR_PREFIX=/usr/local/openresty
  2. export openssl_prefix=/usr/local/tongsuo
  3. export zlib_prefix=$OR_PREFIX/zlib
  4. export pcre_prefix=$OR_PREFIX/pcre
  5. export cc_opt="-DNGX_LUA_ABORT_AT_PANIC -I${zlib_prefix}/include -I${pcre_prefix}/include -I${openssl_prefix}/include"
  6. export ld_opt="-L${zlib_prefix}/lib -L${pcre_prefix}/lib -L${openssl_prefix}/lib64 -Wl,-rpath,${zlib_prefix}/lib:${pcre_prefix}/lib:${openssl_prefix}/lib64"
  7. ./build-apisix-base.sh

该插件默认是禁用状态,你需要将其添加到配置文件(./conf/config.yaml)中才可以启用它:

  1. plugins:
  2. - ...
  3. - gm

由于 APISIX 的默认 cipher 中不包含国密 cipher,所以我们还需要在配置文件(./conf/config.yaml)中设置 cipher:

  1. apisix:
  2. ...
  3. ssl:
  4. ...
  5. # 可按实际情况调整。错误的 cipher 会导致 “no shared cipher” 或 “no ciphers available” 报错。
  6. ssl_ciphers: HIGH:!aNULL:!MD5

配置完成后,重新加载 APISIX,此时 APISIX 将会启用国密相关的逻辑。

测试插件

在测试插件之前,我们需要准备好国密双证书。Tongsuo 提供了生成SM2 双证书的教程。

在下面的例子中,我们将用到如下的证书:

  1. # 客户端加密证书和密钥
  2. t/certs/client_enc.crt
  3. t/certs/client_enc.key
  4. # 客户端签名证书和密钥
  5. t/certs/client_sign.crt
  6. t/certs/client_sign.key
  7. # CA 和中间 CA 打包在一起的文件,用于设置受信任的 CA
  8. t/certs/gm_ca.crt
  9. # 服务端加密证书和密钥
  10. t/certs/server_enc.crt
  11. t/certs/server_enc.key
  12. # 服务端签名证书和密钥
  13. t/certs/server_sign.crt
  14. t/certs/server_sign.key

此外,我们还需要准备 Tongsuo 命令行工具。

  1. ./config enable-ntls -static
  2. make -j2
  3. # 生成的命令行工具在 apps 目录下
  4. mv apps/openssl ..

你也可以采用非静态编译的方式,不过就需要根据具体环境,自己解决动态链接库的路径问题了。

以下示例展示了如何在指定域名中启用 gm 插件:

创建对应的 SSL 对象:

  1. #!/usr/bin/env python
  2. # coding: utf-8
  3. import sys
  4. # sudo pip install requests
  5. import requests
  6. if len(sys.argv) <= 3:
  7. print("bad argument")
  8. sys.exit(1)
  9. with open(sys.argv[1]) as f:
  10. enc_cert = f.read()
  11. with open(sys.argv[2]) as f:
  12. enc_key = f.read()
  13. with open(sys.argv[3]) as f:
  14. sign_cert = f.read()
  15. with open(sys.argv[4]) as f:
  16. sign_key = f.read()
  17. api_key = "edd1c9f034335f136f87ad84b625c8f1"
  18. resp = requests.put("http://127.0.0.1:9180/apisix/admin/ssls/1", json={
  19. "cert": enc_cert,
  20. "key": enc_key,
  21. "certs": [sign_cert],
  22. "keys": [sign_key],
  23. "gm": True,
  24. "snis": ["localhost"],
  25. }, headers={
  26. "X-API-KEY": api_key,
  27. })
  28. print(resp.status_code)
  29. print(resp.text)

将上面的脚本保存为 ./create_gm_ssl.py,运行:

  1. ./create_gm_ssl.py t/certs/server_enc.crt t/certs/server_enc.key t/certs/server_sign.crt t/certs/server_sign.key

输出结果如下所示:

  1. 200
  2. {"key":"\/apisix\/ssls\/1","value":{"keys":["Yn...

完成上述准备后,可以使用如下命令测试插件是否启用成功:

  1. ./openssl s_client -connect localhost:9443 -servername localhost -cipher ECDHE-SM2-WITH-SM4-SM3 -enable_ntls -ntls -verifyCAfile t/certs/gm_ca.crt -sign_cert t/certs/client_sign.crt -sign_key t/certs/client_sign.key -enc_cert t/certs/client_enc.crt -enc_key t/certs/client_enc.key

这里 ./openssl 是前面得到的 Tongsuo 命令行工具。9443 是 APISIX 默认的 HTTPS 端口。

如果一切正常,可以看到连接建立了起来,并输出如下信息:

  1. ...
  2. New, NTLSv1.1, Cipher is ECDHE-SM2-SM4-CBC-SM3
  3. ...

禁用插件

如果不再使用此插件,可将 gm 插件从 ./conf/config.yaml 配置文件中移除,然后重启 APISIX 或者通过插件热加载的接口触发插件的卸载。