咱們有一個saas平臺 部分在azure的cloud service 使用lets encrypt來申請證書。每個商家申請域名以後就須要經過Lets encrypt來獲得證書並綁定證書。git
主要碰到的兩個問題。github
第一個:咱們是使用 AcmeClient (類庫 https://github.com/ebekker/ACMESharp 示例項目 https://github.com/Lone-Coder/letsencrypt-win-simple/) 來申請證書的。發現這個申請的時候會碰到「urn:acme:error:badNonce」 這樣的出錯消息
解決的方法是每次申請一個新證書的進候是須要從新實例化這個類的。web
第二是: 動態綁定證書的時候會致使原來的證書失效,或者新申請的證書綁定錯誤。線程
這個是由於 配置文件ServiceDefinition.csdef沒有辦法設置SNI, 咱們在代碼裏面強制把它設成SNI也會出錯。(IIS打開的時候會看到SNI是沒有勾選的) 。而若是把https的綁定所有取消掉,又會致使https的端口也被關閉掉。server
後面想的是添加一個空的綁定而後刪掉這個空的綁定。 這樣有時候仍是會出錯。blog
最後的想法是添加一個空的的綁定,還有一個沒用的綁定。 刪掉空的綁定。到目前以止工做正常。ssl
如何安裝證書,IIS能用的證書是放在localMachine的 WebHosting 或者 My下面 (運行MMC 添加證書管理能夠看到這個東西)域名
代碼是使用 X509Store 的Add方法。 it
X509Store _store; try { _store = new X509Store("WebHosting", StoreLocation.LocalMachine); _store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite); } catch (CryptographicException) { _store = new X509Store(StoreName.My, StoreLocation.LocalMachine); _store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite); } var keyStoreFlags = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable; var pfxPath =""; //證書的路徑 var host ="";//證書的 host certificate = new X509Certificate2(pfxPath, AppConfig.CertificatePassword, keyStoreFlags); certificate.FriendlyName = host; _store.Add(certificate);
如何使用代碼綁定證書io
咱們是把代碼放在webRole的OnStart 方法裏面。 並使用ServerManager類 .(Microsoft.Web.Administration.dll)
大概代碼是
var serverManager = new ServerManager(); var site = serverManager.Sites[0]; var bindings = site.Bindings.ToList(); foreach (var item in canBindCertificates) { var httpsBinding = bindings.FirstOrDefault(it => it.Protocol == "https" && it.Host == item.FriendlyName); if (httpsBinding != null) { httpsBinding.CertificateStoreName = _store.Name; httpsBinding.CertificateHash = item.GetCertHash(); } else { var binding = site.Bindings.Add($"*:443:{item.FriendlyName}", item.GetCertHash(), _store.Name); binding.Protocol = "https"; binding.SetAttributeValue("sslFlags", 1); //Important property } } serverManager.CommitChanges();
serverManager.CommitChanges();//要保證只有一個線程在跑。否則的話會出錯
配置文件裏面綁定的示例
<Sites> <Site name="Web"> <Bindings> <Binding name="Endpoint1" endpointName="Endpoint1" /> <Binding name="HttpsEndpointEmpty" endpointName="HttpsEndpoint1" hostHeader="" /> <Binding name="HttpsEndpoint1" endpointName="HttpsEndpoint1" hostHeader="placeholder.{xxx}.com" /> //{xxx}是你本身的域名 </Bindings> </Site>