(The Continued Rising Power of Developers)
使用HTTPS,讓網站更安全
PS:經過兩周的學習和部署遷移,目前已經把所有后端都遷到了基於Docker的Jenkins里了,相關文章可以參考《使用Jenkins來發布和代理.NetCore項目》,當然我也在糾結要不要也把vue的前端項目也遷過來,這樣每次只需要動動手就可以實現持續集成和持續部署了,如果你想了解如何vue項目構建鏡像,看我的這個《Docker 部署VUE項目》
今天就用mvp項目做例子,雖然是BlazorServer的項目,但是本質上還是MVC項目,所以如果你的項目是MVP的,同理可得。
不知道docker和Jenkins的相關內容,你學會了么?
1、兩種方案來加鎖
現在網站基本上已經普及了HTTPS化,雖然不能攔截所有,不過通過簡單的配置也能起到很大的作用,所以,HTTPS模式一直也是被大眾所接受,我現在在線的10個項目中,主要是官網,認證中心做了安全協議的配置,關於如何進行安全配置,這里有兩個方案:
1、普通模式:直接在代理服務器中,配置證書,做HTTPS代理,常見的就是在Nginx中處理,我的官網和認證中心都是這么處理的,而且也對Http做了跳轉,訪問域名,無論是HTTP還是HTTPS的,統一都是運行HTTPS安全協議下的,相應的Nginx配置也很簡單,之前也寫過文章《mvc項目加個鎖》。
配置文件查看鏈接:
http://apk.neters.club/.doc/guide/function-sheet.htm
2、項目中配置:上邊的方案雖然可以滿足一定的需求,但是有一個問題,比如我們用HTTPS安全協議的MVC項目做客戶端,去調用認證中心的時候(這里的ids4項目也是https安全協議的),MVC客戶端是不能用第一種方案的,因為第一種方案本質上還是通過nginx路由強制跳轉的。所以如果用第一種方案的話,我們發起認證的時候會報錯,比如客戶端無效或者參數不對。那這個時候我們就需要把我們的MVC客戶端,直接配置HTTPS模式的,也就是在項目內部配置的,這個也是今天要說的重點。
那接下來咱們就說下,如何把項目用HTTPS模式啟動。
2、項目中配置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。
3、在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,我想着應該不會這么尷尬的,那到底該如何配置呢,其實是很簡單的。
4、配置https證書
那既然需要證書,我們就生成一個證書,方案有很多,你可以去某雲上申請免費的證書,也可以使用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,刷新頁面,一切正常。
https://mvp.neters.club
總結:
1、配置Startup.cs;
2、生成證書;
3、配置kestrel監聽端口;