Skip to content

Commit

Permalink
WAF without remote config
Browse files Browse the repository at this point in the history
  • Loading branch information
cataphract committed May 14, 2024
1 parent af61c00 commit ee0e161
Show file tree
Hide file tree
Showing 123 changed files with 17,703 additions and 1,590 deletions.
1,437 changes: 442 additions & 995 deletions .circleci/config.yml

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* @DataDog/apm-proxy
src/security/ @DataDog/asm-cpp
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# build arifacts
*.so
/.build
/.docker-build
/.musl-build

# text editor noise
.*.sw?
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "dd-trace-cpp"]
path = dd-trace-cpp
url = ../dd-trace-cpp.git
[submodule "libddwaf"]
path = libddwaf
url = git@github.com:DataDog/libddwaf.git
88 changes: 75 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
cmake_minimum_required(VERSION 3.7)
# The C code doesn't care about the C++ version.
# dd-trace-cpp works with C++17 or newer.
set(CMAKE_CXX_STANDARD 17)
cmake_minimum_required(VERSION 3.24)

set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
cmake_policy(SET CMP0068 NEW)
cmake_policy(SET CMP0135 NEW)

# This build configuration combines the following other build configurations:
# - `nginx-datadog.cmake`, the actual nginx module source in `src/`,
Expand All @@ -12,9 +14,16 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

project(ngx_http_datadog_module)

if(NOT NGINX_SRC_DIR)
message(FATAL_ERROR "Missing NGINX source directory. Use -DNGINX_SRC_DIR")
option(NGINX_DATADOG_ASM_ENABLED "Build with libddwaf" ON)
set(NGINX_SRC_DIR "" CACHE PATH "The path to a directory with nginx sources")
set(NGINX_VERSION "" CACHE STRING "The nginx version")
if (NGINX_SRC_DIR STREQUAL "" AND NGINX_VERSION STREQUAL "")
message(FATAL_ERROR "Set NGINX_SRC_DIR or, alternatively NGINX_VERSION")
endif()
option(NGINX_PATCH_AWAY_LIBC "Patch away libc dependency" OFF)

# Make curl link against a static zlib (requires cmake 3.24)
set(ZLIB_USE_STATIC_LIBS ON)

# Prefer the build mode "release with debug info" if another mode wasn't
# specified.
Expand All @@ -26,15 +35,31 @@ endif()
if(CMAKE_COMPILER_IS_GNUCXX)
# This warning has a false positive. See
# <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108088>.
add_compile_options(-Wno-error=free-nonheap-object -Wno-error=maybe-uninitialized)
add_compile_options(-Wno-error=free-nonheap-object)

# Looks like a false positive. Doesn't like a constructor taking
# std::optional = nullopt and moving it to a null optional
add_compile_options(-Wno-error=maybe-uninitialized)
endif()

# save frame pointers to make it more profiler friendly
add_compile_options(-fno-omit-frame-pointer)

# Nginx module boilerplate (code within the nginx repository)
include(./nginx-module.cmake)

add_subdirectory(./dd-trace-cpp EXCLUDE_FROM_ALL)

if(NGINX_DATADOG_ASM_ENABLED)
include(./rapidjson.cmake)
# we need neither but libddwaf requires one enabled
set(LIBDDWAF_BUILD_STATIC ON)
set(LIBDDWAF_BUILD_SHARED OFF)
set(LIBDDWAF_TESTING OFF)
set(LIBDDWAF_ENABLE_LTO OFF)
add_subdirectory(./libddwaf EXCLUDE_FROM_ALL)
endif()

# The shared library (nginx module) that we are building.
add_library(ngx_http_datadog_module SHARED)

