nextcloud+nginx+ssl+非443,踩坑记录

这篇具有很好参考价值的文章主要介绍了nextcloud+nginx+ssl+非443,踩坑记录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求描述

pc 移动端app必须都支持
为了省阿里云服务器流量,服务器需要的三个访问路径
1、需要内网可以通过ip+port直接访问
2、外网可以通过ddns访问,因为443和80端口都被封,只能换端口,但依然需要ssl
3、为了防止ddns挂掉,通过阿里云配置内网穿透。阿里云由443端口,所以同样需要ssl。

结构

内网访问,直接访问nextcloud
ddns访问。单个nginx。由于不止一个web服务,所以内网搭建nginx,反向代理到nextcloud。内网nginx负责域名解析,ssl配置。
阿里云访问。nginx+nps。本身备案需要开一个web用于定期检查。又需要内网穿透和域名解析。所以配置nginx,www直接指向阿里云本身(检查要求,www指向阿里云服务器),其他二级域名直接把流量通过内网穿透发送到内网nginx上,内网nginx做域名解析。穿透用的nps

出现问题

阿里云nginx转发到内网nginx,内网nginx做域名解析配置ssl。通过阿里云访问正常。
ddns直接访问内网nginx,网页登录提示
refused to send form data to xxx.xx.xx because it violates the following content security policy directive: "form-action 'self'".
win 客户端提示从https访问,尽管登录 url 以 https 开头,但轮询 url 中没有,你将无法登录,因为这是一个安全问题
手机app登录提示access forbidden invalid request,还有提示严格模式,只允许https访问,即使设置了http。

解决方案

这里直接贴解决办法,具体过程和排查在后面。
nextcloud关键配置

'overwritecondaddr' => '^192\\.168\\.1\\.141$',#nginx的ip
#nextcloud拿到的ip与overwritecondaddr做正则,通过,则会用使用overwriteprotocol定义的值替换http。
'overwriteprotocol' => 'https',

内网nginx配置

        location / {
              proxy_set_header X-Real-IP '192.168.1.144';#设置为nginx所在的ip地址
        #X-Forwarded-For:nextcloud通过此获取客户端实际ip,用于防止密码暴力破解等问题。
        #如果ddns访问或者通过穿透访问时,一个客户端密码试错导致所有客户端都提示ip被锁定,
        #可以看是不是这个配错了,导致nextcloud拿到的所有客户端ip都是nginx的ip或者阿里云的ip
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto 'https';#从nginx访问的,只允许通过https,所以写死,不用$scheme了;
              proxy_set_header Host  $http_host;#因为是带端口的访问,所以这里必须用$http_host
              proxy_pass http://192.168.1.145:8080;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;#升级http为wss,加上这两条以支持wss
              proxy_set_header Connection "upgrade";
      }

关键在proxy_set_header X-Real-IP '192.168.1.144'。X-Real-IP值需要能被nextcloud的config.php中overwritecondaddr的正则匹配成功,成功后会为域名加上https,否则认为不是通过反向代理访问的,不会加https。
根据网上其他nginx配置,都写着X-Real-IP 需要配置为$remote_addr,翻源码后才发现nextcloud不是能这么设置。

过程

注!!!过程中的一些配置仅是提供排查思路,不是最终解决办法
首先遇到的问题是登录提示refused to send form data…,搜了一圈都说是nextcloud的 html/config/config.php配置文件中加入
'overwriteprotocol' => 'https',
'overwritecondaddr' => '^192\\.168\\.1\\.144$',
然而加入并没有用,依然提示。
然后搜了说是ContentSecurityPolicy(CSP)的配置,找到了配置文件,在html\lib\public\AppFramework\Http\ContentSecurityPolicy.php里面

protected $allowedFormActionDomains = [
    '\'self\'',
    'http://pan.example.com:8989',//加入允许的地址,8989是我自己通过外网访问的端口
  ];

