title: GM keywords:
gm
插件能启用国密相关的功能。目前支持通过该插件动态配置国密双证书。
:::note 相关介绍 国密就是国产化的密码算法。在我们日常开发过程中会接触到各种各样的密码算法,如 RSA、SHA256 等等。为了达到更高的安全等级,许多大公司和国家会制定自己的密码算法。国密就是这样一组由中国国家密码管理局制定的密码算法。在国际形势越发复杂多变的今天,密码算法的国产化替代,在一些领域已经成为了一股势不可挡的潮流。 :::
该插件要求 Apache APISIX 运行在编译了 Tongsuo 的 APISIX-Runtime 上。
首先,我们需要安装 Tongsuo(此处我们选择编译出 Tongsuo 的动态链接库):
# TODO: use a fixed release once they have created one. # See https://github.com/Tongsuo-Project/Tongsuo/issues/318 git clone https://github.com/api7/tongsuo --depth 1 pushd tongsuo ./config shared enable-ntls -g --prefix=/usr/local/tongsuo make -j2 sudo make install_sw
其次,我们需要构建 APISIX-Runtime,让它使用 Tongsuo 作为 SSL 库:
export OR_PREFIX=/usr/local/openresty export openssl_prefix=/usr/local/tongsuo export zlib_prefix=$OR_PREFIX/zlib export pcre_prefix=$OR_PREFIX/pcre export cc_opt="-DNGX_LUA_ABORT_AT_PANIC -I${zlib_prefix}/include -I${pcre_prefix}/include -I${openssl_prefix}/include" 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" ./build-apisix-runtime.sh
该插件默认是禁用状态,你需要将其添加到配置文件(./conf/config.yaml
)中才可以启用它:
plugins: - ... - gm
由于 APISIX 的默认 cipher 中不包含国密 cipher,所以我们还需要在配置文件(./conf/config.yaml
)中设置 cipher:
apisix: ... ssl: ... # 可按实际情况调整。错误的 cipher 会导致“no shared cipher”或“no ciphers available”报错。 ssl_ciphers: HIGH:!aNULL:!MD5
配置完成后,重新加载 APISIX,此时 APISIX 将会启用国密相关的逻辑。
在测试插件之前,我们需要准备好国密双证书。Tongsuo 提供了生成SM2 双证书的教程。
在下面的例子中,我们将用到如下的证书:
# 客户端加密证书和密钥 t/certs/client_enc.crt t/certs/client_enc.key # 客户端签名证书和密钥 t/certs/client_sign.crt t/certs/client_sign.key # CA 和中间 CA 打包在一起的文件,用于设置受信任的 CA t/certs/gm_ca.crt # 服务端加密证书和密钥 t/certs/server_enc.crt t/certs/server_enc.key # 服务端签名证书和密钥 t/certs/server_sign.crt t/certs/server_sign.key
此外,我们还需要准备 Tongsuo 命令行工具。
./config enable-ntls -static make -j2 # 生成的命令行工具在 apps 目录下 mv apps/openssl ..
你也可以采用非静态编译的方式,不过就需要根据具体环境,自己解决动态链接库的路径问题了。
以下示例展示了如何在指定域名中启用 gm
插件:
创建对应的 SSL 对象:
#!/usr/bin/env python # coding: utf-8 import sys # sudo pip install requests import requests if len(sys.argv) <= 3: print("bad argument") sys.exit(1) with open(sys.argv[1]) as f: enc_cert = f.read() with open(sys.argv[2]) as f: enc_key = f.read() with open(sys.argv[3]) as f: sign_cert = f.read() with open(sys.argv[4]) as f: sign_key = f.read() api_key = "edd1c9f034335f136f87ad84b625c8f1" resp = requests.put("http://127.0.0.1:9180/apisix/admin/ssls/1", json={ "cert": enc_cert, "key": enc_key, "certs": [sign_cert], "keys": [sign_key], "gm": True, "snis": ["localhost"], }, headers={ "X-API-KEY": api_key, }) print(resp.status_code) print(resp.text)
将上面的脚本保存为 ./create_gm_ssl.py
,运行:
./create_gm_ssl.py t/certs/server_enc.crt t/certs/server_enc.key t/certs/server_sign.crt t/certs/server_sign.key
输出结果如下所示:
200 {"key":"\/apisix\/ssls\/1","value":{"keys":["Yn...
完成上述准备后,可以使用如下命令测试插件是否启用成功:
./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 端口。
如果一切正常,可以看到连接建立了起来,并输出如下信息:
... New, NTLSv1.1, Cipher is ECDHE-SM2-SM4-CBC-SM3 ...
如果不再使用此插件,可将 gm
插件从 ./conf/config.yaml
配置文件中移除,然后重启 APISIX 或者通过插件热加载的接口触发插件的卸载。