Skip to content

Commit e2d1e6e

Browse files
DanielRaileanhafstroemalexpopaconst
authored
feat: added parameter to respect altered target (#42)
* making the plugin use the context target if instructed * version bump * Update schema.lua * mentioning new configs in readme * Update Readme.md Co-authored-by: alexpopaconst <45684246+alexpopaconst@users.noreply.github.com> * Update kong/plugins/aws-request-signing/schema.lua Co-authored-by: alexpopaconst <45684246+alexpopaconst@users.noreply.github.com> --------- Co-authored-by: Henrik Hafstrøm Johnsen <henrik.hafstroem@gmail.com> Co-authored-by: alexpopaconst <45684246+alexpopaconst@users.noreply.github.com>
1 parent 034764a commit e2d1e6e

File tree

4 files changed

+160
-90
lines changed

4 files changed

+160
-90
lines changed

Readme.md

+20-11
Original file line numberDiff line numberDiff line change
@@ -17,54 +17,59 @@ Note that this plugin cannot be used in combination with Kong [upstreams](https:
1717
## Plugin configuration parameters
1818

1919
```lua
20-
aws_assume_role_arn - ARN of the IAM role that the plugin will try to assume
20+
aws_assume_role_arn -- ARN of the IAM role that the plugin will try to assume
2121
type = "string"
2222
required = true
2323

24-
aws_assume_role_name - Name of the role above.
24+
aws_assume_role_name -- Name of the role above.
2525
type = "string"
2626
required = true
2727

28-
aws_region - AWS region where your Lambda is deployed to
28+
aws_region -- AWS region where your Lambda is deployed to
2929
type = "string"
3030
required = true
3131

32-
aws_service - AWS Service you are trying to access (lambda and s3 were tested)
32+
aws_service -- AWS Service you are trying to access (lambda and s3 were tested)
3333
type = "string"
3434
required = true
3535

36-
override_target_host - To be used when deploying multiple lambdas on a single Kong service (because lambdas have different URLs)
36+
override_target_host -- To be used when deploying multiple lambdas on a single Kong service (because lambdas have different URLs)
3737
type = "string"
3838
required = false
3939

40-
override_target_port - To be used when deploying a Lambda on a Kong service that listens on a port other than `443`
40+
override_target_port -- To be used when deploying a Lambda on a Kong service that listens on a port other than `443`
4141
type = "number"
4242
required = false
4343

44-
override_target_protocol - To be used when deploying a Lambda on a Kong service that has a protocol different than `https`
44+
override_target_protocol -- To be used when deploying a Lambda on a Kong service that has a protocol different than `https`
4545
type = "string"
4646
one_of = "http", "https"
4747
required = false
4848

49-
return_aws_sts_error - Whether to return the AWS STS response status and body when credentials fetching failed.
49+
return_aws_sts_error -- Whether to return the AWS STS response status and body when credentials fetching failed.
5050
type = "boolean"
5151
default = false
5252
required = false
5353

54-
sign_query - Controls if the signature will be sent in the header or in the query. By default, header is used, if enabled will sign the query.
54+
sign_query -- Controls if the signature will be sent in the header or in the query. By default, header is used, if enabled will sign the query.
5555
type = "boolean"
5656
required = true
5757
default = false
5858

59-
preserve_auth_header - Controls if the bearer token will be passed to the upstream
59+
preserve_auth_header -- Controls if the bearer token will be passed to the upstream
6060
type = "boolean"
6161
required = true
6262
default = true
6363

64-
preserve_auth_header_key - The header key where the bearer token will be saved and passed to the upstream. works only if 'preserve_auth_header' parameter above is set to true.
64+
preserve_auth_header_key -- The header key where the bearer token will be saved and passed to the upstream. works only if 'preserve_auth_header' parameter above is set to true.
6565
type = "string"
6666
required = true
6767
default = "x-authorization"
68+
69+
use_altered_target -- if another plugin changes the target to something other than what is registered on the service - use that target rather than the overrides of this plugin.
70+
type = "boolean"
71+
required = true
72+
default = false
6873
```
6974

7075
## Using multiple Lambdas with the same Kong Service
@@ -77,6 +82,10 @@ If ***`override_target_host`*** is not specified and multiple Lambdas are used i
7782

7883
You can also set the service protocol and host to something like `http://example.com` and then use `override_target_protocol` and `override_target_host` to changed it on the path level.
7984

85+
The ***`use_altered_target`*** is useful if another plugin with higher priority has changed the target, and we would like that to take precedence over the overrides of this plugin.
86+
This can be used when combining this plugin with e.g. the `canary-release`.
87+
88+
8089
## Installing the plugin
8190

8291
There are two things necessary to make a custom plugin work in Kong:

kong-aws-request-signing-1.0.6-3.rockspec renamed to kong-aws-request-signing-1.0.7-3.rockspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
local plugin_name = "aws-request-signing"
22
local package_name = "kong-" .. plugin_name
3-
local package_version = "1.0.6"
3+
local package_version = "1.0.7"
44
local rockspec_revision = "3"
55

66
local github_account_name = "LEGO"

kong/plugins/aws-request-signing/handler.lua

+53-27
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
local sigv4 = require "kong.plugins.aws-request-signing.sigv4"
1+
local sigv4 = require "kong.plugins.aws-request-signing.sigv4"
22

3-
local kong = kong
4-
local ngx = ngx
5-
local error = error
6-
local type = type
7-
local json = require "cjson"
3+
local kong = kong
4+
local ngx = ngx
5+
local error = error
6+
local type = type
7+
local json = require "cjson"
88

99
local IAM_CREDENTIALS_CACHE_KEY_PATTERN = "plugin.aws-request-signing.iam_role_temp_creds.%s"
10-
local AWSLambdaSTS = {}
10+
local AWSLambdaSTS = {}
1111

1212
local function fetch_aws_credentials(sts_conf)
1313
local sts = require('kong.plugins.aws-request-signing.webidentity-sts-credentials')
1414

1515
local result, err =
16-
sts.fetch_assume_role_credentials(sts_conf.RoleArn, sts_conf.RoleSessionName, sts_conf.WebIdentityToken)
16+
sts.fetch_assume_role_credentials(sts_conf.RoleArn, sts_conf.RoleSessionName, sts_conf.WebIdentityToken)
1717

1818
if err then
1919
return nil, err
@@ -63,17 +63,17 @@ local function get_iam_credentials(sts_conf, refresh, return_sts_error)
6363

6464
if err then
6565
kong.log.err(err)
66-
if(return_sts_error ~= nil and return_sts_error == true ) then
66+
if (return_sts_error ~= nil and return_sts_error == true) then
6767
local errJson = err:gsub("failed to get from node cache:", "")
6868
local resError = json.decode(errJson)
6969
return kong.response.exit(resError.sts_status, { message = resError.message, stsResponse = resError.sts_body })
7070
else
71-
return kong.response.exit(401, {message = generic_error})
71+
return kong.response.exit(401, { message = generic_error })
7272
end
7373
end
7474

7575
if not iam_role_credentials
76-
or (get_now() + 60) > iam_role_credentials.expiration then
76+
or (get_now() + 60) > iam_role_credentials.expiration then
7777
kong.cache:invalidate_local(iam_role_cred_cache_key)
7878
iam_role_credentials, err = kong.cache:get(
7979
iam_role_cred_cache_key,
@@ -83,12 +83,12 @@ local function get_iam_credentials(sts_conf, refresh, return_sts_error)
8383
)
8484
if err then
8585
kong.log.err(err)
86-
if(return_sts_error ~= nil and return_sts_error == true ) then
86+
if (return_sts_error ~= nil and return_sts_error == true) then
8787
local errJson = err:gsub("failed to get from node cache:", "")
8888
local resError = json.decode(errJson)
8989
return kong.response.exit(resError.sts_status, { message = resError.message, stsResponse = resError.sts_body })
9090
else
91-
return kong.response.exit(401, {message = generic_error})
91+
return kong.response.exit(401, { message = generic_error })
9292
end
9393
end
9494
kong.log.debug("expiring key , invalidated iam_cache and fetched fresh credentials!")
@@ -103,7 +103,6 @@ end
103103
function AWSLambdaSTS:access(conf)
104104
local service = kong.router.get_service()
105105
local request_headers = kong.request.get_headers()
106-
local final_host = conf.override_target_host or ngx.ctx.balancer_data.host
107106

108107
if service == nil then
109108
kong.log.err("Unable to retrieve bound service!")
@@ -116,15 +115,42 @@ function AWSLambdaSTS:access(conf)
116115
})
117116
end
118117

