登录 | 注册

轻扣指间,静听心声

玩转frp:优雅地访问内网设备

发表于 05-05 / 352 阅读 / 0 评论 / 需时7.0’

frp远程操控家里的电脑.png

https://github.com/fatedier/frp/releases

内网设备:OpenWRT、群晖、ESXI,Windows
公网设备:CentOS(腾讯云)4M带宽,安装bt面板(安装nginx等)
目标效果:通过frp无端口访问家里的内网设备

其实我家是有公网ip的,通过DDNS和端口转发,完全可以高速(100M)访问内网的设备,远程看4k蓝光都不用转码,非常爽的!
但是呢,为了避免极其偶尔ip变化时恰好要访问,所以要再利用frp备一个随时可用的方案。(本质来说就是折腾)。并且"域名+端口"毕竟不够优雅简洁。

遂有此文,记录备用。下文基本所有涉及到的端口都可以自定义的,并且要在服务器放行。

服务端安装配置

1, 下载frps

wget https://github.com/fatedier/frp/releases/download/v0.58.1/frp_0.58.1_linux_amd64.tar.gz
tar -zxvf frp*.tar.gz
mv frp_0.58.1_linux_amd64 frps

上面把解压后的文件放到frps文件夹里(路径为/usr/local/frps)

2,配置frps

配置frps.toml vim frps.toml

bindPort = 7000
vhostHTTPPort = 8080
vhostHTTPSPort = 8088
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "设置一个用户用"
webServer.password = "设置一个密码"
webServer.tls.certFile = "/www/server/panel/vhost/cert/zizdog.com/fullchain.pem"
webServer.tls.keyFile = "/www/server/panel/vhost/cert/zizdog.com/privkey.pem"
auth.method = "token"
auth.token = "你的token,随便设置一个"

说明:
bindPort frp的主端口,用于和客户端建立联系
vhostHTTPPort frp的http监听端口
webServer.addr frp监控面板(dashbord)的地址,如果需要外网访问,必须为"0.0.0.0"
webServer.port frp监控面板(dashbord)的端口
webServer.userwebServer.password frp监控面板(dashbord)的用户名,密码【可选】
webServer.tls.certFilewebServer.tls.keyFile 【可选】,如果你也和我一样已经部署了bt,那么直接像我一样填写bt面板生成的证书路径,会非常方便的。
auth.method frp服务加密方式,默认就是token
auth.token 对应上一项的密钥,自己设置。

3,启动frps

cd frps
./frps -c frps.toml

此时如果关闭命令窗口,服务就会停止了。可以用后台不挂断的命令运行:

nohup ./frps -c ./frps.ini

但是,如果想要开机运行,最好是新建一个frps的系统服务。

vim /etc/systemd/system/frps.service

然后在 frps.service 内填入:

[Unit]
Description=frps
After=network.target syslog.target
Wants=network.target

[Service]
Type=simple
ExecStart=/root/frps/frps -c /root/frps/frps.toml
Restart=always

[Install]
WantedBy=multi-user.target

保存退出后,就可能通过控制系统服务的方式操作frps了,如下:

systemctl enable frps   #开启开机自启动frps服务
systemctl disable frps   #关闭开机自启动frps服务
systemctl start frps   #启动frps服务
systemctl stop frps   #停止frps服务
systemctl status frps   #查看frps服务状态

4,访问frps的监控面板(dashboard)

此时,访问ip:7500输入用户名和密码就可以了。
但是,前面说了,不要这种加端口的访问,那么可以用nginx代理一下。
我是将 除了用于直接解析到家中公网ip的所有其它二级域名都解析到了主域名zizdog.com上。
因此在bt面板中,网站zizdog.com的配置文件中写入以下内容:

