自建的nextcloud在使用docker部署时,没有选择映射80端口,而且其默认的nginx配置也是把80端口的访问重定向到了443端口,因此只能使用https协议访问。搜索网上资料时发现,大部分的frp(fatedier/frp)教程是把外网的https访问转换成http协议来访问内网客户端,这显然不符合我的需求。

查看frp的发行日志,发现其在0.36版本开始新增了https2https插件,实现了内外网的https转换,下面就做一个简单记录。

服务器端的配置

# filename: frps.ini
[common]
bind_port = 7000
token = xxxxxxx
# https访问时使用的端口
vhost_https_port = 8000

HTTP 和 HTTPS 协议的一个特点是发送的请求都具有 Host 字段,通过该字段描述要访问的服务。基于这个特点,frp 服务端只需要监听在一个端口(通过 vhost_http_portvhost_https_port 指定)。就可以根据请求的 Host 来决定需要路由给哪一个代理,而不需要像 TCP 类型那样为每一个服务绑定一个端口。

简而言之,需要代理的https访问都需要发送到该端口。

客户端配置

#filename: frpc.ini
[common]
server_addr = x.x.x.x
server_port = 7000
token = xxxxxxx

[nextcloud_web]
type = https
custom_domains = www.domain.com
plugin = https2https
# 本地服务地址
plugin_local_addr = 127.0.0.1:8443
# https所需的证书文件
plugin_crt_path = /root/certs/cert.pem
# https所需的密钥文件
plugin_key_path = /root/certs/key.pem

注意要使用正确的证书,如本例的域名为www.domain.com,则应该使用该域名对应的证书,而不是之前自己手动生成的证书。证书的申请在此不再赘述,网上的教程很多。可以在域名提供商处下载免费的单域名证书,也可以用acme.sh生成泛域名证书。

启动frp

  1. 分别启动frps和frpc。注意服务器端放行frps监听的端口。

  2. 尝试通过https://www.domain.com:8000访问nextcloud,会弹出如下提示,告诉我们不是从可信任的域名访问的,根据提示,只需要将我们的域名加入到trusted_domains中即可。

    image-20210822112059743

    如果和我一样使用的是linuxserver发布的nextcloud镜像,则修改config/www/nextcloud/config/config.php,在下图所示的红色矩形框位置添加自己的域名即可,无需重启。Installation wizard — Nextcloud latest Administration Manual latest documentation

进阶设置

  • 利用frp的二级域名功能简化配置

    1. 在服务器端的frps.ini的common中添加subdomain_host字段,如subdomain_host = domain.com

      # frps.ini
      [common]
      subdomain_host = domain.com
    2. 在客户端的frpc.ini中的各个需要配置域名的配置中填写域名前缀,如subdomain = www

      # frpc.ini
      [nextcloud_web]
      # 此处需要把custom_domains字段删除,其他不变
      subdomain = nc
      [web]
      # 仅为示例,其余相关字段省略
      subdomain = web
    3. 这样,可以通过https://nc.domain.com:8000访问nextcloud,通过https://web.domain.com:8000访问web服务页面。

  • 配置端口转发,省略链接后面的端口

    想要省略链接后面的端口号,最简单的方法就是将frp服务端的https监听端口(即vhost_https_port)为443,但是ubuntu默认只有root用户可以监听443端口,所以要么选择以root身份执行frps,要么配置端口转发。

    ubuntu可以利用iptables进行端口转发,使用到的命令为:

    iptables -t -nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8000

    --dport为需要被转发的端口号,--to-port为转发到的端口号,即frp监听的端口。注意iptables的设置默认重启后即失效,可以参考下面参考资料给出的方法,配置自动加载。且部分资料提及需要设置ip_forward=1来打开端口转发功能,本人的系统已经打开,未测试不开启的情况下端口转发是否有效。

    这样,即可使用https://nc.domain.com访问nextcloud了。

参考资料

  1. 文档 | frp (gofrp.org)
  2. Nextcloud 结合frp搭建私有网盘_lggirls的博客-CSDN博客
  3. linux 不能开启443端口_wenzuowei110的博客-CSDN博客
  4. Ubuntu环境下的iptables的端口转发配置实例 - ddif - 博客园 (cnblogs.com)