当前位置: 首页 > news >正文

yii2项目使用frp https2http插件问题

yii2内网项目,使用frp进行内网穿透,使用 https2http插件把内网服务器http流量转成https,会存在一个问题:当使用 $this->redirect(...) 或 $this->goHome() (其实用的也是前者)等重定向时,网址会变成 127.0.0.1,并且协议也从https变成了 http,结果自然是显示找不到

frp client配置类似官网例子:

[common]
server_addr = 47.xx.xxx.xx
server_port = 7900[web_https]
type = https
custom_domains = lab.xxxxx.complugin = https2http
plugin_local_addr = 127.0.0.1:80plugin_crt_path = ./xxxxx.com.pem
plugin_key_path = ./xxxxx.com.key
plugin_host_header_rewrite = 127.0.0.1
plugin_header_X-From-Where = frp

比较通过域名 https://lab.xxxxx.com:8900 访问和通过IP地址访问时 $_SERVER 超级全局变量的结果差异,主要有以下差异:

$_SERVER = Array
([HTTP_X_FROM_WHERE] => frp[HTTP_X_FORWARDED_FOR] => 47.xx.xxx.xx[HTTP_SEC_FETCH_USER] => ?1[HTTP_SEC_FETCH_SITE] => same-origin[HTTP_SEC_FETCH_MODE] => navigate[HTTP_SEC_FETCH_DEST] => document[HTTP_SEC_CH_UA_PLATFORM] => "Linux"[HTTP_SEC_CH_UA_MOBILE] => ?0[HTTP_SEC_CH_UA] => "Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"[HTTP_REFERER] => https://lab.xxxxx.com:8900/[HTTP_HOST] => 127.0.0.1[SERVER_ADDR] => 127.0.0.1[REMOTE_ADDR] => 127.0.0.1
)
$_SERVER = Array
([HTTP_CONNECTION] => keep-alive[HTTP_HOST] => 10.5.10.200[SERVER_ADDR] => 10.5.10.200[REMOTE_ADDR] => 10.5.21.241
)

前一个是frp代理后的结果,后一个是内网直接访问的结果,我们用下图来表示这个过程

用frp内网穿透,是某种形式的反向代理。frp server只起到转发作用,它的配置非常简单,也就指定一下“主控”端口和https监听端口。使用https2http插件时,证书是配置在frp client的(即需要把通常放在公网frp server服务器的证书放一份在frp client,这里也说明frp只适合绝对信得过的client使用该插件)。frp client 上的证书,既用于frp server转发过来的流量的解密(变成http流量转发给nginx),也用于nginx响应的流量的加密(变成https流量转发给frp server,并最终响应给用户)。

我们可以发现,对于nginx来说,它的“客户”是frp client,从IP地址来说,这里的frp client “客户”地址(REMOTE_ADDR)和这里的 server nginx地址(SERVER_ADDR)都是127.0.0.1,相当于“客户”frp client,主机Host也是 127.0.0.1。不过头部中的主机信息 HTTP_HOST 是可以被重写的,对于 http 代理是配置 host_header_rewrite,而对于我们的 https2http插件,需要在 frp client配置 plugin_host_header_rewrite来重写主机Host信息。(frp client中配置 plugin_header_X-xxxx-xxx形式的头部信息,对应了 HTTP_X_xxxx_xxx 形式的头部,只是在我们的情形中,配置 HTTP_HOST、HTTP_X_FORWARDED_HOST、HTTP_PROTO、HTTP_X_FORWARDED_PORT等都不能解决问题)

了解了frp代理的基本原理,我们需要来了解yii2中redirect是怎么进行的。

