-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support APIKey authentication (#5580)
* always load njs module Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * accept api key policy yaml Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add njs and nginx config * move js import to http * update schema and allow update after NIC starts Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * remove hardcoded variable * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * add updated njs * move js set outside location * use nginx.org/apikey secret type Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * simplify njs * make query params work * clean up template files * add api key secret validation to reject duplicated keys, remove repeated maps in config, remove reject code, add unit tests Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix linting, remove unused structs, update crds and codegen Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * add unit tests, unique map names, add validate apikey location block to conf only if api key policy is used Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * add python tests for vs and vsr * fix dockerfile merge * add wait until pods are ready * update error message Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * test setting same namespace * custom objects * add crd print * add unit tests Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * Add example readme for apikey auth policy * clean up * further cleanup * clean up test * add unit tests, clean up code Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * remove logs, refactor, add tests Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * remove logs Signed-off-by: Haywood Shannon <[email protected]> Signed-off-by: Haywood Shannon <[email protected]> * add api key auth to telemetry --------- Signed-off-by: Haywood Shannon <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jim Ryan <[email protected]>
- Loading branch information
Showing
48 changed files
with
2,563 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
# API Key Authentication | ||
|
||
NGINX supports authenticating requests with | ||
[ngx_http_auth_request_module](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html). In this example, we deploy | ||
a web application, configure load balancing for it via a VirtualServer, and apply an API Key Auth policy. | ||
|
||
## Prerequisites | ||
|
||
1. Follow the [installation](https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/) | ||
instructions to deploy the Ingress Controller. In this example we will be using a snippet to turn the policy off on a specific path so ensure that the `enable-snippets` flag is set. | ||
1. Save the public IP address of the Ingress Controller into a shell variable: | ||
|
||
```console | ||
IC_IP=XXX.YYY.ZZZ.III | ||
``` | ||
|
||
1. Save the HTTP port of the Ingress Controller into a shell variable: | ||
|
||
```console | ||
IC_HTTP_PORT=<port number> | ||
``` | ||
|
||
## Step 1 - Deploy a Web Application | ||
|
||
Create the application deployment and service: | ||
|
||
```console | ||
kubectl apply -f cafe.yaml | ||
``` | ||
|
||
## Step 2 - Deploy the API Key Auth Secret | ||
|
||
Create a secret of type `nginx.org/apikey` with the name `api-key-client-secret` that will be used for authorization on the server level. | ||
|
||
This secret will contain a mapping of client IDs to base64 encoded API Keys. | ||
|
||
```console | ||
kubectl apply -f api-key-secret.yaml | ||
``` | ||
|
||
## Step 3 - Deploy the API Key Auth Policy | ||
|
||
Create a policy with the name `api-key-policy` that references the secret from the previous step in the clientSecret field. | ||
Provide an array of headers and queries in the header and query fields of the suppliedIn field, indicating where the API key can be sent | ||
|
||
```console | ||
kubectl apply -f api-key-policy.yaml | ||
``` | ||
|
||
## Step 4 - Configure Load Balancing | ||
|
||
Create a VirtualServer resource for the web application: | ||
|
||
```console | ||
kubectl apply -f cafe-virtual-server.yaml | ||
``` | ||
|
||
Note that the VirtualServer references the policy `api-key-policy` created in Step 3. | ||
|
||
## Step 5 - Test the Configuration | ||
|
||
If you attempt to access the application without providing a valid API Key in a expected header or query param for that VirtualServer: | ||
|
||
```console | ||
curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP http://cafe.example.com:$IC_HTTP_PORT/ | ||
``` | ||
|
||
```text | ||
<html> | ||
<head><title>401 Authorization Required</title></head> | ||
<body> | ||
<center><h1>401 Authorization Required</h1></center> | ||
<hr><center>nginx/1.21.5</center> | ||
</body> | ||
</html> | ||
``` | ||
|
||
If you attempt to access the application providing an incorrect API Key in an expected header or query param for that VirtualServer: | ||
|
||
```console | ||
curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP -H "X-header-name: wrongpassword" http://cafe.example.com:$IC_HTTP_PORT/coffee | ||
``` | ||
|
||
```text | ||
<html> | ||
<head><title>403 Forbidden</title></head> | ||
<body> | ||
<center><h1>403 Forbidden</h1></center> | ||
<hr><center>nginx/1.27.0</center> | ||
</body> | ||
</html> | ||
``` | ||
|
||
If you provide a valid API Key in an a header or query defined in the policy, your request will succeed: | ||
|
||
```console | ||
curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP -H "X-header-name: password" https://cafe.example.com:$IC_HTTPS_PORT/coffee | ||
``` | ||
|
||
```text | ||
Server address: 10.244.0.6:8080 | ||
Server name: coffee-56b44d4c55-vjwxd | ||
Date: 13/Jun/2024:13:12:17 +0000 | ||
URI: /coffee | ||
Request ID: 4feedb3265a0430a1f58831d016e846d | ||
``` | ||
|
||
If you attempt to access the /tea path, the request will be allowed without an API Key, because the auth_request directive is turned off for that path with a location snippet: | ||
|
||
```console | ||
curl --resolve cafe.example.com:$IC_HTTP_PORT:$IC_IP http://cafe.example.com:$IC_HTTP_PORT/tea | ||
``` | ||
|
||
```text | ||
Server address: 10.244.0.5:8080 | ||
Server name: tea-596697966f-dmq7t | ||
Date: 13/Jun/2024:13:16:46 +0000 | ||
URI: /tea | ||
Request ID: 26e6d7dd0272eca82f31f33bf90698c9 | ||
``` | ||
|
||
Additionally you can set [error pages](https://docs.nginx.com/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#errorpage) to handle the 401 and 403 responses. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
apiVersion: k8s.nginx.org/v1 | ||
kind: Policy | ||
metadata: | ||
name: api-key-policy | ||
spec: | ||
apiKey: | ||
suppliedIn: | ||
header: | ||
- "X-header-name" | ||
query: | ||
- "queryName" | ||
clientSecret: api-key-client-secret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
name: api-key-client-secret | ||
type: nginx.org/apikey | ||
data: | ||
client1: cGFzc3dvcmQ= # password | ||
client2: YW5vdGhlci1wYXNzd29yZA== # another-password |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
apiVersion: v1 | ||
kind: Secret | ||
metadata: | ||
name: cafe-secret | ||
type: kubernetes.io/tls | ||
data: | ||
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURMakNDQWhZQ0NRREFPRjl0THNhWFdqQU5CZ2txaGtpRzl3MEJBUXNGQURCYU1Rc3dDUVlEVlFRR0V3SlYKVXpFTE1Ba0dBMVVFQ0F3Q1EwRXhJVEFmQmdOVkJBb01HRWx1ZEdWeWJtVjBJRmRwWkdkcGRITWdVSFI1SUV4MApaREViTUJrR0ExVUVBd3dTWTJGbVpTNWxlR0Z0Y0d4bExtTnZiU0FnTUI0WERURTRNRGt4TWpFMk1UVXpOVm9YCkRUSXpNRGt4TVRFMk1UVXpOVm93V0RFTE1Ba0dBMVVFQmhNQ1ZWTXhDekFKQmdOVkJBZ01Ba05CTVNFd0h3WUQKVlFRS0RCaEpiblJsY201bGRDQlhhV1JuYVhSeklGQjBlU0JNZEdReEdUQVhCZ05WQkFNTUVHTmhabVV1WlhoaApiWEJzWlM1amIyMHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDcDZLbjdzeTgxCnAwanVKL2N5ayt2Q0FtbHNmanRGTTJtdVpOSzBLdGVjcUcyZmpXUWI1NXhRMVlGQTJYT1N3SEFZdlNkd0kyaloKcnVXOHFYWENMMnJiNENaQ0Z4d3BWRUNyY3hkam0zdGVWaVJYVnNZSW1tSkhQUFN5UWdwaW9iczl4N0RsTGM2SQpCQTBaalVPeWwwUHFHOVNKZXhNVjczV0lJYTVyRFZTRjJyNGtTa2JBajREY2o3TFhlRmxWWEgySTVYd1hDcHRDCm42N0pDZzQyZitrOHdnemNSVnA4WFprWldaVmp3cTlSVUtEWG1GQjJZeU4xWEVXZFowZXdSdUtZVUpsc202OTIKc2tPcktRajB2a29QbjQxRUUvK1RhVkVwcUxUUm9VWTNyemc3RGtkemZkQml6Rk8yZHNQTkZ4MkNXMGpYa05MdgpLbzI1Q1pyT2hYQUhBZ01CQUFFd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFLSEZDY3lPalp2b0hzd1VCTWRMClJkSEliMzgzcFdGeW5acS9MdVVvdnNWQTU4QjBDZzdCRWZ5NXZXVlZycTVSSWt2NGxaODFOMjl4MjFkMUpINnIKalNuUXgrRFhDTy9USkVWNWxTQ1VwSUd6RVVZYVVQZ1J5anNNL05VZENKOHVIVmhaSitTNkZBK0NuT0Q5cm4yaQpaQmVQQ0k1ckh3RVh3bm5sOHl3aWozdnZRNXpISXV5QmdsV3IvUXl1aTlmalBwd1dVdlVtNG52NVNNRzl6Q1Y3ClBwdXd2dWF0cWpPMTIwOEJqZkUvY1pISWc4SHc5bXZXOXg5QytJUU1JTURFN2IvZzZPY0s3TEdUTHdsRnh2QTgKN1dqRWVxdW5heUlwaE1oS1JYVmYxTjM0OWVOOThFejM4Zk9USFRQYmRKakZBL1BjQytHeW1lK2lHdDVPUWRGaAp5UkU9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K | ||
tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcWVpcCs3TXZOYWRJN2lmM01wUHJ3Z0pwYkg0N1JUTnBybVRTdENyWG5LaHRuNDFrCkcrZWNVTldCUU5semtzQndHTDBuY0NObzJhN2x2S2wxd2k5cTIrQW1RaGNjS1ZSQXEzTVhZNXQ3WGxZa1YxYkcKQ0pwaVJ6ejBza0lLWXFHN1BjZXc1UzNPaUFRTkdZMURzcGRENmh2VWlYc1RGZTkxaUNHdWF3MVVoZHErSkVwRwp3SStBM0kreTEzaFpWVng5aU9WOEZ3cWJRcCt1eVFvT05uL3BQTUlNM0VWYWZGMlpHVm1WWThLdlVWQ2cxNWhRCmRtTWpkVnhGbldkSHNFYmltRkNaYkp1dmRySkRxeWtJOUw1S0Q1K05SQlAvazJsUkthaTAwYUZHTjY4NE93NUgKYzMzUVlzeFR0bmJEelJjZGdsdEkxNURTN3lxTnVRbWF6b1Z3QndJREFRQUJBb0lCQVFDUFNkU1luUXRTUHlxbApGZlZGcFRPc29PWVJoZjhzSStpYkZ4SU91UmF1V2VoaEp4ZG01Uk9ScEF6bUNMeUw1VmhqdEptZTIyM2dMcncyCk45OUVqVUtiL1ZPbVp1RHNCYzZvQ0Y2UU5SNThkejhjbk9SVGV3Y290c0pSMXBuMWhobG5SNUhxSkpCSmFzazEKWkVuVVFmY1hackw5NGxvOUpIM0UrVXFqbzFGRnM4eHhFOHdvUEJxalpzVjdwUlVaZ0MzTGh4bndMU0V4eUZvNApjeGI5U09HNU9tQUpvelN0Rm9RMkdKT2VzOHJKNXFmZHZ5dGdnOXhiTGFRTC94MGtwUTYyQm9GTUJEZHFPZVBXCktmUDV6WjYvMDcvdnBqNDh5QTFRMzJQem9idWJzQkxkM0tjbjMyamZtMUU3cHJ0V2wrSmVPRmlPem5CUUZKYk4KNHFQVlJ6NWhBb0dCQU50V3l4aE5DU0x1NFArWGdLeWNrbGpKNkY1NjY4Zk5qNUN6Z0ZScUowOXpuMFRsc05ybwpGVExaY3hEcW5SM0hQWU00MkpFUmgySi9xREZaeW5SUW8zY2czb2VpdlVkQlZHWTgrRkkxVzBxZHViL0w5K3l1CmVkT1pUUTVYbUdHcDZyNmpleHltY0ppbS9Pc0IzWm5ZT3BPcmxEN1NQbUJ2ek5MazRNRjZneGJYQW9HQkFNWk8KMHA2SGJCbWNQMHRqRlhmY0tFNzdJbUxtMHNBRzR1SG9VeDBlUGovMnFyblRuT0JCTkU0TXZnRHVUSnp5K2NhVQprOFJxbWRIQ2JIelRlNmZ6WXEvOWl0OHNaNzdLVk4xcWtiSWN1YytSVHhBOW5OaDFUanNSbmU3NFowajFGQ0xrCmhIY3FIMHJpN1BZU0tIVEU4RnZGQ3haWWRidUI4NENtWmlodnhicFJBb0dBSWJqcWFNWVBUWXVrbENkYTVTNzkKWVNGSjFKelplMUtqYS8vdER3MXpGY2dWQ0thMzFqQXdjaXowZi9sU1JxM0hTMUdHR21lemhQVlRpcUxmZVpxYwpSMGlLYmhnYk9jVlZrSkozSzB5QXlLd1BUdW14S0haNnpJbVpTMGMwYW0rUlk5WUdxNVQ3WXJ6cHpjZnZwaU9VCmZmZTNSeUZUN2NmQ21mb09oREN0enVrQ2dZQjMwb0xDMVJMRk9ycW40M3ZDUzUxemM1em9ZNDR1QnpzcHd3WU4KVHd2UC9FeFdNZjNWSnJEakJDSCtULzZzeXNlUGJKRUltbHpNK0l3eXRGcEFOZmlJWEV0LzQ4WGY2ME54OGdXTQp1SHl4Wlp4L05LdER3MFY4dlgxUE9ucTJBNWVpS2ErOGpSQVJZS0pMWU5kZkR1d29seHZHNmJaaGtQaS80RXRUCjNZMThzUUtCZ0h0S2JrKzdsTkpWZXN3WEU1Y1VHNkVEVXNEZS8yVWE3ZlhwN0ZjanFCRW9hcDFMU3crNlRYcDAKWmdybUtFOEFSek00NytFSkhVdmlpcS9udXBFMTVnMGtKVzNzeWhwVTl6WkxPN2x0QjBLSWtPOVpSY21Vam84UQpjcExsSE1BcWJMSjhXWUdKQ2toaVd4eWFsNmhZVHlXWTRjVmtDMHh0VGwvaFVFOUllTktvCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== |
26 changes: 26 additions & 0 deletions
26
examples/custom-resources/api-key/cafe-virtual-server.yaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
apiVersion: k8s.nginx.org/v1 | ||
kind: VirtualServer | ||
metadata: | ||
name: cafe | ||
spec: | ||
host: cafe.example.com | ||
tls: | ||
secret: cafe-secret | ||
policies: | ||
- name: api-key-policy | ||
upstreams: | ||
- name: coffee | ||
service: coffee-svc | ||
port: 80 | ||
- name: tea | ||
service: tea-svc | ||
port: 80 | ||
routes: | ||
- path: /coffee | ||
action: | ||
pass: coffee | ||
- path: /tea | ||
location-snippets: | | ||
auth_request off; | ||
action: | ||
pass: tea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: coffee | ||
spec: | ||
replicas: 2 | ||
selector: | ||
matchLabels: | ||
app: coffee | ||
template: | ||
metadata: | ||
labels: | ||
app: coffee | ||
spec: | ||
containers: | ||
- name: coffee | ||
image: nginxdemos/nginx-hello:plain-text | ||
ports: | ||
- containerPort: 8080 | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: coffee-svc | ||
spec: | ||
ports: | ||
- port: 80 | ||
targetPort: 8080 | ||
protocol: TCP | ||
name: http | ||
selector: | ||
app: coffee | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: tea | ||
spec: | ||
replicas: 1 | ||
selector: | ||
matchLabels: | ||
app: tea | ||
template: | ||
metadata: | ||
labels: | ||
app: tea | ||
spec: | ||
containers: | ||
- name: tea | ||
image: nginxdemos/nginx-hello:plain-text | ||
ports: | ||
- containerPort: 8080 | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: tea-svc | ||
spec: | ||
ports: | ||
- port: 80 | ||
targetPort: 8080 | ||
protocol: TCP | ||
name: http | ||
selector: | ||
app: tea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
const c = require('crypto') | ||
|
||
function hash(r) { | ||
const header_query_value = r.variables.header_query_value; | ||
const hashed_value = c.createHash('sha256').update(header_query_value).digest('hex'); | ||
return hashed_value; | ||
} | ||
|
||
function validate(r) { | ||
const client_name_map = r.variables['apikey_auth_local_map']; | ||
const client_name = r.variables[client_name_map]; | ||
const header_query_value = r.variables.header_query_value; | ||
|
||
if (!header_query_value) { | ||
r.return(401, "401") | ||
} | ||
else if (!client_name) { | ||
r.return(403, "403") | ||
} | ||
else { | ||
r.return(204, "204"); | ||
} | ||
|
||
} | ||
|
||
export default { validate, hash }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.