为FreeNas中的NextCloud开启双向https访问

 

 

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,都会提示“您的连接不是私密连接”、“证书不被信任”之类,可以看到:

为FreeNas中的NextCloud开启双向https访问_第1张图片

可以看到,颁发者是*.abc.cn这个CA,而*.abc.cn不被信任,下面要导入ca.cer到各个浏览器,放在可以信任的根证书颁发机构下。主流的firefox,chrome导一下就好了,连接变成了小锁头,虽然ff不认可,也不影响安全的加密连接。

为FreeNas中的NextCloud开启双向https访问_第2张图片

为FreeNas中的NextCloud开启双向https访问_第3张图片

四、配置双向认证

双向认证安全性要高很多了,相当于银行的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就无法访问了,因为客户端证书还没做呢。当然,这也是双向认证的本意,让没有证书的攻击者无从下手。

为FreeNas中的NextCloud开启双向https访问_第4张图片

五、签发客户端证书

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”一项可选:

为FreeNas中的NextCloud开启双向https访问_第5张图片

Chrome也差不多,界面略有不同而已:

为FreeNas中的NextCloud开启双向https访问_第6张图片

点击确定之后,熟悉的界面又回来了。

七、最后的一些扫尾工作

1、处理新出现的安全提示

开启https之后,后台的安全检查会报出一个新的警告,只要把下面的代码加入到 nc.ssl.conf 就可以了。


       Header always set Strict-Transport-Security "max-age=15552000;includeSubDomains; preload"

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端很简单,步骤类似浏览器。

为FreeNas中的NextCloud开启双向https访问_第7张图片

为FreeNas中的NextCloud开启双向https访问_第8张图片

至于手机端怎么实现双向认证,好像又掉进了另一个坑儿里,说来话长,可能要再开一篇帖子来填坑吧。

你可能感兴趣的:(为FreeNas中的NextCloud开启双向https访问)