Skip to content

Commit

Permalink
feat: disable http2 traffic when using ai-proxy plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
oowl committed Oct 9, 2024
1 parent 0c402b6 commit e3f1549
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 2 deletions.
2 changes: 2 additions & 0 deletions kong/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,8 @@ function Kong.ssl_certificate()
kong.table.clear(ngx.ctx)
end

function Kong.ssl_client_hello()
end

function Kong.preread()
local ctx = get_ctx_table(fetch_table(CTX_NS, CTX_NARR, CTX_NREC))
Expand Down
34 changes: 34 additions & 0 deletions kong/llm/proxy/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ local kong_utils = require("kong.tools.gzip")
local buffer = require "string.buffer"
local strip = require("kong.tools.string").strip
local cycle_aware_deep_copy = require("kong.tools.table").cycle_aware_deep_copy
local kong_global = require("kong.global")
local PHASES = kong_global.phases

local certificate = require("kong.tls.plugins.certificate")
local sni_filter = require("kong.tls.plugins.sni_filter")

local TTL_FOREVER = { ttl = 0 }
-- local SNI_CACHE_KEY = "ai:llm:cert_enabled_snis"

local EMPTY = require("kong.tools.table").EMPTY

Expand Down Expand Up @@ -477,4 +484,31 @@ function _M:access(conf)

end

function _M:init_worker_for_plugin(plugin_name)
-- TODO: remove nasty hacks once we have singleton phases support in core

local orig_ssl_client_hello = kong.ssl_client_hello -- luacheck: ignore
kong.ssl_client_hello = function() -- luacheck: ignore
orig_ssl_client_hello()

local ctx = ngx.ctx
-- ensure phases are set
ctx.KONG_PHASE = PHASES.certificate

kong_global.set_namespaced_log(kong, plugin_name)
local sni_cache_key = "ai:llm:cert_enabled_snis:" .. plugin_name
local snis_set, err = kong.cache:get(sni_cache_key, TTL_FOREVER,
sni_filter.build_ssl_route_filter_set, plugin_name)

if err then
kong.log.err("unable to request client to present its certificate: ",
err)
return ngx.exit(ngx.ERROR)
end
certificate.execute_client_hello(snis_set, { disable_http2 = true })
kong_global.reset_log(kong)

end
end

return _M
4 changes: 3 additions & 1 deletion kong/plugins/ai-proxy/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ local deep_copy = require "kong.tools.table".deep_copy


local _M = deep_copy(require("kong.llm.proxy.handler"))

_M.init_worker = function()
_M.init_worker_for_plugin("ai-proxy")
end

_M.PRIORITY = 770
_M.VERSION = kong_meta.version
Expand Down
3 changes: 3 additions & 0 deletions kong/templates/nginx_kong.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ server {
ssl_certificate_by_lua_block {
Kong.ssl_certificate()
}
ssl_client_hello_by_lua_block {
Kong.ssl_client_hello()
}
> end
# injected nginx_proxy_* directives
Expand Down
3 changes: 3 additions & 0 deletions kong/templates/nginx_kong_stream.lua
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ server {
ssl_certificate_by_lua_block {
Kong.ssl_certificate()
}
ssl_client_hello_by_lua_block {
Kong.ssl_client_hello()
}
> end
set $upstream_host '';
Expand Down
33 changes: 32 additions & 1 deletion kong/tls/plugins/certificate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

--- Copyright 2019 Kong Inc.
local ngx_ssl = require "ngx.ssl"
local ssl_clt = require "ngx.ssl.clienthello"
local sni_filter = require("kong.tls.plugins.sni_filter")
local pl_stringx = require "pl.stringx"
local server_name = ngx_ssl.server_name
Expand All @@ -22,7 +23,6 @@ local EMPTY_T = {}


local function match_sni(snis, server_name)
local matched_sni
if server_name then
-- search plain snis
if snis[server_name] then
Expand Down Expand Up @@ -96,4 +96,35 @@ function _M.execute(snis_set)
end
end

function _M.execute_client_hello(snis_set, options)

if not options then
return
end

if not options.disable_http2 then
return
end

local server_name, err = ssl_clt.get_client_hello_server_name()
if err then
kong.log.debug("unable to get client hello server name: ", err)
return
end

local sni_mapping = match_sni(snis_set, server_name)

if sni_mapping then
-- TODO: improve detection of ennoblement once we have DAO functions
-- to filter plugin configurations based on plugin name

kong.log.debug("enabled, will disable http2 alpn")

local res, err = kong.tls.disable_http2_alpn()
if not res then
kong.log.err("unable to disable http2 alpn: ", err)
end
end
end

return _M
3 changes: 3 additions & 0 deletions spec/fixtures/1.2_custom_nginx.template
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ http {
ssl_certificate_by_lua_block {
Kong.ssl_certificate()
}
ssl_client_hello_by_lua_block {
Kong.ssl_client_hello()
}
> end

# injected nginx_proxy_* directives
Expand Down

0 comments on commit e3f1549

Please sign in to comment.