Awesome
Project status
This project is still a work in progress and not production ready.
Description
This project provides Rust SDK interfaces to the NGINX proxy allowing the creation of NGINX dynamic modules completely in Rust.
In short, this SDK allows writing NGINX modules using the Rust language.
Build
NGINX modules can be built against a particular version of NGINX. The following environment variables can be used to specify a particular version of NGINX or an NGINX dependency:
ZLIB_VERSION
(default 1.3.1) - zlib versionPCRE2_VERSION
(default 10.42 for NGINX 1.22.0 and later, or 8.45 for earlier) - PCRE1 or PCRE2 versionOPENSSL_VERSION
(default 3.2.1 for NGINX 1.22.0 and later, or 1.1.1w for earlier) - OpenSSL versionNGX_VERSION
(default 1.26.1) - NGINX OSS versionNGX_DEBUG
(default to false) - if set to true, then will compile NGINX--with-debug
option
For example, this is how you would compile the examples using a specific version of NGINX and enabling debugging:
NGX_DEBUG=true NGX_VERSION=1.23.0 cargo build --package=examples --examples --release
To build Linux-only modules, use the "linux" feature:
cargo build --package=examples --examples --features=linux --release
After compilation, the modules can be found in the path target/release/examples/
( with the .so
file extension for
Linux or .dylib
for MacOS).
Additionally, the folder .cache/nginx/{NGX_VERSION}/{TARGET}
({TARGET}
means rustc's target triple string) will contain the compiled version of NGINX used to build
the SDK. You can start NGINX directly from this directory if you want to test the module.
The following environment variables can be used to change locations of cache directory and NGINX directory:
CACHE_DIR
(default[nginx-sys's root directory]/.cache
) - the directory containing cache files, means PGP keys, tarballs, PGP signatures, and unpacked source codes. It also contains compiled NGINX in default configuration.NGINX_INSTALL_ROOT_DIR
(default{CACHE_DIR}/nginx
) - the directory containing the series of compiled NGINX in its subdirectoriesNGINX_INSTALL_DIR
(default{NGINX_INSTALL_BASE_DIR}/{NGX_VERSION}/{TARGET}
) - the directory containing the NGINX compiled in the build
Mac OS dependencies
In order to use the optional GNU make build process on MacOS, you will need to install additional tools. This can be done via homebrew with the following command:
brew install make openssl grep
Additionally, you may need to set up LLVM and clang. Typically, this is done as follows:
# make sure xcode tools are installed
xcode-select --install
# instal llvm
brew install --with-toolchain llvm
Linux dependencies
See the Dockerfile for dependencies as an example of required packages on Debian Linux.
Build example
Example modules are available in examples folder. You can use cargo build --package=examples --examples
to build these examples. After building, you can find the .so
or .dylib
in the target/debug
folder. Add --features=linux
to build linux specific modules. NOTE: adding the "linux" feature on MacOS will cause a build failure.
For example (all examples plus linux specific):
cargo build --package=examples --examples --features=linux
Build with external NGINX source tree
If you require a customized NGINX configuration, you can build a module against an existing pre-configured source tree.
To do that, you need to set the NGX_OBJS
variable to an absolute path of the NGINX build directory (--builddir
, defaults to the objs
in the source directory).
Only the ./configure
step of the NGINX build is mandatory because bindings don't depend on any of the artifacts generated by make
.
NGX_OBJS=$PWD/../nginx/objs cargo build --package=examples --examples
Furthermore, this approach can be leveraged to build a module as a part of the NGINX build process by adding the --add-module
/--add-dynamic-module
options to the configure script.
See the following example integration scripts: examples/config
and examples/config.make
.
Docker
We provide a multistage Dockerfile:
# build all dynamic modules examples and specify NGINX version to use
docker buildx build --build-arg NGX_VERSION=1.23.3 -t ngx-rust .
# start NGINX using [curl](examples/curl.conf) module example:
docker run --rm -d -p 8000:8000 ngx-rust nginx -c examples/curl.conf
# test it - you should see 403 Forbidden
curl http://127.0.0.1:8000 -v -H "user-agent: curl"
# test it - you should see 404 Not Found
curl http://127.0.0.1:8000 -v -H "user-agent: foo"
Usage
A complete module example using the SDK can be found here. You can build it with
cargo build --package=examples --example=curl
then set up NGINX to use it:
For example:
daemon off;
master_process off;
# unix:
# load_module modules/libcurl.so;
# error_log logs/error.log debug;
error_log /dev/stdout debug;
working_directory /tmp/cores/;
worker_rlimit_core 500M;
events {
}
http {
access_log /dev/stdout;
server {
listen 8000;
server_name localhost;
location / {
alias /srv/http;
# ... Other config stuff ...
curl on;
}
}
}
Support
This SDK is currently unstable. Right now, our primary goal is collect feedback and stabilize it be before offering support. Feel free contributing by creating issues, PRs, or github discussions.
Currently, the only supported platforms are:
- Darwin (Mac OSX)
- Linux platform
Roadmap
If you have ideas for releases in the future, please suggest them in the github discussions.
Contributing
We welcome pull requests and issues!
Please refer to the Contributing Guidelines when doing a PR.
Authors and acknowledgment
This project uses some great work from dcoles/nginx-rs, arvancloud/nginx-rs.
Projects using the SDK
ngx-strict-sni - Strict SNI validator for Nginx
License
All code in this repository is licensed under the Apache License v2 license.