yii2 redirect 所需的URL信息可以分为两个部分:第一部分是 协议、主机、端口,这部分根据yii\web\Request::getHostInfo() 函数确定;第二部分是相对于文档根的路径,由 Url::to($url)计算得到。我们关心前面的部分,代码如下

    public function getHostInfo(){if ($this->_hostInfo === null) {$secure = $this->getIsSecureConnection();$http = $secure ? 'https' : 'http';if ($this->getSecureForwardedHeaderTrustedPart('host') !== null) {$this->_hostInfo = $http . '://' . $this->getSecureForwardedHeaderTrustedPart('host');} elseif ($this->headers->has('X-Forwarded-Host')) {$this->_hostInfo = $http . '://' . trim(explode(',', $this->headers->get('X-Forwarded-Host'))[0]);} elseif ($this->headers->has('X-Original-Host')) {$this->_hostInfo = $http . '://' . trim(explode(',', $this->headers->get('X-Original-Host'))[0]);} elseif ($this->headers->has('Host')) {$this->_hostInfo = $http . '://' . $this->headers->get('Host');} elseif (isset($_SERVER['SERVER_NAME'])) {$this->_hostInfo = $http . '://' . $_SERVER['SERVER_NAME'];$port = $secure ? $this->getSecurePort() : $this->getPort();if (($port !== 80 && !$secure) || ($port !== 443 && $secure)) {$this->_hostInfo .= ':' . $port;}}}return $this->_hostInfo;}

代码的基本执行路径如下:

解决方案一:

frp client配置中,指定

 plugin_host_header_rewrite = lab.xxxxx.com:8900

这样,frp client 转发到 nginx 时,头部信息 HTTP_HOST 会被改写成设定的值,从而 getHostInfo 执行时会走路径4 (读取头部 Host信息的紫色路径),但仅仅这样是不行的,因为我们需要协议是 https,而 getIsSecureConnection 根据超级全局变量 $_SERVER['HTTPS'] 或者头部信息Forwarded中的proto部分来决定是https还是http(转发时不存在https到http切换会比较简单,因为不需要考虑这一步)。我们一种变通方法是在 yii2 入口文件中,直接指定 $_SERVER['HTTPS']=1(当然,为了兼容内网ip地址访问,可以判断 $_SERVER['SERVER_ADDR']和$_SERVER['REMOTE_ADDR']是否同时为127.0.0.1,因为我们的自我转发中,这是特点)

if ($_SERVER['SERVER_ADDR'] === '127.0.0.1' && $_SERVER['REMOTE_ADDR'] === '127.0.0.1') {  // 是内网穿透自身代理而来的请求$_SERVER['HTTPS'] = '1';  //
}
$application->run();

解决方案二:

frp client配置中,不指定 plugin_host_header_rewrite,但额外指定

plugin_header_Forwarded = for=47.xx.xxx.xx;host=lab.xxxxx.com:8900;proto=https

然后在 yii2 的配置中,对组件 request 添加配置(下面 baseUrl后面部分)

            'baseUrl' => '/admin',  //-----------后端基础目录'trustedHosts' => [  // https://www.yiiframework.com/doc/api/2.0/yii-web-request#$secureHeaders-detail'127.0.0.1/24',  // 从代理转发的,这里设置白名单,这样 $secureHeaders 中的 X-Forwarded-Host 等头部才被允许],'secureHeaders' => [  // frp配置: plugin_header_Forwarded = 'Forwarded',    // 我们添加的 集合了各项 forwarded, 参考 yii\web\Request::getSecureForwardedHeaderParts()'X-Forwarded-For','X-Forwarded-Host','X-Forwarded-Proto','X-Forwarded-Port','Front-End-Https','X-Rewrite-Url','X-Original-Host',],

这样配置后,frp client 转发时会带上头部 Forwarded,并且这个Forwarded头部将被 yii2 允许(转发主机白名单,可接受头部等)。从而,代码执行流程会按前面图中红色路径走。

路径2、3、5也可以考虑,不过和第一个方案一样,需要指定 $_SERVER['HTTPS'] = 1来指定协议,而且端口不一定好处理。

相关文章:

yii2项目使用frp https2http插件问题