118+
local target_altered = false
119+
120+
local balancer_host = ngx.ctx.balancer_data.host
121+
local balancer_port = ngx.ctx.balancer_data.port
122+
local signed_host = balancer_host
123+
local signed_port = balancer_port
124+
125+
if balancer_host ~= service.host then
126+
target_altered = true
127+
end
128+
if balancer_port ~= service.port then
129+
target_altered = true
130+
end
131+
132+
119133
if conf.override_target_protocol then
120134
kong.service.request.set_scheme(conf.override_target_protocol)
121135
end
122-
if conf.override_target_port and conf.override_target_host then
123-
kong.service.set_target(conf.override_target_host, conf.override_target_port)
124-
elseif conf.override_target_host then
125-
kong.service.set_target(conf.override_target_host, service.port)
126-
elseif conf.override_target_port then
127-
kong.service.set_target(final_host, conf.override_target_port)
136+
137+
local perform_override = true
138+
if conf.use_altered_target and target_altered then
139+
perform_override = false
140+
end
141+
142+
if perform_override then
143+
if conf.override_target_port and conf.override_target_host then
144+
signed_host = conf.override_target_host
145+
signed_port = conf.override_target_port
146+
kong.service.set_target(conf.override_target_host, conf.override_target_port)
147+
elseif conf.override_target_host then
148+
signed_host = conf.override_target_host
149+
kong.service.set_target(conf.override_target_host, signed_port)
150+
elseif conf.override_target_port then
151+
signed_port = conf.override_target_port
152+
kong.service.set_target(signed_host, conf.override_target_port)
153+
end
128154
end
129155

