NAT环境下,内网的机器是无法被外部访问到的。比如下面的LaptopA和B,都不能被公网的7.7.7.7访问到的。
在路由器的帮助下,才能实现双向通讯。但是大部份情况下,家用路由器不支持将Laptop暴露给外网。
这个时候,如果有一个服务能够直接穿透家用路由器而直接用TCP链接,把Laptop:xxxx和7.7.7.7:xxxx等效起来,那么就相当于直接把laptop暴露在公网了。
而frp则是这样的工具,能够完美的实现这个技能。在它的帮助下,能够让访问7.7.7.7:8080的时候,相当于在访问laptop:8080。
如果laptop:8080上面是个http服务的话,那么相当于在laptop:8080上面搭建了一个公网可以访问的web服务,只不过它的访问地址是7.7.7.7:8080。而frp更是直接内置了,一个静态的web服务器插件:static_file,可以直接提供静态文件的web服务。
因为laptop经常关机,所以它的应用场景只能是对可用性要求不高的环境,比如说图床,当然如果搭配公开的cloudlare这样的的CDN,那么一个月开机一次,就足够支持一般的图床应用了。
比如说可能是个基于laptop:8080的图床等等服务,再也不需要云空间的存储要求。
frp分为服务器端frps和客户端frpc,服务器端frps运行在7.7.7.7上面,客户端frpc运行在laptop上面。
这个体系中,frp不仅仅会监听对外服务的8080端口,而且自己也需要一个frp自己的端口用于服务器端frps和客户端frpc通讯,
frpc客户端与frps服务端在frp端口建立链接后,会根据客户端frpc的配制,决定如何将客户端frpc的资源暴露于7.7.7.7这个frps服务器端。所以frp服务器真正提供服务的端口,其实是由frp客户端来指定的。
安装之后,frpc和frps各有自己的ini格式的配置文件,启动命令非常相似
- frpc -c frpc.ini #启动Laptop上面的客户端
- frps -c frps.ini #启动7.7.7.7上面的服务器端
比如说frps.ini中,指定frps和frpc自己的通讯端口是7000.
[common]
bind_port = 7000
frpc.ini
[common]
server_addr = 7.7.7.7
server_port = 7000
[test_static_file]
type = tcp
remote_port = 8080
#这个由frp的静态服务插件来实现http静态服务,当然也可以用别的服务来实现。比如说端口转发等等。
plugin = static_file
# 要对外暴露的文件目录
plugin_local_path = C:/Documents/sites/frp_sites/pub
服务器和客户端启动之后,访问 http://7.7.7.7:8080,就可以直接访问Laptop上面 C:/Documents/sites/frp_sites/pub 里面的文件了。
比如说laptop://C:/Documents/sites/frp_sites/pub/hello.png,可以通过http://7.7.7.7:8080/hello.png来访问。
这个配制中,还是非常的原始,只可以适用于演示。
实际上上面这个配制,任何frp客户端都可以连接frps上去,这非常的不安全。所以需要在frpc和frps之间进行认证,frp支持的认证方法有token和oidc,oidc的认证略微复杂,直接使用token来设置密码最简单。
在上面的frps.ini和frpc.ini的common节中,同时加入:
authentication_method = token
token = 47866af5-cc5f-4798-a658-8a39bb61f53e
借用电影疯狂的石头的话说,7.7.7.7:7000可不是公共厕所,想来就来 :) 。
这样frpc和frps就会进行连接认证了。
进一步的,http://7.7.7.7:8080/hello.png,这样的URL实在太丑陋了,所以Nginx做反向代理,我们新建一个站点: frp.a.com 。
设置DNS,将frp.a.com指向7.7.7.7之后,
使用http://frp.a.com/hello.png,就可以非常友好的访问laptop://C:/Documents/sites/frp_sites/pub/hello.png了。
server {
server_name frp.a.com;
listen 80 ;
location / {
proxy_pass http://7.7.7.7:8080;
}
}
这个地方,还有点点可以改进的地方,既然http://7.7.7.7:8080/hello.png这样的网址,对外部来说已经不需要了,那么能不能换成只能Nginx内部 访问的网址,比如说 http://127.0.0.1:8080?
当然是可以的,这个时候需要在服务器端的frps.ini中配制指定:
pproxy_bind_addr = 127.0.0.1
这个设置,会让frp只监听127.0.0.1:8080,而不是服务器的*:8080。这样frp只接受乃至服务器本身的连接,外部不可访问7.7.7.7:8080了,就更加的安全了。
如果是windows,希望把frp运行在后台服务中,而不是一个丑陋的cmd黑框框,可以使用nssm来帮助实现
更多的frp服务器端和客户端配制参见: