Skip to content

Commit

Permalink
Otel collector plugin (openclarity#255)
Browse files Browse the repository at this point in the history
* First rev to build OpenTelemetry Collector exporter plugin.

* Added build of otel-collector in docker container.

* Updated path and example configs to fix errors.

* Additional processing to use more defaults for spans without many attributes.

* Fixes for linting older package versions.

* Fix for attribute initialization.

* Add config option to lookup IPs and convert to hostnames. Added more defaults to fill out spans with little information.

* Added otel-collector plugin to license-check.

* Cleanup of otel-collector docker build process.

* Fix for new config "prefer_hostnames".

* Add OTel collector with APIClarity to docker and release workflows.

* Fixes to normalize otel-collector plugin docker build.

* Fixes for docker tags.

* Normalized OTel-collector plugin build to match other plugins.

* Updated Makefile for otel-collector plugin licensei cache.

* Added collector plugin to README as traffic source.
  • Loading branch information
jnapper7 authored Nov 14, 2022
1 parent 530b38b commit 4376302
Show file tree
Hide file tree
Showing 22 changed files with 2,500 additions and 9 deletions.
17 changes: 16 additions & 1 deletion .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ on:
branches:
- master

env:
OTEL_COLLECTOR_VERSION: 0.60.0

jobs:
docker:
name: Docker
Expand Down Expand Up @@ -87,4 +90,16 @@ jobs:
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
build-args: |
VERSION=latest
VERSION=latest
- name: Build OpenTelemetry Collector with APIClarity plugin
uses: docker/build-push-action@v2
with:
context: plugins
tags: ghcr.io/openclarity/otel-apiclarityexporter:latest
file: plugins/Dockerfile.otel-collector
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
build-args: |
OTEL_COLLECTOR_VERSION=${{ env.OTEL_COLLECTOR_VERSION }}
13 changes: 13 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:

env:
GO_VERSION: 1.17
OTEL_COLLECTOR_VERSION: 0.60.0

jobs:
verification:
Expand Down Expand Up @@ -160,6 +161,18 @@ jobs:
build-args: |
VERSION=${{ github.event.inputs.version }}
- name: Build and Push OpenTelemetry Collector with APIClarity plugin
uses: docker/build-push-action@v2
with:
context: plugins
tags: ghcr.io/openclarity/otel-apiclarityexporter:${{ github.event.inputs.version }}
file: plugins/Dockerfile.otel-collector
push: true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
build-args: |
OTEL_COLLECTOR_VERSION=${{ env.OTEL_COLLECTOR_VERSION }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
Expand Down
15 changes: 11 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ backend_test: ## Build Backend test
@(cd backend && go build --tags=json1 -o bin/backend_test cmd/test/main.go && ls -l bin/)

.PHONY: api3-verify
api3-verify:
api3-verify:
@(echo "Checking if api3 code was generated")
@(cd api3; ./generate.sh --verify)
@(cd api3; ./generate.sh --verify)

.PHONY: api3
api3:
@(cd api3; ./generate.sh)
api3:
@(cd api3; ./generate.sh)

.PHONY: api
api: api3 ## Generating API code
Expand Down Expand Up @@ -91,6 +91,7 @@ test: ## Run Unit Tests
cd plugins/gateway/kong && go test ./...
cd plugins/gateway/tyk/v3.2.2 && go test ./...
cd plugins/taper && go test ./...
cd plugins/otel-collector/apiclarityexporter && go test ./...

.PHONY: clean
clean: clean-ui clean-backend ## Clean all build artifacts
Expand All @@ -110,12 +111,15 @@ bin/golangci-lint-${GOLANGCI_VERSION}:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b ./bin/ v${GOLANGCI_VERSION}
@mv bin/golangci-lint $@

# TODO: remove temporarily exempted package from typecheck linter
.PHONY: lint
lint: bin/golangci-lint ## Run linter
cd backend && ../bin/golangci-lint run
cd plugins/gateway/kong && ../../../bin/golangci-lint run
cd plugins/gateway/tyk/v3.2.2 && ../../../../bin/golangci-lint run
cd plugins/taper && ../../bin/golangci-lint run
cd plugins/otel-collector/apiclarityexporter && ../../../bin/golangci-lint run \
--skip-files '../../../../../../go/pkg/mod/github.com/klauspost/compress'


.PHONY: fix
Expand All @@ -124,6 +128,7 @@ fix: bin/golangci-lint ## Fix lint violations
cd plugins/gateway/kong && ../../../bin/golangci-lint run --fix
cd plugins/gateway/tyk/v3.2.2 && ../../../../bin/golangci-lint run --fix
cd plugins/taper && ../../bin/golangci-lint run --fix
cd plugins/otel-collector/apiclarityexporter && ../../../bin/golangci-lint run --fix

bin/licensei: bin/licensei-${LICENSEI_VERSION}
@ln -sf licensei-${LICENSEI_VERSION} bin/licensei
Expand All @@ -139,13 +144,15 @@ license-check: bin/licensei ## Run license check
cd plugins/gateway/kong && ../../../bin/licensei check --config=../../../.licensei.toml
cd plugins/gateway/tyk/v3.2.2 && ../../../../bin/licensei check --config=../../../../.licensei.toml
cd plugins/taper && ../../bin/licensei check --config=../../.licensei.toml
cd plugins/otel-collector/apiclarityexporter && ../../../bin/licensei check --config=../../../.licensei.toml

.PHONY: license-cache
license-cache: bin/licensei ## Generate license cache
cd backend && ../bin/licensei cache --config=../.licensei.toml
cd plugins/gateway/kong && ../../../bin/licensei cache --config=../../../.licensei.toml
cd plugins/gateway/tyk/v3.2.2 && ../../../../bin/licensei cache --config=../../../../.licensei.toml
cd plugins/taper && ../../bin/licensei cache --config=../../.licensei.toml
cd plugins/otel-collector/apiclarityexporter && ../../../bin/licensei cache --config=../../../.licensei.toml

.PHONY: check
check: lint test ## Run tests and linters
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ APIClarity approaches API Security in 2 different ways:
Both approaches described above are way more effective when APIClarity is primed with the OpenAPI specifications of the APIs analyzed or tested. However, not all applications have an OpenAPI specification available. For this reason one of the main functionality of APIClarity is the automatic reconstruction of OpenAPI specifications based on observed API traffic. In this case, users have the ability to review and approve the reconstructed specifications.

## Security Modules
APIClarity is structured in a modular architecture, which allows to easily add new functionalities.
APIClarity is structured in a modular architecture, which allows to easily add new functionalities.

In the following a brief description of the modules currently implemented:

- **Spec Diffs** This module compares the API traces with the OAPI specifications provided by the user or previously reconstructed. The result of this comparison provides:
- List of API endpoints that are observed but not documented in the specs, i.e. _Shadow APIs_;
- List of API endpoints that are observed but marked as deprecated in the specs, i.e. _Zombie APIs_;
- List of difference between of the APIs observed and their documented specification.
- [**Trace Analyzer**](./backend/pkg/modules/internal/traceanalyzer/README.md) This module analyzes path, headers and body of API requests and responses to discover potential security issues, such as weak authentications, exposure of sensitive information, potential Broken Object Level Authorizations (BOLA) etc.
- [**Trace Analyzer**](./backend/pkg/modules/internal/traceanalyzer/README.md) This module analyzes path, headers and body of API requests and responses to discover potential security issues, such as weak authentications, exposure of sensitive information, potential Broken Object Level Authorizations (BOLA) etc.
- [**BFLA Detector**](./backend/pkg/modules/internal/bfla/README.md) This module detects potential Broken Function Level Authorization. In particular it observes the API interactions and build an authorization model that captures what clients are supposed to be authorized to make the various API calls. Based on such authorization model it then signals violations which may represent potential issues in the API authorization procedures.
- **Fuzzer** This module actively tests API endpoints based on their specification attempting in discovering security issues in the API server implementation.

Expand Down Expand Up @@ -48,6 +48,9 @@ APIClarity supports integrating with the following traffic sources. Install APIC
* Tyk API Gateway
* [Integration instructions](https://github.com/openclarity/apiclarity/tree/master/plugins/gateway/tyk)

* OpenTelemetry Collector (traces only)
* [Integration instructions](https://github.com/openclarity/apiclarity/tree/master/plugins/otel-collector)

The integrations (plugins) for the supported traffic sources above are located in the [plugins directory within the codebase](https://github.com/openclarity/apiclarity/tree/master/plugins) and implement the [plugins API](https://github.com/openclarity/apiclarity/tree/master/plugins/api) to export the API events to APIClarity. To enable and configure the supported traffic sources, please check the ```trafficSource:``` section in [Helm values](https://github.com/openclarity/apiclarity/blob/master/charts/apiclarity/values.yaml).
Contributions of integrations with additional traffic sources are more than welcome!

Expand Down
31 changes: 31 additions & 0 deletions plugins/Dockerfile.otel-collector
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
FROM golang:1.18-alpine3.14 AS otelcol

RUN apk add --update --no-cache gcc g++
ARG OTEL_COLLECTOR_VERSION=0.60.0
ADD https://github.com/open-telemetry/opentelemetry-collector/releases/download/v${OTEL_COLLECTOR_VERSION}/ocb_${OTEL_COLLECTOR_VERSION}_linux_amd64 /usr/local/bin/ocb
RUN chmod 755 /usr/local/bin/ocb

WORKDIR /otelcol-build
ADD https://raw.githubusercontent.com/open-telemetry/opentelemetry-collector-releases/v${OTEL_COLLECTOR_VERSION}/distributions/otelcol/manifest.yaml ./
COPY otel-collector/scripts/modify_otelcol_builder.awk /usr/local/bin/modify_otelcol_builder.awk
RUN /usr/local/bin/modify_otelcol_builder.awk <./manifest.yaml >./otelcol-builder-${OTEL_COLLECTOR_VERSION}.yaml

COPY api ./api/
COPY otel-collector/apiclarityexporter ./otel-collector/apiclarityexporter/
RUN /usr/local/bin/ocb --config ./otelcol-builder-${OTEL_COLLECTOR_VERSION}.yaml
# Note that this shouldn't be necessary, but in some cases the file seems to be
# copied with the execute bit lost (see #1317)
RUN chmod 755 ./otelcol

FROM alpine:3.14 as certs
WORKDIR /
RUN apk --update add ca-certificates

ARG USER_UID=10001
USER ${USER_UID}

COPY --from=otelcol /otelcol-build/otelcol /
COPY otel-collector/configs/otel-collector-config.yaml /etc/otelcol/config.yaml
ENTRYPOINT ["/otelcol"]
CMD ["--config", "/etc/otelcol/config.yaml"]
EXPOSE 4317 8888 55678 55679
17 changes: 15 additions & 2 deletions plugins/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ DOCKER_REGISTRY ?= ghcr.io/openclarity
VERSION ?= $(shell git rev-parse HEAD)
DOCKER_TAG ?= ${VERSION}
TYK_VERSION ?= v3.2.2
OTEL_COLLECTOR_VERSION ?= 0.60.0

.PHONY: docker
docker: docker-kong docker-tyk docker-taper
docker: docker-kong docker-tyk docker-taper docker-otelcollector

.PHONY: docker-kong
docker-kong:
Expand All @@ -27,8 +28,15 @@ docker-tyk:
go mod edit -replace github.com/openclarity/apiclarity/plugins/[email protected]=./../../../common && \
cd -)

.PHONY: docker-otelcollector
docker-otelcollector: Dockerfile.otel-collector
@DOCKER_BUILDKIT=1 docker build \
--file Dockerfile.otel-collector \
--build-arg OTEL_COLLECTOR_VERSION=${OTEL_COLLECTOR_VERSION} \
-t otel-apiclarityexporter:${DOCKER_TAG} .

.PHONY: push-docker
push-docker: push-docker-kong push-docker-tyk push-docker-taper
push-docker: push-docker-kong push-docker-tyk push-docker-taper push-docker-otelcollector

.PHONY: push-docker-kong
push-docker-kong: docker-kong
Expand All @@ -44,3 +52,8 @@ push-docker-tyk: docker-tyk
push-docker-taper: docker-taper
@echo "Publishing passive taper Docker image ..."
docker push ${DOCKER_REGISTRY}/passive-taper:${DOCKER_TAG}

.PHONY: push-docker-otelcollector
push-docker-otelcollector: docker-otelcollector
@echo "Publishing otel-apiclarityexporter Docker image ..."
docker push ${DOCKER_REGISTRY}/otel-apiclarityexporter:${DOCKER_TAG}
69 changes: 69 additions & 0 deletions plugins/otel-collector/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# APIClarity HTTP Exporter

| Status | |
| ------------------------ | --------------------- |
| Stability | traces [stable] |
| Supported pipeline types | traces |
| Distributions | [contrib] |

Exports traces and/or metrics via HTTP to an [APIClarity](
https://github.com/openclarity/apiclarity/blob/master/plugins/api/swagger.yaml)
endpoint for analysis.

The following settings are required:

- `endpoint` (no default): The target base URL to send data to (e.g.: https://example.com:4318).
The trace signal will be added to this base URL, i.e. "/api/telemetry" will be appended.

The following settings can be optionally configured:

- `tls`: see [TLS Configuration Settings](../../config/configtls/README.md) for the full set of available options.
- `timeout` (default = 30s): HTTP request time limit. For details see https://golang.org/pkg/net/http/#Client
- `read_buffer_size` (default = 0): ReadBufferSize for HTTP client.
- `write_buffer_size` (default = 512 * 1024): WriteBufferSize for HTTP client.

Example:

```yaml
exporters:
apiclarity:
endpoint: https://example.com:4318/
```
The full list of settings exposed for this exporter are documented [here](./config.go)
with detailed sample configurations [here](./testdata/config.yaml).
[contrib]: https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib
## Using the plugin
In order to use the APIClarity Exporter, you will need to build your own OpenTelemetry Collector with the Exporter included. The instructions to [build a custom collector are here.](https://opentelemetry.io/docs/collector/custom-collector/)
An example builder-config.yaml file including the exporter could be:
```yaml
dist:
name: otelcol-api
description: "OTel Collector distribution with APIClarity support"
output_path: ./otelcol-api

exporters:
- gomod: "github.com/openclarity/apiclarity/plugins/otel-collector/apiclarityexporter v0.0.0"
- gomod:
"github.com/open-telemetry/opentelemetry-collector-contrib/exporter/jaegerexporter
v0.53.0"
- import: go.opentelemetry.io/collector/exporter/loggingexporter
gomod: go.opentelemetry.io/collector v0.53.0

replaces:
- github.com/openclarity/apiclarity/plugins/otel-collector/apiclarityexporter v0.0.0 => github.com/openclarity/apiclarity/plugins/otel-collector/apiclarityexporter v0.0.0-20220915093602-8a11adcdb9e1
- github.com/openclarity/apiclarity/plugins/api v0.0.0 => github.com/openclarity/apiclarity/plugins/api v0.0.0-20220915093602-8a11adcdb9e1

receivers:
- import: go.opentelemetry.io/collector/receiver/otlpreceiver
gomod: go.opentelemetry.io/collector v0.53.0

processors:
- import: go.opentelemetry.io/collector/processor/batchprocessor
gomod: go.opentelemetry.io/collector v0.53.0
```
Loading

0 comments on commit 4376302

Please sign in to comment.