*Thinking...*

> **Examining User Needs**
> 
> I'm focused on the user's ultimate aim: securing their Nginx web server against DDoS threats by leveraging Cloudflare. Pinpointing this goal allows me to properly start mapping out the process, ensuring the guide directly addresses the user's specific need.
> 
> 
> **Analyzing Cloudflare's Role**
> 
> I'm now zeroing in on Cloudflare's core function: its reverse proxy setup. Understanding that DNS directs traffic through their edge servers is critical. This helps establish the foundation for explaining how Cloudflare intercepts and filters traffic, a core concept for the user's ultimate goal.
> 
> 
Connecting an Nginx server to Cloudflare is one of the most effective ways to mitigate Distributed Denial of Service (DDoS) attacks. Cloudflare acts as a reverse proxy, sitting between your visitors and your origin server. It filters out malicious traffic before it ever reaches your infrastructure.

Here is a comprehensive, step-by-step guide on how to set this up, including best practices to ensure attackers cannot bypass Cloudflare to hit your server directly.

---

### Phase 1: Add Your Site to Cloudflare

Before configuring Nginx, you must route your domain's traffic through Cloudflare.

1.  **Create an Account:** Go to [Cloudflare.com](https://www.cloudflare.com/) and sign up.
2.  **Add Site:** Enter your domain name (e.g., `example.com`) and click **Add Site**.
3.  **Select Plan:** Choose the Free plan (sufficient for basic DDoS protection) or a paid tier.
4.  **Review DNS Records:** Cloudflare will scan your existing DNS records. Ensure your `A` record points to your Nginx server's public IP address.
    *   **Crucial Step:** Make sure the "Proxy Status" toggle is set to **Proxied** (the Orange Cloud icon). This masks your real IP address.
5.  **Change Nameservers:** Cloudflare will provide two nameservers (e.g., `bob.ns.cloudflare.com`). Go to your Domain Registrar (GoDaddy, Namecheap, etc.) and replace your current nameservers with the ones provided by Cloudflare.
6.  **Wait for Propagation:** This can take anywhere from a few minutes to 24 hours.

---

### Phase 2: Configure Nginx to Restore Real Visitor IPs

By default, when traffic passes through Cloudflare, Nginx sees all requests coming from Cloudflare's IP addresses, not the actual visitor's IP. This is problematic for logging and security blocking. You need to configure Nginx to read the `CF-Connecting-IP` header.

1.  **Open your Nginx configuration file:**
    Usually located at `/etc/nginx/nginx.conf` or `/etc/nginx/conf.d/default.conf`.

2.  **Add Cloudflare IP Ranges:**
    You must tell Nginx to trust Cloudflare's IPs and extract the real IP from the headers. Add the following block inside the `http { ... }` block of your `nginx.conf`.

    *Note: Cloudflare IP ranges change occasionally. It is best practice to automate this, but here is the manual configuration.*

    ```nginx
    # /etc/nginx/nginx.conf

    http {
        # ... existing configuration ...

        # Trust Cloudflare IPv4 addresses
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        set_real_ip_from 103.22.200.0/22;
        set_real_ip_from 103.31.4.0/22;
        set_real_ip_from 141.101.64.0/18;
        set_real_ip_from 108.162.192.0/18;
        set_real_ip_from 190.93.240.0/20;
        set_real_ip_from 188.114.96.0/20;
        set_real_ip_from 197.234.240.0/22;
        set_real_ip_from 198.41.128.0/17;
        set_real_ip_from 162.158.0.0/15;
        set_real_ip_from 104.16.0.0/13;
        set_real_ip_from 104.24.0.0/14;
        set_real_ip_from 172.64.0.0/13;
        set_real_ip_from 131.0.72.0/22;

        # Trust Cloudflare IPv6 addresses
        set_real_ip_from 2400:cb00::/32;
        set_real_ip_from 2606:4700::/32;
        set_real_ip_from 2803:f800::/32;
        set_real_ip_from 2405:b500::/32;
        set_real_ip_from 2405:8100::/32;
        set_real_ip_from 2a06:98c0::/29;
        set_real_ip_from 2c0f:f248::/32;

        # Define the header that contains the real IP
        real_ip_header CF-Connecting-IP;
    }
    ```

3.  **Test and Reload Nginx:**
    ```bash
    sudo nginx -t
    sudo systemctl reload nginx
    ```

---

### Phase 3: Prevent Direct IP Access (Critical for DDoS Protection)

Even if you use Cloudflare, if an attacker discovers your server's origin IP address (e.g., by scanning the internet), they can bypass Cloudflare and DDoS your server directly. You must configure your firewall to **only accept traffic from Cloudflare IPs**.

#### Option A: Using UFW (Uncomplicated Firewall) - Recommended for Ubuntu/Debian

If you are using UFW, you can run a script to allow only Cloudflare IPs on ports 80 and 443.

1.  **Create a script:**
    ```bash
    nano setup-cloudflare-ufw.sh
    ```

2.  **Paste the following code:**
    ```bash
    #!/bin/bash
    
    # Reset UFW to default deny incoming
    ufw default deny incoming
    ufw default allow outgoing

    # Allow SSH (Change 22 if you use a custom port!)
    ufw allow 22/tcp

    # Download Cloudflare IP lists
    wget https://www.cloudflare.com/ips-v4 -O ips-v4
    wget https://www.cloudflare.com/ips-v6 -O ips-v6

    # Allow Cloudflare IPs on HTTP and HTTPS
    for ip in `cat ips-v4`; do ufw allow from $ip to any port 80 proto tcp; done
    for ip in `cat ips-v4`; do ufw allow from $ip to any port 443 proto tcp; done
    for ip in `cat ips-v6`; do ufw allow from $ip to any port 80 proto tcp; done
    for ip in `cat ips-v6`; do ufw allow from $ip to any port 443 proto tcp; done

    # Enable UFW
    ufw enable
    
    # Cleanup
    rm ips-v4 ips-v6
    ```

3.  **Run the script:**
    ```bash
    chmod +x setup-cloudflare-ufw.sh
    sudo ./setup-cloudflare-ufw.sh
    ```

#### Option B: Using Nginx `allow`/`deny` Rules

If you cannot use a system firewall, you can enforce this within Nginx server blocks.

1.  **Create a configuration file** (e.g., `/etc/nginx/cloudflare-allow.conf`) containing the `allow` directives for the IPs listed in Phase 2, followed by `deny all;`.

    ```nginx
    # /etc/nginx/cloudflare-allow.conf
    allow 173.245.48.0/20;
    allow 103.21.244.0/22;
    # ... add all other IPs from Phase 2 ...
    allow 2c0f:f248::/32;
    
    # Deny everyone else
    deny all;
    ```

2.  **Include this file in your server block:**
    ```nginx
    server {
        listen 80;
        server_name example.com;

        include /etc/nginx/cloudflare-allow.conf;

        location / {
            # ...
        }
    }
    ```

---

### Phase 4: Configure SSL/TLS (Full Encryption)

To ensure the connection is secure from the visitor to Cloudflare AND from Cloudflare to Nginx:

1.  **Cloudflare Settings:**
    *   Go to the **SSL/TLS** tab in the Cloudflare dashboard.
    *   Set the encryption mode to **Full (Strict)**.

2.  **Nginx Settings:**
    *   You must have a valid SSL certificate on your Nginx server.
    *   You can use a free Let's Encrypt certificate, or generate a **Cloudflare Origin CA Certificate** (recommended).
    *   **To use Origin CA:**
        1.  In Cloudflare Dashboard > SSL/TLS > Origin Server > Create Certificate.
        2.  Copy the Certificate and Private Key to your server (e.g., `/etc/ssl/certs/cf_origin.pem` and `/etc/ssl/private/cf_origin.key`).
        3.  Update your Nginx config:

    ```nginx
    server {
        listen 443 ssl;
        server_name example.com;

        ssl_certificate /etc/ssl/certs/cf_origin.pem;
        ssl_certificate_key /etc/ssl/private/cf_origin.key;

        # ... rest of config ...
    }
    ```

### Phase 5: Enable "Under Attack Mode" (Emergency)

If you are actively receiving a DDoS attack despite these settings:

1.  Log in to Cloudflare.
2.  Go to the **Overview** tab (or the Quick Actions menu on the right).
3.  Toggle **"Under Attack Mode"** to **On**.
4.  This presents a JavaScript challenge (captcha style) to every visitor before they can access your site, filtering out automated bot traffic almost entirely.

### Summary of Protection

By following these steps, your architecture changes from:
`Visitor -> Your Server`

To:
`Visitor -> Cloudflare (DDoS Filter) -> Firewall Check -> Nginx`

Attackers trying to hit your IP directly will be dropped by the firewall (Phase 3), and attackers hitting the domain will be absorbed by Cloudflare's massive network capacity.