feios
文章18
字数23.9k
分类4
配置frp内网穿透

配置frp内网穿透

通过frp stcp实现windows远程连接

开始使用

为何要用 frp

国内特殊的互联网环境导致个人的家庭宽带很难获得外网ip,导致无法在外网访问自家的内网。通过使用一台具有外网ip的主机进行frp内网穿透,可以方便的在外网访问内网,不过对于远程桌面这种信息敏感的应用场景,需要更安全的配置方法。

frp带给我们stcp的方法来更安全地突破内网限制。
以下是官方给的原理图

architecture.png

下载地址

fatedier/frp: A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet. github.com 图标

基本使用方法(Windows 远程桌面)

单独使用这种最基本的连接方式不够安全,通常情况下建议只用于入门和测试设备之间是否能连通

服务端

以当前版本 0.35.1 为例,在linux下配置服务端:

// 下载
$ wget https://github.com/fatedier/frp/releases/download/v0.35.1/frp_0.35.1_linux_amd64.tar.gz
// 解压
$ tar -zxvf frp_0.35.1_linux_amd64.tar.gz
// 进入文件目录
$ cd frp_0.35.1_linux_amd64
// 编辑服务端配置文件
$ vi frps.ini
//frps.ini

[common]
bind_port = 7000
// 启动服务端
$ ./frps -c ./frps.ini

客户端

Windows / Mac 下载解压即可
win: https://github.com/fatedier/frp/releases/download/v0.35.1/frp_0.35.1_windows_amd64.zip
win+r 打开cmd,在文件目录下执行start frpc.exe即可启动,文章底部有更好的办法

mac: https://github.com/fatedier/frp/releases/download/v0.35.1/frp_0.35.1_darwin_amd64.tar.gz
进入“终端”,在目录下输入指令./frpc -c ./frpc.ini

// frpc.ini

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

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 3389
remote_port = 3389

设置“允许远程连接到此计算机”
IMG_5297.jpg

通过这些设置之后,你电脑的3389端口会暴露到外网,在任何有网的地方访问x.x.x.x即可连接
IMG_5296.jpg

生产环境用法

stcp

这是一种更安全的连接方法,相当于连接远程的一方要念对暗号才能打开大门,在此之前,端口不会暴露在互联网上,增加了安全性

IMG_5295.png
*图片来自网络

服务端

在有外网ip的机器上,

# frps.ini

[common]
bind_port = 7000
// token 鉴权
authentication_method = token
token = token
// 只允许 tls 连接
tls_only = true

// 网页状态面板
dashboard_port = 8888
dashboard_user = admin
dashboard_pwd = admin

通过 ./frps -c ./frps.ini 启动服务端

客户端 1

在需要通过外网访问的机器上

# frpc.ini

[common]
server_addr = x.x.x.x
server_port = 7000
authentication_method = token
token = token
tls_enable = true

[frp_visitor]
type = stcp
# stcp 的访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = frp
# 只有 sk 一致的用户才能访问到此服务
sk = token
# 绑定本地端口用于访问 远程桌面 服务
bind_addr = 127.0.0.1
bind_port = 6000
# true 启用加密
use_encryption = false
# true 启用压缩
use_compression = false

通过 ./frpc -c ./frpc.ini 启动客户端

客户端 2

在需要连接远程的机器上

# frpc.ini

[common]
server_addr = x.x.x.x
server_port = 7000
authentication_method = token
token = token
tls_enable = true

[frp]
type = stcp
sk = token
local_ip = 127.0.0.1
local_port = 3389
# true 启用加密
use_encryption = false
# true 启用压缩
use_compression = false

通过 ./frpc -c ./frpc.ini 启动客户端


xtcp

这是一种基于stcp上的p2p(点对点)的连接方法,理论上延迟更低。但是目前功能开发不够完善,还不太稳定,建议还是首选stcp。

IMG_5294.png
*图片来自网络

frpc.ini 中的 type = stcp 改成 xtcp即可

服务端

不变

客户端 1

在需要通过外网访问的机器上

# frpc.ini

[common]
server_addr = x.x.x.x
server_port = 7000
authentication_method = token
token = token
tls_enable = true

[frp_visitor]
type = xtcp
# stcp 的访问者
role = visitor
# 要访问的 stcp 代理的名字
server_name = frp
# 只有 sk 一致的用户才能访问到此服务
sk = token
# 绑定本地端口用于访问 远程桌面 服务
bind_addr = 127.0.0.1
bind_port = 6000
# true 启用加密
use_encryption = false
# true 启用压缩
use_compression = false

通过 ./frpc -c ./frpc.ini 启动客户端

客户端 2

在需要连接远程的机器上

# frpc.ini

[common]
server_addr = x.x.x.x
server_port = 7000
authentication_method = token
token = token
tls_enable = true

[frp]
type = xtcp
sk = token
local_ip = 127.0.0.1
local_port = 3389
# true 启用加密
use_encryption = false
# true 启用压缩
use_compression = false

通过 ./frpc -c ./frpc.ini 启动客户端


建立本地 http 服务器

官方示例

