Skip to content

Building from Source

Rumen Damyanov edited this page Aug 23, 2025 · 1 revision

Building from Source

This comprehensive guide covers building nginx-torblocker from source code, including compilation options, cross-platform builds, optimization settings, and troubleshooting common build issues.

Overview

Building nginx-torblocker from source gives you complete control over compilation options, allows customization for specific environments, and enables development of new features. This guide covers all aspects of the build process.

Quick Start

Standard Build Process

For most users, this is the recommended approach:

# 1. Download Nginx source
wget https://nginx.org/download/nginx-1.26.0.tar.gz
tar -xzf nginx-1.26.0.tar.gz
cd nginx-1.26.0

# 2. Configure with torblock module
./configure --add-dynamic-module=/path/to/nginx-torblocker/src

# 3. Build the module
make modules

# 4. Install the module
sudo cp objs/ngx_http_torblocker_module.so /usr/lib/nginx/modules/

Verification

Test that the build was successful:

# Check module file
ls -la /usr/lib/nginx/modules/ngx_http_torblocker_module.so

# Test loading in Nginx
echo "load_module modules/ngx_http_torblocker_module.so;" | sudo nginx -t -c /dev/stdin

Detailed Build Instructions

1. Prerequisites Setup

Ubuntu/Debian:

# Essential build tools
sudo apt update
sudo apt install -y build-essential

# Nginx compilation dependencies
sudo apt install -y libpcre3-dev libssl-dev zlib1g-dev

# Optional: Additional libraries
sudo apt install -y libgeoip-dev     # For GeoIP support
sudo apt install -y libgd-dev        # For image filter module
sudo apt install -y libxslt1-dev     # For XSLT module

CentOS/RHEL:

# Essential build tools
sudo yum groupinstall -y "Development Tools"

# Nginx compilation dependencies
sudo yum install -y pcre-devel openssl-devel zlib-devel

# Optional: Additional libraries
sudo yum install -y GeoIP-devel      # For GeoIP support
sudo yum install -y gd-devel         # For image filter module
sudo yum install -y libxslt-devel    # For XSLT module

macOS:

# Install Xcode command line tools
xcode-select --install

# Install dependencies via Homebrew
brew install pcre openssl zlib

# Optional: Additional libraries
brew install geoip libgd libxslt

2. Source Code Preparation

Download and prepare source code:

#!/bin/bash
# build-prep.sh

set -e

# Configuration
NGINX_VERSION="1.26.0"
BUILD_DIR="$HOME/nginx-build"
TORBLOCK_SRC="$PWD/src"

# Create build directory
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"

# Download Nginx source
echo "Downloading Nginx $NGINX_VERSION..."
if [ ! -f "nginx-$NGINX_VERSION.tar.gz" ]; then
    wget "https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz"
fi

# Extract source
echo "Extracting Nginx source..."
if [ ! -d "nginx-$NGINX_VERSION" ]; then
    tar -xzf "nginx-$NGINX_VERSION.tar.gz"
fi

cd "nginx-$NGINX_VERSION"

echo "Nginx source prepared at: $PWD"
echo "Torblock source at: $TORBLOCK_SRC"

3. Configuration Options

The ./configure script accepts numerous options. Here are the most relevant for nginx-torblocker:

Basic Configuration

./configure \
    --prefix=/usr/local/nginx \
    --sbin-path=/usr/local/nginx/sbin/nginx \
    --conf-path=/usr/local/nginx/conf/nginx.conf \
    --add-dynamic-module=/path/to/nginx-torblocker/src

Production Configuration

./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --http-client-body-temp-path=/var/cache/nginx/client_temp \
    --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
    --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
    --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
    --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
    --with-compat \
    --with-file-aio \
    --with-threads \
    --with-http_addition_module \
    --with-http_auth_request_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_mp4_module \
    --with-http_random_index_module \
    --with-http_realip_module \
    --with-http_secure_link_module \
    --with-http_slice_module \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --with-http_sub_module \
    --with-http_v2_module \
    --with-http_geoip_module=dynamic \
    --add-dynamic-module=/path/to/nginx-torblocker/src

Development Configuration

./configure \
    --prefix=/usr/local/nginx-dev \
    --with-debug \
    --with-cc-opt="-g -O0 -DDEBUG" \
    --with-ld-opt="-Wl,-E" \
    --add-dynamic-module=/path/to/nginx-torblocker/src

4. Compilation Process

Execute the build:

#!/bin/bash
# build.sh

set -e

# Configuration
NGINX_SRC="$PWD"
PARALLEL_JOBS=$(nproc)  # Use all available CPU cores

echo "Starting compilation with $PARALLEL_JOBS parallel jobs..."

