用nginx实现微信公众号相关的反向代理。

将原网站(微信业务)直接通过前端代理服务器(A)反向代理到后端机器(B)上会报一个 xxxx not in whitelist hint 的错误。
因为原来白名单IP为 A服务器IP,由于业务上需要修改公众号太多,于是想不修改公众号的情况下是否也可以实现。

最后经人点拨后实现了,感谢@Wendal~兽

“要么改源码,修改api url,变成a服务器的域名
要么改dns,设置为a机器的ip
然后a服务器的nginx再反代出去”

我采用的反代方式:
A(test.com)->B(127.0.0.1)
B(修改host)->A(反向代理指向微信的api)

server{
    listen 443;
    server_name api.weixin.qq.com;
    access_log logs/weixin.qq.access.log;
    error_log logs/weixin.qq.error.log;
    ssl on;
    ssl_certificate /usr/local/nginx/conf/server.crt;
    ssl_certificate_key /usr/local/nginx/conf/server.nopass.key;
    location / {
        index index.html;
        proxy_pass https://api.weixin.qq.com;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-proto https;
    }

}

补充:
由于*.weixin.qq.com的域名很多,我就想能不能像泛解析那样用一个正则或通配符创建一个站点满足所有需求?答案是可以的,见配置

server {
    listen  80;
    server_name  ~^(?<subdomain>.+).weixin.qq.com$;
    location / {
        index index.html;
        proxy_pass http://$subdomain.weixin.qq.com;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-proto https;
    }
}
server{
    listen 443;
    server_name ~^(?<subdomain>.+).weixin.qq.com;
    access_log logs/x.weixin.qq.access.log;
    error_log logs/x.weixin.qq.error.log;
    ssl on;
    ssl_certificate /usr/local/nginx/conf/cert/mp.weixin.qq.com/server.crt;
    ssl_certificate_key /usr/local/nginx/conf/cert/mp.weixin.qq.com/server.nopass.key;
    location / {
        index index.html;
        proxy_pass https://$subdomain.weixin.qq.com;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-proto https;
        proxy_buffers 8 512k;
        proxy_buffer_size 2024k;
        proxy_busy_buffers_size 2024k;
        proxy_read_timeout 3000;
    }

}

需要注意的是,可能你会遇到 502的问题,我遇到这个问题的时查看了站点错误日志:

2019/07/11 15:51:33 [error] 21964#0: *689699 no resolver defined to resolve demo.open.weixin.qq.com, client: x.x.x.x, server: ~^(?<subdomain>.+).weixin.qq.com, request: "GET /jssdk/images/p2166127561.jpg HTTP/1.1", host: "demo.open.weixin.qq.com"

搜了下解决办法,也很简单:
在nginx.conf的http 中加上:resolver 8.8.8.8; 然后reload即可。

还有backend 需要修改/etc/hosts的域名有:
x.x.x.x api.weixin.qq.com
x.x.x.x file.api.weixin.qq.com
x.x.x.x mp.weixin.qq.com
x.x.x.x open.weixin.qq.com
x.x.x.x open.work.weixin.qq.com
x.x.x.x demo.open.weixin.qq.com
x.x.x.x qyapi.weixin.qq.com
#x.x.x.x pay.weixin.qq.com
#x.x.x.x api.mch.weixin.qq.com
#x.x.x.x fraud.mch.weixin.qq.com

===========分割线==========

继续补充:
在后来的使用中发现用微信企业打款时要报“证书错误”,经过各种排查摸索(尝试更换证书、修改spbill_create_ip 的IP、不使用nginx获取真实ip 都不行),最后尝试直接从B机去访问 api.mch.weixin.qq.com ,居然可以(企业打款中白名单中包含B机的IP)。当然这算哪门子事,如果不反向代理微信,随着增加后端机器,那么IP白名单也就要增加,又要修改各公众号的设置,解决不了根本的问题。(由于开通企业打款的客户就几家,暂时不管了)

参考:https://www.cnblogs.com/jingxiaoniu/p/6745254.html

posted @ 2019-07-10 07:31 ikoDotA 阅读(...) 评论(...) 编辑 收藏
ikoDotA's 新浪微博