使用cloudflare tunnel打洞,随时随地访问内网服务

  由于我家的网络只有ipv6,没有公网ipv4,导致两个问题:

  • ipv4网络下,无法访问家里的服务。
  • 常用端口(80,443)被屏蔽了,要访问的话,必须带上端口号,例如:example.com:9527

  cloudflare tunnel很好地解决了这两个问题,有了它我们甚至不需要公网ipv4或ipv6,可以把它理解为免费的打洞工具frp。唯一的缺点是速度可能不够理想,我家里的网络,单连接只有几百k/s,多连接可以跑满上行带宽2M/s,公司的网络单连接也能跑满上行带宽。可以把cloudflare作为备用,在无法使用ipv6的情况下,也至少能低速访问自己的服务。

安装

前置条件

  • 一台已连接互联网的linux服务器(不需要公网ip)
  • cloudflare账户,虽然cloudflare tunnel套餐是免费的,但可能需要绑卡
  • 一些基础的linux知识

如果对下面的内容有疑惑,欢迎提问

准备

   首先需要有一个域名,并把它的DNS迁到cloudflare,因为我的域名就是在cloudflare买的,所以这里没有教程,不赘述。随后进入Cloudflare Zero Trust控制面板,初次使用需要选择Plan,选择Free Plan,白嫖就完事了sticker

服务器安装cloudflared

  在linux服务器上安装cloudflared,我的系统是manjaro,直接yay -S cloudflared就欧了,安装成功后,在命令行执行cloudflared应该就有输出。

配置与转发

  在服务器上配置tunnel,有两种配置方式,一种是通过cloudflare控制台,另一种是通过命令行。我使用的是命令行,写脚本比较方便,有如下几步(以下示例使用yunyuyuan作为服务器的用户名,example.com作为域名):

  1. 创建tunnel

    # 登录cloudflare cloudflared tunnel login # 创建一个tunnel,名字自定,这里用my-tunnel cloudflared tunnel create my-tunnel

    然后, 执行cloudflared tunnel list显示my-tunnel的ID:

    ~ $ cloudflared tunnel list ID NAME CREATED CONNECTIONS xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx my-tunnel 2023-01-08T02:26:41Z 2xLAX, 2xSJC
  2. 编写配置文件,vim ~/.cloudflared/config.yml

    tunnel: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx credentials-file: /home/yunyuyuan/.cloudflared/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json ingress: # ssh - hostname: ssh.example.com service: ssh://localhost # vnc远程桌面,端口5900 - hostname: vnc.example.com service: tcp://localhost:5900 # 其他http服务 - hostname: file.example.com service: http://localhost:9527 - hostname: speed-test.example.com service: http://localhost:9898 # 如果都没有匹配,则返回404,这句不能少 - service: http_status:404
  3. 写一个脚本,自动更新DNS以及运行tunnel,vim ~/tunnel-sh.sh

    # update cloudflare DNS record /usr/bin/cloudflared tunnel route dns my-tunnel ssh.example.com /usr/bin/cloudflared tunnel route dns my-tunnel vnc.example.com /usr/bin/cloudflared tunnel route dns my-tunnel file.example.com /usr/bin/cloudflared tunnel route dns my-tunnel speed-test.example.com # run tunnel /usr/bin/cloudflared tunnel run my-tunnel
  4. 开机自启

    新建一个service,sudo vim /etc/systemd/system/cloudflared-tunnel.service

    [Unit] Description=cloudflared tunnel Wants=network-online.target After=network-online.target StartLimitInterval=300 [Service] User=yunyuyuan ExecStart=sh /home/yunyuyuan/tunnel-sh.sh # 如果启动失败,自动重试,因为开机自启大概率报错网络问题 Restart=always RestartSec=30 [Install] WantedBy=default.target

    启动&开机自启

    sudo systemctl start cloudflared-tunnel.service sudo systemctl enable cloudflared-tunnel.service

  以上完成后,http服务便可以正常使用,访问http://file.example.com/wtf相当于访问服务器的http://localhost:9527/wtf。服务端到此已配置完毕。

ssh访问

  需要在客户端也安装cloudflared,安装方式和上面一样,我的客户端是Windows,下载cloudflared-windows-amd64.exe文件,然后添加一个ssh配置

Host ssh.example.com # 把 D:\tools\cloudflared-windows-amd64.exe 改成你自己的目录 ProxyCommand D:\tools\cloudflared-windows-amd64.exe access ssh --hostname %h

  使用ssh yunyuyuan@ssh.example.com即可ssh登录。

vnc远程桌面

  客户端使用vnc远程桌面访问服务器(假设服务器已经开启了vnc server),需要先在客户端的命令行里执行cloudflared access tcp --hostname vnc.example.com --url tcp://localhost:5901,这个命令把vnc.example.com(对应服务器的tcp://localhost:5900)映射到客户端本地的tcp://localhost:5901。   然后我们用vnc viewer,或者其他vnc软件,使用localhost:5901登录VNC。

浏览器访问SSH&VNC

  浏览器本身不支持ssh和vnc,cloudflare的application提供了ssh和vnc浏览器渲染功能。首先,创建一个application,域名输入vnc.example.com,在Settings界面选择Browser rendering为VNC: 选择VNC选择VNC   保存后,访问http://vnc.example.com,输入密码登陆VNC(我的域名是vnc.yunyuyuan.net): 浏览器上的VNC浏览器上的VNC   SSH同理,域名输入ssh.example.comBrowser rendering选择SSH,保存后访问http://ssh.example.com可以看到一个终端界面。

Tips

  上面把file.example.com等4个域名都用在了cloudflare tunnel,如果你的客户端有ipv6,此时不用通过cloudflare tunnel便可访问服务器,则可以新建一个file-direct.example.com的DNS解析,ip指向服务器的公网ipv6就可以了。   做一个门户界面,把服务的URL都放到上面,切换是否使用代理,显示不同的链接。不代理的url是http://file-direct.example.com:9527,代理的url是http://file.example.com门户门户

1年前
0