# Build modules only (faster for module development)
make modules -j$PARALLEL_JOBS

# Or build everything
# make -j$PARALLEL_JOBS

# Check build results
if [ -f "objs/ngx_http_torblocker_module.so" ]; then
    echo "✓ Build successful!"
    ls -la objs/ngx_http_torblocker_module.so
else
    echo "✗ Build failed!"
    exit 1
fi

Platform-Specific Builds

Ubuntu/Debian Packaging

Build Debian packages:

#!/bin/bash
# build-deb.sh

set -e

NGINX_VERSION="1.26.0"
TORBLOCK_VERSION="1.1.1"
DISTRO="noble"  # or jammy, focal, etc.

# Install packaging tools
sudo apt install -y devscripts debhelper

# Prepare source package
cd nginx-$NGINX_VERSION

# Create debian directory structure
mkdir -p debian/source

# Configure for package build
./configure \
    --prefix=/usr/share/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --add-dynamic-module=../nginx-torblocker/src

# Build package
dpkg-buildpackage -us -uc

echo "Package built: nginx-torblocker_${TORBLOCK_VERSION}~${DISTRO}_$(dpkg --print-architecture).deb"

CentOS/RHEL RPM Building

Build RPM packages:

#!/bin/bash
# build-rpm.sh

set -e

# Install RPM build tools
sudo yum install -y rpm-build rpmdevtools

# Set up RPM build environment
rpmdev-setuptree

# Copy source to RPM directory
cp nginx-1.26.0.tar.gz ~/rpmbuild/SOURCES/
cp -r nginx-torblocker ~/rpmbuild/SOURCES/

# Create spec file (nginx-torblocker.spec)
cat > ~/rpmbuild/SPECS/nginx-torblocker.spec << 'EOF'
Name:           nginx-torblocker
Version:        1.1.1
Release:        1%{?dist}
Summary:        Nginx module for blocking Tor exit nodes

License:        MIT
URL:            https://github.com/yourusername/nginx-torblocker
Source0:        nginx-1.26.0.tar.gz
Source1:        nginx-torblocker

BuildRequires:  gcc, pcre-devel, openssl-devel, zlib-devel
Requires:       nginx

%description
A dynamic Nginx module for blocking traffic from Tor exit nodes.

%prep
%setup -q -n nginx-1.26.0

%build
./configure --add-dynamic-module=%{SOURCE1}/src
make modules

%install
mkdir -p %{buildroot}/usr/lib64/nginx/modules
cp objs/ngx_http_torblocker_module.so %{buildroot}/usr/lib64/nginx/modules/

%files
/usr/lib64/nginx/modules/ngx_http_torblocker_module.so

%changelog
* $(date "+%a %b %d %Y") Your Name <[email protected]> - 1.1.1-1
- Initial package build
EOF

# Build RPM
rpmbuild -ba ~/rpmbuild/SPECS/nginx-torblocker.spec

echo "RPM built in ~/rpmbuild/RPMS/"

Cross-Platform Building

Cross-compilation for ARM

#!/bin/bash
# cross-build-arm.sh

set -e

# Install cross-compilation tools
sudo apt install -y gcc-aarch64-linux-gnu

# Set cross-compilation environment
export CC=aarch64-linux-gnu-gcc
export AR=aarch64-linux-gnu-ar
export STRIP=aarch64-linux-gnu-strip

# Configure for ARM64
./configure \
    --crossbuild=Linux::aarch64 \
    --with-cc=aarch64-linux-gnu-gcc \
    --with-cc-opt="-static-libgcc" \
    --with-ld-opt="-static-libgcc" \
    --add-dynamic-module=/path/to/nginx-torblocker/src

# Build
make modules

echo "ARM64 module built: objs/ngx_http_torblocker_module.so"

Build Optimization

Performance Optimizations

# High-performance build configuration
./configure \
    --add-dynamic-module=/path/to/nginx-torblocker/src \
    --with-cc-opt="-O3 -march=native -mtune=native -flto" \
    --with-ld-opt="-Wl,-O1 -Wl,--as-needed -flto"

Size Optimizations

# Minimal size build
./configure \
    --add-dynamic-module=/path/to/nginx-torblocker/src \
    --with-cc-opt="-Os -ffunction-sections -fdata-sections" \
    --with-ld-opt="-Wl,--gc-sections -s"

Debug Builds

# Debug build with extensive logging
./configure \
    --add-dynamic-module=/path/to/nginx-torblocker/src \
    --with-debug \
    --with-cc-opt="-g -O0 -DDEBUG -fsanitize=address" \
    --with-ld-opt="-fsanitize=address"

Advanced Build Options

Custom Module Configuration

Modify src/config for advanced options:

# src/config - Module configuration file