yii2内网项目,使用frp进行内网穿透,使用 https2http插件把内网服务器http流量转成https,会存在一个问题:当使用 $this->redirect(...) 或 $this->goHome() (其实用的也是前者)等重定向时,…...

关于 interface{} 会有啥注意事项?下

我们一起来回顾一下上一次说到的 interface{} 可以用来做多态 接口类型分为空接口类型和非空接口类型,他们的底层数据结构不太一样 这里顺便说一下,用来作态需要满足这样的条件: 首先得有父类指针指向子类的对象这个接口还必须是非空接口…...

ansible组件介绍和简单playbook测试

一、ansible inventory 在大规模的配置管理工作中,管理不同业务的机器,机器的信息都存放在ansible的inventory组件里面。在工作中,配置部署针对的主机必须先存放在Inventory里面,然后ansible才能对它进行操作。默认的Ansible的in…...

[数据结构]:13-插入排序(顺序表指针实现形式)(C语言实现)

目录 前言 已完成内容 插入排序实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-PSeqListFunction.cpp 04-SortCommon.cpp 05-SortFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容,除其中使用到C引用外,全为C语言代…...

es6 new Promise

Promise 是一个构造函数,本身身上有 all、reject、resolve 这几个方法,原型上有 then、catch 等方法。所以 Promise new 出来的对象确定就有 then、catch 方法。Promise 的构造函数接收一个参数,是函数,而且传入两个参数&#xff…...

Python爬虫实战:使用Requests和BeautifulSoup爬取网页内容

标题:Python爬虫实战:使用Requests和BeautifulSoup爬取网页内容 Python爬虫技术是网络爬虫中的一种,它可以从互联网上抓取各种网页信息,如文本、图片、视频等,并将它们存储在本地数据库中。Python语言具有简单易学、语…...

质量指标——什么是增量覆盖率?它有啥用途?

目录 引言 什么是增量覆盖率 增量覆盖率有啥用途 1、对不同角色同学的用途 2、对不同规模的业务需求的用途 增量覆盖率的适用人员 增量覆盖率不太适用的情况 引言 有些质量团队,有时会拿「增量覆盖率」做出测试的准出卡点。 但在实际的使用过程中,…...

Hive---拉链表

拉链表 文章目录拉链表定义用途案例全量流程增量流程合并过程第一步第二步第三步案例二(含分区)创建外部表orders增量分区表历史记录表定义 拉链表是一种数据模型,主要是针对数据仓库设计中表存储数据的方式而定义的,顾名思义&am…...

日常文档标题级别规范

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…...

C++学习记录——십이 vector

文章目录1、vector介绍和使用2、vector模拟实现insert和erase和迭代器失效补齐其他函数深浅拷贝难点思考1、vector介绍和使用 vector可以管理任意类型的数组&#xff0c;是一个表示可变大小数组的序列容器。 通过vector文档来看它的使用。 #include <iostream> #inclu…...

Lombok常见用法总结

目录一、下载和安装二、常见注释&#xff08;一&#xff09;Data&#xff08;二&#xff09;Getter和Setter&#xff08;三&#xff09;NonNull和NotNull&#xff08;不常用&#xff09;&#xff08;四&#xff09;ToString&#xff08;不常用&#xff09;&#xff08;五&#…...

【Ajax】异步通信

一.概述 概念&#xff1a;AJAX(Asynchronous JavaScript And XML)&#xff1a;异步的 JavaScript 和 XML 作用&#xff1a; 与服务器进行数据交换&#xff1a;通过AJAX可以给服务器发送请求&#xff0c;并获取服务器响应的数据 使用了AJAX和服务器进行通信&#xff0c;就可以使…...

近红外吸收荧光染料IR-808,IR-808 NH2,IR-808 amine,发射808nm 性质分享

中文名称&#xff1a;IR-808 氨基英文名称&#xff1a;IR-808 NH2&#xff0c;IR-808 amine&#xff0c;IR-808-NH2规格标准&#xff1a;10mg&#xff0c;25mg&#xff0c;50mgCAS&#xff1a;N/A产品描述&#xff1a;IR-808&#xff0c;发射808nm&#xff0c;酯溶性染料修饰氨…...