通过自定义域名访问内网的 Web 服务 gofrp.org 图标

服务端

# frps.ini

[common]
bind_port = 7000
// token 鉴权
authentication_method = token
token = token
// 只允许 tls 连接
tls_only = true

// 
vhost_http_port = 8080

// 网页状态面板
dashboard_port = 8888
dashboard_user = admin
dashboard_pwd = admin

客户端

[common]
server_addr = x.x.x.x
server_port = 7000
token = token
tls_enable = true

[web]
type = http
local_port = #port
custom_domains = #domains

更优雅的使用方式

网上其他教程都简单粗暴的地直接运行命令启动frp,但显然不够优雅,基于这个原因我研究了两种更优雅的使用方式

进程守护脚本

这个东西一旦不小心关闭,远程就无法进行下去。
所以做了一个守护脚本,30s自动检测进程是否存在,一定程度上避免了因为意外关闭导致的麻烦

1007AADA-3180-4A59-8E80-738D1F5E0A19.png

@ECHO OFF
setlocal enabledelayedexpansion



rem 设置进程检测延迟, 单位 (秒)
set /a check_delay = 30



mode 82,12
set "d=%~p0"
set "d=%d:\= %"
for %%a in (%d%) do set name=%%a
set /a var=0
start frpc.exe
:loop
set /a var=%1+1
set /a var2=%var%-1
if %var2%==0 (set num= ) else (set num= 已重启 !var2! 次 restart_service.txt中具有详细信息)
title %name% 进程守护%num%
echo ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
echo ┃             ______     ______     __  __               ┃ 
echo ┃            /\___  \   /\___  \   /\ \_\ \              ┃ 
echo ┃            \/_/  /__  \/_/  /__  \ \____ \              ┃
echo ┃              /\_____\   /\_____\  \/\_____\             ┃
echo ┃              \/_____/   \/_____/   \/_____/             ┃
echo ┃                                        ┃
echo ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
echo 正在守护 %name% 进程, 当前 %check_delay%s 检测一次, 延迟可在文件中修改
tasklist|find /i "frpc.exe"
if %errorlevel%==0 (
goto true
) else (
goto false
)
goto :loop

:true
echo 日期:%DATE% 时间:%time%  ok
ping -n %check_delay% -w 500 127.1>nul
cls
goto loop

:false
start frpc.exe
echo 未检测到进程
echo 启动 %name% ...
echo 程序重新启动于 日期:%DATE% 时间:%time% >> restart_service.txt
ping -n 5 -w 500 127.1>nul
cls
call :loop %var%

通过 Windows 服务的方式运行 (推荐)

优势

这种方法无运行窗口,开机以服务方式启动。放在启动项的方式,则需要登录之后才能运行

85915105-5192-4D6B-A265-705339045196.png

winsw/winsw: A wrapper executable that can run any executable as a Windows service, in a permissive license. github.com 图标

我下载的版本: https://github.com/winsw/winsw/releases/download/v2.10.2/WinSW.NET4.exe

下载之后,把文件放在frp目录下,新建一个‘文件名’+.xml的文件,比如WinSW.NET4.xml,并写上以下内容

// WinSW.NET4.xml

<service>
<id>frp</id>
<name>frp</name>
<description>Frp Client</description>
<executable>frpc</executable>
<arguments>-c frpc.ini</arguments>
<logmode>reset</logmode>
</service>

便捷管理

新建一个cmd,复制以下内容,就能便捷管理了

7E5DEE14-1725-481F-A1AB-6BADACFAE6D7.png

// 安装服务.cmd

    @ECHO OFF
    :home
    title frp 注册成 Windows 服务
    cls
    echo 当前服务运行状态:
    WinSW.NET4.exe status
    echo ---------------------------------------------------------------
    echo     请选择任务。
    echo ---------------------------------------------------------------
    echo     [1]安装服务
    echo     [2]安装服务并启动
    echo     [3]启动服务
    echo     [4]停止服务并等待,直到它实际上停止为止
    echo     [5]卸载服务
    echo     [6]退出脚本。
    echo ---------------------------------------------------------------

    choice /n /c 12345678 /m "请输入数字选择:"
    cls
    if errorlevel 6 exit
    if errorlevel 5 goto uninstall
    if errorlevel 4 goto stopwait
    if errorlevel 3 goto start
    if errorlevel 2 goto installandstart
    if errorlevel 1 goto install
    
    :install
    WinSW.NET4.exe install
    goto choice

    :installandstart
    WinSW.NET4.exe install
    WinSW.NET4.exe start
    goto choice

    :start
    WinSW.NET4.exe start
    goto choice

    :stopwait
    WinSW.NET4.exe stopwait
    goto choice

    :uninstall
    WinSW.NET4.exe stop
    WinSW.NET4.exe uninstall
    goto choice

    :choice
    echo ---------------------------------------------------------------
    echo     [1]返回
    echo     [2]退出脚本
    echo ---------------------------------------------------------------
    choice /n /c 12 /m "请输入数字选择:"
    cls
    if errorlevel 2 exit
    if errorlevel 1 goto home