130156

@@ -135,12 +161,12 @@ function AWSLambdaSTS:access(conf)
135161
}
136162

137163
local iam_role_credentials = get_iam_credentials(sts_conf, request_headers["x-sts-refresh"],
138-
conf.return_aws_sts_error)
164+
conf.return_aws_sts_error)
139165

140-
-- we only send those two headers for signing
166+
-- we only send those headers for signing
141167
local upstream_headers = {
142-
host = final_host,
143-
-- those will be nill thus we only pass the host on requests without body
168+
host = signed_host,
169+
-- those will be nil which means that we only pass the host on requests without body
144170
["content-length"] = request_headers["content-length"],
145171
["content-type"] = request_headers["content-type"]
146172
}
@@ -165,8 +191,8 @@ function AWSLambdaSTS:access(conf)
165191
headers = upstream_headers,
166192
body = req_body,
167193
path = ngx.var.upstream_uri,
168-
host = final_host,
169-
port = service.port,
194+
host = signed_host,
195+
port = signed_port,
170196
query = kong.request.get_raw_query(),
171197
access_key = iam_role_credentials.access_key,
172198
secret_key = iam_role_credentials.secret_key,
@@ -189,6 +215,6 @@ function AWSLambdaSTS:access(conf)
189215
end
190216

191217
AWSLambdaSTS.PRIORITY = 15
192-
AWSLambdaSTS.VERSION = "1.0.6"
218+
AWSLambdaSTS.VERSION = "1.0.7"
193219

