public async Task TestRequestAndInstallDnsCertificate() { var config = new AppSettingsAuthConfig(); var client = ArmHelper.GetWebSiteManagementClient(config); var kuduClient = KuduHelper.GetKuduClient(client, config); var body = new DnsAzureInstallModel() { AzureWebAppEnvironment = new AzureWebAppEnvironment(config.Tenant, config.SubscriptionId, config.ClientId, config.ClientSecret, config.ResourceGroupName, config.WebAppName), AcmeConfig = new AcmeConfig() { Host = "letsencrypt.ai4bots.com", PFXPassword = "******", RegistrationEmail = "*****@*****.**", RSAKeyLength = 2048 }, RelativeRecordSetName = "letsencrypt", ZoneName = "ai4bots.com", ResourceGroupName = "dns", SubscriptionId = new Guid("14fe4c66-c75a-4323-881b-ea53c1d86a9d"), CertificateSettings = new CertificateServiceSettings() }; var res = await kuduClient.HttpClient.PostAsync( "https://webappcfmv5fy7lcq7o.scm.azurewebsites.net/letsencrypt/api/certificates/challengeprovider/dns/azure/certificateinstall/azurewebapp?api-version=2017-09-01", new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")); await ValidateResponse(body.AcmeConfig, res); }
public async Task TestRequestAndInstallCertificate() { var config = new AppSettingsAuthConfig(); var client = ArmHelper.GetWebSiteManagementClient(config); var kuduClient = KuduHelper.GetKuduClient(client, config); var body = new HttpKuduInstallModel() { AzureEnvironment = new AzureWebAppEnvironment(config.Tenant, config.SubscriptionId, config.ClientId, config.ClientSecret, config.ResourceGroupName, config.WebAppName), AcmeConfig = new AcmeConfig() { Host = "letsencrypt.sjkp.dk", PFXPassword = "******", RegistrationEmail = "*****@*****.**", RSAKeyLength = 2048 }, AuthorizationChallengeProviderConfig = new AuthorizationChallengeProviderConfig(), CertificateSettings = new CertificateServiceSettings() }; var res = await kuduClient.HttpClient.PostAsync( "https://webappcfmv5fy7lcq7o.scm.azurewebsites.net/letsencrypt/api/certificates/challengeprovider/http/kudu/certificateinstall/azurewebapp?api-version=2017-09-01", new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")); await ValidateResponse(body.AcmeConfig, res); }
public ActionResult Hostname(string id) { var settings = new AppSettingsAuthConfig(); var model = new HostnameModel(); List <ValidationResult> validationResult = null; if (settings.IsValid(out validationResult)) { var client = ArmHelper.GetWebSiteManagementClient(settings); var site = client.Sites.GetSiteOrSlot(settings.ResourceGroupName, settings.WebAppName, settings.SiteSlotName); model.HostNames = site.HostNames; model.HostNameSslStates = site.HostNameSslStates; model.Certificates = client.Certificates.GetCertificates(settings.ServicePlanResourceGroupName).Value; model.InstalledCertificateThumbprint = id; if (model.HostNames.Count == 1) { model.ErrorMessage = "No custom host names registered. At least one custom domain name must be registed for the web site to request a letsencrypt certificate."; } } else { var errorMessage = string.Join(" ,", validationResult.Select(s => s.ErrorMessage)); model.ErrorMessage = $"Application settings was invalid, please wait a little and try to reload page if you just updated appsettings. Validation errors: {errorMessage}"; } return(View(model)); }
public async Task TestRequestDnsCertificate() { var config = new AppSettingsAuthConfig(); var client = await ArmHelper.GetWebSiteManagementClient(config); var kuduClient = KuduHelper.GetKuduClient(client, config); var body = new DnsAzureModel() { AzureDnsEnvironment = new AzureDnsEnvironment(config.Tenant, new Guid("14fe4c66-c75a-4323-881b-ea53c1d86a9d"), config.ClientId, config.ClientSecret, "dns", "ai4bots.com", "@"), AcmeConfig = new AcmeConfig() { Host = "ai4bots.com", PFXPassword = "******", RegistrationEmail = "*****@*****.**", RSAKeyLength = 2048 } }; var res = await kuduClient.HttpClient.PostAsync( "https://webappcfmv5fy7lcq7o.scm.azurewebsites.net/letsencrypt/api/certificates/challengeprovider/dns/azure?api-version=2017-09-01", new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json")); await ValidateResponse(body.AcmeConfig, res); }
public ActionResult Index(AuthenticationModel model) { if (ModelState.IsValid) { try { using (var client = ArmHelper.GetWebSiteManagementClient(model)) { //Update web config. var site = client.Sites.GetSite(model.ResourceGroupName, model.WebAppName); var webappsettings = client.Sites.ListSiteAppSettings(model.ResourceGroupName, model.WebAppName); if (model.UpdateAppSettings) { var newAppSettingsValues = new Dictionary <string, string> { { AppSettingsAuthConfig.clientIdKey, model.ClientId.ToString() }, { AppSettingsAuthConfig.clientSecretKey, model.ClientSecret.ToString() }, { AppSettingsAuthConfig.subscriptionIdKey, model.SubscriptionId.ToString() }, { AppSettingsAuthConfig.tenantKey, model.Tenant }, { AppSettingsAuthConfig.resourceGroupNameKey, model.ResourceGroupName }, { AppSettingsAuthConfig.servicePlanResourceGroupNameKey, model.ServicePlanResourceGroupName } }; foreach (var appsetting in newAppSettingsValues) { if (!webappsettings.Properties.ContainsKey(appsetting.Key)) { webappsettings.Properties.Add(appsetting.Key, appsetting.Value); } else { webappsettings.Properties[appsetting.Key] = appsetting.Value; } } client.Sites.UpdateSiteAppSettings(model.ResourceGroupName, model.WebAppName, webappsettings); } else { var appSetting = new AppSettingsAuthConfig(); if (!ValidateModelVsAppSettings("ClientId", model.ClientId.ToString(), appSetting.ClientId.ToString()) || !ValidateModelVsAppSettings("ClientSecret", appSetting.ClientSecret, model.ClientSecret) || !ValidateModelVsAppSettings("ResourceGroupName", appSetting.ResourceGroupName, model.ResourceGroupName) || !ValidateModelVsAppSettings("SubScriptionId", appSetting.SubscriptionId.ToString(), model.SubscriptionId.ToString()) || !ValidateModelVsAppSettings("Tenant", appSetting.Tenant, model.Tenant) || !ValidateModelVsAppSettings("ServicePlanResourceGroupName", appSetting.ServicePlanResourceGroupName, model.ServicePlanResourceGroupName)) { model.ErrorMessage = "One or more app settings are different from the values entered, do you want to update the app settings?"; return(View(model)); } } } return(RedirectToAction("Hostname")); } catch (Exception ex) { Trace.TraceError(ex.ToString()); model.ErrorMessage = ex.ToString(); } } return(View(model)); }
public void TestRemove() { var config = new AppSettingsAuthConfig(); var service = new CertificateService(config, new CertificateServiceSettings { }); service.RemoveExpired(180); }
public async Task TestRemove() { var config = new AppSettingsAuthConfig(); var service = new WebAppCertificateService(config, new CertificateServiceSettings { }); await service.RemoveExpired(180); }
public static async Task RenewCertificate([TimerTrigger(typeof(MyDailySchedule), RunOnStartup = true)] TimerInfo timerInfo) { Console.WriteLine("Renew certificate"); var config = new AppSettingsAuthConfig(); var count = (await new CertificateManager(new AppSettingsAuthConfig()).RenewCertificate(renewXNumberOfDaysBeforeExpiration: config.RenewXNumberOfDaysBeforeExpiration)).Count(); Console.WriteLine($"Completed renewal of '{count}' certificates"); }
public void TestScmUri() { var model = new AppSettingsAuthConfig(); var uri = "letsencrypt.azurewebsites.net"; var result = KuduHelper.MakeScmUri(uri, model); Assert.AreEqual(new Uri("https://letsencrypt.scm.azurewebsites.net"), result); }
public async Task <IHttpActionResult> RenewExisting([FromUri(Name = "api-version")] string apiversion = null) { Trace.TraceInformation("Renew certificate"); var config = new AppSettingsAuthConfig(); var res = await new CertificateManager(new AppSettingsAuthConfig()).RenewCertificate(renewXNumberOfDaysBeforeExpiration: config.RenewXNumberOfDaysBeforeExpiration); Trace.TraceInformation($"Completed renewal of '{res.Count()}' certificates"); return(Ok(res)); }
public static async Task RenewCertificate([TimerTrigger(typeof(MyDailySchedule), RunOnStartup = true)] TimerInfo timerInfo) { Console.WriteLine("Renew certificate"); var config = new AppSettingsAuthConfig(); var certManager = new CertificateManager(new AppSettingsAuthConfig()); var renewedCerts = await certManager.RenewCertificate(renewXNumberOfDaysBeforeExpiration : config.RenewXNumberOfDaysBeforeExpiration, throwOnRenewalFailure : config.ThrowOnRenewalFailure); Console.WriteLine($"Completed renewal of '{renewedCerts.Count()}' certificates"); }
public void IsValid() { List <ValidationResult> res = null; var config = new AppSettingsAuthConfig(); Assert.IsFalse(config.IsValid(out res)); Console.WriteLine(string.Join(" ,", res.Select(s => s.ErrorMessage))); }
public async Task AddChallenge() { var config = new AppSettingsAuthConfig(); var provider = new AzureDnsAuthorizationChallengeProvider(new AzureDnsEnvironment(config.Tenant, new Guid("14fe4c66-c75a-4323-881b-ea53c1d86a9d"), config.ClientId, config.ClientSecret, "dns", "ai4bots.com", "@")); await provider.PersistsChallenge(new DnsChallenge("dns01", new DnsChallengeAnswer()) { RecordValue = "Test 1" }); }
public async Task RenewCertificateConstructorTest() { var settings = new AppSettingsAuthConfig(); var mgr = new CertificateManager(settings, settings, new WebAppCertificateService(settings, new CertificateServiceSettings() { UseIPBasedSSL = settings.UseIPBasedSSL }), new KuduFileSystemAuthorizationChallengeProvider(settings, new AuthorizationChallengeProviderConfig())); var result = await mgr.RenewCertificate(renewXNumberOfDaysBeforeExpiration : 200); Assert.AreNotEqual(0, result.Count()); }
public ActionResult PleaseWait() { var settings = new AppSettingsAuthConfig(); List <ValidationResult> validationResult = null; if (settings.IsValid(out validationResult)) { return(RedirectToAction("Hostname")); } return(View()); }
public async Task RenewCertificateDnsChallengeTest() { var config = new AppSettingsAuthConfig(); var dnsEnvironment = new AzureDnsEnvironment(config.Tenant, new Guid("14fe4c66-c75a-4323-881b-ea53c1d86a9d"), config.ClientId, config.ClientSecret, "dns", "ai4bots.com", "@"); var mgr = new CertificateManager(config, config, new WebAppCertificateService(config, new CertificateServiceSettings() { UseIPBasedSSL = config.UseIPBasedSSL }), new AzureDnsAuthorizationChallengeProvider(dnsEnvironment)); var result = await mgr.RenewCertificate(renewXNumberOfDaysBeforeExpiration : 200); Assert.AreNotEqual(0, result.Count()); }
public static WebSiteManagementClient GetWebSiteManagementClient(IAuthSettings model) { var settings = new AppSettingsAuthConfig(); var authContext = new AuthenticationContext(settings.AuthenticationEndpoint + model.Tenant); var token = authContext.AcquireToken(settings.TokenAudience.ToString(), new ClientCredential(model.ClientId.ToString(), model.ClientSecret)); var creds = new TokenCredentials(token.AccessToken); var websiteClient = new WebSiteManagementClient(settings.ManagementEndpoint, creds); websiteClient.SubscriptionId = model.SubscriptionId.ToString(); return(websiteClient); }
/// <summary> /// For backwards compatability /// </summary> /// <param name="config"></param> public CertificateManager(AppSettingsAuthConfig config) { this.settings = config; this.acmeConfig = config; this.challengeProvider = new KuduFileSystemAuthorizationChallengeProvider(this.settings, new AuthorizationChallengeProviderConfig() { DisableWebConfigUpdate = config.DisableWebConfigUpdate }); this.certificateService = new CertificateService(this.settings, new CertificateServiceSettings() { UseIPBasedSSL = config.UseIPBasedSSL }); }
public IEnumerable <Target> RenewCertificate(bool debug = false) { Trace.TraceInformation("Checking certificate"); var settings = new AppSettingsAuthConfig(); var ss = SettingsStore.Instance.Load(); using (var client = ArmHelper.GetWebSiteManagementClient(settings)) { var certs = client.Certificates.GetCertificates(settings.ServicePlanResourceGroupName).Value; var expiringCerts = certs.Where(s => s.ExpirationDate < DateTime.UtcNow.AddDays(settings.RenewXNumberOfDaysBeforeExpiration) && (s.Issuer.Contains("Let's Encrypt") || s.Issuer.Contains("Fake LE"))); if (expiringCerts.Count() == 0) { Trace.TraceInformation(string.Format("No certificates installed issued by Let's Encrypt that are about to expire within the next {0} days. Skipping.", settings.RenewXNumberOfDaysBeforeExpiration)); } foreach (var toExpireCert in expiringCerts) { Trace.TraceInformation("Starting renew of certificate " + toExpireCert.Name + " expiration date " + toExpireCert.ExpirationDate); var site = client.Sites.GetSite(settings.ResourceGroupName, settings.WebAppName); var sslStates = site.HostNameSslStates.Where(s => s.Thumbprint == toExpireCert.Thumbprint); if (!sslStates.Any()) { Trace.TraceInformation(String.Format("Certificate {0} was not assigned any hostname, skipping update", toExpireCert.Thumbprint)); continue; } var target = new Target() { WebAppName = settings.WebAppName, Tenant = settings.Tenant, SubscriptionId = settings.SubscriptionId, ClientId = settings.ClientId, ClientSecret = settings.ClientSecret, ResourceGroupName = settings.ResourceGroupName, Email = settings.Email ?? ss.FirstOrDefault(s => s.Name == "email").Value, Host = sslStates.First().Name, BaseUri = settings.BaseUri ?? ss.FirstOrDefault(s => s.Name == "baseUri").Value, ServicePlanResourceGroupName = settings.ServicePlanResourceGroupName, AlternativeNames = sslStates.Skip(1).Select(s => s.Name).ToList(), UseIPBasedSSL = settings.UseIPBasedSSL, SiteSlotName = settings.SiteSlotName }; if (!debug) { RequestAndInstallInternal(target); } yield return(target); } } }
private void SetViewBagHostnames() { var settings = new AppSettingsAuthConfig(); var client = ArmHelper.GetWebSiteManagementClient(settings); var site = client.Sites.GetSiteOrSlot(settings.ResourceGroupName, settings.WebAppName, settings.SiteSlotName); var model = new HostnameModel(); ViewBag.HostNames = site.HostNames.Where(s => !s.EndsWith(settings.AzureWebSitesDefaultDomainName)).Select(s => new SelectListItem() { Text = s, Value = s }); }
public async Task RequestCertificateDnsChallengeTest() { var config = new AppSettingsAuthConfig(); var dnsEnvironment = new AzureDnsEnvironment(config.Tenant, new Guid("14fe4c66-c75a-4323-881b-ea53c1d86a9d"), config.ClientId, config.ClientSecret, "dns", "ai4bots.com", "@"); var res = await CertificateManager.RequestDnsChallengeCertificate(dnsEnvironment, new AcmeConfig() { Host = "ai4bots.com", PFXPassword = "******", RegistrationEmail = "*****@*****.**", RSAKeyLength = 2048 }); Assert.IsTrue(res.CertificateInfo.Certificate.Subject.Contains("ai4bots.com")); }
// Please set the following connection strings in app.config for this WebJob to run: // AzureWebJobsDashboard and AzureWebJobsStorage static void Main() { var config = new JobHostConfiguration(); config.UseTimers(); //A host ID must be between 1 and 32 characters, contain only lowercase letters, numbers, and //dashes, not start or end with a dash, and not contain consecutive dashes. var environment = new AppSettingsAuthConfig(); var hostId = "le-" + environment.WebAppName + environment.SiteSlotName; config.HostId = hostId.Substring(0, hostId.Length > 32 ? 32 : hostId.Length).TrimEnd(new[] { '-' }).ToLower(); var host = new JobHost(config); host.RunAndBlock(); }
public async Task TestRenewCertificate() { var config = new AppSettingsAuthConfig(); var client = ArmHelper.GetWebSiteManagementClient(config); var kuduClient = KuduHelper.GetKuduClient(client, config); var res = await kuduClient.HttpClient.PostAsync("https://webappcfmv5fy7lcq7o-vnext.scm.azurewebsites.net/letsencrypt/api/certificates/renew?api-version=2017-09-01", new StringContent("")); Assert.AreEqual(System.Net.HttpStatusCode.OK, res.StatusCode); var model = JsonConvert.DeserializeObject <CertificateInstallModel[]>(await res.Content.ReadAsStringAsync()); Assert.AreEqual(1, model.Count()); File.WriteAllBytes(Path.GetFileName(model.First().CertificateInfo.Name), model.First().CertificateInfo.PfxCertificate); }
/// <summary> /// Used for automatic installation of hostnames bindings and certificate /// upon first installation on the site extension and if hostnames are specified in app settings /// </summary> public void SetupHostnameAndCertificate() { Trace.TraceInformation("Setup hostname and certificates"); var settings = new AppSettingsAuthConfig(); using (var client = ArmHelper.GetWebSiteManagementClient(settings)) { var s = client.Sites.GetSite(settings.ResourceGroupName, settings.WebAppName); foreach (var hostname in settings.Hostnames) { if (s.HostNames.Any(existingHostname => string.Equals(existingHostname, hostname, StringComparison.InvariantCultureIgnoreCase))) { Trace.TraceInformation("Hostname already configured skipping installation"); continue; } Trace.TraceInformation("Setting up hostname and lets encrypt certificate for " + hostname); client.Sites.CreateOrUpdateSiteOrSlotHostNameBinding(settings.ResourceGroupName, settings.WebAppName, settings.SiteSlotName, hostname, new HostNameBinding() { CustomHostNameDnsRecordType = CustomHostNameDnsRecordType.CName, HostNameType = HostNameType.Verified, SiteName = settings.WebAppName, Location = s.Location }); } if (settings.Hostnames.Any()) { RequestAndInstallInternal(new Target() { BaseUri = settings.BaseUri, ClientId = settings.ClientId, ClientSecret = settings.ClientSecret, Email = settings.Email, Host = settings.Hostnames.First(), ResourceGroupName = settings.ResourceGroupName, SubscriptionId = settings.SubscriptionId, Tenant = settings.Tenant, WebAppName = settings.WebAppName, ServicePlanResourceGroupName = settings.ServicePlanResourceGroupName, AlternativeNames = settings.Hostnames.Skip(1).ToList(), SiteSlotName = settings.SiteSlotName, UseIPBasedSSL = settings.UseIPBasedSSL }); } } }
public ActionResult Install(RequestAndInstallModel model) { if (ModelState.IsValid) { var s = SettingsStore.Instance.Load(); s.Add(new LetsEncrypt.SiteExtension.Models.SettingEntry() { Name = "email", Value = model.Email }); var baseUri = model.UseStaging == false ? "https://acme-v01.api.letsencrypt.org/" : "https://acme-staging.api.letsencrypt.org/"; s.Add(new LetsEncrypt.SiteExtension.Models.SettingEntry() { Name = "baseUri", Value = baseUri }); SettingsStore.Instance.Save(s); var settings = new AppSettingsAuthConfig(); var target = new Target() { ClientId = settings.ClientId, ClientSecret = settings.ClientSecret, Email = model.Email, Host = model.Hostnames.First(), WebAppName = settings.WebAppName, SiteSlotName = settings.SiteSlotName, ResourceGroupName = settings.ResourceGroupName, SubscriptionId = settings.SubscriptionId, Tenant = settings.Tenant, BaseUri = baseUri, ServicePlanResourceGroupName = settings.ServicePlanResourceGroupName, AlternativeNames = model.Hostnames.Skip(1).ToList(), UseIPBasedSSL = settings.UseIPBasedSSL }; var thumbprint = CertificateManager.RequestAndInstallInternal(target); if (thumbprint != null) { return(RedirectToAction("Hostname", new { id = thumbprint })); } } SetViewBagHostnames(); return(View(model)); }
public async Task <ActionResult> AddHostname() { var settings = new AppSettingsAuthConfig(); using (var client = await ArmHelper.GetWebSiteManagementClient(settings)) { var s = client.WebApps.GetSiteOrSlot(settings.ResourceGroupName, settings.WebAppName, settings.SiteSlotName); foreach (var hostname in settings.Hostnames) { client.WebApps.CreateOrUpdateSiteOrSlotHostNameBinding(settings.ResourceGroupName, settings.WebAppName, settings.SiteSlotName, hostname, new HostNameBinding { CustomHostNameDnsRecordType = CustomHostNameDnsRecordType.CName, HostNameType = HostNameType.Verified, SiteName = settings.WebAppName, }); } } return(View()); }
public ActionResult Hostname(string id) { var settings = new AppSettingsAuthConfig(); var client = ArmHelper.GetWebSiteManagementClient(settings); var site = client.Sites.GetSite(settings.ResourceGroupName, settings.WebAppName); var model = new HostnameModel(); model.HostNames = site.HostNames; model.HostNameSslStates = site.HostNameSslStates; model.Certificates = client.Certificates.GetCertificates(settings.ServicePlanResourceGroupName).Value; model.InstalledCertificateThumbprint = id; if (model.HostNames.Count == 1) { model.ErrorMessage = "No custom host names registered. At least one custom domain name must be registed for the web site to request a letsencrypt certificate."; } return(View(model)); }
public async Task AddCertificateDnsChallengeTest() { var config = new AppSettingsAuthConfig(); var dnsEnvironment = new AzureDnsEnvironment(config.Tenant, new Guid("14fe4c66-c75a-4323-881b-ea53c1d86a9d"), config.ClientId, config.ClientSecret, "dns", "ai4bots.com", "letsencrypt"); var mgr = new CertificateManager(config, new AcmeConfig() { Host = "letsencrypt.ai4bots.com", PFXPassword = "******", RegistrationEmail = "*****@*****.**", RSAKeyLength = 2048 }, new WebAppCertificateService(config, new CertificateServiceSettings() { UseIPBasedSSL = config.UseIPBasedSSL }), new AzureDnsAuthorizationChallengeProvider(dnsEnvironment)); var result = await mgr.AddCertificate(); Assert.IsNotNull(result); }
public ActionResult AddHostname() { var settings = new AppSettingsAuthConfig(); using (var client = ArmHelper.GetWebSiteManagementClient(settings)) { var s = client.Sites.GetSite(settings.ResourceGroupName, settings.WebAppName); foreach (var hostname in settings.Hostnames) { client.Sites.CreateOrUpdateSiteHostNameBinding(settings.ResourceGroupName, settings.WebAppName, hostname, new Microsoft.Azure.Management.WebSites.Models.HostNameBinding() { CustomHostNameDnsRecordType = Microsoft.Azure.Management.WebSites.Models.CustomHostNameDnsRecordType.CName, HostNameType = Microsoft.Azure.Management.WebSites.Models.HostNameType.Verified, SiteName = settings.WebAppName, Location = s.Location }); } } return(View()); }
public async Task GetPublishingCredentials() { var model = new AppSettingsAuthConfig(); var helper = ArmHelper.GetWebSiteManagementClient(model); var kuduClient = KuduHelper.GetKuduClient(helper, model); //var res = await kuduClient.GetScmInfo(); var dir = await kuduClient.GetFile("site/wwwroot/host.json"); using (var ms = new MemoryStream()) { var sw = new StreamWriter(ms); sw.WriteLine("Hell asd asd asd "); sw.Flush(); await kuduClient.PutFile("site/wwwroot/.well-known/acme-challenge2/test.json", ms); } }