0.前言
由于想利用nginx学习均衡负载和反向代理的相关方法,未来项目中极有可能应用其中,所以决定先利用自己的服务器入手。六月份还无耐心地试过一次,没有成功,这次决心重来。由于之前Apache上的网站均使用Let’s Encrypt的证书加密过,所以直接通过nginx反向代理无法访问Https的服务,所以坑开始了。
此次,希望可以利用Nginx做前端代理,Apache做后端服务器,但也不想改变现有的网站结构,同时未来还可能会在服务器上搭建一个轻量级的git服务。
1.软件版本
- Ubuntu 版本:Ubuntu 16.04.4 LTS
- Apache 版本:Apache/2.4.18 (Ubuntu)
- Nginx 版本:nginx/1.10.3 (Ubuntu)
- Laravel 版本:5.5.X
2.删除Let’s Encrypt的Https证书
由于之前Apache上的网站均使用Let’s Encrypt的证书加密过,所以这里需要删除所有的Https证书和相关文件。我选择比较愚蠢的办法,删除了位于12/etc/apche2/sites-available/etc/apache2/sites-enabled
下,所有后缀名为:*-ssl.conf
的文件,并删除/etc
目录下 letsencrypt
文件夹下的所有文件,最后重启apache服务器。
3.配置Apache虚拟主机
首先,改变Apache的监听端口,修改ports.conf
文件,如下:
其次,更改每一个虚拟主机的配置文件,如下:
Apache配置完成。
4.配置Nginx
4.1.设置反向代理端口
修改Nginx根目录下的nginx.conf
配置文件,在其 http 属性下添加:
- 属性 proxy_pass 的IP末尾是否带‘/’,可以参考Nginx之前端代理Laravel的解释。
此时,已经可以访问静态网页的网站,并能够正确加载所有js、css样式等。
但基于Laravel框架构建的动态网页,js、css定位错误,动态生成类似 http://127.0.0.1:8080/js/xxx.js 的资源定位。我们访问的是80端口,但这里css文件下载路径,确变成了8080端口,无法正常加载我们所需要的文件。借用别人文章里调试的截图,如下:
4.2.增加 proxy_set_header 配置
这里需要增加一个代理配置属性,增加proxy_set_header Host $host:$server_port;
为了保证Laravel能正确获取客户端IP,还可以增加proxy_set_header X-Real-IP $remote_addr;
和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
属性。
笔者并没有仔细分析以上两个属性的用法,详细可参看HTTP 请求头中的 X-Forwarded-For。
此时,在没有进行Https加密的情况下,基于Laravel框架的网站已经能够正常访问了。
4.3.给所有代理网站加上Https证书
这里,我依旧选择的是免费的Let’s Encrypt的证书加密,按照官方教程,顺利安装好证书,并强制使用Https访问网站。然而,我们优秀的Laravel框架又翻车了。
经过Nginx反向代理,可以通过Https访问对应的html文件,但是所有的js、css资源文件却都是http的,Chrome、Edge等浏览器都会以不安全为由,拦劫这样的资源加载,我们又看到了熟悉的纯html网页,通过浏览器的检查功能,我们可以看到如下文字:
这个锅,Nginx不背!原因是,如果检测到传入连接是安全的,Laravel 5.x将通过route()帮助程序生成安全URL。如果应用程序隐藏在负载均衡器或代理(例如Cloudflare)后面,通常会发生问题,因为应用服务器和负载均衡器/代理之间的连接可能不安全。根据Laravel 5.5的官方文档可以找到解决方式。另外在“题 Laravel从路由生成安全的https URL”问题下,也有相当多的讨论可供参考。
更改App\Http\Middleware\TrustProxies
文件中的$proxies
参数。
同样,可以选择信任所有代理者。如果您使用的是Amazon AWS或其他“云”负载均衡器提供商,您可能不知道实际余额的IP地址。在这种情况下,您可以使用信任所有代理:**
最后,在nginx的nginx.conf
配置文件对应代理的location
字段中添加proxy_set_header X-Forwarded-Proto $scheme;
,并在server
属性末尾,添加如下代码:
至此,终于能够正常的访问基于Laravel框架的Htps加密网站。
4.4.无法获得二级域名/三级域名的情况下,如何仅代理二级目录问题
在知乎上看到过一个相关问题,“域名的二级目录nginx反向代理到laravel项目,如何解决路由问题?”,在 勤劳一沙鸥 的Nginx之前端代理Laravel里有相应的解决方案,不再赘述。
4.5.19年3月底的再次更新部分
之前是自己的主机下有多个虚拟主机网站,这次自己也遇到了4.4的情况,无法申请别人域名的情况下,如何完成二级目录的代理,同时我也是前后端分离项目。前端使用Vue.js
,服务器直接使用Nginx,后端使用Spring
,服务器使用Tomcat,如何实现不跨域的前后端通信,这就需要用到Nginx的反向代理了。我的配置http
属性下添加了如下代码:
其中,^~ /api/
是指以/api/
开头的url统统转发到后端的http://api_domain/api/
链接下,而^~ /test/
是指以/test/
开头的url统统转发到后端的http://api_domain/
链接下。剩下的所有链接,直接转跳至index.html,因为 Vue.js 帮我们完成了所有的路由操作,如果不转跳就会出现404错误。
5.总结
找遍google里的相关文章,基本上没有很好完整解决Laravel框架从代理到https加密的问题,所以希望写下这篇文章,能够帮助到一些朋友。
转载请注明出处,无偿提供。