194220
return AWSLambdaSTS

kong/plugins/aws-request-signing/schema.lua

+86-51
Original file line numberDiff line numberDiff line change
@@ -11,61 +11,96 @@ return {
1111
-- this plugin will only run within Nginx HTTP module
1212
protocols = typedefs.protocols_http
1313
},
14-
{ config = {
15-
type = "record",
16-
fields = {
17-
{ aws_assume_role_arn = {
18-
type = "string",
19-
encrypted = true, -- Kong Enterprise-exclusive feature, does nothing in Kong CE
20-
required = true,
21-
} },
22-
{ aws_assume_role_name = {
23-
type = "string",
24-
encrypted = true, -- Kong Enterprise-exclusive feature, does nothing in Kong CE
25-
required = true,
26-
} },
27-
{ aws_region = {
28-
type = "string",
29-
required = true,
30-
} },
31-
{ aws_service = {
32-
type = "string",
33-
required = true,
34-
} },
35-
{ override_target_host = {
36-
type = "string",
37-
not_match = "^https?://"
38-
} },
39-
{ override_target_port = {
40-
type = "number"
41-
} },
42-
{ override_target_protocol = {
43-
type = "string",
14+
{
15+
config = {
16+
type = "record",
17+
fields = {
18+
{
19+
aws_assume_role_arn = {
20+
type = "string",
21+
encrypted = true, -- Kong Enterprise-exclusive feature, does nothing in Kong CE
22+
required = true,
23+
}
24+
},
25+
{
26+
aws_assume_role_name = {
27+
type = "string",
28+
encrypted = true, -- Kong Enterprise-exclusive feature, does nothing in Kong CE
29+
required = true,
30+
}
31+
},
32+
{
33+
aws_region = {
34+
type = "string",
35+
required = true,
36+
}
37+
},
38+
{
39+
aws_service = {
40+
type = "string",
41+
required = true,
42+
}
43+
},
44+
{
45+
override_target_host = {
46+
type = "string",
47+
not_match = "^https?://"
48+
}
49+
},
50+
{
51+
override_target_port = {
52+
type = "number"
53+
}
54+
},
55+
{
56+
override_target_protocol = {
57+
type = "string",
4458
one_of = {
4559
"http",
4660
"https",
4761
},
48-
} },
49-
{ return_aws_sts_error = {
50-
type = "boolean",
51-
required = true,
52-
default = false,
53-
} },
54-
{ sign_query = {
55-
type = "boolean",
56-
required = true,
57-
default = false,
58-
} },
59-
{ preserve_auth_header = {
60-
type = "boolean",
61-
required = true,
62-
default = true,
63-
} },
64-
{ preserve_auth_header_key = {
65-
type = "string",
66-
required = true,
67-
default = "x-authorization",
68-
} }
62+
}
63+
},
64+
{
65+
use_altered_target = {
66+
type = "boolean",
67+
required = true,
68+
default = false,
69+
description =
70+
"Instructs the plugin to use the context target if its host or port were altered "..
71+
" (by other plugins) during the signing, bypassing the override_target_host "..
72+
"and override_target_port parameters. Works by comparing the service target parameters"..
73+
" with the context target parameters. Ignored if the target was not altered."
74+
}
75+
},
76+
{
77+
return_aws_sts_error = {
78+
type = "boolean",
79+
required = true,
80+
default = false,
81+
}
82+
},
83+
{
84+
sign_query = {
85+
type = "boolean",
86+
required = true,
87+
default = false,
88+
}
89+
},
90+
{
91+
preserve_auth_header = {
92+
type = "boolean",
93+
required = true,
94+
default = true,
95+
}
96+
},
97+
{
98+
preserve_auth_header_key = {
99+
type = "string",
100+
required = true,
101+
default = "x-authorization",
102+
}
103+
}
69104
}
70105
},
71106
}

0 commit comments

Comments
 (0)