最近看了一些视频,想研究一下内网穿透frp方案,该文档记录了frp的测试和配置过程。能给新入门的朋友一些过程记录。
我们采用docker镜像的方式进行按照frps,frpc服务,这样最快了,免编译。前提是你的虚拟机要安装docker环境。
我们去到docker hub中去查找frp,下载下载量最多的就行啦。
docker pull snowdreamtech/frps
docker pull snowdreamtech/frpc
我们根据frp github 页面页面上docker 运行命令,我们看到了其使用的配置文件。常规操作,我们将docker内的配置,拷贝到宿主机中。运行时再映射到docker容器中,这样方便我们修改配置,然后重新运行docker。先临时运行容器。
docker run -ti --rm --network host --name frps snowdreamtech/frps:latest
docker cp frps:/etc/frp/frps.ini .docker run -ti --rm --network host --name frpc snowdreamtech/frpc:latest
docker cp frpc:/etc/frp/frpc.ini .
发现配置太简陋,拷贝了个寂寞。如果想要丰富的配置文件,参考frp github页面中conf/frp_full.ini文件。
先运行服务器
docker run --network host --name frps --restart=always
-v /home/frp/app/frps/config/frps.ini:/etc/frp/frps.ini
-d snowdreamtech/frps:latest
然后运行客户端
docker run --network host --name frpc --restart=always
-v /home/frp/app/frpc/config/frpc.ini:/etc/frp/frpc.ini
-d snowdreamtech/frpc:latest
frps的配置文件比较通用,如下所示。我们可以通过http://frps_ip:7500来查看frps的仪表盘界面。
frp@ubuntu-18:~/app$ cat frps/config/frps.ini
[common]
bind_addr = 0.0.0.0
bind_port = 7000 #frps-c连接端口
vhost_http_port = 8080 #http vhost端口
vhost_https_port = 4433 #https vhost端口
# set dashboard_addr and dashboard_port to view dashboard of frps
# dashboard_addr's default value is same with bind_addr
# dashboard is available only if dashboard_port is set
dashboard_addr = 0.0.0.0
dashboard_port = 7500 #frps 的仪表盘页面端口
# dashboard user and passwd for basic auth protect
dashboard_user = admin
dashboard_pwd = admin
# dashboard TLS mode
dashboard_tls_mode = false
# dashboard_tls_cert_file = server.crt
# dashboard_tls_key_file = server.key
frpc公共配置如下:
[common]
server_addr = 127.0.0.1
server_port = 7000
ssh是linux访问后台的常用手段。代理ssh就直接使用tcp透传就行。这样我就可以使用ssh frp@frps_ip:6000
远程我的虚拟机了。很开心!
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
使用tcp和端口对端口的方式。这样就需要frps服务器开放另外的一些端口。一般服务器也不会开发很多端口出来的。所以这种方式仅限于同时使用数量少的情况。
[nginx]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port= 10086
这样我们就可以http://frps_ip:10086就可以访问我们的80-nginx服务了。可以使用range:修饰,指定一系列的端口映射。可以参考frpc_full.ini。
# if you want to expose multiple ports,
# add 'range:' prefix to the section name
# frpc will generate multiple proxies
# such as 'tcp_port_6010', 'tcp_port_6011' and so on.
[range:tcp_port]
type = tcp
local_ip = 127.0.0.1
local_port = 80-90remote_port = 10086-10096
use_encryption = false
use_compression = false
通过指定custom_domains字段,帮助frps将http流量根据host字段来转发到目标设备。即虚拟主机的概念。需要注意的是,在frps连接的所有http流中proxy custom_domains需要唯一。frps就是拿这个域名进行分流的。
由于我们没有域名,就直接写ip。这种方法仅限于在可以访问到frps_ip的主机使用,这样就只能映射一个http。这样做的好处就是服务器端口可以固定一个,参考frps配置vhost_http_port为8080。即所有的http(s)流量都走8080端口。这样方便防火墙设置和管理。
[nginx]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains=frps_ip
这样我就使用http://frps_ip:8080来访问我们本地的nginx服务。
相关知识可以参考下面网站
https://www.cnblogs.com/hahaha111122222/p/8509150.html
https://www.cnblogs.com/TianyuSu/p/11961994.html
正好我们有个花生壳,有个域名和2个端口映射资源。我们可以配置一下。
1)设置花生壳代理端口为frps的vhost_http_port(8080)。
2)将下面配置添加到frpc.ini,重启frpc容器。
3)打开一个无痕窗口(避免缓存)输入花生壳的地址https://fasd5asdac36.yirdp.fun 即可访问我们内网设备的管理页面。
[http-nginx-hsk]
type = http
local_ip = 192.168.11.121
local_port = 80
custom_domains=fasd5asdac36.yirdp.fun
# cat frpc.ini
[common]
server_addr = frps_ip
server_port = 7000
# authentication_method = token
# authenticate_new_work_conns = true
# token = 12345678
[device-1]
type = http
local_ip = 127.0.0.1
local_port = 80
custom_domains=device-1.yyyyyy.xxx
[device-2]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 21580
[tcp-ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 21581
测试方法使用浏览器访问http://frps_ip:8080/正常即可。要想形成域名生态,需要支持泛域名解析,然后把泛域名都解析frps服务器地址即可。奈何我们没有公网ip,没有域名。哈哈哈
frp的项目客户端和服务器都是使用go开发的。不太适合小的嵌入式设备使用。在网上找了一个c写的frp客户端,名为xfrpc。github地址https://github.com/liudf0716/xfrpc.git,openwrt有frp和xfrp 2个包支持。
•下载
git clone https://github.com/liudf0716/xfrpc.git
上面下载报错了,说握手错误。
我设置
git config --global http.sslverfy=false
然后将https改成http居然下载成功了,真是活久见。
git clone http://github.com/liudf0716/xfrpc.git
后来我又使用https又下载成功。
•编译
sudo apt-get update
sudo apt-get install -y libjson-c-dev libevent-dev libssl-dev zlib1g-dev
cd xfrp
mkdir build
cmake -D THIRDPARTY_STATIC_BUILD=ON ..
make
挺顺利就编完了。按照上面的配置可以正常连接服务器,使用功能。
将openwrt-package中的xfrpc包拷贝到qsdk/package中。运行make menuconfig
选中 xfrpc。就可进行编译了。编译命令make package/xfrpc/compile V=s
。
编译挺顺利顺利的。运行时报登录失败问题。
[3][Mon Sep 11 19:07:16 2023][19412](login.c:123) login falied!
[3][Mon Sep 11 19:07:16 2023][19412](control.c:435) login failed
对比x86与嵌入式的日志打印差异,发现tinestam有差异,嵌入式的timestamp异常的大。查看代码, 发现原因是xfrpc对unsignd long 和int64处理的不好导致的。所以使用32位机器要小心一点,里面可能还有类似问题。
嵌入式打印:"timestamp": 7277744305519840168
x86打印:"timestamp": 1694481861,
异常代码:
struct login {
long int timestamp;
};
JSON_MARSHAL_TYPE(j_login_req, “timestamp”, int64, lg->timestamp);
将int64改成int,修正:
JSON_MARSHAL_TYPE(j_login_req, “timestamp”, int32, lg->timestamp);
重新编译后可在嵌入式设备上正常连接上frps服务器,功能正常。
今天就到这里。谢谢大家。