基于frp实现内网穿透


前言

之前为了实现远程编程,折腾了一阵子autossh,利用反向代理把内网服务器的ssh映射到了公网端口,详见下面这篇。

小想法 | 基于VSCode和ssh实现远程编程/炼丹

这次需求扩大了一点,比如说想访问内网搭建的网站、数据库等等,但这些都不能直接在公网进行访问autossh就有点不大给力了。

之前还了解过花生壳、ngrok这些,但是一般需要money要限速或者说不大友好,然后一想大家都在推荐frp,这回就来折腾一下吧!(主要是以后忘了还可以回来看嘻嘻

总体感受就是,frp搭建起来比autossh方便多了呀!



简介

What is frp?

frp is a fast reverse proxy to help you expose a local server behind a NAT or firewall to the Internet. As of now, it supports TCP and UDP, as well as HTTP and HTTPS protocols, where requests can be forwarded to internal services by domain name.

frp also has a P2P connect mode.

frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透。

architecture

FRP,fast reverse proxy。使用 Go 语言开发,支持 Windows、Linux、macOS、ARM 等多平台部署。

其实简单地说也就是借助一台有公网IP的服务器作为中转,把内外网直接的流量连接起来。

其开源仓库:https://github.com/fatedier/frp

What should I prepare?

内网主机(客户端):能上互联网(外网),或者说能连上你的公网服务器就行。(但没有公网IP)

可以是电脑(Windows,MacOS,Linux)/嵌入式设备(如树莓派)…对的,frp跨平台

公网主机(服务端):有公网IP,或者绑定了域名能通过端口访问也行。

以及

连接内网的你喜欢的设备




搭建过程

分为服务器端客户端两部分。

下载程序

根据对应的操作系统及架构,从 Release 页面下载最新版本的程序。

目前最新的版本是 v0.31.1

比如Windows64位下载 frp_0.31.1_windows_amd64.zip

Linux64位一般是这个 frp_0.31.1_linux_amd64.tar.gz

其他系统/架构的对应下载就好了。

下载对应的文件

frpsfrps.ini 放到具有公网 IP 的机器上。

frpcfrpc.ini 放到处于内网环境的机器上。

服务器端的搭建

可以在服务器上可以用wget下载。

sudo mkdir -p /etc/frp
cd /etc/frp
sudo wget "https://github.com/fatedier/frp/releases/download/v0.31.1/frp_0.31.1_linux_amd64.tar.gz"
sudo tar xzvf frp_0.31.1_linux_amd64.tar.gz
sudo mv frp_0.31.1_linux_amd64/* /etc/frp

然而国内下载速度感人,大概8M的文件就几KB/s…

于是还不如直接搭个梯子到外面下载好了再传到服务器上。

服务器端server嘛,当然用的是 frpsfrps.ini

完整版的 frps_full.ini里面有很详细的注释,也可以用来参考。


最简单的配置就直接这样写

# frps.ini
[common]
bind_port = 7000

然后启动frps(Linux下)

/etc/frp/frps -c /etc/frp/frps.ini

再去把系统的防.火|墙打开,以及阿里云等平台的安全组规则设好允许入站出站

这个firewall搞死我了emmm折腾了老半天最后发现没放行端口……

后面再写一篇关于firewall配置的。

好了,下面到客户端。


客户端(内网主机)的搭建

同理把frp解压的文件放到/etc/frp文件夹下。

客户端client,用的是 frpcfrpc.ini

# frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000

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

[Mysql]
type = tcp
local_ip = 127.0.0.1   #也可以是局域网中的内网IP
local_port = 3306
remote_port = 7002

其中common里的server_addr是公网主机的公网IP,server_port设成与服务端一样的端口。

每个方框[.+]里的是name,下面都对应着一个规则,要求不能重名。

type可以是tcp/udp/http/https/stcp/xtcp(具体看官方文档),一般就tcp/http啦。

local_iplocal_port为本地地址及端口。

remote_port为公网的端口,这个可以在服务端进行限制,注意要在服务端放行这些端口啊!


客户端可以在多个主机上运行,只要name不重名就行。

而后启动客户端

/etc/frp/frpc -c /etc/frp/frpc.ini

Windows下:

frpc.exe -c frpc.ini

client

start proxy success表示启动成功。


远程访问

现在就可以直接通过公网IP的7001端口访问内网的ssh,通过7002端口访问内网的Mysql啦!

远程编程,访问网页,管理数据库什么的都可以实现啦!

好棒呀!





进阶

Dashboard

frp服务器端提供了一个在web端查看运行状态的展示界面。

配置如下,在common中添加如下信息:

# frps.ini
[common]
dashboard_port = 7500 # 注意开放端口
# dashboard 用户名密码,默认都为 admin
dashboard_user = admin
dashboard_pwd = admin

而后重启服务端,就可以在http://[server_addr]:7500 访问 dashboard 界面,用户名密码默认为 admin

Dashboard_Overview

Dashboard_Proxies

还别说,挺好看的唉!

看了一下,基于vue写的。


Admin UI

在客户端也提供了一个类似于dashboard的查看状态和管理配置的界面。

# frpc.ini
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin

然后本地就可以通过 http://127.0.0.1:7400 来访问查看状态修改配置了。

这里如果想通过内网IP(如192.168.1.66)查看的话,需要把admin_addr修改为 0.0.0.0(允许所有访问),或者对应的本地IP(如192.168.1.66)。

同时也需要在本地的firewall打开这个端口,否则在内网的其他主机也无法访问。(折腾了老半天才发现emmm

当然,想要在公网访问的话,把7400端口映射到外网就好了,不过安全起见算了吧。

AdminUI


开启加密、压缩

在客户端加入use_encryptionuse_compression这两个参数。

# frpc.ini
[ssh]
type = tcp
local_port = 22
remote_port = 6000
use_encryption = true
use_compression = true

开机自启

这次直接把frp作为一个service好了,用systemd好了!

服务端:

新建一个文件,名叫 frps.service,写入

# frps.service
[Unit]
Description=Frp Server
After=syslog.target network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/etc/frp/frps -c /etc/frp/frps.ini
ExecStop=/usr/bin/killall frps
#启动失败1分钟后再次启动
RestartSec=1min
KillMode=control-group
#重启控制:总是重启
Restart=always

[Install]
WantedBy=multi-user.target

客户端:

frpc.service

# frpc.service
[Unit]
Description=Frp Client
After=syslog.target network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/etc/frp/frpc -c /etc/frp/frpc.ini
ExecStop=/usr/bin/killall frpc
#启动失败1分钟后再次启动
RestartSec=1min
KillMode=control-group
#重启控制:总是重启
Restart=always

[Install]
WantedBy=multi-user.target

而后将此文件放到 服务器端和客户端的/etc/systemd/system/ 目录下。

killall frps(或frpc),再调用

sudo systemctl enable frps.service

sudo systemctl enable frpc.service

这样就成功配置了开机自启。

而且可以通过下列命令进行管理:

sudo systemctl start frpc.service    # 启动
sudo systemctl stop frpc.service     # 停止
sudo systemctl restart frpc.service  # 重启
sudo systemctl status frpc.service   # 查看状态

frps同理。

查看状态





Summary

frp很强大的呢!

比如还可以在一定情况下绕过服务器实现点对点P2P连接,不过前提是内网和你的设备两端都要装frpc客户端。

更多且看官方文档https://github.com/fatedier/frp

关键这个配置起来贼方便啊

于是这样就可以通过公网IP,访问到你内网的资源啦,嘻嘻嘻~

好了,完事!

溜了溜了。



Reference

  1. 官方仓库及介绍 https://github.com/fatedier/frp
  2. 官方中文文档 https://github.com/fatedier/frp/blob/master/README_zh.md
  3. https://www.iplaysoft.com/frp.html
  4. Frp后台自动启动的几个方法 https://blog.csdn.net/x7418520/article/details/81077652
  5. Systemd 服务管理教程 https://cloud.tencent.com/developer/article/1516125
  6. 小想法 | 基于VSCode和ssh实现远程编程/炼丹

还看到过一个免费的内网穿透服务,Sakura Frp https://www.natfrp.com/


文章作者: MiaoTony
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 MiaoTony !
评论
  目录