Document Server开启https
首先按官方的流程创建一个容器
sudo docker run -i -t -d -p 443:443 --restart=always \
-v /app/onlyoffice/DocumentServer/data:/var/www/onlyoffice/Data onlyoffice/documentserver-de
onlyoffice默认会在容器的 /var/www/onlyoffice/Data 目录下查找SSL证书,通过 -v 我们把电脑上的 /app/onlyoffice/DocumentServer/data 映射给容器的 /var/www/onlyoffice/Data。然后我们根据官方指引生成证书到 /app/onlyoffice/DocumentServer/data 目录下
openssl genrsa -out onlyoffice.key 2048
openssl req -new -key onlyoffice.key -out onlyoffice.csr
openssl x509 -req -days 365 -in onlyoffice.csr -signkey onlyoffice.key -out onlyoffice.crt
openssl dhparam -out dhparam.pem 2048
mkdir -p /app/onlyoffice/DocumentServer/data/certs
cp onlyoffice.key /app/onlyoffice/DocumentServer/data/certs/
cp onlyoffice.crt /app/onlyoffice/DocumentServer/data/certs/
cp dhparam.pem /app/onlyoffice/DocumentServer/data/certs/
chmod 400 /app/onlyoffice/DocumentServer/data/certs/onlyoffice.key
按照官方指引完成之后,看似一切正常,但是访问 https://localhost 直接失败。。。通过查看docker的日志发现是 /var/www/onlyoffice/Data/certs 目录,即 /app/onlyoffice/DocumentServer/data/certs 没有权限导致的。通过以下命令可以查看对应文件权限:
docker exec -it 09 bash
ll /var/www/onlyoffice/Data/certs
修改权限
exit
chmod -R 755 /app/onlyoffice/DocumentServer/data/certs
docker exec -it 09 bash
ll /var/www/onlyoffice/Data/certs
重启容器,访问https://localhost,成功。
node example开启https
直接上代码吧,修改 /bin/www
#!/usr/bin/env node
var debug = require("debug")("OnlineEditorsExampleNodeJS");
var app = require("../app");
var path = require("path");
var config = require('config');
var fileSystem = require("fs");
var https = require('https');
var privateCrt = fileSystem.readFileSync(path.join(process.cwd(), 'https/onlyoffice.crt'), 'utf8');
var privateKey = fileSystem.readFileSync(path.join(process.cwd(), 'https/onlyoffice.key'), 'utf8');
var HTTPS_OPTOIN = {
key: privateKey,
cert: privateCrt
};
var SSL_PORT = 3001;
var HTTP_PORT = process.env.PORT || config.get('server.port') || 3000;
app.set("port", HTTP_PORT);
var server = app.listen(app.get("port"), function() {
debug("Express server listening on port " + server.address().port);
});
var httpsServer = https.createServer(HTTPS_OPTOIN, app);
httpsServer.listen(SSL_PORT, function() {
console.log(`HTTPS Server is running on ${SSL_PORT}`);
});
启动后通过3001端口访问https页面,在浏览器正常打开,再创建个文档试试,提示文档无法保存且报错文件下载失败。。。
再看下docker日志,发现以下报错:
自签证书导致的
可以通过修改容器的 /etc/onlyoffice/documentserver/default.json 文件内的 rejectUnauthorized 为 false 来取消这个证书的验证。
你可能需要先通过以下命令先安装vim
apt-get update
apt-get install vim
如果docker内无法安装可以把docker内的文件复制出来修改
docker cp CONTAINER_ID:/etc/onlyoffice/documentserver/default.json /home
docker cp /home CONTAINER_ID:/etc/onlyoffice/documentserver/default.json
修改完成后重启容器,一切正常运行~
解决办法很简单,寻找办法过程确很痛苦,痛苦的主要来源:对docker和SSL证书了解程度不够。
怎样的证书才被信任?
打开百度可以看到以下三级的证书结构
其中, Global Root CA 是根证书。它已经在我们的客户端本地存储,以 macos
为例,可以通过 keychain
查找到。
在中间的这一个证书,称为中级证书。
最底下的证书就是在服务端配置好的证书。
服务器的证书由中级证书负责签名,而其中级证书又由根证书负责签名。根证书通常是值得信任的机构,因为其必须遵守严格要求、审计、公众审查等。这一切都是为了保持证书颁发机构的社会信任。
在我们访问 https 的站点资源时,虽然服务器配置好的相关的证书,但我们如何能够验证该证书的有效性呢?浏览器会收到证书本身以及与证书关联的公共密钥。它使用公钥验证数字签名,并查看签名者是由什么证书签名,并且超上一个链接移动,继续对上一个签名进行身份验证,并跟踪签名它的证书的链——直到最终它到达浏览器信任库中的根证书之一。如果无法将证书链接回其受信任的根目录之一,则它将不信任该证书。
整个过程就是一个证书链。
即 Server certificate -> Intermediate certificate(中级证书, 这中间可能会链接到另一个中级证书)-> Root certificate 。
中级证书
为什么会产生中级证书,直接从服务端的证书到最后的根证书不是更高效么?
原因是根证书太宝贵了,而颁发证书的风险太大。于是根证书颁发了很多中级证书,即 CA (证书颁发机构)用自己的私钥进行签名,使中级证书可信任。CA 有了中级证书之后,以后就都用中级证书自己的私钥来签名并颁发给最终用户 SSL 证书(即服务端配置的证书)。
所以,
根证书: 受权威机构信任,已经在用户设备中存储;
中级证书:由根证书签名而得到信任,负责给下一级的证书签名;
服务端证书:由中级证书签名而得到信任。
通过颁发中级证书并使用中级证书签署证书,增加根证书的安全性。这有助于在发生误发或安全事件时最小化和划分损害,当安全事件发生时,不需要撤销根证书,只需撤销中级证书,使从该中级证书发出的证书组不受信任。