0

I have a nginx + apache configuration running. I am VERY VERY new to nginx and I am having quite a time trying to learn it.

First I want to do a basic rewrite. As per my understanding, when nginx is used as a reverse proxy - .htaccess from apache should still work. Sadly - my understanding of it was not exactly correct - some parts work and others don't it seems.

So I tried to do a basic re-write with .htaccess

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?index.* /fp/ [P]

I find that using the [P] flag in .htaccess instead of a normal re-write - results in an error that /index.html can't be found (which there isn't any index.html on the entire site so clearly it can't be found).

I tried using the [L] flag as well, but instead of that silently forwarding as I would expect it instead did a redirect so the user could see /fp/ in the address bar - not the outcome I was looking for.

So - I moved the redirect up to the nginx config. That seemed to work okay.

The nginx redirect I did do was very basic using an if statement

    if ($uri = '/'){
        rewrite / /fp/ break;
    }

This redirect only redirects on / not on /index.php or any other files.

Next I have a file called /login.php. I want to forward a user to https:// if the are accessing via http://

So I tried to do an apache scheme check with $_SERVER['REQUEST_SCHEME']; The problem is - that's returning http whether its https:// or http://

The login.php is in /

So for starters, how can I get the http to redirect to https only on the login.php page.

I should also note I attempted to do a redirect from http to https with .htaccess but as the server is returning http and never https that resulted in an infinite loop.

That aside, why is it that the apache .htaccess [P] flag results in searching for an index.html and why do silect redirects suddenly become public?

If I need to show my configs - please tell me which ones :)

UPDATING TO SHOW CONFIG

nginx.conf

server {
proxy_pass_request_headers      on;
index index.php;
listen      192.227.210.138:80;
server_name adsactlyhits.com www.adsactlyhits.com;
error_log  /var/log/apache2/domains/adsactlyhits.com.error.log error;

location / {
    if ($uri = '/'){
        rewrite / /fp/ break;
    }
    proxy_pass      http://192.227.210.138:8080;
    location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
        root           /home/adsactly/web/adsactlyhits.com/public_html;
        access_log     /var/log/apache2/domains/adsactlyhits.com.log combined;
        access_log     /var/log/apache2/domains/adsactlyhits.com.bytes bytes;
        expires        max;
        try_files      $uri @fallback;
    }
}

location /error/ {
    alias   /home/adsactly/web/adsactlyhits.com/document_errors/;
}

location @fallback {
    proxy_pass      http://192.227.210.138:8080;
}
location ~ /\.svn/  {return 404;}
location ~ /\.git/  {return 404;}
location ~ /\.hg/   {return 404;}
location ~ /\.bzr/  {return 404;}

include /home/adsactly/conf/web/nginx.adsactlyhits.com.conf*;
}

snginx.conf

server {
listen      192.227.210.138:443;
server_name adsactlyhits.com www.adsactlyhits.com;
ssl         on;
ssl_certificate      /home/adsactly/conf/web/ssl.adsactlyhits.com.pem;
ssl_certificate_key  /home/adsactly/conf/web/ssl.adsactlyhits.com.key;
error_log  /var/log/apache2/domains/adsactlyhits.com.error.log error;

location / {
    if ($uri = '/'){
        rewrite / /fp/ break;
    }

    proxy_pass      http://192.227.210.138:8080;
    proxy_cache cache;
    proxy_cache_valid 15m;
    proxy_cache_valid 404 1m;
    proxy_no_cache $no_cache;
    proxy_cache_bypass $no_cache;
    proxy_cache_bypass $cookie_session $http_x_update;

    location ~* ^.+\.(jpeg|jpg|png|gif|bmp|ico|svg|tif|tiff|css|js|ttf|otf|webp|woff|txt|csv|rtf|doc|docx|xls|xlsx|ppt|pptx|odf|odp|ods|odt|pdf|psd|ai|eot|eps|ps|zip|tar|tgz|gz|rar|bz2|7z|aac|m4a|mp3|mp4|ogg|wav|wma|3gp|avi|flv|m4v|mkv|mov|mpeg|mpg|wmv|exe|iso|dmg|swf)$ {
        proxy_cache    off;
        root           /home/adsactly/web/adsactlyhits.com/public_html;
        access_log     /var/log/apache2/domains/adsactlyhits.com.log combined;
        access_log     /var/log/apache2/domains/adsactlyhits.com.bytes bytes;
        expires        max;
        try_files      $uri @fallback;
    }
}

location /error/ {
    alias   /home/adsactly/web/adsactlyhits.com/document_errors/;
}

location @fallback {
    proxy_pass      http://192.227.210.138:8080;
}

location ~ /\.ht    {return 404;}
location ~ /\.svn/  {return 404;}
location ~ /\.git/  {return 404;}
location ~ /\.hg/   {return 404;}
location ~ /\.bzr/  {return 404;}

include /home/adsactly/conf/web/nginx.adsactlyhits.com.conf*;
}

http://theurl.com/test.php

<?php echo $_SERVER['REQUEST_SCHEME']; ?>

returns: http

https://theurl.com/test.php

<?php echo $_SERVER['REQUEST_SCHEME']; ?>

returns: http

