需求背景:一些内网服务,无法对外直接对外开放,又希望可以外网访问
原理:(外网) frps < 外网 | 内网-> frpc <- 本地 -> nginx <-> 内网服务
我们用到的工具是frp ,它是一个隧道工具,类似的还有很多,用它的原因是因为配置简单、文档全,解释下各端的用途:
- frps:服务端,需要有公网域名,外网访问从这里进来
- frpc:客户端,部署在内网,frps和frpc之间建立了穿透隧道
- nginx:做反向代理转发,将frpc的流量转发到内网其他服务上
1 配置frps
frps.toml
bindPort = 7000 vhostHTTPPort = 8080
启动
frps -c frps.yaml
这里的7000是与frpc通信的,8080是对外的http访问接口,注意都要开下防火墙端口
2 配置frpc
frpc.toml
serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "web" type = "http" localPort = 8080 customDomains = ["frp.yourdomain.com"]
这里的x.x.x.x是上面frps的IP,还需要把frp.yourdomain.com做dns解析到这个公网IP
其实是支持多组服务配置的,通过域名区分,类似泛域名
启动
frps -c frps.yaml
如果你的内网服务是跑在本机的且是端口访问不需要Host,那到这里就可以停止了,否则请继续配置
3 配置Nginx转发
default.conf
server { listen 8080; server_name _; location / { proxy_pass http://intra.yourdomain.com; #proxy_set_header Host $http_host; 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; } }
这里本地要启一个Nginx,在8080,转发到内网服务intra.yourdomain.com(这个是外网没法直接访问的),特别注意不要写set_header,不要用上游的,要用默认的,否则会找不到host(因为上游带过来的是frp.yourdomain.com)
正常的话,访问http://frp.yourdomain:8080就可以了,如果不行的话,逐一排查:
- frps的7000是否外网通
- frps的8080是否外网通
- 本地的8080是否能正常访问nginx
- 本地的8080是否能正常反代
frp提供了很多配置,玩法很多,大家可以参考官方文档