关于内网穿透
内网穿透,也即 NAT 穿透,进行 NAT 穿透是为了使具有某一个特定源 IP 地址和源端口号的数据包不被 NAT 设备屏蔽而正确路由到内网主机。下面就相互通信的主机在网络中与 NAT 设备的相对位置介绍内网穿透方法。
为什么要使用内网穿透
为了外网要访问内网,因为当不在同一局域网内,ip和地址互相ping不同的话,最简单的方式是使用向日葵与teamview,但是用起来并不方便。
使用frp进行内网穿透
关于frp的介绍
frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务,支持 tcp, http, https 等协议类型,并且 web 服务支持根据域名进行路由转发。
准备工作
在使用frp之前,需要一台有公网IP的服务器(外网主机),一台需要实现内网穿透的机器(内网主机),SSH工具,及一个域名。
进行配置
服务端配置
下载源文件
| wget https://github.com/fatedier/frp/releases/download/v0.33.0/frp_0.33.0_linux_amd64.tar.gz
|
解压
| tar -zxvf frp_0.33.0_linux_amd64.tar.gz
|
进入解压目录
| cd frp_0.33.0_linux_amd64/
|
配置文件
修改配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| [common]
bind_port = 7000
token = 52010
dashboard_port = 7500
dashboard_user = admin dashboard_pwd = admin enable_prometheus = true
log_file = /var/log/frps.log log_level = info log_max_days = 3
[secret_ssh_visitor] type = stcp role = visitor server_name = secret_ssh sk = 123456 bind_addr = 127.0.0.1 bind_port = 8000
|
设置与启动frp服务
| sudo mkdir -p /etc/frp sudo cp frps.ini /etc/frp sudo cp frps /usr/bin sudo cp systemd/frps.service /usr/lib/systemd/system/
sudo systemctl enable frps
sudo systemctl start frps
sudo systemctl restart frps
|
防火墙开放端口, 根据自身服务器设置,以阿里云为例,如果设置了访问规则,则要放开7000、75000、8000三个端口
| firewall-cmd --permanent --add-port=7000/tcp
firewall-cmd --permanent --add-port=7500/tcp
firewall-cmd --permanent --add-port=8000/tcp
firewall-cmd --reload
|
验证是否成功
在浏览器中输入:http://服务器的ip:后台管理端口 (后台管理端口的设置在配置文件中) 进入之后会显示登陆需要使用的账号密码,同样的也是在配置文件frps.ini中
客户端部署(以树莓派为例)
下载源文件
| wget https://github.com/fatedier/frp/releases/download/v0.33.0/frp_0.33.0_linux_amd64.tar.gz
|
解压
| tar -zxvf frp_0.33.0_liux_amd64.tar.gz
|
进入解压目录
| cd frp_0.33.0_linux_amd64/
|
配置文件
修改配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| [common]
bind_addr = 0.0.0.0
bind_port = 7000
authentication_timeout = 0
token = 52010
[secret_ssh] type = stcp
sk = 123456
local_ip = 127.0.0.1 local_port = 22
|
在frp_0.33.0_linux_amd64目录下,临时启动命令
设置为开机自动启动
| sudo mkdir -p /etc/frp sudo cp frpc.ini /etc/frp sudo cp frpc /usr/bin sudo cp systemd/frpc.service /usr/lib/systemd/system/
sudo systemctl enable frpc
sudo systemctl daemon-reload sudo systemctl start frpc
sudo systemctl restart frpc
|
frpc.ini进一步部署
服务端部署(Linux VPS)
| [common] bind_addr = 0.0.0.0
bind_port = 7000
privilege_token = 123456
vhost_http_port = 8080
vhost_https_port = 443
dashboard_port = 7500
|
客户端部署(后附每个穿透方案的详解)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| [common] server_addr = your_server_ip server_port = 7000 privilege_token = 123456
login_fail_exit = false
admin_addr = 127.0.0.1 admin_port = 7400
[ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 8000
[ftp] type = tcp local_ip = 127.0.0.1 local_port = 21,10000-10010 remote_port = 2121,10000-10010
[range:VNC] type = tcp local_ip = 127.0.0.1 local_port = 5900 remote_port = 5900
[dns] type = udp local_ip = 8.8.8.8 local_port = 53 remote_port = 8500
[http_proxy] type = tcp remote_port = 9000 plugin = http_proxy
[web] type = http local_ip = 127.0.0.1 local_port = 80 custom_domains = www.dengxj.com,dengxj.com
|
详解
通过 TCP 访问内网机器
| [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 8000
|
通过 UDP 访问内网机器
|
[dns] type = udp local_ip = 8.8.8.8 local_port = 53 remote_port = 8500
|
通过 FRP 客户端代理其它内网机器访问外网
|
[http_proxy] type = tcp remote_port = 9000 plugin = http_proxy
|
通过自定义域名访问部署于内网的 Web 服务 点此查看实例
| [web] type = http local_ip = 127.0.0.1 local_port = 80 custom_domains = 二级域名全称(eg. nwct.dengxj.com)
|
高阶应用
通过代理连接 FRP 服务端
在只能通过代理访问外网的环境内,FRP 客户端支持通过 HTTP_PROXY 参数来配置代理和 FRP 服务端进行通信。要使用此功能可以通过设置系统环境变量 HTTP_PROXY 或者通过在 FRP 客户端 的配置文件中设置 http_proxy 参数来使用此功能。
| [common] server_addr = your_server_ip server_port = 7000 protocol = tcp http_proxy = http://user:pwd@your_server_ip:8080
|
安全地暴露内网服务(STCP)
对于一些比较敏感的服务如果直接暴露于公网上将会存在安全隐患,FRP 也提供了一种安全的转发方式 STCP。使用 STCP (secret tcp) 类型的代理可以避免让任何人都能访问到穿透到公网的内网服务,要使用 STCP 模式访问者需要单独运行另外一个 FRP 客户端。
下面就以创建一个只有自己能访问到的 SSH 服务代理为例,FRP 服务端和其它的部署步骤相同,主要区别是在 FRP 客户端上。
| [common] server_addr = your_server_ip server_port = 7000
[secret_ssh] type = stcp sk = abcdefg local_ip = 127.0.0.1 local_port = 22
|
其次在要访问这个服务的机器上启动另外一个 FRP 客户端,配置如下:
| [common] server_addr = your_server_ip server_port = 7000
[secret_ssh_visitor] type = stcp role = visitor server_name = secret_ssh sk = abcdefg bind_addr = 127.0.0.1 bind_port = 6005
|
这样就可以通过本机 6005 端口对内网机器 SSH 服务进行访问。
点对点内网穿透
在传输大量数据时如果都经过服务器中转的话,这样会对服务器端带宽压力比较大。
FRP 提供了一种新的代理类型 XTCP 来解决这个问题,XTCP 模式下可以在传输大量数据时让流量不经过服务器中转。
使用方式同 STCP 类似,需要在传输数据的两端都部署上 FRP 客户端上用于建立直接的连接。
首先在 FRP 服务端 配置上增加一个 UDP 端口用于支持该类型的客户端: bind_udp_port = 7001
| [common] bind_addr = 0.0.0.0 bind_port = 7000 privilege_token = 123456
vhost_http_port = 8080 vhost_https_port = 443
dashboard_port = 7500
bind_udp_port = 7001
|
其次配置 FRP 客户端,和常规 TCP 转发不同的是这里不需要指定远程端口。
修改前:
| [common] server_addr = your_server_ip server_port = 7000
[ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 8000
|
修改后:
| [common] server_addr = your_server_ip server_port = 7000
[p2p_ssh] type = xtcp sk = abcdefg local_ip = 127.0.0.1 local_port = 22
|
然后在要访问这个服务的机器上启动另外一个 FRP 客户端,配置如下:
| [common] server_addr = your_server_ip server_port = 7000
[p2p_ssh_visitor] type = xtcp role = visitor server_name = p2p_ssh sk = abcdefg bind_addr = 127.0.0.1 bind_port = 6006
|
这样就可以通过本机 6006 端口对内网机器 SSH 服务进行访问。
目前 XTCP 模式还处于开发的初级阶段,并不能穿透所有类型的 NAT 设备,所以穿透成功率较低。穿透失败时可以尝试 STCP 的方式。
参考文档
1.FRP内网穿透_内网穿透 无需公网ip
2.使用FRP实现内网穿透,远程访问内网服务器