原文链接
背景描述
由于frp的http和https,都是从用户的服务中完整输出数据的,这对于一些使用frp的用户,网络比较差/上传低,打开自己的这些服务,要加载大半天的。
我们可以使用nginx的反代缓存,把frp用户的http和https中的静态资源缓存到服务器本地,从而减少frp用户本身的网络资源请求访问,直接略过大部分,从而在服务器加速。
效果是拔群的!
nginx反向代理缓存配置
新建缓存目录
mkdir -pv /home/nginx/cache
赋予权限
chmod -R 777 /home/nginx/cache
在nginx.conf中http{}里添加以下参数
proxy_cache_path /home/nginx/cache levels=1:2 keys_zone=frp_cache:100m max_size=5g inactive=30d;
resolver 8.8.8.8;
server {
listen 80;
server_name aiuyo.com;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://$host:8680;
proxy_redirect http://$host/ http://$http_host/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
location ~* \.(jpg|jpeg|gif|png|svg|css|scss|js|ico|xml|woff|woff2|ttf|otf|eot)$ {
proxy_pass http://$host:8680;
proxy_redirect http://$host/ http://$http_host/;
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_cache frp_cache;
proxy_cache_key $uri$is_args$args;
proxy_cache_valid 200 206 301 302 304 3d;
expires 30d;
}
}
server{
listen 443 ssl;
ssl on;
server_name *.aiuyo.com;
ssl_certificate /root/.acme.sh/aiuyo.com/fullchain.cer;
ssl_certificate_key /root/.acme.sh/aiuyo.com/aiuyo.com.key;
ssl_trusted_certificate /root/.acme.sh/aiuyo.com/ca.cer;
location / {
proxy_ssl_server_name on;
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_set_header Host $host:$server_port;
proxy_pass https://$host:8643; #通过域名访问frp服务
}
location ~* \.(jpg|jpeg|gif|png|svg|css|scss|js|ico|xml|woff|woff2|ttf|otf|eot)$ {
proxy_ssl_server_name on;
proxy_pass https://$host:8643; #通过域名访问frp服务
proxy_redirect https://$host/ https://$http_host/;
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_cache frp_cache;
proxy_cache_key $uri$is_args$args;
proxy_cache_valid 200 206 301 302 304 3d;
expires 30d;
}
}
配置说明
(jpg|jpeg|gif|png|svg|css|scss|js|ico|xml|woff|woff2|ttf|otf|eot)为需要进行缓存的静态资源,你可以添加或者修改。
proxy_cache_valid为服务器缓存,其中200 206 301 302 304为HTTP状态码(http://tool.chinaz.com/pagestatus/)针对状态码缓存,而最后面的 30d 为缓存过期时间,当用户没有在这个有效时间内访问到这个资源,则会过期清除,直到用户重新访问到这个资源则重新缓存。
expires 为访问用户本地缓存
d 天数 h 小时 m 分钟 s 秒
http://127.0.0.1:8680;的8080端口为你frp.ini配置文件vhost_http_port = 8680端口
http://127.0.0.1:8643;的8443端口为你frp.ini配置文件vhost_https_port = 8643端口
对应的frps.ini配置如下:
# if you want to support virtual host, you must set the http port for listening (optional)
# Note: http port and https port can be same with bind_port
vhost_http_port = 8680
vhost_https_port = 8643
其中的端口可以根据自己的需要修改。
配置成功后,并且访问目标网站,让nginx进行缓存,在/home/nginx/cache目录里会生成多个缓存目录和文件。
对于nginx https代理frp https的理解
我的理解是这样的:
如果使用了自定义域名,frp是根据$host值判断该往哪个内网服务转发请求的,因此转给frp的请求中一定要包含$host,否则frp无法正常处理请求。
因此以下2个配置很重要:
proxy_ssl_server_name on;
proxy_pass https://$host:8643; #通过域名访问frp服务
proxy_pass中不能写成IP的形式。
举一个我的例子,我内网服务器192.168.2.99上部署着2个服务,elasticsearch和kibana,端口分别是9200和5601,我现在想要把这2个服务穿透出去,并配置成https。具体配置如下:
frps.ini中的主要配置:
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = 7000
……
# if you want to support virtual host, you must set the http port for listening (optional)
# Note: http port and https port can be same with bind_port
vhost_http_port = 8680
vhost_https_port = 8643
然后通过上边配置的nginx进行代理转发请求到frp上。
frpc.ini的配置如下:
[es]
type=https
custom_domains=es.aiuyo.com
local_ip=192.168.2.99
local_port=9200
use_encryption=true
use_compression=true
[kb]
type=https
custom_domains=kb.aiuyo.com
local_ip=192.168.2.99
local_port=5601
use_encryption=true
use_compression=true
文章评论
http://127.0.0.1:8680;的8080端口为你frp.ini配置文件vhost_http_port = 8680端口
http://127.0.0.1:8643;的8443端口为你frp.ini配置文件vhost_https_port = 8643端口
8680和8643是固定的么?
@callmesoul 不是固定的,这个是你的frp服务端的http端口和https端口。
请教下老大:可不可以这样
frps服务器配置nginx,listen 443 ssl;不放证书,直接将域名转发给frps,frps-frpc-frpc上的nginx。
第一个nginx只写这个 location / {proxy_ssl_server_name on;
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_set_header Host $host:$server_port;
proxy_pass https://$host:8643;}
您觉得可以嘛?这样frpc的https是不是就可以获取访客的IP呢?现在https,frp没有办法获取访客ip
@hello 你可以试试,我也不太清楚,我也没试过。我有空试下吧。
@hello 请问您成功了吗?我也想这么弄,一直有问题。
老大您好,我觉得您的思路非常好。想请教下您,如果用阿里云OSS+CDN对nginx反代的的缓存静态资源加速,效果会不会更好?新手+弱鸡,如果可行的话,哪里有合适的教程可以学习下。看了下OSS+CDN,要对应web服务器建立对应目录,然后在上传至oss。感觉如果您的思路上+oss+cdn,是不是更牛?更符合商用?
@hello 不了解阿里云的OSS和CDN,不好意思。
有没有碰到这个问题?设置好后,访问www.xxxx.com域名,然后浏览器地址自动变为www.xxx.com:8680这样的,能否让8680不显示呢?老大?试了好久,没找到合适办法
@hello 这个应该是你应用内部处理的问题,看看你应用内部是怎么跳转的,跳转的时候出问题了。
为什么https要加proxy_ssl_server_name on;而http却不用?
@lwz 其实具体什么原因,我也不知道,既然你问起来了,我就试了一下,不配置proxy_ssl_server_name on;还真的不行,因此找找了相关资料,希望能够帮助到你
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_server_name
https://www.jianshu.com/p/f608611dc694
该成$host之后,依旧502,nginx错误日志显示:no resolver defined to resolve xxx.yyy.com,应该是无法解析该域名,但是DNSPod已经将该域名指向了frp服务器
@daneric 提示no resolver defined to resolve xxx.yyy.com主要原因你是没有配置resolver 8.8.8.8;
在nginx上启用了sni,按照这样操作还是会502,原因是ssl握手不成功。有什么好的解决方案吗
@G-HO 可以说出你的需求,大家一起看看有没有什么办法
大佬,请教一下,你文章中的NGINX是在FRPS服务器上部署的还是FRPC内网客户端上部署呢?
@Jason frps是部署在具有公网IP的服务器上的,客户端是在内网部署的frpc