-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Add Nginx njs script Signed-off-by: Anurag Rajawat <[email protected]> * feat: Add nginx-inc ingress controller support Signed-off-by: Anurag Rajawat <[email protected]> * docs: Add nginx docs Signed-off-by: Anurag Rajawat <[email protected]> --------- Signed-off-by: Anurag Rajawat <[email protected]>
- Loading branch information
Anurag Rajawat
authored
Nov 19, 2024
1 parent
840c0a4
commit b27c041
Showing
20 changed files
with
1,111 additions
and
482 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
204 changes: 204 additions & 0 deletions
204
docs/receivers/other/ingress-controller/nginx-inc/nginx_inc.md
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,204 @@ | ||
# Nginx Incorporation Ingress Controller | ||
|
||
## Description | ||
|
||
This guide provides a step-by-step process to integrate SentryFlow | ||
with [Nginx Inc.](https://docs.nginx.com/nginx-ingress-controller/) Ingress Controller, aimed at enhancing API | ||
observability. It includes detailed commands for each step along with their explanations. | ||
|
||
SentryFlow make use of following to provide visibility into API calls: | ||
|
||
- [Nginx njs](https://nginx.org/en/docs/njs/) module. | ||
- [Njs filter](../../../../../filter/nginx). | ||
|
||
## Prerequisites | ||
|
||
- Nginx Inc. Ingress Controller. | ||
Follow [this](https://docs.nginx.com/nginx-ingress-controller/installation/installing-nic/) to deploy it. | ||
|
||
## How to | ||
|
||
To Observe API calls of your workloads served by Nginx inc. ingress controller in Kubernetes environment, follow | ||
the below | ||
steps: | ||
|
||
1. Create the following configmap in the same namespace as ingress controller. | ||
|
||
```shell | ||
cat <<EOF | kubectl apply -f - | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: sentryflow-nginx-inc | ||
namespace: <ingress-controller-namespace> | ||
data: | ||
sentryflow.js: | | ||
const DEFAULT_KEY = "sentryFlow"; | ||
const ResStatusKey = ":status" | ||
const MAX_BODY_SIZE = 1_000_000; // 1 MB | ||
function requestHandler(r, data, flags) { | ||
r.sendBuffer(data, flags); | ||
r.done(); | ||
let responseBody = "" | ||
try { | ||
responseBody = new TextDecoder("utf-8") | ||
.decode(new Uint8Array(data)); | ||
} catch (error) { | ||
r.error(`failed to decode data, error: ${error}`) | ||
} | ||
if (responseBody.length > MAX_BODY_SIZE) { | ||
responseBody = "" | ||
} | ||
let apiEvent = { | ||
"metadata": { | ||
"timestamp": Date.parse(r.variables.time_iso8601.split("+")[0]) / 1000, | ||
"receiver_name": "nginx", | ||
"receiver_version": ngx.version, | ||
}, | ||
"source": { | ||
"ip": r.remoteAddress, | ||
"port": r.variables.remote_port, | ||
}, | ||
"destination": { | ||
"ip": r.variables.server_addr, | ||
"port": r.variables.server_port, | ||
}, | ||
"request": { | ||
"headers": {}, | ||
"body": r.requestText || "", | ||
}, | ||
"response": { | ||
"headers": {}, | ||
"body": responseBody, | ||
}, | ||
"protocol": r.variables.server_protocol, | ||
}; | ||
for (const header in r.headersIn) { | ||
apiEvent.request.headers[header] = r.headersIn[header]; | ||
} | ||
apiEvent.request.headers[":scheme"] = r.variables.scheme | ||
apiEvent.request.headers[":path"] = r.uri | ||
apiEvent.request.headers[":method"] = r.variables.request_method | ||
apiEvent.request.headers["body_bytes_sent"] = r.variables.body_bytes_sent | ||
apiEvent.request.headers["request_length"] = r.variables.request_length | ||
apiEvent.request.headers["request_time"] = r.variables.request_time | ||
apiEvent.request.headers["query"] = r.variables.query_string | ||
for (const header in r.headersOut) { | ||
apiEvent.response.headers[header] = r.headersOut[header]; | ||
} | ||
apiEvent.response.headers[ResStatusKey] = r.variables.status | ||
ngx.shared.apievents.set(DEFAULT_KEY, JSON.stringify(apiEvent)); | ||
} | ||
async function dispatchHttpCall(r) { | ||
try { | ||
let apiEvent = ngx.shared.apievents.get(DEFAULT_KEY); | ||
await r.subrequest("/sentryflow", { | ||
method: "POST", body: apiEvent, detached: true | ||
}) | ||
} catch (error) { | ||
r.error(`failed to dispatch HTTP call to SentryFlow, error: ${error}`) | ||
return; | ||
} finally { | ||
ngx.shared.apievents.clear(); | ||
} | ||
r.return(200, "OK"); | ||
} | ||
export default {requestHandler, dispatchHttpCall}; | ||
EOF | ||
``` | ||
|
||
2. Add the following volume and volume-mount in ingress controller deployment: | ||
|
||
```yaml | ||
... | ||
volumes: | ||
- name: sentryflow-nginx-inc | ||
configMap: | ||
name: sentryflow-nginx-inc | ||
... | ||
... | ||
volumeMounts: | ||
- mountPath: /etc/nginx/njs/sentryflow.js | ||
name: sentryflow-nginx-inc | ||
subPath: sentryflow.js | ||
``` | ||
3. Update ingress controller configmap as follows: | ||
```yaml | ||
... | ||
data: | ||
http-snippets: | | ||
js_path "/etc/nginx/njs/"; | ||
subrequest_output_buffer_size 8k; | ||
js_shared_dict_zone zone=apievents:1M timeout=300s evict; | ||
js_import main from sentryflow.js; | ||
location-snippets: | | ||
js_body_filter main.requestHandler buffer_type=buffer; | ||
mirror /mirror_request; | ||
mirror_request_body on; | ||
server-snippets: | | ||
location /mirror_request { | ||
internal; | ||
js_content main.dispatchHttpCall; | ||
} | ||
location /sentryflow { | ||
internal; | ||
# Update SentryFlow URL with path to ingest access logs if required. | ||
proxy_pass http://sentryflow.sentryflow:8081/api/v1/events; | ||
proxy_method POST; | ||
proxy_set_header accept "application/json"; | ||
proxy_set_header Content-Type "application/json"; | ||
} | ||
``` | ||
4. Download SentryFlow manifest file | ||
```shell | ||
curl -sO https://raw.githubusercontent.com/5GSEC/SentryFlow/refs/heads/main/deployments/sentryflow.yaml | ||
``` | ||
|
||
5. Update the `.receivers` configuration in `sentryflow` [configmap](../../../../../deployments/sentryflow.yaml) as | ||
follows: | ||
|
||
```yaml | ||
filters: | ||
server: | ||
port: 8081 | ||
# Following is required for `nginx-inc-ingress-controller` receiver. | ||
nginxIngress: | ||
deploymentName: <nginx-ingress-controller-deploy-name> | ||
configMapName: <nginx-ingress-configmap-name> | ||
sentryFlowNjsConfigMapName: <sentryflow-nginx-inc-configmap-name> | ||
|
||
receivers: | ||
others: | ||
- name: nginx-inc-ingress-controller # SentryFlow makes use of `name` to configure receivers. DON'T CHANGE IT. | ||
namespace: <ingress-controller-namespace> # Kubernetes namespace in which you've deployed the ingress controller. | ||
... | ||
``` | ||
|
||
6. Deploy SentryFlow | ||
|
||
```shell | ||
kubectl apply -f sentryflow.yaml | ||
``` | ||
|
||
7. Trigger API calls to generate traffic. | ||
|
||
8. Use SentryFlow [log client](../../../../client) to see the API Events. |
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,95 @@ | ||
# Nginx Web Server | ||
|
||
## Description | ||
|
||
This guide provides a step-by-step process to integrate SentryFlow | ||
with [Nginx webserver](https://nginx.org/), aimed at enhancing API | ||
observability. It includes detailed commands for each step along with their explanations. | ||
|
||
SentryFlow make use of following to provide visibility into API calls: | ||
|
||
- [Nginx njs](https://nginx.org/en/docs/njs/) module. | ||
- [Njs filter](../../../../../filter/nginx). | ||
|
||
## Prerequisites | ||
|
||
- Nginx web server. | ||
- [Nginx-njs-module](https://github.com/nginx/njs?tab=readme-ov-file#downloading-and-installing). | ||
|
||
## How to | ||
|
||
To Observe API calls of your application running on a virtual machine (VM) behind a Nginx web server, follow the below | ||
steps: | ||
|
||
1. Copy [sentryflow.js](../../../../../filter/nginx/sentryflow.js) file to `/etc/nginx/njs/` directory as | ||
`sentryflow.js`. | ||
2. Edit `nginx.conf` file located in `/etc/nginx/` directory as follows: | ||
|
||
```nginx configuration | ||
load_module /etc/nginx/modules/ngx_http_js_module.so; | ||
... | ||
http { | ||
... | ||
subrequest_output_buffer_size 8k; | ||
js_path "/etc/nginx/njs/"; | ||
js_shared_dict_zone zone=apievents:1M timeout=60s evict; | ||
js_import main from sentryflow.js; | ||
... | ||
server { | ||
location / { | ||
js_body_filter main.requestHandler buffer_type=buffer; | ||
mirror /mirror_request; | ||
mirror_request_body on; | ||
} | ||
location /mirror_request { | ||
internal; | ||
js_content main.dispatchHttpCall; | ||
} | ||
location /sentryflow { | ||
internal; | ||
# SentryFlow URL with path to ingest access logs. | ||
proxy_pass http://<sentryflow_url>/api/v1/events; | ||
proxy_method POST; | ||
proxy_set_header accept "application/json"; | ||
proxy_set_header Content-Type "application/json"; | ||
} | ||
... | ||
} | ||
} | ||
``` | ||
|
||
Here is the sample [nginx.conf](../../../../../filter/nginx/nginx.conf) file for reference. | ||
|
||
3. Reload `nginx`: | ||
|
||
```shell | ||
$ sudo nginx -s reload | ||
``` | ||
|
||
4. Update the `.receivers` configuration in `sentryflow` [configmap](../../../../deployments/sentryflow.yaml) as | ||
follows: | ||
|
||
```yaml | ||
filters: | ||
server: | ||
port: 8081 | ||
|
||
receivers: | ||
others: | ||
- name: nginx-webserver # SentryFlow makes use of `name` to configure receivers. DON'T CHANGE IT. | ||
... | ||
``` | ||
|
||
5. Deploy SentryFlow | ||
|
||
```shell | ||
kubectl apply -f sentryflow.yaml | ||
``` | ||
|
||
6. Trigger API calls to generate traffic. | ||
|
||
7. Use SentryFlow [log client](../../../../client) to see the API Events. |
Oops, something went wrong.