Post

I Analyzed 30 Days Of Traffic Hitting My Homelab Reverse Proxy 116 Million Requests Were Attacks Heres What Theyre Actually Looking For

I Analyzed 30 Days Of Traffic Hitting My Homelab Reverse Proxy 116 Million Requests Were Attacks Heres What Theyre Actually Looking For

I Analyzed 30 Days Of Traffic Hitting My Homelab Reverse Proxy 116 Million Requests Were Attacks Heres What Theyre Actually Looking For

INTRODUCTION

When you expose a self‑hosted reverse proxy to the public internet, the noise you hear is rarely just benign curiosity. In a recent deep‑dive I pulled 30 days of access logs from my Nginx Proxy Manager instance and discovered that over 116 million requests were not legitimate user traffic – they were automated scans, credential‑stuffing attempts, and a variety of other malicious payloads.

The headline numbers were startling: 5.4 million total requests, with 1.2 million flagged as high‑severity attacks. But the real insight came from dissecting what those attackers were searching for. Were they hunting for exposed Docker APIs? Trying to locate default admin panels? Or simply probing for misconfigured reverse proxy headers?

In this guide I walk through the entire workflow that turned raw logs into actionable intelligence. You will learn how to:

  • instrument a reverse proxy to capture granular request metadata,
  • parse and classify traffic using open‑source tooling,
  • identify the most common reconnaissance patterns that precede an exploit,
  • harden your homelab infrastructure against the most prevalent attack vectors, and
  • automate remediation steps that keep your services available without drowning in false positives.

The post is written for seasoned DevOps engineers and sysadmins who already run a self‑hosted stack behind a reverse proxy. If you manage Emby, arr stacks, personal apps, or any other containerized workloads, the techniques below will help you transform raw traffic into a security‑focused asset.

By the end of the article you’ll have a repeatable process for turning log data into defensive intelligence, a set of configuration tweaks that reduce noise, and a clear roadmap for scaling these practices as your homelab grows.

UNDERSTANDING THE TOPIC

What is a Reverse Proxy in a Homelab Context

A reverse proxy sits in front of one or more backend services and terminates inbound HTTP(S) traffic on their behalf. In a homelab you typically run Nginx, Caddy, or Nginx Proxy Manager (NPM) to expose multiple services – such as Emby, Nextcloud, or custom APIs – under distinct hostnames or subdomains.

The reverse proxy provides several critical benefits:

  • Simplified TLS termination – you can manage certificates centrally without configuring TLS on each container.
  • Host‑based routing – a single public IP can forward traffic to dozens of internal services based on the Host header.
  • Request sanitization – you can strip unwanted headers, enforce rate limits, or inject security headers before traffic reaches the backend.

However, because the proxy is the public‑facing entry point, it also becomes a prime target for automated scanning tools that crawl the internet looking for exposed services.

Historical Perspective

The concept of a reverse proxy dates back to the early 1990s when early web servers needed a way to distribute load across multiple backends. Early implementations were monolithic, but modern open‑source solutions like Nginx, HAProxy, and Caddy have added rich feature sets – including built‑in health checks, dynamic upstream configuration, and extensive logging.

Nginx Proxy Manager, built on top of Nginx, adds a web UI that simplifies the creation of reverse proxy rules, SSL management, and WAF‑style rule sets. While the UI lowers the barrier for newcomers, it also introduces a larger attack surface if not hardened correctly.

