微软Azure平台 cloud service动态申请证书并绑定证书碰到的坑

咱们有一个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>

相关文章
相关标签/搜索