最近遇到一个在 Windows 上运行 FRP 的需求,并且要开机自启、无明显感知。结合之前在办公室电脑设置虚拟机自启动的一些操作,在此一并简单做一个记录。
一、内网穿透
端口映射
目前主流的端口映射工具包括 frp、rathole、tailscale、zerotier 等等。frp 基于 go 语言构建,使用简便且应用广泛。rathole 由群友推荐给博主,是基于 rust 语言构建的,整体使用体验差不多。tailscale 据称具有良好的性能优势,对并发性能有需求时可以考虑。zerotier 则是基于 udp 构建的互联,支持打洞和虚拟局域网的构建。
如果你的网络是 NAT1,还可以尝试比如 Natter 这样的工具(点击前往)进行打洞实现向公网暴露本地端口。关于这些工具的具体使用在此就不再赘述了,仅用作简单的推荐。
Argo Tunnel
CloudFlare Argo Tunnel 可以作为一个简便、快捷的内网穿透工具,它是通过本地客户端与 Argo 边缘节点建立隧道从而实现免公网IP接入 CloudFlare 的网络。支持的协议主要是 HTTP、HTTPS 这样的 WEB 协议,同时也能在此基础上承载如 websocket、grpc 等流量。在客户端的配置中,首先要安装对应版本的客户端:
随后,我们需要按照一般的流程创建一个隧道以获取隧道的配置参数:
# 登陆,并选择授权使用的域名
cloudflared tunnel login
# 创建隧道,此处参数:创建create | 删除delete | 列出list
cloudflared tunnel create argo-sample
# 绑定域名
cloudflared tunnel route dns argo-sample argo-sample.luotianyi.vc
# 临时测试(下发CF提供的临时子域名)
cloudflared tunnel --url localhost:2333
# 正式运行,可参考下文添加运行参数
cloudflared tunnel run --url localhost:2333 argo-sample
到这一步,在 Linux 上就可以直接使用 syetemd 引导隧道启动了。但是在 Windows 上会存在一个问题,使用命令行创建的隧道 pem 和 json 文件位于用户目录如 C:\Users\luminous\.cloudflared 下,当其他用户或以 service 启动隧道时是获取不到这些信息的。来解决这个问题,就需要按照上一步获取的隧道参数写一个 YMAL 格式的 .yml 配置文件。
# Argo隧道的UUID
tunnel: c4c811c0-a514-4f02-9164-0e607d97fb85
# Argo隧道的json路径
credentials-file: C:\cloudflared\c4c811c0-a514-4f02-9164-0e607d97fb85.json
ingress:
# 设置Argo绑定的域名
- hostname: argo-sample.luotianyi.vc
service: http://localhost:8880
# 默认返回404错误
- service: http_status:404
# 设置log路径(非必要)
logfile: C:\cloudflared\cloudflared.log
配置好 config.yml 后,选择合适的参数启动 cloudflared 即可。–protocol 参数默认为 quic,建议使用 http2 或 h2mux 来避免潜在的 qos 等问题。–edge-ip-version 用于指定使用 4(IPv4) 或 6(IPv6) 连接至边缘节点。–region 参数目前仍在开发中,当前仅支持使用 –region=us 指定连入位于美国的边缘节点。
cloudflared --config=C:\cloudflared\config.yml --protocol http2 --edge-ip-version 4 tunnel run
参数文档:点击前往
使用配置文件启动也有一个很明显的好处,yml 和 json 配合能够向任意客户端提供该隧道的凭证信息。因此,你可以很轻松地在不同的客户端上启动该隧道,而不需要每次更换客户端时都进行删除重建以获取适用于本机的配置参数。
二、开机启动
结合以上的实例,我选择了几个例子来介绍常用的开机自启方法。
Linux Systemd
Linux 下博主一般喜欢使用 systemd 来引导进程的启动,因为不需要特殊的依赖。使用任意编辑器 /etc/systemd/system/example.service,将修改好的一下内容添加进去即可。
[Unit]
Description=Examle Service
After=network.target
[Service]
Type=simple
#当不需要用户权限时,可以使用nobody
User=root
Restart=on-failure
RestartSec=5s
#可指定该进程的运行目录
WorkingDirectory=/home
#执行命令需要绝对路径,请先在ssh中确定其可运行
ExecStart=/home/cloudflared tunnel run --url localhost:2333 argo-sample
[Install]
WantedBy=multi-user.target
随后,使用systemctl和service指令即可对进程进行管理:
◉ 重载配置:systemctl daemon-reload
◉ 进程管理:service example start|stop|restart
◉ 设置自启:systemctl enable|disable example
Linux PM2
有些朋友在开发或使用 Node.js,守护进程常常会用到 pm2 管理器,实际上 pm2 也可守护其他的软件进程。但是如果你没有使用 Node.js 或对 pm2 完全没有了解,那还是建议使用 systemd 来进行进程守护。
# 安装PM2管理器
npm -i pm2 -g
# 其中-x指定二进制文件,-n指定名称,--后为传递的参数
pm2 start -x '/home/frps' -n frp -- -c /home/frps.ini
# 如python文件,使用--interpreter参数指定类型
pm2 start sample.py --interpreter python -n sample -- -c config.json
# 保存当前配置
pm2 save
# 生成开机进程
pm2 startup
systemctl enable pm2-root
# 列出程序并管理进程
pm2 ls
pm2 start|restart|stop|delete frps
Windows StartUp
通过 Win+R 组合键打开运行窗口,输入 shell:Common Startup 回车能够打开 Windows 的启动文件夹。在该文件夹中的脚本、程序或者它们的快捷方式在进入系统时会自动执行一次,这样就实现了开机自启。不过这样启动部分程序会存在一定的问题,比如博主之前一直是在frp的目录下放一个内容为 .\frpc.exe -c .\frpc.ini 的 bat 脚本并将其快捷方式放在启动文件夹里,这样的话在进程运行后会弹出 cmd 的黑框,若关闭该 Terminal 则程序就停止了。
解决这个问题也并不复杂,可以使用Bat2Exe(点击前往)或Bat to EXE Converter(点击前往)这样的程序将脚本封装为EXE,在其中勾选Hide Console选项即可,启动后程序便会在后台静默运行。
三、结语
以上就是博主关于内网穿透和Argo的简单总结,关于这块感觉大家使用的方式挺多的,比如python会更倾向于使用supervisor。博主见识有限,没有办法一一总结出来,暂且整理至此,如果以后有新的发现会进行补充。
再次也欢迎大家在评论区分享你的经验,如果文章中存在错误也在评论中指出~