家庭数据中心系列 应用发布之反向代理篇(下)
本文最后更新于 375 天前,其中的信息可能已经有所发展或是发生改变,如有失效可到评论区留言。

在上篇中,我们介绍了不同情况下的家庭宽带分别应该采用哪种方式来部署反向代理,那在下篇中,我们会介绍反向代理工作的原理和配置要点。

反向代理要能够正常工作,需要解决2个问题:应用与域名的绑定以及传递参数的正确配置。

1、合理规划应用对应的三级域名和解析结果

因为反向代理工作的基本原理就是根据http request里的host字段内容来甄别请求需要访问的目标应用到底是哪一个,所以第一步就需要为不同应用分配对应的三级域名(例如二级域名是example.com,则app1对应app1.example.com,app2对应app2.example.com,依次类推),且各个三级域名解析出的地址需要对应到到家庭宽带的公网IPv4地址(如果是多拨,则需要按照规划对应到不同WAN口的IPv4公网地址上,对外发布的port挑一个自己喜欢的就成,腾讯和阿里云CDN都能够自定义源站的port)。


为什么不谈IPv6?在上篇中我们也提到过,有IPv6公网地址要简单得多,所有应用对应的三级域名都解析到反向代理设备的公网IPv6上即可。IPv4环境更复杂,我们就以IPv4地址举例。另外,如果是上篇中提到的家庭宽带没有公网地址,则只能使用cloudflare的tunnel方式进行部署,其实访问速度感觉和cloudflare有公网地址的部署方式也差不多,甚至可能更快(因为通过公网更容易被针对和负优化)。


这一步的达成需要每个应用对应的三级域名都能实现动态解析到家庭宽带的公网IP上,动态域名客户端推荐使用爱快内置的,其支持多个主流域名提供商,且解析的三级域名数量没有限制:

image.png

其他的方式也行,比如梅林软件市场里的动态域名插件DDNS-Go(如果没记错的话~,应该也是支持多个域名提供商),只要支持的记录数量没有限制即可,一个可是远远不够的。

2、传递需要的参数到上游应用服务器

很多应用的server端都需要根据客户端发送过来的请求里的内容进行一些策略上的判断(比如http request里的host,refer,X-Real-IP,X-Forwarded-For等信息),但是在经过反向代理以后,默认情况下反向代理发出的请求不一定会带上这些信息(我们上一篇文章说过,客户端到反向代理以及反向代理到应用是两个完全独立的过程),结果就是无法匹配应用server端的策略而导致访问失败。所以反向代理需要将客户端请求里带来的一些需要的信息插入自己发出的请求中。

这一步的达成只需要根据应用端的实际需要(比如nextcloud和wordpress都要提前在应用里写死访问域名),在反向代理软件里正确配置即可。具体使用什么软件来实现反向代理没有具体要求,大家可以用自己习惯的就成:宝塔Linux面板、1Panel面板、NPM、源码部署的NGINX都可以。

以我的NGINX配置为例简单说明重点参数(这个配置可以放在nginx主配置里,不过为了更有条理,推荐为每个域名创建单独的反向代理配置文件,然后在主配置里引用即可):


#PROXY-START/

location ^~ /
{
    proxy_pass http://192.168.1.1:8080; #指定访问具体应用的协议、IP地址、端口,也称之为上游服务器。
    proxy_set_header Host host:server_port;  #确定反向代理发送请求给应用时候的host字段内容及访问端口

    proxy_set_header X-Real-IP remote_addr; #将变量'remote_addr'的值赋值给X-Real-IP字段
    proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for; #将变量'proxy_add_x_forwarded_for'的值赋值给X-Forwarded-For字段
    proxy_set_header REMOTE-HOST remote_addr; #将变量'remote_addr'的值赋值给REMOTE-HOST字段
    proxy_set_header Upgrade http_upgrade;
    proxy_set_header Connectionconnection_upgrade;
    proxy_http_version 1.1;
    # proxy_hide_header Upgrade;

    add_header X-Cache upstream_cache_status;
    #Set Nginx Cache

    setstatic_filesDpoqv14 0;
    if ( uri ~* "\.(gif|png|jpg|css|js|woff|woff2)" )
    {
        set static_filesDpoqv14 1;
        expires 1m;
    }
    if (static_filesDpoqv14 = 0 )
    {
        add_header Cache-Control no-cache;
    }
}
#PROXY-END/

proxy_set_header Host这个参数重点说明一下,有好几种变量赋值的方式:

1、$host
只传递域名,不带port信息,这种情况适用于反向代理有80和443端口的情况(例如反向代理是建立在云主机上)。因为是众所周知的80和443端口,所以不需要专门说明,这个就叫默契。

2、$host:$server_port
传递客户端请求到达反向代理时候访问的域名以及port信息,这种一般是反向代理对外监听端口非标(不是80和443端口)的情况。默认情况下如果家庭宽带有公网IP地址且直接对外发布的时候都是这种情况。这种情况下需要将反向代理监听端口的信息也告诉给应用(其实这里说法是不准确的,这个监听端口严格意义上来说应该是客户端请求访问的实际端口,而公网IP地址和端口都在路由器上,所以应该是出口路由器上映射的端口,不过我为了方便,就把反向代理监听端口和路由器上映射的端口设置成一样了),这样说的原因是因为有的应用会直接在响应中生成访问链接,这个访问链接如果不带上对外发布的真实端口信息是无法访问的。

3、$host:$proxy_port
传递客户端请求到达反向代理时候的访问的域名以及后端应用的端口(目前没用过,不知道用在什么场景)

4、$http_host
传递客户端请求达到反向代理时候host字段的内容,正常情况下等同于$host:$server_port,不正常情况下host字段为空,则什么都不显示,这个就比较尴尬了,所以一般保险点还是用$host:$server_port


另外,proxy_set_header X-Real-IP $remote_addrproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forproxy_set_header REMOTE-HOST $remote_addr这3个都是为了给后端应用传递客户端的真实访问地址(因为默认情况下应用只能看到反向代理的IP地址),那么这几个的区别在哪里呢?

X-Real-IPREMOTE-HOST这2个在我的配置中是没有区别的,大家可以看到这2个字段的值都是变量$remote_addr赋予的,对应的是客户端请求达到这个反向代理时候的源IP地址。关键在于X-Forwarded-For,其对应的变量$proxy_add_x_forwarded_for,这个变量是由2部分变量组成:$http_x_forwarded_for$remote_addr,他们之间用逗号分开。所以如果经过了多个代理服务器,且每个代理服务器都配置了proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for,那么X-Forwarded-For这个字段里的显示结果就是:代理服务器3 IP,代理服务器2 IP,代理服务器1 IP,客户端真实地址。


最后,其实反向代理的上游服务器也未必就是应用,也有可能是另一个反向代理,例如反向代理形式工作的web应用防火墙,而CDN本质上也是反向代理。由此可见,客户端请求达到真实应用端的时候,可能通过了N层代理,这个更加说明了每层代理正确配置传递参数的重要性。

具体的反向代理配置步骤参看文章:linux面板系列 配置反向代理并使用非443端口进行发布docker系列 使用docker基于NPM搭建自己的反向代理

博客内容均系原创,转载请注明出处!更多博客文章,可以移步至网站地图了解。博客的RSS地址为:https://blog.tangwudi.com/feed,欢迎订阅;如有需要,可以加入Telegram群一起讨论问题。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
       
error:
zh_CN
春节
快乐