本文主要介绍Nodejs多站点切换Htpps协议的详细解释和相关材料的简单例子。有需要的朋友可以参考一下。
Nodejs多站点切换Htpps协议详解
纯粹是赶时髦。折腾了两天,终于把个人站的所有服务从http协议切换到https。虽然整个过程不算太麻烦,但不得不承认,我个人对互联网安全的知识还是比较欠缺的。
Letsencrypt由Mozilla、Cisco、EFF等组织发起,免费向广大互联网网站提供SSL证书。目的是加速互联网从Http到Https的转变。很高兴在周末不期而遇,这对于一个互联网散户来说绝对是天大的利好,于是决定利用周末来折腾:先领证,再换程序;
获取letsencrypt发布的免费SSL证书相对简单。我还是windows服务器,目前还搞不定Linux,所以需要下载letsencrypt-win-simple的安装包,运行letsencrypt.exe。第一步是输入你的邮箱,如果不是第一次申请,我就跳过前两步。那么有五个选项供你选择。一般选择M,输入M,就到了需要输入证书的域。然后,输入这个域对应的站点的根目录,输入一个在线运行的域就可以了。指定的根目录需要可以直接访问,因为他会访问你输入的域和根目录下的一个文件。我想知道他是如何在我的站点中创建那些目录和验证文件的。也就是说,他会在你指定的目录下创建两层目录。认证完成后,会在C: users administrator appdata roaming lets encrypt-win-simple https acme-v01.api.letsencrypt.org目录下生成一个证书文件;接下来就比较随意了;
如果你有一个主域和一个站点,那么你可以用证书更改程序;
如果就这样结束了,你有没有觉得体验的太快了?按照上面的步骤,一个域下可以生成一个证书,那么自然可以重复这些步骤,在多个域下生成多个证书。问题在于必要性,也许折腾是在为你的幼稚和无知买单;
好吧,我幼稚;我生成了一个主域和两个二级域的证书,然后我改了程序!
我的站点是用Nodejs构建的,有3个小站点通过http-proxy代理连接在一起。我没有用Nginx更多的用业余的玩法去理解NodeJS。接下来,主站监听443端口,从站通过http-proxy代理分发。
var https=require( https );
var http=require( http );
var fs=require( fs );
var server=http . create server(app);
var https server=https . create server({
key: fs.readFileSync(。/privatekey.pem ),
cert: fs.readFileSync(。/certificate.pem )
},app);
http server . listen(443);
server . listen(80);
中间件看起来像什么:
app.use(function(req,res,next){
var proxy=http proxy . createproxyserver({
标题:{
x-forward-IP :req . IP . match(/([ w ] )/g)[1] }
});
proxy.on(error ,function (err,req,res) {
res.writeHead(500,{
内容类型:文本/普通
});
res.end(出了点问题。);
});
switch (req.headers.host){
案例“m.famanoder.cn”:
proxy.web(req,res,{ target: https://localhost:2333 });
打破;
案例 cdn.famanoder.cn :
proxy.web(req,res,{ target: https://localhost:3222 });
打破;
默认值:
next();
}
});
这样,https访问主域就没有问题了。问题是二级站点的访问浏览器会一直提示网站的证书不可信。除了像这样访问辅助站点,别无选择:https://cdn.famanoder.com:4000/,是的,使用端口访问当然没有问题。这种情况下,没有代理,但总觉得不方便,别扭,只好再想想。
这又是一个巧合。起床下班的时候看到一篇文章,除了标题,全是英文,但是直觉告诉我,有我想要的东西。我迷迷糊糊的看了一下,真的恍然大悟:在命令行启动letsencrypt plus - san参数申请证书,可以将多个附属域绑定到一个域,也就是说多个域可以共享同一套证书,那么代理的问题自然就解决了;进入主域后,输入多个域,用逗号隔开,然后他会依次去每个域验证,最后生成一组公共的证书;于是我决定:今晚加餐!
通过访问以下格式的地址来验证Letsencrypt:
http://cdn.famanoder.com/.知名/acme-challenge/rhha 4 dx 3 yauzi 7 tu _ c 6 p 9 mpk-tnpulvn 5 hmqro 2n 1 _ Q
他会依次访问每个域的这个乱码文件,估计这个文件里还有他想要的另一个乱码内容。打开看看就知道了;主站用的Express和cdn站点用的native Nodejs,两个站点的访问结果都是直接下载的文件,MIME头可能要改。因为现在多个域想要访问同一个目录中的文件,所以只需填写多个根目录所属的目录,例如D:,并修改路由文件,如下所示:
//www(快速)
app.get(/)。知名/acme-challenge/:ids ,function(req,res,next){
要求( fs )。readFile(D:/。已知/acme-challenge/ req . params . ids,function(err,data){
err console . log(err);
res.end(数据);
});
});
//www(Koa2)
router.get(/)。知名/acme-challenge/:ids ,async (cx,next)={
wait next();
let data=await fs . read file sync( D: CX . request . URL);
CX . response . body=data;
});
//cdn
if(req . URL . index of( acme-challenge )!=-1) {
var pathname=url.parse(req.url)。路径名;
fs.readFile(D:路径名,函数(错误,数据){
err console . log(err);
res.writeHead(200,{
内容类型:文本/html
});
res.end(数据);
返回false
});
}
返回false
这样多个域依次验证,生成同一套证书,有效期3个月。有效期内系统正常,3个月后自动续费;然后可以继续走http-proxy代理,二级站点的https访问不需要端口;下一步就是把所有的http都换成https,或者直接去掉协议。//www.famanoder.com格式没问题,浏览器会自动识别对应的协议;
由于Letsencrypt的验证域必须可以在线访问,所以本地开发需要单独配置。比如也可以用Git自带的openssl生成一组证书用于开发调试,但是浏览器会提示证书不可信;
总之,说复杂不复杂,说简单也没那么简单。这只是一件事。折腾是在为天真无知买单!
感谢您的阅读,希望能帮到您,也感谢您对本站的支持!