(The Continued Rising Power of Developers)
使用HTTPS,让网站更安全
PS:经过两周的学习和部署迁移,目前已经把所有后端都迁到了基于Docker的Jenkins里了,相关文章可以参考《使用Jenkins来发布和代理.NetCore项目》,当然我也在纠结要不要也把vue的前端项目也迁过来,这样每次只需要动动手就可以实现持续集成和持续部署了,如果你想了解如何vue项目构建镜像,看我的这个《Docker 部署VUE项目》
今天就用mvp项目做例子,虽然是BlazorServer的项目,但是本质上还是MVC项目,所以如果你的项目是MVP的,同理可得。
不知道docker和Jenkins的相关内容,你学会了么?
那接下来咱们就说下,如何把项目用HTTPS模式启动。
这个是很简单的,只需要简单配置下启动服务就行。
首先就是注册相应的服务,基本自己不需要怎么修改,对于下边的AddHttpsRedirection你可以酌情处理,一般仅仅是生产模式使用就行。
// 配置Hsts
services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromDays(60);
options.ExcludedHosts.Add("mvp.neters.club");
});
// 非开发环境
if (!_env.IsDevelopment())
{
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status308PermanentRedirect;
options.HttpsPort = 443;
});
}
然后配置中间件
if (!env.IsDevelopment())
{
app.UseHsts();
}
app.UseHttpsRedirection();
其他的就不需要处理了,本地测试一看,没有什么问题
如果说你仅仅使用Linux+Nginx的话,应该就是到了这里了,毕竟已经启动了HTTPS安全模式了,配置好代理就可以起飞了,但是本文要说的就是Docker。
可是我们都知道,如果你使用Docker的话,容器内部是没有localhost的,因为是用的IPv6,那这种配置就是不行。而且如果不配置的话,容器内默认启动的是http协议的80端口,这个和我们的需求不一样,我们需要的是直接启动https的:
那怎么办呢,如果你看过我之前的讲解,可能就想到了,我们可以在Program里直接配置域名,可以达到目的:
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.UseUrls("https://*:443") // 手动指定https
;
});
这样看起来,按理说这回应该就没有问题了吧,提交到Docker来看看
竟然还报错了你看🙄
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
其实定心一看,应该也能明白发生了什么,就是在Docker中这么启动HTTPS的话,是不允许的,因为没有服务证书,本地vs开发肯定不会有这个问题,这就是环境的差异性。
这个就是今天的重点问题出现了,在Docker中如何合理配置安全证书HTTPS。也咨询了下别人,有的建议直接用k8s,有的说直接用Linux,不用Docker,我想着应该不会这么尴尬的,那到底该如何配置呢,其实是很简单的。
那既然需要证书,我们就生成一个证书,方案有很多,你可以去某云上申请免费的证书,也可以使用openssl工具来生成自己的,生成的过程略,自行百度很简单。
但是这样的话,放到公网也是不行,毕竟自己创建的没啥用,除非你用自建的放项目里,用nginx再代理正式的。
所以还是要正规的,这里我用某讯云的上的pfx来处理。
现在有了正式,就需要配置端口监听了,直接配置kestrel:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureKestrel(options =>
{
options.Listen(IPAddress.IPv6Any, 443, listenOptions =>
{
listenOptions.UseHttps(Path.Combine(AppContext.BaseDirectory, "socialnetwork.pfx"), "123456");
});
})
//.UseUrls("https://*:443")
;
});
注意这里的监听方式用的是IPv6Any,端口443,然后下边配置路径和密码,这个证书反正是假的,你自己的可要保护好。
如果想要看更多详细的内容,可以看官方的issue:
https://github.com/dotnet/AspNetCore.Docs/issues/6199
那现在提交上去,再来看看
没有问题了,撒花,基于IPv6的端口是443的容器,当然你也可以自定义修改端口。
剩下的就是映射到宿主机端口。
docker run --name=mvpcontainer -d \
-v /etc/localtime:/etc/localtime -it \
-p 5050:443 laozhangisphi/mvpimg
然后正常的nginx代理5050,刷新页面,一切正常。