ngx_addon_name=ngx_http_torblocker_module

# Define module type
HTTP_MODULES="$HTTP_MODULES ngx_http_torblocker_module"

# Source files
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_torblocker_module.c"

# Header files
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/ngx_http_torblocker_module.h"

# Compilation flags
ngx_feature="torblock module dependencies"
ngx_feature_name="NGX_HTTP_TORBLOCK"
ngx_feature_run=no
ngx_feature_incs="#include <sys/socket.h>"
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct sockaddr_in sin;"

. auto/feature

# Add custom defines
if [ $ngx_found = yes ]; then
    CORE_INCS="$CORE_INCS $ngx_addon_dir"
    
    # Add custom compilation flags
    case "$NGX_PLATFORM" in
        Linux:*)
            ngx_feature_libs="-ldl"
            ;;
        FreeBSD:*)
            ngx_feature_libs=""
            ;;
        Darwin:*)
            ngx_feature_libs=""
            ;;
    esac
fi

Conditional Compilation

Add feature flags to the module:

// In ngx_http_torblocker_module.h

#ifndef NGX_HTTP_TORBLOCK_H
#define NGX_HTTP_TORBLOCK_H

// Feature flags - can be controlled via configure
#ifndef NGX_HTTP_TORBLOCK_ENABLE_GEOIP
#define NGX_HTTP_TORBLOCK_ENABLE_GEOIP 1
#endif

#ifndef NGX_HTTP_TORBLOCK_ENABLE_CACHING
#define NGX_HTTP_TORBLOCK_ENABLE_CACHING 1
#endif

#ifndef NGX_HTTP_TORBLOCK_ENABLE_STATS
#define NGX_HTTP_TORBLOCK_ENABLE_STATS 1
#endif

// Conditional compilation blocks
#if NGX_HTTP_TORBLOCK_ENABLE_GEOIP
#include <GeoIP.h>
#endif

#endif /* NGX_HTTP_TORBLOCK_H */

Build Automation

Continuous Integration Build

GitHub Actions build configuration:

# .github/workflows/build-matrix.yml
name: Build Matrix

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        nginx-version: ['1.24.0', '1.26.0', '1.27.0']
        ubuntu-version: ['jammy', 'noble']
        arch: ['amd64', 'arm64']
        
    steps:
    - uses: actions/checkout@v4
    
    - name: Set up build environment
      run: |
        sudo apt update
        sudo apt install -y build-essential libpcre3-dev libssl-dev zlib-devel
        
    - name: Download Nginx source
      run: |
        wget https://nginx.org/download/nginx-${{ matrix.nginx-version }}.tar.gz
        tar -xzf nginx-${{ matrix.nginx-version }}.tar.gz
        
    - name: Configure build
      run: |
        cd nginx-${{ matrix.nginx-version }}
        ./configure --add-dynamic-module=$GITHUB_WORKSPACE/src
        
    - name: Build module
      run: |
        cd nginx-${{ matrix.nginx-version }}
        make modules
        
    - name: Test module
      run: |
        cd nginx-${{ matrix.nginx-version }}
        ls -la objs/ngx_http_torblocker_module.so
        file objs/ngx_http_torblocker_module.so
        
    - name: Upload artifacts
      uses: actions/upload-artifact@v4
      with:
        name: nginx-torblocker-${{ matrix.nginx-version }}-${{ matrix.ubuntu-version }}-${{ matrix.arch }}
        path: nginx-${{ matrix.nginx-version }}/objs/ngx_http_torblocker_module.so

Local Build Script

Comprehensive local build automation:

#!/bin/bash
# build-all.sh - Complete build automation

set -e

# Configuration
NGINX_VERSIONS=("1.24.0" "1.26.0" "1.27.0")
BUILD_TYPES=("release" "debug" "optimized")
BUILD_DIR="$HOME/nginx-builds"
MODULE_SRC="$PWD/src"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log() {
    echo -e "${GREEN}[$(date +'%H:%M:%S')]${NC} $1"
}

warn() {
    echo -e "${YELLOW}[$(date +'%H:%M:%S')] WARNING:${NC} $1"
}

error() {
    echo -e "${RED}[$(date +'%H:%M:%S')] ERROR:${NC} $1"
    exit 1
}

# Create build directory
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"

