nginx ssl 反向代理wordpress重定向错误

623 views
Skip to first unread message

van14...@gmail.com

unread,
Apr 9, 2016, 12:12:47 PM4/9/16
to ustc_lug
假设我在内网A机器上已经成功配置好wordpress, 即通过http:xxx.xxx.xxx.xxx 可以正常访问, 包括登陆后台. 现在想在B机器上使用反向代理访问A. B的配置如下:

server{
  listen 443 ssl;
  server_name a.example.com;
  ssl_certificate fullchain.pem;
  ssl_certificate_key privkey.pem;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;
  ssl_ciphers '****'; /此次省略/
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_stapling on;
  ssl_stapling_verify on;
  add_header Strict-Transport-Security max-age=15768000;
  location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    proxy_pass http://IPofA:8080;
    proxy_read_timeout 90;

    proxy_redirect http://localhost:8080 https://
a.example.com;
    #proxy_redirect off;

  }
  access_log /var/log/nginx/wp.access.log;
  error_log /var/log/nginx/wp.error.log;
}
server{
  listen 80;
  listen [::]:80;
  server_name 
a.example.com;
  return 301 https://$host$request_uri;
}

如果此时, 我在wp后台填写站点为: http://a.example.com; 则css(以http://方式引入)不能正常加载; 而改成https://a.example.com; 则登陆后台说是该服务器正在将此地址的请求循环重定向。问下原因? 如何解决?

Zhang Cheng

unread,
Apr 9, 2016, 12:36:03 PM4/9/16
to USTC LUG

On Sun, Apr 10, 2016 at 12:12 AM, van14...@gmail.com <van14...@gmail.com> wrote:
如果此时, 我在wp后台填写站点为: http://a.example.com; 则css(以http://方式引入)不能正常加载; 而改成https://a.example.com; 则登陆后台说是该服务器正在将此地址的请求循环重定向。问下原因? 如何解决?

​循环重定向,应该是因为wp认为这个请求是来自http的,所以尝试重定向到https,导致了循环。

​看起来你的结构是 browser --> nginx --> nginx --> php,即中间还有一个nginx,你需要在中间这个nginx上加上点配置,告诉php当前的请求是来自https的。

如果你第二个nginx是通过fastcgi来调用php的话,加上这个配置试试:

fastcgi_param  HTTPS on;


​PS,我不用wordpress,刚才下载了wp的代码搜索了一下,在./wordpress/wp-includes/functions.php中有如下代码:

/**
 * Determine if SSL is used.
 *
 * @since 2.6.0
 *
 * @return bool True if SSL, false if not used.
 */
function is_ssl() {
if ( isset($_SERVER['HTTPS']) ) {
if ( 'on' == strtolower($_SERVER['HTTPS']) )
return true;
if ( '1' == $_SERVER['HTTPS'] )
return true;
} elseif ( isset($_SERVER['SERVER_PORT']) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
return true;
}
return false;
}



--
Cheng,
Best Regards

Aron Xu

unread,
Apr 9, 2016, 12:40:10 PM4/9/16
to ustc...@googlegroups.com
在wp-config.php里加:

if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS'] = 'on';
> --
> -- 来自USTC LUG
> 请使用gmail订阅,不要灌水。
> 更多信息more info:http://groups.google.com/group/ustc_lug?hl=en?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "USTC_LUG" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to ustc_lug+u...@googlegroups.com.
> To post to this group, send email to ustc...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Regards,
Aron Xu

Hugo

unread,
Apr 9, 2016, 1:44:10 PM4/9/16
to ustc...@googlegroups.com
wp 后台填 https://a.example.com,至于 CSS 新地址登陆后重装一下主题应该就好了。。。

在 16/4/10 上午12:12, van14...@gmail.com 写道:

Abel Van

unread,
Apr 10, 2016, 3:33:48 AM4/10/16
to USTC_LUG
我的架构的确如你说说, 非常有效啊. 我就加了一句

fastcgi_param  HTTPS on;

当然此时我也在内网机器上监听了ssl端口:
listen 443;


然后更改了后台地址, 暂时登陆不上去故用functions.php

update_option( 'siteurl', 'https://a.example.com' );
update_option
( 'home', 'https://a.example.com' );

然后就一切正常了, 用https://a.example.com访问主页/后台都正常了.

话说, 我看到内网机器实际上已经有了这个:

fastcgi_param  HTTPS              $https if_not_empty;

