赞
踩
NextCloud已经使用几个月了,体验非常好。后台的安全检测一直建议我升级https,最近空了准备动手操作一下。
记录流程之前先介绍一下环境,安装的过程可以参考我的另一篇文章:https://blog.csdn.net/xinew4712/article/details/103576690
升级https之前,先把NextCloud升级到最新版,目前版本是 18.0.4。
FreeNas也升级到最新的稳定版,目前版本是 FreeNAS-11.3-U2.1。
NextCloud的运行环境是 F.A.M.P 具体为:
FreeBSD 11.2-STABLE
Apache 2.4
MariaDB 10.2
PHP 7.2
开启https,首先要准备证书,很多巨头都有免费证书可以用,而这次我准备自己创建证书链。主要是考虑终端少,只有自己家人在用,手工导入并信任一下根证书操作量不大。再一原因是免费的证书大多有效期为一年,好懒得每年更新一次啊。免费的https证书一般都是单向认证,即服务端认证,我想搞成类似网银U盾(本质也是证书)的双向认证,只有持有证书的客户端才能访问Apache下的指定资源,安全系数更高。
生成证书用的JAVA的JDK自带生成SSL证书的工具:keytool,此处删除几千字,是写好又删除的。因为很久以前用keytool做过证书,这次先入为主地上来就用,走到最后发现keytool生成的证书Apache用不了,必须要转换。keytool生成的证书是JKS格式,Apache应该用openssl生成,格式为x509。强行转换也可以,要用一个工具ExportPrivateKey.zip,具体流程太复杂,删除掉不提,直接用openssl简单又快捷。
第一次用openssl做的时候,自签名证书在Chrome上遇到了证书无效的错误,而firefox和IE都是正常的,主要是因为Chrome浏览器要求证书中必须包含“Subject Alternative Names”这一参数。
所以在生成证书之前,先做一下准备工作,创建一个文本,内容如下:
- [root@Nginx xinew]$more host.ext
- subjectAltName = @alt_names
- extendedKeyUsage = serverAuth
-
- [alt_names]
-
- # 域名,如有多个用DNS.2,DNS.3…来增加
- DNS.1 = xinew.abc.cn
- # IP地址
- IP.1 = 192.168.1.1
- IP.2 = 192.168.1.70
- IP.3 = 192.168.111.159
准备工作完毕,开始制做证书,由于自己要当CA,还要做双向认证,为避免混淆,再创建2个目录 ./pri 和 ./cer ,pri用于存放私钥和中间文件,cer目录用于存放证书。
一、签发CA根证书
1、创建CA私钥
openssl genrsa -aes256 -out pri/ca.key 2048 先设置一个4位密码
- [root@Nginx xinew]$openssl genrsa -aes256 -out pri/ca.key 2048
- Generating RSA private key, 2048 bit long modulus
- ......+++
- ...+++
- e is 65537 (0x10001)
- Enter pass phrase for pri/ca.key:
- Verifying - Enter pass phrase for pri/ca.key:
然后再删除密码,怕忘。
openssl rsa -in pri/ca.key -out pri/ca.key
- [root@Nginx xinew]$openssl rsa -in pri/ca.key -out pri/ca.key
- Enter pass phrase for pri/ca.key:
- writing RSA key
2、创建CA签名请求
openssl req -new -key pri/ca.key -out pri/ca.req -subj "/C=CN/ST=SC/L=CD/O=xinew/OU=xinew/CN=*.abc.cn"
3、签发CA根证书
openssl x509 -req -days 6666 -sha1 -extensions v3_ca -signkey pri/ca.key -in pri/ca.req -out cer/ca.cer
- [root@Nginx xinew]$openssl x509 -req -days 6666 -sha1 -extensions v3_ca -signkey pri/ca.key -in pri/ca.req -out cer/ca.cer
- Signature ok
- subject=/C=CN/ST=SC/L=CD/O=xinew/OU=xinew/CN=*.abc.cn
- Getting Private key
二、服务端证书
1、创建服务端私钥
openssl genrsa -aes256 -out pri/server.key 2048 还是先设置一个4位密码。
然后再删除密码,这一步不做的话,每次重启Apache都要交互一下密码。也许有直接创建无密码私钥的方法,没好好去查。
openssl rsa -in pri/server.key -out pri/server.key
2、创建服务端证书请求
openssl req -new -key pri/server.key -out pri/server.req -subj "/C=CN/ST=SC/L=CD/O=xinew/OU=xinew/CN=xinew.abc.cn"
3、利用CA根证书,签发服务端证书
openssl x509 -req -CA cer/ca.cer -CAkey pri/ca.key -in pri/server.req -out cer/server.cer -days 6666 -extfile host.ext -sha256 -set_serial 0x1111
注意这里用到了host.ext,不加这个参数的话,Chrome不认。还要注意第2步的域名要填完整的,真实存在的域名,可以直接访问到NextCloud的域名哈。
4、转为p12格式
openssl pkcs12 -export -cacerts -inkey pri/ca.key -in cer/ca.cer -out cer/ca.p12
pc端导入ca.cer没问题,手机端有的不行,要用p12格式。当然转换server.cer也可以的,但如果改天再弄个xinew2.abc.cn就不行了。
三、单向https认证测试
将上一步生成的两个文件 server.key、server.cer 考到 /usr/local/www/nextcloud/config/ 下,此时可以测试单向认证了。
找到Apache配置文件目录,我的是user/local/etc/apache24/conf 打开httpd.conf文件,注意不要把FreeNas的Apache和Jails的Apache搞混了啊,操作之前一定要小心核对一下。
找到下面两行代码
#LoadModule ssl_module modules/mod_ssl.so
#Include etc/apache24/extra/httpd-ssl.conf
去掉前面的#号
编辑httpd-ssl.conf,把VirtualHost段的内容全部删除掉。进入Includes目录,cp nc.conf nc.ssl.conf
为了调试方便,将Nat路径上的所有IP都加入到ServerName,调试完毕只保留域名即可。
ServerName xinew.*.*:8443,192.168.1.70:443,192.168.1.1:8443,192.168.111.158:8443
并进入下面几行内容:
SSLEngine on
SSLCertificateFile /usr/local/www/nextcloud/config/server.crt
SSLCertificateKeyFile /usr/local/www/nextcloud/config/server.key
重启Apache,这里用浏览器打开 https://xinew.abc.cn:8443,都会提示“您的连接不是私密连接”、“证书不被信任”之类,可以看到:
可以看到,颁发者是*.abc.cn这个CA,而*.abc.cn不被信任,下面要导入ca.cer到各个浏览器,放在可以信任的根证书颁发机构下。主流的firefox,chrome导一下就好了,连接变成了小锁头,虽然ff不认可,也不影响安全的加密连接。
四、配置双向认证
双向认证安全性要高很多了,相当于银行的U盾,只允许证书持有者访问。这对于暴露于公网,且使用了开源平台的私有小项目来说大概是最佳实践了。
将 /usr/local/etc/apache24/Includes 下的 nc.ssl.conf 中加入
SSLCACertificateFile "/usr/local/www/nextcloud/config/ca.cer"
SSLVerifyClient require
SSLVerifyDepth 10
这里的ca.cer就是一、3步骤中创建的CA根证书。如果此时重启,https就无法访问了,因为客户端证书还没做呢。当然,这也是双向认证的本意,让没有证书的攻击者无从下手。
五、签发客户端证书
1、创建客户端私钥
openssl genrsa -aes256 -out pri/client.key 2048 配置一个4位密码
2、去除密码
openssl rsa -in pri/client.key -out pri/client.key
3、创建客户端证书请求
注意这里的CN,随便填什么都行,客户端无所谓的。
openssl req -new -key pri/client.key -out pri/client.req -subj "/C=CN/ST=SC/L=CD/O=xinew/OU=xinew/CN=xinew"
4、用CA根证书,签发客户端证书
openssl x509 -req -days 6666 -sha1 -extensions v3_req -CA cer/ca.cer -CAkey pri/ca.key -CAserial ca.srl -CAcreateserial -in pri/client.req -out cer/client.cer
5、转换成p12格式
注意这里要多加一步,安全机制上要防止私自复制的证书被导入浏览器,所以这一步转格式的同时要加上密码。
$openssl pkcs12 -export -clcerts -inkey pri/client.key -in cer/client.cer -out cer/client.p12
- [root@Nginx xinew]$openssl pkcs12 -export -clcerts -inkey pri/client.key -in cer/client.cer -out cer/client.p12
- Enter Export Password:
- Verifying - Enter Export Password:
六、双向认证测试
为FireFox导入client.p12证书,再次刷新NextCloud的登录界面,会弹出证书选择窗口,由于FF只装了一个客户端证书,下拉菜单中只有“xinew”一项可选:
Chrome也差不多,界面略有不同而已:
点击确定之后,熟悉的界面又回来了。
七、最后的一些扫尾工作
1、处理新出现的安全提示
开启https之后,后台的安全检查会报出一个新的警告,只要把下面的代码加入到 nc.ssl.conf 就可以了。
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=15552000;includeSubDomains; preload"
</IfModule>
2、去除无关的调试IP
来到 /usr/local/etc/apache24/Includes 目录,在 nc.ssl.conf 中,ServerName中配置了很多调试IP,以避免出现NAT错误,双向调通之后,这些过程IP可以都删除了,只保留xinew.abc.cn:8443即可。
同理,来到目录 /usr/local/www/nextcloud/config ,编辑config.php
trusted_domains,项目下,只保留xinew.abc.cn:8443即可。(非必须)
3、关闭传统http访问
来到 /usr/local/etc/apache24/Includes 目录,将nc.conf改名:
mv nc.conf nc.conf.http
使得80端口的虚拟主机失效,然后再来到 /usr/local/etc/apache24 目录,编辑httpd.conf
将Linsten 80 一行注释,否则会暴露php源码。
重启之后,传统的http访问就被关闭了。但由于NextCloud在Jails中,它的80端口无人监听,请求会转发给FreeNas,这时原NextCloud的http页面就变成访问FreeNas了,FreeNas是没有必要暴露于公网的,即然http已经关闭,顺手也要把公网到家各个路由节点的NAT配置清除。
4、公网域名的内网解析
与NAS在同一局域网的设备,比如家里的PC、移动到家的手机、Pad如果仍通过公网域名访问NextCloud,数据将沿着一条出口转内销的路径与NextCloud互动,虽然能用,但效率太低,这时就需要在家里的路由设备上,为这个公网域名指定一个内网IP,TTL与公网保持一致,设置稍短一些,比如10分钟。有条件的也可以在办公环境下做类似的设置,让数据沿最优路由传输。抛开工作、居家两大场景,在外移动期间的偶尔使用,就依赖各大运营商的4G网络吧。
5、更新所有终端接入方式
此时的所有终端的NextCloud已经不能用了,要更新一下接入IP,导入一下证书。PC端很简单,步骤类似浏览器。
至于手机端怎么实现双向认证,好像又掉进了另一个坑儿里,说来话长,可能要再开一篇帖子来填坑吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。