已经配好了ssl,访问用的是https,但提示拒绝发送,说明这个表单发送的地址不是https://pan.example.com:8989,那就试试http(实际试过各种,不带http的,不带端口号的,文档也没说清楚,我也不懂,又搜到不带http/https的配置,简直无语)
设置后,web登录成功。然后尝试win 客户端登录。登录时客户端提示
尽管登录 url 以 https 开头,但轮询 url 中没有,你将无法登录,因为这是一个安全问题
文字和句子我都看懂了,但是轮询哪里的url啊,不知道怎么改,继续搜
搜了一圈,解决办法依然和refused to send form data… 的一样,我…
(╯‵□′)╯︵┻━┻
但是搜到一个关于nextcloud介绍的,偶然看到一个管理员设置里的手机与电脑切页,下面有个服务器地址nextcloud nginx,nginx,ssl,服务器

看到帖子里是https,我这是http,一瞬间似乎明白了问题。refused to send form data… 因为地址是https,但表单提交的地址是http,所以在CSP中加入http域名信任能成功。所以客户端登录提示尽管用了https,但url没有,说明什么,说明nextcloud内部生成的连接都是http的。
我w(゚Д゚)w
我配了'overwriteprotocol','overwritecondaddr'这两个了啊,怎么内部还是http的。
那就继续试,首先注释掉overwritecondaddr。登录管理员,看服务器地址,是https了。再试试客户端,都登录成功。最后试下内网ip访问,完蛋,http://192.168.1.145:8080被重定向到https://192.168.1.145:8080,然后浏览器提示重定向次数过多,无法打开web。内网无法通过ip访问,难道在家还要通过宽带那上传小水管绕一圈?同步的时候不得把上行吃满。
不行,再查。然而到此就毫无头绪了,本来nginx+ssl+非443端口就没几个人搞。那只能,查源码!!
╥﹏╥…
直接利用github的搜索功能,查找overwritecondaddroverwriteprotocol是如何生效的。然后在html\lib\private\AppFramework\Http\Request.php里找到了如下代码

        /**
   * Check overwrite condition
   * @param string $type
   * @return bool
   */
  private function isOverwriteCondition(string $type = ''): bool {
      $regex = '/' . $this->config->getSystemValue('overwritecondaddr', '')  . '/';
      $remoteAddr = isset($this->server['REMOTE_ADDR']) ? $this->server['REMOTE_ADDR'] : '';
      return $regex === '//' || preg_match($regex, $remoteAddr) === 1
      || $type !== 'protocol';
  }

  /**
   * Returns the server protocol. It respects one or more reverse proxies servers
   * and load balancers
   * @return string Server protocol (http or https)
   */
  public function getServerProtocol(): string {
      if ($this->config->getSystemValue('overwriteprotocol') !== ''
          && $this->isOverwriteCondition('protocol')) {
          return $this->config->getSystemValue('overwriteprotocol');
      }

      if ($this->fromTrustedProxy() && isset($this->server['HTTP_X_FORWARDED_PROTO'])) {
          if (strpos($this->server['HTTP_X_FORWARDED_PROTO'], ',') !== false) {
              $parts = explode(',', $this->server['HTTP_X_FORWARDED_PROTO']);
              $proto = strtolower(trim($parts[0]));
          } else {
              $proto = strtolower($this->server['HTTP_X_FORWARDED_PROTO']);
          }

          // Verify that the protocol is always HTTP or HTTPS
          // default to http if an invalid value is provided
          return $proto === 'https' ? 'https' : 'http';
      }

      if (isset($this->server['HTTPS'])
          && $this->server['HTTPS'] !== null
          && $this->server['HTTPS'] !== 'off'
          && $this->server['HTTPS'] !== '') {
          return 'https';
      }

      return 'http';
  }

第7行,isOverwriteCondition()方法中,获取overwritecondaddr值,拼接正则表达式,第8行获取REMOTE_ADDR,拿去匹配正则表达式。
第20行,getServerProtocol()方法,调用isOverwriteCondition()判断是否需要覆盖协议,而覆盖的就是overwriteprotocol中的值,也就是设置的https。
所以只要让isOverwriteCondition()返回true,内部就会使用https代替http,那么问题就出在了正则表达式的匹配上。那就打印$remoteAddr看看,在第8行后面插入print 'remote addr 测试'.$remoteAddr;,重启nextcloud。刷新web页面,直接出现了错误提示,在页面顶部就出现了打印的内容nextcloud nginx,nginx,ssl,服务器

