• 推荐!搬瓦工官方代理,自动更换被封IPJust My Socks

ad

使用frp实现内网穿透

之前写过如何搭建Git服务器方便协同开发(Windows上搭建Git服务器&Linux上搭建Git服务器),但是当你将一些web服务发布在内网时,在外网工作的人(例如家里)就无法访问这些web服务,而内网穿透的作用就是在内网没有公网IP时可以被外网访问,从而实现不同局域网内主机间的通信。这篇文章就介绍一下如何使用frp实现免费内网穿透,无需公网IP,包括内容穿透服务器端与客户端的搭建。

 

什么是内网穿透

简单来说内网穿透就是实现不同局域网内的主机间的通信,通俗点讲,当你在宿舍写代码,想访问机房里的服务,但是机房没有外网IP,所有的web服务都是通过内网发布的(192.168.xx.xx等),那你在宿舍就无法访问到这些服务,可你又不想去机房,那么应该怎么办呢?内网穿透就可以帮你解决这个困境。通过内网穿透,你用宿舍的网络就可以访问到机房的web服务。

或者是你用宿舍的网络,可以SSH访问机房的服务器(服务器没有公网IP)。

 

内网穿透工具-frp

内网穿透的工具有很多,常用的例如ngrok和frp。ngrok的2.x版本不再开源,1.x版本最近一次更新是在2年前,而frp却依然在维护,更新频繁,并且frp的配置相对于ngrok来说更加简单易上手。

frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议。

 

动手实现内网穿透

有公网IP的服务器1台

实现内网穿透,首先需要一台有公网IP的服务器。

VPS推荐:月付2.5美元的Vultr年付最低18.79美元的搬瓦工

服务器系统推荐:除非有特殊原因,不建议选择对新手不太友好的Centos,推荐Ubuntu 16.04。

 

frp服务器端搭建与配置

去官网下载最新的release版本

wget https://github.com/fatedier/frp/releases/download/v0.20.0/frp_0.20.0_linux_amd64.tar.gz

解压压缩包并命重命名文件夹:

tar xzvf frp_0.20.0_linux_amd64.tar.gz
mv frp_0.20.0_linux_amd64 frp

进入frp文件夹下:cd frp,修改frps.ini文件,例如设置http访问端口是8080(以下示例为 http 服务,https 服务配置方法相同, 服务器端的vhost_http_port 替换为vhost_https_port,客户端的type 设置为https 即可):

# frps.ini
[common]
bind_port = 7000
vhost_http_port = 8080

之后启动frps:

# 控制台式启动,按ctrl+C停止
./frps -c ./frps.ini
# 后台启动,日志保存在nohup.out
nohup ./frps -c ./frps.ini &

 

frp客户端搭建与配置

去官网下载最新的release版本(注意要与服务器端的版本对应),这里以64位Windows版本为例,下载好后包括如下文件:

frp-windows-dir

修改文件frpc.ini,添加对应的web服务:

[common]
server_addr = x.x.x.x
server_port = 7000

[web]
type = http
local_port = 8089
custom_domains = www.your_domain.com

其中,x.x.x.x是你VPS的IP,端口是你服务器配置文件中配置bind_port,local_port则是你内网发布的web服务对应的端口,例如我内网服务是localhost:8089,最后的custom_domains则是你的域名,添加A记录解析到你的VPS的IP x.x.x.x上即可(域名购买可参考:Namesilo优惠券与解析)。

如果你想用frp运行多个web服务,那么可以结合nginx实现(https://github.com/fatedier/frp/issues/287)

首先是nginx的配置:

server {
  listen 80;
  server_name app1.* app2.* app3.*;
  ## send request back to apache ##
  location / {
  client_max_body_size    1000m;  
  # 假设frps端口8080
  proxy_pass http://127.0.0.1:8080;  
	proxy_redirect off;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header Host $http_host;
	proxy_set_header X-NginX-Proxy true;
 }
}

之后是frps的配置:

[common]
bind_addr = 0.0.0.0
bind_port = 7000
vhost_http_port = 8080
auth_token = openittoken
subdomain_host = testapp.com

[app1]
type = http
auth_token = openittoken
subdomain = app1
[app2]
type = http
auth_token = openittoken
subdomain = app2
[app3]
type = http
auth_token = openittoken
subdomain = app3

最后是frpc的配置:

[common]
server_addr = *.23.72.*
server_port = 7000
auth_token =openittoken

[app1]
type = http
local_port = 8081

[app2]
type = http
local_port = 8082

[app3]
type = http
local_port = 8083

将*.testapp.com解析到你的服务器ip,这样就实现了:

app1.testapp.com => client:8081
app2.testapp.com => client:8082
app3.testapp.com => client:8083

修改完毕后启动frpc即可,需要在控制台(cmd)中运行:

frpc -c frpc.ini

frp-windows-start

如上图所示,这样就是启动成功了。

 

内网穿透效果

以我的配置为例,在8089端口用Nginx配置了一个web服务:

内网穿透本机服务

此时,你打开你在客户端配置文件里配置的域名加上你在服务器端配置文件里配置的端口,就可以访问这个内网里的web服务了:

内网穿透远程访问

 

内网穿透安全性

按照上面的配置方法,只要别人知道你的域名和端口就能访问你的web服务,如果你不想别人访问,frp也支持设置密码,只需要在客户端配置文件里加上用户名和密码就可以:

[common]
server_addr = x.x.x.x
server_port = 7000

[web]
type = http
local_port = 8089
custom_domains = www.your_domain.com
# 设置认证的用户名
http_user = flyzy2005
# 设置认证的密码
http_pwd = flyzy2005

之后重启客户端服务,再通过内网穿透的方式来访问局域网里的web服务就会发现需要验证了:

内网穿透验证

 

利用SSH访问内网服务器

前几个部分介绍的是web服务如何通过frp实现内网穿透,从而达到在外网访问内网服务的目的,接下来介绍下如何使用frp实现外网ssh连接内网服务器。

服务器的配置(frps)不需要改,跟上一部分一致即可,只需要在客户端配置(frpc)中加上如下配置:

[common]
server_addr = x.x.x.x
server_port = 7000

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000

其中,local_iplocal_port是你本机(内网服务器)的ip和ssh端口,remote_port则是服务器的端口,如果是例子中的配置,则你可以通过ssh [email protected] -p 6000来ssh你的内网服务器。

如果你有多台内网服务器,而只有一个外网IP,那么只需要在多个内网服务器上同时运行frpc,指定不通的remote_port即可。

点赞
  1. Louise说道:

    按照站长的搭建成功啦! 不过静态网页没什么问题但是wordpress网页在手机端访问和电脑端通过代理访问的时候会非常的慢而且显示不出来,请问是不是我参数设置的问题还是别的~(网站:http://blog.psychiwave.club/)

  2. HZM说道:

    站长你好,请问一下要怎么添加多个域名? 直接输入多个Custom_domains=XXX吗?

    1. flyzy小站说道:

      像这样:custom_domains = web01.yourdomain.com,web02.yourdomain.com,web03.yourdomain.com