照理说似乎应该没有问题才是啊? 问题可能就出在第一个nginx转发https的请求却被第二个nginx误认为是http? 但是我已经写明了是
proxy_pass https://IPofA:8080;



在 2016年4月10日星期日 UTC+8上午12:36:03,Zhang Cheng写道:

Zhang Cheng

unread,
Apr 10, 2016, 3:46:02 AM4/10/16
to USTC LUG
2016-04-10 15:33 GMT+08:00 Abel Van <van14...@gmail.com>:
我的架构的确如你说说, 非常有效啊. 我就加了一句

fastcgi_param  HTTPS on;

当然此时我也在内网机器上监听了ssl端口:
listen 443;


然后更改了后台地址, 暂时登陆不上去故用functions.php

update_option( 'siteurl', 'https://a.example.com' );
update_option
( 'home', 'https://a.example.com' );

然后就一切正常了, 用https://a.example.com访问主页/后台都正常了.

话说, 我看到内网机器实际上已经有了这个:

fastcgi_param  HTTPS              $https if_not_empty;


​第一个nginx收到了https请求,在第一个nginx中$https的值为on,但是第二个nginx收到的请求是来自8080端口的http请求,所以第二个nginx中$https的值为空。

fastcgi_param HTTPS $https if_not_empty;

​在第二个nginx中,由于$https值为空,所以上述配置并没有给后端的fastcgi传递HTTPS这个环境变量。

我给你的配置:fastcgi_param HTTPS on,是强制给fastcgi传递HTTPS=on这个环境变量。
 
照理说似乎应该没有问题才是啊? 问题可能就出在第一个nginx转发https的请求却被第二个nginx误认为是http? 

​第二个nginx为什么会知道前面的nginx收到的是https的请求呢?虽然第一个nginx在proxy时加上了 X-Forward-Proto 这个Header,但是一般后端的nginx是不会认这个header的,毕竟用户也可以自己发送这个header。

除此之外,第二个nginx也并不知道第一个nginx跟自己是一家人,也可能它是别家的nginx呢?所以,每个nginx只管自己的事情,不会管别人的事情。

你内网的nginx不需要监听443端口,监听了这个端口、开启了ssl,并不会改变$https这个变量的值。这个变量是per request的,根据每个请求的实际情况赋值的。



--
Cheng,
Best Regards

van14...@gmail.com

unread,
Apr 10, 2016, 3:50:50 AM4/10/16
to ustc_lug
嗯, 大致理解了. 话说如果有好几个app都在内网, 目前看来最方便是每个app开个端口. 但如果我想反向代理到子目录, 应该怎么配置呢? 内网假设就只有一台server, 但是假设通过http://IPofA/appname可以正常访问. 然后我想pass_proxy到该子目录好像不行啊.
 
发件人: Zhang Cheng
发送时间: 2016-04-10 15:46
收件人: USTC LUG
主题: Re: [USTC-LUG] nginx ssl 反向代理wordpress重定向错误
--
-- 来自USTC LUG
请使用gmail订阅,不要灌水。
更多信息more info:http://groups.google.com/group/ustc_lug?hl=en?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "USTC_LUG" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ustc_lug/stdn8ootM0U/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ustc_lug+u...@googlegroups.com.

Zhang Cheng

unread,
Apr 10, 2016, 3:55:23 AM4/10/16
to USTC LUG

2016-04-10 15:50 GMT+08:00 van14...@gmail.com <van14...@gmail.com>:
嗯, 大致理解了. 话说如果有好几个app都在内网, 目前看来最方便是每个app开个端口. 但如果我想反向代理到子目录, 应该怎么配置呢? 内网假设就只有一台server, 但是假设通过http://IPofA/appname可以正常访问. 然后我想pass_proxy到该子目录好像不行啊.

​如果没有什么特殊需求的话,那么其实内网并不需要nginx,最前端的nginx​直接proxy到内网的各个App,例如:

server {
    location /app1/ {
        proxy_pass http://$ip_of_a:$port_of_app1;
    }

   location /app2/ {
        fastcgi_pass http://$ip_of_a:$port_of_app2;
    }

   ...
}

​由于特殊原因,内网必须要​部署一个nginx的话,那么内网的nginx就用上面的配置,而最外面的nginx则直接将所有请求都 

proxy_pass http://$ip_of_a:$port_of_nginx_on_a;



--
Cheng,
Best Regards
Reply all
Reply to author
Forward
0 new messages