0

I have an Nginx reverse proxy that sits in front of an Apache container.

What I'm trying to do is just a simple no-www to www redirect in the htaccess file on the Apache side.

Here's the related .htaccess code in Apache:

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Here's the .conf file from Nginx reverse proxy. Note some code are generated by certbot for SSL.

server {
    server_name example.com www.example.com;
    location / {
        proxy_pass http://1.2.3.4:1234;
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot    

    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 404; # managed by Certbot
}

My issue is, for some reason, calling example.com or www.example.com in the browser results in www.www.example.com (double www).

Seems that this condition in htaccess is not being executed properly: RewriteCond %{HTTP_HOST} !^www\. [NC]

Any ideas?

IMB
  • 15,163
  • 19
  • 82
  • 140
  • As you are ORing the two RewriteCond statements, it only requires the first to be true for `www.` to be prefixed to the HTTP_HOST value. The HTTP_HOST value is obviously received correctly by Apache, otherwise you would not be getting `www.www.`. – Richard Smith Dec 02 '22 at 10:30
  • @RichardSmith In this case Apache wil always receive an HTTPS request because Nginx forces HTTPS first before it reaches Apache, therefore `RewriteCond %{HTTPS} off` is never true, right? – IMB Dec 02 '22 at 10:33
  • Nginx is talking to Apache using HTTP (see your `proxy_pass`). Nginx sets the `X-Forwarded-Proto` header, but does Apache use that when setting its HTTPS variable? – Richard Smith Dec 02 '22 at 10:45
  • @RichardSmith I actually do not know how Apache is getting it or how to send it properly. I've tried suggestions [here](https://stackoverflow.com/a/16042648/748789) but no success. If I use `https` in `proxy_pass` I get `502 Bad Gateway` from Nginx. – IMB Dec 02 '22 at 11:22
  • If you are using Nginx to terminate HTTPS, you do not need the `RewriteCond %{HTTPS} off [OR]` condition and can remove it (and the problem). – Richard Smith Dec 02 '22 at 11:43
  • @RichardSmith that is correct but it got me intrigued as to why Apache is not reading it, so it has become "for science" purposes now. – IMB Dec 02 '22 at 11:44

0 Answers0