server{
    listen  80;
    listen  443;
    server_name     frp.zizdog.com;
    if ($server_port !~ 443){
        rewrite ^(/.*)$ https://$host$1 permanent;
    }
    
    location / {
            proxy_pass https://127.0.0.1:7500;
            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;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

此时,我们就实现了,当访问frp.zizdog.com时,会转发到7500端口,也就打开了frp的dashbord,并且强制https。

同样的思路,我们可以提前把所有想通过域名来定向到内网特定位置的内容都写好。当然,这部分还要配合内网的反向代理来共同实现!这部分在下在frpc的配置中再补充。先搞frps端。

如:想要通过op.zizdog.com访问家中的OpenWRT,配置如下:

server{
    listen  80;
    listen  443;
    server_name     op.zizdog.com;
    
    location / {
            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;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

如:想要通过esxi.zizdog.com访问家中的ESXI,配置如下:

server{
    listen  80;
        listen 443;
    server_name esxi.zizdog.com;

    location / {
            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;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

基本就是一个思路:

用nginx将指定域名定向到服务器的8080端口,也就是frps的http端口。 举一反三的话可以把 群晖,内网站点都搞定。

客户端安装配置

这内网有一台winServer2012是7x24小时开机的,所以就以此为例来写了;当然,您也可以把frpc部署到 群晖等其它设备中。只要一直在线就行。

下载frp_0.58.1_windows_amd64.zip

我解压后放在了C:\frpc里面;配置frpc.toml

serverAddr = "公网ip"
serverPort = 7000

auth.method = "token"
auth.token = "你在frps中设置的"

[[proxies]]
name = "RDP"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 33891

这里再次强调所有端口在服务端放行

启动客户端

命令行进入目录

.\frpc.exe -c .\frpc.ini

放行端口

中间强调一下放行相应端口,如果你访问不成功,先想想是不是对应的端口没放开。

访问

例如要访问这台winServer2012,远程桌面客户端访问服务器ip:33891就ok了

设置客户端开机自启动

两个办法:

1,新建计划任务

新建frp.vbs文件,内容如下(替换c:\frpc\为自己的相应位置)

Set ws = CreateObject("Wscript.Shell") 
ws.run "cmd /c c:\frpc\frpc.exe -c c:\frpc\frpc.ini",vbhide

将frp.vbs文件的快捷方式放到启动目录。一定要是快捷方式哦!!

C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

不同版本系统位置不尽相同,可以:开始-运行-shell:startup,直接打开文件夹。

另外,如果不想要看到运行窗口的话,新建frp.bat文件输入以下内容(替换c:\frpc\为自己的相应位置)

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cd C:\frp
frpc -c frpc.ini
exit

同样的,将frp.bat的快捷方式放到启动目录就可以了。

1.2,设置frpc开机自动启动时不管用户是否登陆都要运行

这个比较重要,不然每次都得在本地启动并进去,之后才能顺利外网使用frp访问。
这里要用到windows自带的“任务计划程序” ,操作如下。
首先我们简化一下启动脚本start.bat

@echo off
:home
frpc -c frpc.ini
goto home

打开开始菜单,输入 “任务计划程序” 将会自动搜索,接着打开它。点击右侧的 “创建任务”。

1.png

任务名称随意填写,安全选项选择 “不管用户是否登录都要运行”,这样可以让你的电脑在断电自动启动后自动运行 frp,你就可以远程桌面连接电脑了。
“使用最高权限运行” 也是可选的,根据个人需要可以选上。
最后勾选 “隐藏”,就不会在启动时弹出命令行窗口了。

2.png

接着转到 “触发器” 页,点击新建,选择 “启动时”。

3.png

接着转到 “操作” 页,点击新建,选择 “启动程序”
在程序或脚本一栏选择第一步创建的 start.bat,下面的 “起始于” 填写 start.bat 的路径(不要包含 start.bat)
例如你的 start.bat 在 C:\frp\start.bat,那么你只需要在 “起始于” 填写 C:\frp\

4.png

2,复用nssm工具将frpc新建为系统服务

下载nssm解压后在win64/32找到 nssm.exe 放在frpc目录里,管理员身份打开cmd 后cd到frpc目录下运行

nssm install frpc

会弹出操作框

frpc-nssm-1.jpg

之后到 任务管理器→服务 中启动 frpc 服务即可。以后重启系统frpc服务也会自动重启了。
如果改动的frpc的配置,要手动重启一下该服务。

frpc中http的配置

[[proxies]]
name = "openwrt"
type = "http"
localIP = "127.0.0.1"
localPort = 1001
customDomains = ["op.zizdog.com"]

[[proxies]]
name = "esxi"
type = "http"
localIP = "127.0.0.1"
localPort = 1002
customDomains = ["esxi.zizdog.com"]

[[proxies]]
name = "bmc"
type = "http"
localIP = "127.0.0.1"
localPort = 1003
customDomains = ["bmc.zizdog.com"]

[[proxies]]
name = "nas"
type = "http"
localIP = "127.0.0.1"
localPort = 1004
customDomains = ["nas.zizdog.com"]

以上内容为了通过相应的域名访问相应的内网内容。同样地,为了方便反向代理,我在winServer2012上也安装了bt面板,并安装了nginx(其实只单独安装nginx也行,不一定要装宝塔)。
并在【站点127.0.0.1】中配置内容:

server{
    listen  1001;
    server_name     127.0.0.1;
    
    location / {
            proxy_pass https://192.168.1.1;
            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;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

server{
    listen  1002;
    server_name     127.0.0.1;
    
    location / {
            proxy_pass https://192.168.1.2;
            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;

        proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}
server{
    listen  1003;
    server_name     127.0.0.1;
    
    location / {
            proxy_pass https://bmc.zizdog.com;
            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;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

server{
    listen  1004;
    server_name     127.0.0.1;
    
    location / {
            proxy_pass http://192.168.1.4:5000;
            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;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    }
}

说明:以其中一个为例。

当frpc与frps打通时,我们通过op.zizdog.com访问,则frpc端会去找本地(也就是winServer2012)的1001端口“要”内容并返回给frps。
我们在winServer2012中的nginx中将1001端口又定向到了局域网的192.168.1.1地址处(也就是路由器),因此,我们也就可以通过op.zizdog.com访问到我们家中的路由器了。

其它几处配置都是一个意思,想访问其它什么内网设备,继续添加配置内容即可。
值得一提的是,我们在服务端已经“复用”了主站的ssl,所以可以很方便的实现全域的ssl访问,十分舒爽!

番外

远程唤醒家里的电脑,这个很有必要,不然就要一直开机备用,不环保。网上方法多的是,个人有个最简单低成本的方法,买个20几块的米家插座,电脑设置通电开机,就可以了。

done!

本文最后更新时间为 2024-06-27 21:12

评论功能已关闭!
可点击网站右下角图标,直接给博主发实时信息。