这个ip不就是我客户端的ip吗,说好的overwriteprotocol是去匹配代理服务器ip的,为啥代理服务器ip地址是客户端ip。看来问题出在nginx上,于是修改nginx配置。

上配置

 http{

map $host $path_pool{#二级域名和ip映射池,就不用每个二级域名配一个server了
      doc.example.com              http://192.168.1.146;
      pan.example.com    http://192.168.1.145:8080;
    panOut.example.com      http://192.168.1.145:8080;
  }
server {

#用于阿里云穿透,穿透软件通过其他端口接收请求后,在内网执行请求,所以是在内网访问443端口
      listen 443 ssl;
      listen 8989 ssl;#用于ddns访问的端口。
      server_name *.example.com;#直接匹配这个域名的所有二级域名

# 动态证书路径,这里使用了$ssl_server_name,就不用为每个域名单独配置证书,证书名字直接改成pan.example.com.pem,放到目录下。
# 每次请求会拼接出证书路径,缺点是对性能会有损失,可以看nginx文档
      ssl_certificate /home/nginx/ssl/$ssl_server_name.pem;  
      ssl_certificate_key /home/nginx/ssl/$ssl_server_name.key;  # 绝对路径,同上
      ssl_session_timeout 5m;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置,不懂,抄的
      ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置。不懂,抄的
      ssl_prefer_server_ciphers on;#不懂,抄的

#设定非80端口访问时,强制到https。也就是访问http://pan.example.com:8989时,会返回浏览器497错误,然后重定向到https
      error_page 497 https://$http_host$request_uri;
    location / {
        proxy_set_header REMOTE_ADDR $remote_addr;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header REMOTE-HOST $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto 'https';#从nginx访问的,只允许通过https,所以写死,不用$scheme了;
        proxy_set_header Host  $http_host;#注意使用$http_host
        proxy_pass $path_pool;#$path_pool定义在上面了
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;#升级http为wss,加上这两条以支持wss
        proxy_set_header Connection "upgrade";#
        }
#nextcloud文档说要配这个,因为用域名+端口方式,所以$host记得都改成$http_host,$host是不带端口的
    location = /.well-known/carddav {
        return 301 $scheme://$http_host/remote.php/dav;
    }
#nextcloud文档说要配这个
    location = /.well-known/caldav {
        return 301 $scheme://$http_host/remote.php/dav;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root  /usr/share/nginx/html;
    }
}
}

配置有点长,顺便贴一下其他我觉得有用的部分。还记得,nextcloud里取REMOTE_ADDR去匹配代理服务器的正则吗,所以nginx配置里首先尝试修改 proxy_set_header remote-addr $remote_addr;,直接$remote_addr替换为nginx的ip。看了开头的结局方案就知道,这么改没用。
o(≧口≦)o
nextcloud的代码怎么骗人呢。于是,把这里所有$remote_addr都替换成nginx的ip,成功了,nextcloud里显示服务器地址是https,内网也可以用ip+port打开,win客户端,手机app都可以了。那么就再一个个改回$remote_addr,毕竟nextcloud的防止暴力破解还是需要的。最终定位到X-Real-IP,所以只用把X-Real-IP设置为nginx 的ip就可以了。
但是这个server并不只有nextcloud用,可能其他web服务又需要remote-addr,那就复制一个server,单独匹配nextcloud的域名吧,单独修改。
到此结束,于是写了这篇文档给这个坑绑条绳子,有人踩进来的话还能爬出去
ಥ_ಥ文章来源地址https://www.toymoban.com/news/detail-808693.html

