Skip to content

Commit

Permalink
feat(ai-proxy): disbale the http2 alpn handshake for the request hitt…
Browse files Browse the repository at this point in the history
…ing the route configured with ai-proxy
  • Loading branch information
oowl committed Oct 12, 2024
1 parent 021cbe1 commit 9d538a0
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 213 deletions.
4 changes: 4 additions & 0 deletions changelog/unreleased/kong/feat-ai-proxy-disable-h2-alpn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
message: |
**ai-proxy**: Disabled HTTP/2 ALPN handshake for connections on routes configured with AI-proxy.
type: feature
scope: Plugin
3 changes: 3 additions & 0 deletions kong-3.9.0-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ build = {
["kong.status"] = "kong/status/init.lua",
["kong.status.ready"] = "kong/status/ready.lua",

["kong.tls.plugins.certificate"] = "kong/tls/plugins/certificate.lua",
["kong.tls.plugins.sni_filter"] = "kong/tls/plugins/sni_filter.lua",

["kong.tools.dns"] = "kong/tools/dns.lua",
["kong.tools.grpc"] = "kong/tools/grpc.lua",
["kong.tools.utils"] = "kong/tools/utils.lua",
Expand Down
4 changes: 4 additions & 0 deletions kong/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,10 @@ function Kong.ssl_certificate()
kong.table.clear(ngx.ctx)
end

function Kong.ssl_client_hello()
local ctx = get_ctx_table(fetch_table(CTX_NS, CTX_NARR, CTX_NREC))
ctx.KONG_PHASE = PHASES.client_hello
end

function Kong.preread()
local ctx = get_ctx_table(fetch_table(CTX_NS, CTX_NARR, CTX_NREC))
Expand Down
60 changes: 60 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,57 @@ 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 sni_cache_key = "ai:llm:cert_enabled_snis:" .. plugin_name
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.client_hello

kong_global.set_namespaced_log(kong, 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

local worker_events = kong.worker_events
if not worker_events or not worker_events.register then
return
end

local function invalidate_sni_cache()
kong.cache:invalidate(sni_cache_key)
end

worker_events.register(function(data)
invalidate_sni_cache()
end, "crud", "plugins")

worker_events.register(function(data)
invalidate_sni_cache()
end, "crud", "routes")

worker_events.register(function(data)
invalidate_sni_cache()
end, "crud", "services")

worker_events.register(function(data)
invalidate_sni_cache()
end, "crud", "ca_certificates")
end

return _M
18 changes: 18 additions & 0 deletions kong/pdk/client/tls.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,24 @@ local function new()
ngx.ctx.CLIENT_VERIFY_OVERRIDE = v
end

---
-- Prevents the TLS handshake from negotiating HTTP/2 ALPN.
-- if successful, the TLS handshake will not negotiate HTTP/2 ALPN to turn to HTTP1.1.
--
-- @function kong.client.tls.disable_http2_alpn
-- @phases client_hello
-- @treturn true|nil Returns `true` if successful, `nil` if it fails.
-- @treturn nil|err Returns `nil` if successful, or an error message if it fails.
--
-- @usage
-- local res, err = kong.client.tls.disable_http2_alpn()
-- if not res then
-- -- do something with err
-- end
function _TLS.disable_http2_alpn()
check_phase(PHASES.client_hello)
return kong_tls.disable_http2_alpn()
end

return _TLS
end
Expand Down
1 change: 1 addition & 0 deletions kong/pdk/private/phases.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ local PHASES = {
--init = 0x00000001,
init_worker = 0x00000001,
certificate = 0x00000002,
client_hello = 0x00000008,
--set = 0x00000004,
rewrite = 0x00000010,
access = 0x00000020,
Expand Down
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
Loading

0 comments on commit 9d538a0

Please sign in to comment.