# Build for each version and type
for nginx_version in "${NGINX_VERSIONS[@]}"; do
    for build_type in "${BUILD_TYPES[@]}"; do
        log "Building Nginx $nginx_version ($build_type)"
        
        # Download source if needed
        if [ ! -f "nginx-$nginx_version.tar.gz" ]; then
            log "Downloading Nginx $nginx_version..."
            wget "https://nginx.org/download/nginx-$nginx_version.tar.gz"
        fi
        
        # Extract to build-specific directory
        build_dir="nginx-$nginx_version-$build_type"
        if [ ! -d "$build_dir" ]; then
            tar -xzf "nginx-$nginx_version.tar.gz"
            mv "nginx-$nginx_version" "$build_dir"
        fi
        
        cd "$build_dir"
        
        # Configure based on build type
        case "$build_type" in
            "release")
                configure_opts="--with-cc-opt=-O2"
                ;;
            "debug")
                configure_opts="--with-debug --with-cc-opt='-g -O0'"
                ;;
            "optimized")
                configure_opts="--with-cc-opt='-O3 -march=native'"
                ;;
        esac
        
        # Configure and build
        ./configure \
            --add-dynamic-module="$MODULE_SRC" \
            $configure_opts
            
        make modules
        
        # Verify build
        if [ -f "objs/ngx_http_torblocker_module.so" ]; then
            log "✓ Build successful: $build_dir"
            
            # Copy to output directory
            output_dir="../output/$nginx_version/$build_type"
            mkdir -p "$output_dir"
            cp objs/ngx_http_torblocker_module.so "$output_dir/"
            
            # Generate build info
            cat > "$output_dir/build-info.txt" << EOF
Build Information:
- Nginx Version: $nginx_version
- Build Type: $build_type
- Build Date: $(date)
- Module Size: $(stat -c%s objs/ngx_http_torblocker_module.so) bytes
- Build Host: $(hostname)
- Compiler: $(gcc --version | head -n1)
EOF
        else
            error "Build failed: $build_dir"
        fi
        
        cd "$BUILD_DIR"
    done
done

log "All builds completed successfully!"
log "Output directory: $BUILD_DIR/output"

Troubleshooting Build Issues

Common Build Errors

Missing Dependencies

Error:

./configure: error: the HTTP rewrite module requires the PCRE library.

Solution:

# Ubuntu/Debian
sudo apt install -y libpcre3-dev

# CentOS/RHEL
sudo yum install -y pcre-devel

# macOS
brew install pcre

SSL/TLS Errors

Error:

./configure: error: SSL modules require the OpenSSL library.

Solution:

# Ubuntu/Debian
sudo apt install -y libssl-dev

# CentOS/RHEL
sudo yum install -y openssl-devel

# macOS
brew install openssl
# May need to specify path:
# --with-cc-opt="-I/usr/local/opt/openssl/include"
# --with-ld-opt="-L/usr/local/opt/openssl/lib"

Module Configuration Errors

Error:

adding module in /path/to/nginx-torblocker/src
./configure: error: no /path/to/nginx-torblocker/src/config was found

Solution:

# Check that config file exists
ls -la /path/to/nginx-torblocker/src/config

# If missing, ensure you're pointing to the correct directory
./configure --add-dynamic-module=/correct/path/to/nginx-torblocker/src

Compilation Errors

Error:

src/ngx_http_torblocker_module.c: In function 'ngx_http_torblocker_handler':
src/ngx_http_torblocker_module.c:150: error: 'ngx_str_t' has no member named 'data'

Solution: This usually indicates version compatibility issues. Check that the module is compatible with your Nginx version.

Build Verification

Test that your built module works correctly:

#!/bin/bash
# verify-build.sh

MODULE_PATH="/usr/lib/nginx/modules/ngx_http_torblocker_module.so"

echo "=== Build Verification ==="

# Check file exists and is readable
if [ ! -f "$MODULE_PATH" ]; then
    echo "✗ Module file not found: $MODULE_PATH"
    exit 1
fi

echo "✓ Module file exists: $MODULE_PATH"

# Check file type
file_type=$(file "$MODULE_PATH")
echo "File type: $file_type"

# Check file size
file_size=$(stat -c%s "$MODULE_PATH" 2>/dev/null || stat -f%z "$MODULE_PATH")
echo "File size: $file_size bytes"

# Check dependencies
echo "Dependencies:"
ldd "$MODULE_PATH" 2>/dev/null || otool -L "$MODULE_PATH" 2>/dev/null || echo "Could not check dependencies"

# Test loading in Nginx
echo "Testing module loading..."
if nginx -t -c <(echo "load_module $MODULE_PATH;") 2>/dev/null; then
    echo "✓ Module loads successfully"
else
    echo "✗ Module failed to load"
    exit 1
fi

echo "=== Verification Complete ==="

Next Steps

After successfully building from source:

  1. Installation: Deploy your built module to production systems
  2. Testing: Run comprehensive tests to ensure functionality
  3. Development: Use Development Setup for ongoing development
  4. Configuration: Apply settings from Advanced Configuration
  5. Troubleshooting: Reference debugging techniques if issues arise
Clone this wiki locally