nginx 反向代理 apache url 静默重写和 https 重写

nginx 反向代理 apache url 静默重写和 https 重写

我正在运行 nginx + apache 配置。我对 nginx 非常非常陌生,我花了相当多的时间来学习它。

首先,我想进行基本的重写。根据我的理解,当 nginx 用作反向代理时 - apache 中的 .htaccess 应该仍然有效。遗憾的是 - 我的理解并不完全正确 - 有些部分有效,而其他部分似乎无效。

所以我尝试用 .htaccess 做了基本的重写

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

我发现在 .htaccess 中使用 [P] 标志而不是正常的重写会导致无法找到 /index.html 的错误(整个网站上没有任何 index.html,所以显然找不到它)。

我也尝试使用 [L] 标志,但它并没有像我期望的那样默默转发,而是进行了重定向,以便用户可以在地址栏中看到 /fp/——这不是我想要的结果。

因此 - 我将重定向移至 nginx 配置。这似乎运行正常。

我所做的 nginx 重定向非常简单,使用 if 语句

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

此重定向仅重定向至 /,而不重定向至 /index.php 或任何其他文件。

https://接下来我有一个名为 /login.php 的文件。如果用户通过以下方式访问,我想将用户转发到http://

所以我尝试使用 Apache 方案检查,$_SERVER['REQUEST_SCHEME'];问题是 - 它返回的http是它https://还是http://

login.php 位于 /

那么对于初学者来说,如何才能让 http 仅在 login.php 页面上重定向到 https。

我还应该注意,我尝试使用 .htaccess 从 http 重定向到 https,但由于服务器返回的是 http 而不是 https,因此导致了无限循环。

除此之外,为什么 apache .htaccess [P] 标志会导致搜索 index.html 以及为什么 silect 重定向会突然变得公开?

如果我需要展示我的配置 - 请告诉我哪些:)

更新以显示配置

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*;
}

配置文件

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']; ?>

返回:http

https://theurl.com/test.php

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

返回:http

答案1

那么首先,我如何才能让 http 仅在 login.php 页面上重定向到 https

关键是 http 和 https 的服务器块不同。如果您从单个服务器块提供服务,那么您的控制会受到更多限制。类似这样的方法应该可行。

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
}

从更大角度来看,您应该通过 https 为整个网站提供服务,以避免这些问题,除非有非常好的理由必须使用 http。您的应用程序可能必须意识到网站在 http 和 https 之间被分段,以支持此设置。

此外,通常不需要将 Nginx 和 Apache 一起使用。Nginx 可以完成 Apache 可以完成的大部分工作,同时使用两者会增加复杂性。

当你需要在 Nginx 中使用“if”时,你应该考虑Nginx“if is evil”文章。我确实使用 if,但仅用于设置控制缓存指令的变量,而不是用于任何关键或流程相关的变量。您应该尽可能避免使用“if”。

更新

本文向您展示如何将协议等标头传递到下一层,以便它知道原始协议。您最好完全摆脱 Apache,让 Nginx 使用 php-fpm 调用 PHP。

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;
}

删除 If 重定向

相反

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

您可以尝试类似这样的操作。等号运算符是精确匹配运算符。这将提供更好的性能(略微)和更可靠的操作。

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

location / {
  // etc
}

我自己没有使用过重写,所以我不知道这是否是完成你尝试做的事情的最佳方法。

相关内容