This crate provides a couple of example using ngx crate:
- awssig.rs - An example of NGINX dynamic module that can sign GET request using AWS Signature v4.
- curl - An example of the Access Phase NGINX dynamic module that blocks HTTP requests if
user-agent
header starts withcurl
. - httporigdst - A dynamic module recovers the original IP address and port number of the destination packet.
To build all these examples simply run:
cargo build --package=examples --examples
This module demonstrates how to create a minimal dynamic module with http_request_handler
, that checks for User-Agent headers and returns status code 403 if UA starts with curl
, if a module is disabled then uses core::Status::NGX_DECLINED
to indicate the operation is rejected, for example, because it is disabled in the configuration (curl off
). Additionally, it demonstrates how to write a defective parser.
An example of nginx configuration file that uses that module can be found at curl.conf.
How to build and run in a Docker container curl example:
# 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.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"
This module uses NGX_HTTP_PRECONTENT_PHASE and provides examples, of how to use external dependency and manipulate HTTP headers before sending client requests upstream.
An example of nginx configuration file that uses that module can be found at awssig.conf.
This dynamic module recovers the original IP address and port number of the destination packet. It is useful, for example, with container sidecars where all outgoing traffic is redirected to a separate container with iptables before reaching the target.
This module can only be built with the "linux" feature enabled, and will only successfully build on a Linux OS.
This module uses the Rust crate libc and Linux getsockopt socket API.
load_module "modules/libhttporigdst.so";
http {
server {
# use iptables to capture all outgoing traffic and REDIRECT
# to listening port 15501
listen 15501;
# binding variables provided by module will lazily activate it
# and store a context
# variables can be used in config
location / {
# Return if no backend is available or proxy_pass
# return 200 "recv'd: $server_addr:$server_port\n\nproxy_pass http://$server_orig_addr:$server_orig_port\n";
proxy_pass http://$server_orig_addr:$server_orig_port;
}
}
}
The following embedded variables are provided:
- server_orig_addr
- Original IP address
- server_orig_port
- Original port
- Clone the git repository.
https://github.com/nginxinc/ngx-rust
- Compile the module from the cloned repo.
cd ${CLONED_DIRECTORY}/ngx-rust
cargo build --package=examples --example=httporigdst --features=linux
- Copy the shared object to the modules directory, /etc/nginx/modules.
cp ./target/debug/examples/libhttporigdst.so /etc/nginx/modules
- Add the
load_module
directive to your configuration.
load_module "modules/libhttporigdst.so";
- Reload NGINX.
nginx -t && nginx -s reload
- Redirect traffic outbound.
iptables -t nat -N NGINX_REDIRECT && \
iptables -t nat -A NGINX_REDIRECT -p tcp -j REDIRECT --to-port 15501 --dport 15001 && \
iptables -t nat -N NGINX_OUTPUT && \
iptables -t nat -A OUTPUT -p tcp -j NGINX_OUTPUT && \
iptables -t nat -A NGINX_OUTPUT -j NGINX_REDIRECT
- Redirect traffic inbound.
iptables -t nat -N NGINX_IN_REDIRECT && \
iptables -t nat -A NGINX_IN_REDIRECT -p tcp -j REDIRECT --to-port 15501 --dport 15001 && \
iptables -t nat -N NGINX_INBOUND && \
iptables -t nat -A PREROUTING -p tcp -j NGINX_INBOUND && \
iptables -t nat -A NGINX_INBOUND -p tcp -j NGINX_IN_REDIRECT
- Test with
curl
(this step assumes you've uncommented the return directive).
curl --output - ${LISTEN_IP}:15001
recv'd: ${LISTEN_IP}:15501
proxy_pass http://${LISTEN_IP}:15001
This module only supports IPv4.