Expand All @@ -49,6 +74,7 @@ target_sources(ngx_http_datadog_module
src/datadog_variable.cpp
src/dd.cpp
src/defer.cpp
src/glibc_compat.c
src/global_tracer.cpp
src/log_conf.cpp
src/ngx_event_scheduler.cpp
Expand All @@ -61,18 +87,33 @@ target_sources(ngx_http_datadog_module
src/string_util.cpp
src/tracing_library.cpp
)
if(NGINX_DATADOG_ASM_ENABLED)
target_sources(ngx_http_datadog_module
PRIVATE
src/security/blocking.cpp
src/security/client_ip.cpp
src/security/collection.cpp
src/security/context.cpp
src/security/ddwaf_obj.cpp
src/security/header_tags.cpp
src/security/library.cpp)
target_compile_definitions(ngx_http_datadog_module PRIVATE WITH_WAF)
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(ngx_http_datadog_module PRIVATE -Wall -Werror)
endif()


target_include_directories(ngx_http_datadog_module
PRIVATE
src/
)

add_dependencies(ngx_http_datadog_module
nginx_module
dd_trace_cpp-objects
)

target_link_libraries(ngx_http_datadog_module dd_trace_cpp-objects nginx_module)
if(NGINX_DATADOG_ASM_ENABLED)
target_link_libraries(ngx_http_datadog_module rapidjson libddwaf_objects)
endif()

# Remove the "lib" prefix to match NGINX convention
set_property(TARGET ngx_http_datadog_module PROPERTY PREFIX "")
Expand All @@ -82,7 +123,28 @@ if(CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set_property(TARGET ngx_http_datadog_module PROPERTY SUFFIX ".so")
target_link_options(ngx_http_datadog_module PRIVATE -undefined dynamic_lookup)
else()
target_link_libraries(ngx_http_datadog_module -static-libstdc++ -static-libgcc)
target_link_libraries(ngx_http_datadog_module -static-libstdc++ -static-libgcc)
endif()
endif()

if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/nginx_module.ld)
set_target_properties(ngx_http_datadog_module PROPERTIES LINK_DEPENDS ${LINKER_SCRIPT})
target_link_options(ngx_http_datadog_module PRIVATE "-Wl,--version-script=${LINKER_SCRIPT}")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(EXPORTED_SYMBOLS ${CMAKE_SOURCE_DIR}/nginx_module.exported)
set_target_properties(ngx_http_datadog_module PROPERTIES LINK_DEPENDS ${EXPORTED_SYMBOLS})
target_link_options(ngx_http_datadog_module PRIVATE "-Wl,-exported_symbols_list" "-Wl,${EXPORTED_SYMBOLS}")
endif()

if(NGINX_PATCH_AWAY_LIBC)
include(./patchelf.cmake)
patch_away_libc(ngx_http_datadog_module)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
include(./split_debug_info.cmake)
split_debug_info(ngx_http_datadog_module)
endif()

# vim: et ts=2 sw=2:
23 changes: 0 additions & 23 deletions Dockerfile

This file was deleted.

71 changes: 61 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@

BUILD_DIR ?= .build
BUILD_TYPE ?= RelWithDebInfo
WAF ?= OFF
MAKE_JOB_COUNT ?= $(shell nproc)
PWD ?= $(shell pwd)
NGINX_SRC_DIR ?= $(PWD)/nginx
ARCH ?= $(shell arch)
DOCKER_REPOS ?= public.ecr.aws/b1o7r7e0/nginx_musl_toolchain

SHELL := /bin/bash

.PHONY: build
build: build-deps sources
cmake -B$(BUILD_DIR) -DNGINX_SRC_DIR=$(PWD)/nginx -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) . && cmake --build $(BUILD_DIR) -j $(MAKE_JOB_COUNT) -v
# -DCMAKE_C_FLAGS=-I/opt/homebrew/Cellar/pcre2/10.42/include/ -DCMAKE_CXX_FLAGS=-I/opt/homebrew/Cellar/pcre2/10.42/include/ -DCMAKE_LDFLAGS=-L/opt/homebrew/Cellar/pcre2/10.42/lib -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang
cmake -B$(BUILD_DIR) -DNGINX_SRC_DIR=$(NGINX_SRC_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DNGINX_DATADOG_ASM_ENABLED=$(WAF) . \
&& cmake --build $(BUILD_DIR) -j $(MAKE_JOB_COUNT) -v
chmod 755 $(BUILD_DIR)/ngx_http_datadog_module.so
@echo 'build successful 👍'

Expand Down Expand Up @@ -49,28 +57,71 @@ lint: .clang-format
clean:
rm -rf \
.build \
.docker-build
.musl-build

.PHONY: clobber
clobber: clean
rm -rf \
nginx

.PHONY: build-in-docker
build-in-docker:
bin/run_in_build_image.sh make BUILD_DIR=.docker-build build
DOCKER_PLATFORM := linux/$(ARCH)
ifeq ($(DOCKER_PLATFORM),linux/x86_64)
DOCKER_PLATFORM := linux/amd64
endif
ifeq ($(DOCKER_PLATFORM),linux/aarch64)
DOCKER_PLATFORM := linux/arm64
endif

# For testing changes to the build image
.PHONY: build-musl-toolchain
build-musl-toolchain:
docker build --progress=plain --platform $(DOCKER_PLATFORM) --build-arg ARCH=$(ARCH) -t $(DOCKER_REPOS) build_env

.PHONY: build-push-musl-toolchain
build-push-musl-toolchain:
docker build --progress=plain --platform linux/amd64 --build-arg ARCH=x86_64 -t $(DOCKER_REPOS):latest-amd64 build_env
docker push $(DOCKER_REPOS):latest-amd64
docker build --progress=plain --platform linux/arm64 --build-arg ARCH=aarch64 -t $(DOCKER_REPOS):latest-arm64 build_env
docker push $(DOCKER_REPOS):latest-arm64
docker buildx imagetools create -t $(DOCKER_REPOS):latest \
$(DOCKER_REPOS):latest-amd64 \
$(DOCKER_REPOS):latest-arm64

.PHONY: build-musl
build-musl:
docker run --init --rm \
--platform $(DOCKER_PLATFORM) \
--env ARCH=$(ARCH) \
--env BUILD_TYPE=$(BUILD_TYPE) \
--env NGINX_VERSION=$(NGINX_VERSION) \
--env WAF=$(WAF) \
--mount "type=bind,source=$(PWD),destination=/mnt/repo" \
$(DOCKER_REPOS):latest \
make -C /mnt/repo build-musl-aux

# this is what's run inside the container nginx_musl_toolchain
.PHONY: build-musl-aux
build-musl-aux:
cmake -B .musl-build \
-DCMAKE_TOOLCHAIN_FILE=/sysroot/$(ARCH)-none-linux-musl/Toolchain.cmake \
-DNGINX_PATCH_AWAY_LIBC=ON \
-DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \
-DNGINX_VERSION="$(NGINX_VERSION)" \
-DNGINX_DATADOG_ASM_ENABLED="$(WAF)" . \
&& cmake --build .musl-build -j $(MAKE_JOB_COUNT) -v


.PHONY: test
test: build-in-docker
cp .docker-build/libngx_http_datadog_module.so test/services/nginx/ngx_http_datadog_module.so
test: build-musl
cp -v .musl-build/ngx_http_datadog_module.so* test/services/nginx/
test/bin/run $(TEST_ARGS)

.PHONY: test-parallel
test-parallel: build-in-docker
cp .docker-build/libngx_http_datadog_module.so test/services/nginx/ngx_http_datadog_module.so
cp -v .musl-build/ngx_http_datadog_module.so* test/services/nginx/
test/bin/run_parallel $(TEST_ARGS)

.PHONY: lab
lab: build-in-docker
cp .docker-build/libngx_http_datadog_module.so lab/services/nginx/ngx_http_datadog_module.so
lab: build-musl
cp -v .musl-build/ngx_http_datadog_module.so* lab/services/nginx/
lab/bin/run $(TEST_ARGS)
Loading

0 comments on commit ee0e161

Please sign in to comment.