一、背景
自kong2.6.x版本起,kong开始支持external-plugins(外部其他语言插件)。外部插件是在独立于 Kong Gateway 本身的进程上运行的插件,允许使用任何可用的适当插件服务器的编程语言。每个插件服务器托管一个或多个插件,并通过 Unix 套接字与主 Kong Gateway 进程通信。Kong Gateway 可以管理这些进程,根据需要启动、重新启动和停止。
目前kong官方给出了go、python、js语言的外部插件开发工具包,本文以go语言为例,详解如何开发外部插件。
二、配置更改
首先,我们给要开发的插件起个名字:hello-pdk 。
接下来,我们需要更改以下配置:
kong_defaults.lua:
plugins = bundled, hello-pdk
…………
pluginserver_names = other-one
pluginserver_other_one_socket = /usr/local/kong/hello-pdk.socket
pluginserver_other_one_start_cmd = /tmp/hello/hello-pdk
pluginserver_other_one_query_cmd = /tmp/hello/hello-pdk -dump
其中需要注意的是,/tmp/hello/hello-pdk为我们生成的插件二进制文件路径, /usr/local/kong/hello-pdk.socket为插件开启的socket地址,默认情况下,该socket路径为/usr/local/kong/。pluginserver_names可以任意取。
三、hello world代码开发
根据go语言开发包文档:Plugins in Other Languages - v2.6.x | Kong Docs
1.首先我们需要声明出插件所需的结构体:
const Version = "1.0.0"
const Priority = 1
type MyConfig struct {
Path string
Reopen bool
}
func New() interface{} {
return &MyConfig{}
}
2.声明出插件所需要接管的nginx生命周期函数:
func (conf *MyConfig) Access (kong *pdk.PDK) {
kong.Log.Info("access")
}
func (conf *MyConfig) Response (kong *pdk.PDK) {
kong.Log.Warn("response")
kong.Response.Exit(200,"hello go-pdk",nil)
}
这里为了演示,我们在respone阶段直接打印hello go-pdk。与lua插件一样,go插件可以接管以下nginx生命周期:
●Certificate
●Rewrite
●Access
●Response
●Preread
●Log
3.启动插件服务
func main () {
server.StartServer(New, Version, Priority)
}
需要用到的pdk工具包:
import (
"github.com/Kong/go-pdk"
"github.com/Kong/go-pdk/server"
)
4.编译
go build -o hello-pdk main.go
注意文件名要与之前配置文件的插件名一致。
四、开启插件
konga控制后台内开启我们写的插件:
或者不安装konga,也可以通过kong的管理API,自己添加打开我们编写的插件。
五、测试插件
由于kong的插件只能在services周期内,因此为了测试,我们至少需要在konga内添加一个services。
添加完成后,我们使用curl http://127.0.0.1:8000/test 进行测试:
可以看到kong输出了我们的测试字符。
根据整个插件流程,我们可以综合各个阶段,实现WAF的主要功能。