Key Features and Capabilities

  • Host‑based routing – map any domain or subdomain to a specific upstream container.
  • Path‑based routing – forward /api/* to a particular service while keeping the same public endpoint.
  • SSL termination with Let’s Encrypt – automatic certificate issuance and renewal.
  • Access control lists (ACLs) – restrict access by IP, geolocation, or custom patterns.
  • Rate limiting and request size limits – mitigate abuse without affecting legitimate users.
  • Custom WAF rules – block known attack signatures such as SQL injection or path traversal attempts.

Pros and Cons

AdvantagesDisadvantages
Centralized TLS management reduces certificate sprawlUI can become a single point of failure if not properly monitored
Ability to expose dozens of services on a single public IPDefault configurations may leave unnecessary endpoints exposed
Rich logging and metrics integration with Prometheus/GrafanaComplex rule sets can be difficult to audit manually
Open‑source and community‑driven developmentPerformance overhead compared to lightweight HAProxy for very high QPS

Use Cases and Scenarios

  • Home media servers – expose Plex, Jellyfin, or Emby without configuring TLS on each container.
  • Development sandboxes – route dev.local to a set of containerized CI/CD tools.
  • IoT gateways – provide a single entry point for multiple smart‑home APIs while enforcing strict rate limits.
  • Zero‑trust edge – combine ACLs with upstream authentication to emulate a modern edge proxy.

The adoption of reverse proxies in homelab environments has accelerated alongside the rise of container orchestration platforms like Docker Swarm and Kubernetes. As more services become exposed, attackers are refining their reconnaissance techniques – from simple port scans to sophisticated credential‑stuffing campaigns that target default admin interfaces.

Future developments are likely to focus on:

  • Behavioral analytics – using machine learning to differentiate normal traffic from malicious patterns in real time.
  • Service mesh integration – leveraging sidecar proxies to offload routing decisions from the edge layer.
  • Zero‑trust networking – combining reverse proxy ACLs with mutual TLS and service identity verification.

Understanding these trends helps you design a reverse proxy that not only routes traffic but also acts as a security gatekeeper for your entire homelab ecosystem.

PREREQUISITES

Before you begin the analysis, ensure your environment meets the following requirements:

ComponentMinimum VersionReason
Docker Engine20.10+Required for container runtime and image pulls.
Docker Compose2.4+Simplifies multi‑container orchestration.
Nginx Proxy Manager2.9+Provides the logging hooks used in the analysis.
Ubuntu/Debian22.04 LTSTested OS for the provided commands.
OpenSSH8.9+Needed for secure remote access to the host.
jq1.6+Used in log parsing scripts.
awk, grep, sedCore utilitiesEssential for log processing pipelines.

Network and Security Considerations

  • Public IP allocation – Ensure you have a static public IPv4 address or a stable dynamic DNS record.
  • Port exposure – Only expose ports 80 and 443 to the internet; all other services should remain bound to localhost or an internal network.
  • Firewall – Use ufw or iptables to restrict inbound traffic to the proxy ports and block obvious scanning ranges (e.g., known cloud provider IP blocks).

User Permissions

All commands that modify Docker containers or edit configuration files must be executed with a user that belongs to the docker group or via sudo.

Pre‑Installation Checklist

  1. Verify Docker is installed and functional (docker version).
  2. Pull the latest Nginx Proxy Manager image (docker pull jc21/nginx-proxy-manager).
  3. Create a dedicated directory for persistent storage (/opt/npm-data).
  4. Ensure your domain’s DNS records point to the public IP (A record).
  5. Open ports 80 and 443 in your firewall and confirm they are reachable (nc -zv your.domain.com 80).

INSTALLATION & SETUP

Below is a step‑by‑step guide to deploy Nginx Proxy Manager, configure logging, and prepare the environment for traffic analysis.

1. Pull and Run the Proxy Manager Container

1
2
3
4
5
6
7
8
9
docker run -d \
  --name npm \
  --restart unless-stopped \
  -p 80:80 \
  -p 443:443 \
  -p 81:81 \
  -v /opt/npm-data:/data \
  -v /opt/npm-data/logs:/logs \
  jc21/nginx-proxy-manager:latest

Explanation of flags

  • -d – Run container in detached mode.
  • --name npm – Assign a predictable container name for later reference ($CONTAINER_NAMES).
  • -p 80:80 and -p 443:443 – Map public HTTP and HTTPS ports to the container.
  • -p 81:81 – Expose the admin UI on an alternate port (optional, should be firewalled).
  • -v /opt/npm-data:/data – Persist configuration and database files.
  • -v /opt/npm-data/logs:/logs – Mount a host directory for log collection.

2. Access the Admin UI

Open a browser and navigate to http://your.domain.com:81. The default admin credentials are admin@admin.com / changeme. Immediately change the password and enable two‑factor authentication if possible.

3. Configure Logging

Nginx Proxy Manager writes access logs to /logs/access.log. To ensure logs are captured in a structured format suitable for parsing, enable JSON output via environment variable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# docker-compose.yml snippet
services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    environment:
      - LOG_LEVEL=info
      - LOG_JSON=true
    volumes:
      - /opt/npm-data:/data
      - /opt/npm-data/logs:/logs
    ports:
      - "80:80"
      - "443:443"
      - "81:81"

After updating the compose file, restart the container:

1
docker compose up -d npm

4. Verify Log Rotation

Create a simple logrotate configuration to prevent unbounded log growth:

1
2
3
4
5
6
7
8
9
10
cat <<'EOF' > /etc/logrotate.d/nginx-proxy-manager
/opt/npm-data/logs/*.log {
    daily
    rotate 14
    compress
    missingok
    notifempty
    create 0640 1000 1000
}
EOF

Reload logrotate:

1
logrotate -f /etc/logrotate.d/nginx-proxy-manager

5. Harvest Logs for Analysis

The raw access logs are stored as newline‑delimited JSON objects. To extract a 30‑day window, use the following command:

1
docker exec $CONTAINER_ID sh -c "jq -r 'select(.time // empty | strptime(\"%Y-%m-%dT%H:%M:%S.%fZ\") | now - .time < 2592000)' /logs/access.log > /opt/npm-data/logs/30day_access.json"

Key points

  • $CONTAINER_ID refers to the container ID of the running Nginx Proxy Manager instance.
  • The jq filter selects records whose timestamp falls within the last 2592000 seconds (30 days).
  • Output is saved to a dedicated file for downstream processing.

6. Install Supporting Tooling

1
apt-get update && apt-get install -y jq awk grep sed

These utilities provide the foundation for the log‑parsing pipeline described later.

CONFIGURATION & OPTIMIZATION

With the reverse proxy operational and logs being collected, the next phase focuses on shaping the proxy’s behavior to surface the information you need while minimizing noise.

1. Enable Detailed Access Logging

In the Nginx Proxy Manager UI, navigate to Settings → Logging and ensure the following options are checked:

  • Log Request Headers – captures client‑provided headers such as User-Agent and Referer.
  • Log Response Headers – records server‑generated headers for later analysis.
  • Log Request Body – optional, useful for inspecting POST payloads that may contain exploit attempts.

Enable these settings and apply the changes.

2. Implement Rate Limiting

Rate limiting helps throttle abusive clients that generate a high volume of requests in a short period. Add a global rule that limits requests to 10 per second per IP:

1
2
3
4
5
6
7
8
# In the Nginx Proxy Manager configuration file (e.g., /data/config.json)
{
  "rate_limit": {
    "limit": 10,
    "burst": 20,
    "period": 1
  }
}

After editing, restart the container to apply:

1
docker restart $CONTAINER_ID

3. Deploy Custom WAF Rules

Nginx Proxy Manager supports custom Nginx directives via the Custom Nginx Configuration section. Below is a set of rules that block common attack patterns:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Block SQL injection attempts
if ($args ~* "union select") {
    return 403;
}

# Block path traversal
if ($request_uri ~* "\.\.") {
    return 403;
}

# Block known scanning tools
if ($http_user_agent ~* "(nmap|nikto|sqlmap|acunetix|dirbuster)") {
    return 403;
}

Insert the above snippet into the Custom Nginx Configuration field and save.

4. Harden TLS Settings

Modern TLS configurations mitigate downgrade attacks and enforce strong cipher suites. Add the following to the SSL/TLS Settings for each domain:

1
2
ssl_protocols TLSv1.2 TLSv1.3;
ssl
This post is licensed under CC BY 4.0 by the author.