![](https://cdn.jsdelivr.net/gh/Misaka-blog/imgs@main/20230122131157.png)
无需公网IP!CloudFlare Tunnel 零成本实现内网穿透
背景
家里有一台24小时运行的NAS,顺便跑了一些服务。当在公司时,需要访问这些服务,就比较麻烦。传统的方法使用frp做内网穿透。该方案需要一台公网服务器,且有被攻击的风险。 最终使用 CloudFlare Tunnel的方案实现内网穿透,远程访问web服务和SSH连接。
方案简单对比如下:
Frp | Cloudflare Tunnel | |
---|---|---|
成本 | 一台公网的服务器 | 一个域名 |
安全 | 自己保障 | 自带简单防护 |
速度/延迟 | 取决与服务器带宽和延迟 | 取决内网访问国外的质量 |
难度 | 需要一点点linux基础 | docker即可 |
增加服务的方式 | 客户端修改配置文件 | 网页操作 |
总结:
cloudflare除了延迟之外,其他的各方面都有众多优势,特别是安全性方面优势明显。同时因为延迟的问题,不建议做远程桌面等,HTTP的服务是比较适合的。
前提
- 内网24小时运行的主机
- 内网可以连接到cloudflare
- 注册cloudflare
- 有一个域名,并托管到cloudflare
- 内网连接外网稳定
部署流程
创建tunnels
进入账号,点击
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021628257.png)
然后点击
![tunnel](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081543460.png)
点击create tunnel
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021628301.png)
输入自定义的名字
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021628552.png)
然后就将进入到了安装服务的页面
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021628835.png)
这里可以选择多个安装方式,因为我平时使用docker,这里就用docker作为部署方式,复制命令,然后在运行docker
注意:这里是前台启动的方式,需要在命令中加 -d 作为后台启动。比如
docker run -d cloudflare/cloudflared:latest tunnel --no-autoupdate run --token XXXXX
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021628692.png)
等待服务启动后,页面下方会显示连接的客户端,点击Next
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021629216.png)
这里就是你配置内网映射的地方了
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021631309.png)
配置完成后,稍等1-2分钟,等待域名解析记录上传,然后就可以访问了。
多域名部署
tunnel并不是一个服务一个域名,可以做到一个服务映射多个服务,进入列表,点击配置
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021631055.png)
![](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404021631621.png)
继续添加服务即可。
通过 Web SSH 访问服务器
CloudFlare 的 Zero Trust 支持通过 Tunnels 访问 SSH 类型的应用,可以通过 Web SSH 的方式访问服务器;支持多种登陆认证方式,安全性远高于直接暴露公网端口
创建 SSH 应用
- 创建应用
在 Cloudflare 控制台 > Zero Trust > Access > Applications 选择 Add an application 创建新的应用;应用类型为 Self-hosted
![homelab-cloudflare-ssh-application-create.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081624542.png)
- 配置应用信息
指定应用名称,并为应用配置域名;session 的过期时间可以按需配置
![homelab-cloudflare-ssh-configuration-application.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081624576.png)
- 指定访问策略
需要配置访问策略,只允许特定的邮箱登陆;如果需要使用其他的认证方式,如 GitHub/Google SSO 等,可以在 Cloudflare 控制台 > Zero Trust > Settings > Authentication > Login Methods 中添加
![homelab-cloudflare-ssh-configuration-policy.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081624945.png)
- 修改应用类型
在 Additional settings 中,将 Browser rendering 的类型改为 SSH;然后选择保存,这样就配置好 SSH 应用了
![homelab-cloudflare-ssh-set-application-type.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081625339.png)
访问
访问刚才配置的 SSH 服务的域名;会提示使用邮箱或者配置的方式进行登陆
![homelab-cloudflare-ssh-application-login.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081625469.png)
登陆后需要输入服务器的用户名和密码(或者私钥)进行登陆
![homelab-cloudflare-ssh-login-page.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081625148.jpeg)
配置短期证书
在使用时,需要输入用户进行登陆,如果用户不允许密码登陆,还需要使用私钥进行验证;这种方式非常不方便;因此 Cloudflare 提供了短期证书的方式进行认证登陆,用于替代 SSH 密钥
创建用户
如果通过 Web SSH 访问服务器,那么用户必须和使用 SSO 登陆的用户名一致,比如 SSO 登陆账户是 abc,那么服务器也只能使用同名的用户进行短期证书登陆,其他用户名是不支持的
- 创建同名用户
如果想让该用户拥有 root 权限,需要将该用户添加到 wheel 用户组
生成公钥证书
在 Cloudflare 控制台 > Zero Trust > Access > Service Auth > SSH 选择刚才创建的 SSH 应用,然后生成证书
![homelab-cloudflare-service-auth-ssh-generate-key.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081625498.png)
配置公钥
将刚才生成的公钥添加在要登陆的服务器上,路径可以自己配置,最好和 SSH 的配置放在一起
- 将公钥添加到
/etc/ssh/cloudflare-ca.pub
cat <<EOF > /etc/ssh/cloudflare-ca.pub 生成的公钥内容,如 ecdsa-sha2-nistp256 xxxxxxxx open-ssh-ca@cloudflareaccess.org EOF
- 修改 SSH 配置
需要开启公钥认证,并且指定刚才添加的公钥为可信任的 CA 公钥;将以下内容添加到 /etc/ssh/sshd_config
文件中
PubkeyAuthentication yes TrustedUserCAKeys /etc/ssh/cloudflare-ca.pub
- 连接 SSH 用户
用 cloudflare
生成用户配置,并写入到 ~/.ssh/config
文件中
cloudflared access ssh-config --hostname terminal.mydomain.com --short-lived-cert >> ~/.ssh/config
或者可以手动修改写入配置
Match host terminal.mydomain.com exec "/usr/local/bin/cloudflared access ssh-gen --hostname %h" HostName terminal.mydomain.com ProxyCommand /usr/local/bin/cloudflared access ssh --hostname %h IdentityFile ~/.cloudflared/terminal.mydomain.com-cf_key CertificateFile ~/.cloudflared/terminal.mydomain.com-cf_key-cert.pub
重启 SSH
sudo systemctl restart ssh
重启完成后,访问配置的 SSH 域名,通过 SSO 登陆后,即可进入到 Web SSH 命令行界面;登陆的用户为 SSO 登陆用户 abc
![homelab-cloudflare-service-auth-ssh-login.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081625428.png)
![homelab-cloudflare-ssh-login-page.png](https://cdn.jsdelivr.net/gh/upfind/pic-cloud/pic/202404081625366.jpeg)