到了这里,关于nextcloud+nginx+ssl+非443,踩坑记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在Nginx服务器如何安装SSL证书

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 Nginx安装步骤:安装详细步骤 进入数字证书管理服务/SSL 证书 /免费证书 点击下载 服务器类型选择Nginx 点击下载 将下载好的证书压缩包进行解压:会有下图两个文件 将证书文件和私钥文件上传到Nginx服

    2024年02月09日
    浏览(54)
  • 【服务器训练调整yolov8时踩坑问题,修改记录】

    *** 另外网上yolov8教程特别多,关于数据集准备和制作这块,可以直接拆分的时候图片也拆分,也可以只记录在txt中,有三种方式所以在制作的时候都可以选择。需要也可以私信把我的处理脚本发你。 近期在服务器利用yolov8训练一些通用模型,发现不同时间段clone的yolov8内容和

    2024年02月19日
    浏览(39)
  • Nginx服务器安装证书并启用SSL(acme.sh)

    您已购置vps服务器,例如阿里云全球站ecs、AWS EC2、Azure VM、GCP Compute等 安全组已开启80、443端口,且访问源设置为0.0.0.0/0 域名已设置A记录指向当前操作服务器,若您使用aws ec2,有公有 IPv4 DNS,可供使用 取消Settings for a TLS enabled server下的注释内容 报错信息 Solution 将nginx.conf

    2024年02月02日
    浏览(61)
  • 在Ubuntu服务器上安装和配置Nextcloud- 搭建Nextcloud私有云盘并公网远程访问

    Nextcloud,它是ownCloud的一个分支,是一个文件共享服务器,允许您将个人内容(如文档和图片)存储在一个集中的位置,就像Dropbox一样。与Nextcloud的不同之处在于,它的所有功能都是开源的。它还将敏感数据的控制和安全返回给您,从而消除了对第三方云托管服务的使用。 在本教程中

    2024年02月11日
    浏览(57)
  • SpringBoot + Vue2项目打包部署到服务器后,使用Nginx配置SSL证书,配置访问HTTP协议转HTTPS协议

    配置nginx.conf文件,这个文件一般在/etc/nginx/...中,由于每个人的体质不一样,也有可能在别的路径里,自己找找... 证书存放位置,可自定义存放位置 两个文件 后端配置 把.pfx拷贝到resource下,然后配置一下yml

    2024年02月02日
    浏览(75)
  • 关于Nextcloud连接Onlyoffice成功后提示“ONLYOFFICE服务器无法连接,请联系管理员。“错误的处理方法

    好不容易才把onlyoffice连接成功,你竟然还给我来这个错误,实在是不应该呀,都最后一公里了,可不能放弃,必须得把它给解决。 现在不妨从开始说起: 在Docker容器内部 ,宿主机相当于一个网关,宿主机根据不同的端口给每个容器分配一个独立的IP地址。这时所有Docker上所

    2023年04月09日
    浏览(78)
  • 私有云服务器搭建教程(保姆级)——台式电脑+ubuntu+docker+nextcloud+mysql+花生壳内网穿透

    随着移动互联网的发展,越来越多的人使用云网盘存储他们的文档、照片、视频等文件。不知从什么时候起,我们不知不觉开始为享受云存储的服务付费买单。一次上传,随处访问,越来越成为人们的日常需求。随之而来的是各云网盘每月的定期收费,以及强制将用户分为免

    2024年02月02日
    浏览(47)
  • nginx配置监听443端口,开启ssl协议,走 https 访问_nginx 443(1)

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新Linux运维全套学习资料》,

    2024年04月22日
    浏览(47)
  • Nginx 配置SSL,开放https协议和443端口

    目录 一、准备工作 二、生成私钥(key) 三、生成证书签名请求/公钥(csr) 四、生成证书(crt) 五、给nginx配证书 六、访问测试 阅读本文前您需要学会如何安装Nginx, 如果您还不会安装Nginx请参考CentOS7安装Nginx,或者直接关注本栏目Nginx。         如果是在Windows下,请

    2024年02月04日
    浏览(39)
  • docker中使用nginx配置ssl证书,443端口无法连接

    环境:docker + 云服务器+域名 准备:下载ssl证书文件,安全组开放443端口, nginx容器映射443端口 (切记!!!我就是这里忘记配置, 结果弄了好久); 如果上面操作都做好了,在nginx也配置了,但是还是有问题,那么就是你的nginx没有映射443端口,博主这里就是踩了这个坑,话不多说

    2024年02月07日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包