一图来看你需要拥有那些知识储备

技术实践 数据 关系型数据 MySQLSQLServerOraclePostgrSQLDB2 大数据存储 RedisMemcacheMongoDBHBaseHive 大数据处理 Hadoop 数据报表看板 DataGearGrafanaKibanaMetaBase 消息对列 Rabbit MQRock MQActive MQKafka 大数据搜索 SolrElasticSearchLucenHive 服务提…...

复位和时钟控制(RCC)

目录 复位 系统复位 电源复位 备份区复位 时钟控制 什么是时钟&#xff1f; 时钟来源 二级时钟源: 如何使用CubeMX配置时钟 复位 系统复位 当发生以下任一事件时&#xff0c;产生一个系统复位&#xff1a;1. NRST引脚上的低电平(外部复位) 2. 窗口看门狗计数终止(WWD…...

OpenWrt 专栏介绍00

文章目录OpenWrt 专栏介绍00专栏章节介绍关于联系方式OpenWrt 专栏介绍00 专栏章节介绍 本专栏主要从开发者角度&#xff0c;一步步深入理解OpenWrt开发流程&#xff0c;本专栏包含以下章节&#xff0c;内如如下&#xff1a; 01.OperWrt 环境搭建02.OperWrt 包管理系统03.Op…...

udk开发-稀里糊涂

一、EDK2简介 1.EDK2工作流 ​ 二、EDK2 Packages 1.Packages介绍 ​ EDK2 Packages是一个容器&#xff0c;其中包含一组模块及模块的相关定义。每个Package是一个EDK2单元。 整个Project的源代码可以被分割成不同的Pkg。这样的设计不仅可以降低耦合性&#xff0c;还有利于分…...

Java之内部类

目录 一.内部类 1.什么是内部类 2.内部类存在的原因 3. 内部类的分类 4.内部类的作用 二.成员内部类 1.基本概念 2.成员内部类的注意点 1.成员内部类可以用private方法进行修饰 2.成员内部类可以直接访问外部类的私有属性 3.外部类可以通过对象访问内部类的私有属性 …...

【MyBatis】篇二.MyBatis查询与特殊SQL

文章目录1、MyBatis获取参数值case1-单个字面量类型的参数case2-多个字面量类型的参数case3-map集合类型的参数case4-实体类类型的参数case5-使用Param注解命名参数总结2、MyBatis的各种查询功能case1-查询结果是一个实体类对象case2-查询结果是一个List集合case3-查询单个数据…...

CE认证机构和CE证书的分类

目前&#xff0c;CE认证已普遍被应用在很多行业的商品中&#xff0c;也是企业商品进入欧洲市场的必备安全合格认证。在船舶海工行业中&#xff0c;也同样普遍应用&#xff0c;很多时候&#xff0c;对于规范中没有明确认证要求的设备或材料&#xff0c;而船舶将来还会去欧洲水域…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

Mac下Android Studio扫描根目录卡死问题记录

环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中&#xff0c;提示一个依赖外部头文件的cpp源文件需要同步&#xff0c;点…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

CppCon 2015 学习:REFLECTION TECHNIQUES IN C++

关于 Reflection&#xff08;反射&#xff09; 这个概念&#xff0c;总结一下&#xff1a; Reflection&#xff08;反射&#xff09;是什么&#xff1f; 反射是对类型的自我检查能力&#xff08;Introspection&#xff09; 可以查看类的成员变量、成员函数等信息。反射允许枚…...

Android屏幕刷新率与FPS(Frames Per Second) 120hz

Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数&#xff0c;单位是赫兹&#xff08;Hz&#xff09;。 60Hz 屏幕&#xff1a;每秒刷新 60 次&#xff0c;每次刷新间隔约 16.67ms 90Hz 屏幕&#xff1a;每秒刷新 90 次&#xff0c;…...