Bruce
  • 103
  • 1
  • 5
  • You've asked three very similar question within the past few days. You've gotten some answers. Your questions are generally not well written, they don't state the high level problem and they're not particularly clear. I suggest you need to hire a consultant. – Tim May 02 '17 at 01:00
  • Hey Tim, first, that was a bit harsh to tell someone trying to learn. I'd advise you not become a teacher - scholls don't take kindly to teachers telling students to give up and hire someone to do it for them. That asside I am used to stackexchange and generally when questions are different, even when related, you ask a new question. You'll note not one of my other questions was about infinite loops and https redirects. – Bruce May 02 '17 at 01:03
  • 1
    Server Fault is a site to help experienced ICT professionals solve difficult problems, rather than a site to teach the basics. I suggest that you need to read some documentation, go with some tutorials, or in some way upskill, rather than asking a series of questions. You haven't given big picture either - using Nginx and Apache together is often (but not always) a sign of an architecture that hasn't been well considered. If you gave better background and asked shorter, more precise questions you might get better answers. – Tim May 02 '17 at 01:12
  • Sadly I think youre actually being serious when you say that. You talk to me as if I started using a computer yesterday because I am having trouble with nginx configs after 15+ years of apache. You talk of if this being only for experienced ICT professions to solve hard tasks... and ignore the sidebar of questions about apache rewrites to Nginx, apache mod-rewrite to nginx rewrte, Migrating apache rewrites to Nginx, nginx rewrite rules, Using nginx as a reverse proxt proxy for php site using Apache with URL rewriting - so if this place is for difficult problems like these Im in good company. – Bruce May 02 '17 at 01:22
  • Agreed with @Tim. My first question when seeing this was: why in the world is he complicating things with two web servers? – EEAA May 02 '17 at 01:23
  • Additionally, I'll agree on another point. Your questions could use more focus and clarity. Omit all extraneous details, focus on a clear problem statement, including code snippets and examples where necessary. – EEAA May 02 '17 at 01:32
  • Simplify things for yourself. Ditch Apache. Or ditch nginx. Choose one. There's no need for two in your situation. – EEAA May 02 '17 at 01:33
  • Im not sure how three questions about nginx rewrites would lead anyone to assume they know what the situation is. Since you seem intrigued the answer is - I am the developer of a open source marketing platform and social network - and not everyone who downloads the script has access to cdn's. So a load balance between nginx and apache helps a lot when serving up lots of photo and video content mixed with php content and various other things. Its a huge load on apache. – Bruce May 02 '17 at 01:46
  • Are you using Nginx as a load balancer or as a reverse proxy? Huge load can be reduced by using a CDN (which are really cheap to free now, eg CloudFlare or CloudFront) and also by caching anonymous requests. Alternately just use AWS S3 to host and serve static resources from a subdomain. – Tim May 02 '17 at 01:50
  • If you are only running Apache to serve PHP stuff, then your best option is to run PHP via the PHP-FPM daemon and tell nginx to use FastCGI to send the requests to PHP. This is faster than having Apache serve PHP stuff, and will also remove the useless complexity of the setup. – Tero Kilkanen May 02 '17 at 11:26

1 Answers1

1

So for starters, how can I get the http to redirect to https only on the login.php page

The key is different server blocks for http and https. If you serve from a single server block you have more limited control. Something like this should work.

server {
  server_name example.com;
  listen 80; 

  location = login.php {
    return 302 https://example.com/login.php;
  }
}

server {
  server_name example.com;
  listen 443 ssl;

  # define any locations required
}

Bigger picture, you should just serve your entire site over https to avoid these problems, unless there's a very good reason you must use http. Your application might have to be aware of the site being segmented across http and https to support this setup.

Also, Nginx and Apache together is usually unnecessary. Nginx can do most things Apache can do, and using both adds to complexity.

Any time you find yourself needing to use "if" in Nginx you should think about the Nginx "if is evil" article. I do use if, but only to set variables for control caching directives, not for anything critical or flow related. You should avoid using "if" wherever possible.

Update

This article shows you how to pass headers such as protocol on to the next layer so it knows the original protocol. You'd be better off getting rid of Apache entirely and having Nginx call PHP using php-fpm.

location / {
  proxy_set_header HOST $host;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  proxy_pass http://example.com/new/prefix;
}

Removing that If redirect

Instead of this

location / {
  if ($uri = '/'){
    rewrite / /fp/ break;
  }
  // etc
}

You could try something like this. The equals operator is an exact match operator. This will give better performance (slightly) and more reliable operation.

location = / {
    rewrite / /fp/ break;
}

location / {
  // etc
}

I haven't used rewrite myself so I don't know if that's the best way to do whatever it is you're trying to do.

Tim
  • 31,888
  • 7
  • 52
  • 78
  • My blocks are separately set - yet still $_SERVER['REQUEST_SCHEME'] always shows http. The address bar shows https. The address bar shows it as secure - so clearly ssl is working. Its just not being handed to the variable. – Bruce May 02 '17 at 01:27
  • You haven't given enough information to help solve that additional problem. Is that PHP code? Is Nginx proxying to Apache? If so how and using what protocol? How is Apache running PHP? Proxies often set up headers to pass that information to the next layer in the stack. Please edit your question to remove superfluous information and add relevant information such as full Nginx configuration (it's usually compact) and either full or relevant parts Apache configuration. – Tim May 02 '17 at 01:32
  • 1
    @Bruce I've updated my answer based on your edit. – Tim May 02 '17 at 01:51
  • I will be sitting down to read that article and see what I can work out after my dinner is done ;) – Bruce May 02 '17 at 01:52