由于我家的网络只有ipv6,没有公网ipv4,导致两个问题:
- ipv4网络下,无法访问家里的服务。
- 常用端口(80,443)被屏蔽了,要访问的话,必须带上端口号,例如:example.com:9527
cloudflare tunnel很好地解决了这两个问题,我们甚至不需要公网ipv4或ipv6,可以把它理解为免费的frp,唯一的缺点是速度不够理想,可以把cloudflare作为备用,在无法使用ipv6的情况下,也至少能低速访问自己的服务。
安装
前置条件
- 一台已连接互联网的linux服务器(不需要公网ip)
- cloudflare账户,虽然cloudflare tunnel套餐是免费的,但可能需要绑卡
- 一些基础的linux知识,如果对下面的内容有疑惑,欢迎提问
准备
首先需要有一个域名,并把它的DNS迁到cloudflare,这里不赘述。随后进入Cloudflare Zero Trust控制面板,初次使用需要选择Plan,选择Free Plan,白嫖就完事了。
服务器安装cloudflared
需要在服务器上安装cloudflared,我的系统是manjaro,直接yay -S cloudflared
就欧了,安装成功后,在命令行执行cloudflared
应该就有输出。
配置与转发
在服务器上配置tunnel,有两种配置方式,一种是通过cloudflare控制台,另一种是通过命令行。我使用的是命令行,写脚本比较方便,有如下几步(以下示例使用yunyuyuan作为用户名,example.com作为域名):
- 创建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
- 编写配置文件,
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
- 写一个脚本,自动更新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
- 开机自启
新建一个service,
sudo vim /etc/systemd/system/cloudflared-tunnel.service
[Unit] Description=cloudflared tunnel Wants=network-online.target After=network-online.target [Service] User=yunyuyuan ExecStart=sh /home/yunyuyuan/tunnel-sh.sh [Install] WantedBy=default.target
启动&开机自启
sudo systemctl start cloudflared-tunnel.service sudo systemctl enable cloudflared-tunnel.service
以上完成后,http服务便可以正常使用,访问http://file.example.com/wtf
相当于访问服务器的http://localhost:5885/wtf
。服务端到此已配置完毕。
ssh访问
需要在客户端也安装cloudflared,安装方式和上面一样,我的客户端是Windows,下载一个.msi文件安装,命令行执行install命令就行了。然后#添加一个ssh配置:
Host ssh.example.com
# 把 D:\tools\cloudflared-windows-amd64.exe 改成你自己的目录
ProxyCommand D:\tools\cloudflared-windows-amd64.exe access ssh --hostname %h
使用ssh [email protected]
即可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: 保存后,访问http://vnc.example.com
,输入密码登陆VNC: SSH同理,域名输入ssh.example.com
,Browser rendering选择SSH,保存后访问http://ssh.example.com
可以看到一个终端界面。
Tips
上面把file.example.com
等4个域名都用在了cloudflare tunnel,如果你有ipv6,想要不通过cloudflare tunnel访问服务器,则可以新建一个_file.example.com
的DNS解析,ip指向服务器的公网ipv6就可以了。
可以做一个门户界面,把服务都放到上面,切换是否使用代理,显示不同的链接,不代理的url是http://_file.example.com:9527
,代理的url是http://file.example.com
: